From 57f0e27186b86b12af2952ff13303894693a8240 Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Tue, 9 Apr 2019 06:43:08 +0200 Subject: [PATCH 1/8] parsing only for tests --- src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index f6bd06a5..e03bd5e1 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -195,7 +195,7 @@ public class ZUGFeRDImporter { /** * needs to be called to be able to call the getters */ - public void parse() { + protected void parse() { DocumentBuilderFactory factory = null; DocumentBuilder builder = null; Document document = null; From e60105f8b7a1e698acb970b0ea8e838d1d8d2868 Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Tue, 9 Apr 2019 07:03:56 +0200 Subject: [PATCH 2/8] use Constructores with parameters --- .../ZUGFeRD/ZUGFeRDImporter.java | 66 ++++++++++--------- .../ZUGFeRD/ZUGFeRDImporterException.java | 23 +++++++ .../mustangproject/toecount/FileChecker.java | 3 +- .../org/mustangproject/toecount/Toecount.java | 3 +- .../MustangReaderWriterCustomXMLTest.java | 10 ++- .../ZUGFeRD/MustangReaderWriterEdgeTest.java | 11 ++-- .../ZUGFeRD/MustangReaderWriterTest.java | 21 ++---- 7 files changed, 74 insertions(+), 63 deletions(-) create mode 100644 src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporterException.java diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index e03bd5e1..8a63b603 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -44,11 +44,13 @@ import java.io.*; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Scanner; import java.util.logging.Logger; //root.setNamespace(Namespace.getNamespace("http://www.energystar.gov/manageBldgs/req")); public class ZUGFeRDImporter { + /* * call extract(importFilename). containsMeta() will return if ZUGFeRD data has * been found, afterwards you can call getBIC(), getIBAN() etc. @@ -77,42 +79,28 @@ public class ZUGFeRDImporter { private byte[] rawXML = null; private String bankName; private boolean amountFound; - private boolean extractAttempt = false; private boolean parsed = false; private String xmpString = null; // XMP metadata private static final Logger LOG = Logger.getLogger(ZUGFeRDImporter.class.getName()); - /** - * Extracts a ZUGFeRD invoice from a PDF document represented by a file name. - * Errors are just logged to STDOUT. - * - * @param pdfFilename the filename of the pdf - */ - public void extract(String pdfFilename) { + public ZUGFeRDImporter(String pdfFilename) { try { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFilename)); - extractLowLevel(bis); bis.close(); - } catch (IOException ioe) { - ioe.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + throw new ZUGFeRDExportException(e); } } - static String convertStreamToString(java.io.InputStream is) { - // source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to - // https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks - java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; - } - - /** - * get xmp metadata of the PDF, null if not available - * - * @return string - */ - public String getXMP() { - return xmpString; + public ZUGFeRDImporter(InputStream pdfStream) { + try { + extractLowLevel(pdfStream); + } catch (IOException e) { + e.printStackTrace(); + throw new ZUGFeRDExportException(e); + } } /** @@ -121,9 +109,7 @@ public class ZUGFeRDImporter { * * @param pdfStream a inputstream of a pdf file */ - public void extractLowLevel(InputStream pdfStream) throws IOException { - PDEmbeddedFilesNameTreeNode etn; - extractAttempt = true; + private void extractLowLevel(InputStream pdfStream) throws IOException { try (PDDocument doc = PDDocument.load(pdfStream)) { // PDDocumentInformation info = doc.getDocumentInformation(); PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); @@ -131,7 +117,8 @@ public class ZUGFeRDImporter { InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); xmpString = convertStreamToString(XMP); - etn = names.getEmbeddedFiles(); + + PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); if (etn == null) { return; } @@ -200,9 +187,6 @@ public class ZUGFeRDImporter { DocumentBuilder builder = null; Document document = null; - if (!extractAttempt) { - throw new RuntimeException("extract() or extractLowLevel() must be used before parsing."); - } if (!containsMeta) { throw new RuntimeException("No suitable data/ZUGFeRD file could be found."); } @@ -376,6 +360,16 @@ public class ZUGFeRDImporter { parsed = true; } + /** + * get xmp metadata of the PDF, null if not available + * + * @return string + */ + public String getXMP() { + return xmpString; + } + + /** * @return if export found parseable ZUGFeRD data */ @@ -604,4 +598,12 @@ public class ZUGFeRDImporter { return (meta != null) && (meta.length() > 0) && ((meta.contains("SpecifiedExchangedDocumentContext") //$NON-NLS-1$ /* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */)); } + + static String convertStreamToString(java.io.InputStream is) { + // source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to + // https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks + Scanner s = new Scanner(is).useDelimiter("\\A"); + return s.hasNext() ? s.next() : ""; + } + } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporterException.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporterException.java new file mode 100644 index 00000000..a1ea969f --- /dev/null +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporterException.java @@ -0,0 +1,23 @@ +/** ********************************************************************** + * + * Copyright 2019 ak on 09.04.19. + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ +package org.mustangproject.ZUGFeRD; + +public class ZUGFeRDImporterException extends RuntimeException { + +} diff --git a/src/main/java/org/mustangproject/toecount/FileChecker.java b/src/main/java/org/mustangproject/toecount/FileChecker.java index 26142289..9ad2a9d2 100755 --- a/src/main/java/org/mustangproject/toecount/FileChecker.java +++ b/src/main/java/org/mustangproject/toecount/FileChecker.java @@ -49,9 +49,8 @@ public class FileChecker { if ((!isPDF) && (!thisRun.shallIgnoreFileExt())) { return false; } - ZUGFeRDImporter zi = new ZUGFeRDImporter(); + ZUGFeRDImporter zi = new ZUGFeRDImporter(filename); try { - zi.extract(filename); if (zi.canParse()) { thisRun.incZUGFeRDCount(); return true; diff --git a/src/main/java/org/mustangproject/toecount/Toecount.java b/src/main/java/org/mustangproject/toecount/Toecount.java index 6ae88e3d..2cf1c3b3 100755 --- a/src/main/java/org/mustangproject/toecount/Toecount.java +++ b/src/main/java/org/mustangproject/toecount/Toecount.java @@ -406,8 +406,7 @@ public class Toecount { ensureFileNotExists(xmlName); // All params are good! continue... - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extract(pdfName); + ZUGFeRDImporter zi = new ZUGFeRDImporter(pdfName); byte[] XMLContent = zi.getRawXML(); if (XMLContent == null) { System.err.println("No ZUGFeRD XML found in PDF file"); diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java index 6a69321f..44474c38 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java @@ -272,10 +272,9 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { } // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extract(TARGET_PDF); - // Reading ZUGFeRD + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // Reading ZUGFeRD String amount = null; String bic = null; String blz = null; @@ -474,10 +473,9 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { } // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extract(TARGET_PDF); - // Reading ZUGFeRD + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // Reading ZUGFeRD String amount = null; String bic = null; String blz = null; diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index 29c29d51..6af0cfe8 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -336,10 +336,10 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp */ public void testAImport() throws IOException { - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extractLowLevel(this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf")); - // Reading ZUGFeRD + InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf"); + ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); + // Reading ZUGFeRD String amount = null; String bic = null; String blz = null; @@ -401,10 +401,9 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp } // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extract(TARGET_PDF); - // Reading ZUGFeRD + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // Reading ZUGFeRD String amount = null; String bic = null; String blz = null; diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index 469ec565..320e853d 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -346,14 +346,10 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta */ public void testAImport() throws IOException { - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - try (InputStream inputStream = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf")) { - zi.extractLowLevel(inputStream); - } + InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf"); + ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); // Reading ZUGFeRD - String amount = null; String blz = null; String bic = null; @@ -384,14 +380,10 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta } public void testForeignImport() throws IOException { - ZUGFeRDImporter zi = new ZUGFeRDImporter(); + InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf"); + ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); - try (InputStream inputStream = this.getClass() - .getResourceAsStream("/zugferd_invoice.pdf")) { - zi.extractLowLevel(inputStream); - } // Reading ZUGFeRD - String amount = zi.getAmount(); assertEquals("\n" + @@ -522,10 +514,9 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta } // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extract(TARGET_PDF); - // Reading ZUGFeRD + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // Reading ZUGFeRD String amount = null; String bic = null; String iban = null; From e2e957a45058c4105454ca79ab973bfe12b4838d Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Tue, 9 Apr 2019 23:25:43 +0200 Subject: [PATCH 3/8] refactoring Importer --- .../ZUGFeRD/ZUGFeRDImporter.java | 452 ++++-------------- .../MustangReaderWriterCustomXMLTest.java | 77 +-- .../ZUGFeRD/MustangReaderWriterEdgeTest.java | 72 +-- .../ZUGFeRD/MustangReaderWriterTest.java | 30 +- 4 files changed, 139 insertions(+), 492 deletions(-) diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 8a63b603..9ea0b067 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -33,30 +33,22 @@ import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.*; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; import java.io.*; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.logging.Logger; - -//root.setNamespace(Namespace.getNamespace("http://www.energystar.gov/manageBldgs/req")); +import java.util.*; public class ZUGFeRDImporter { - /* - * call extract(importFilename). containsMeta() will return if ZUGFeRD data has - * been found, afterwards you can call getBIC(), getIBAN() etc. - * - */ - /** * @var if metadata has been found */ @@ -64,24 +56,12 @@ public class ZUGFeRDImporter { /** * @var the reference (i.e. invoice number) of the sender */ - private String foreignReference; - private String BLZ; - private String BIC; - private String IBAN; - private String KTO; - private String holder; - private String amount; - private String dueDate; - private HashMap additionalXMLs = new HashMap(); + private HashMap additionalXMLs = new HashMap<>(); /** * Raw XML form of the extracted data - may be directly obtained. */ private byte[] rawXML = null; - private String bankName; - private boolean amountFound; - private boolean parsed = false; private String xmpString = null; // XMP metadata - private static final Logger LOG = Logger.getLogger(ZUGFeRDImporter.class.getName()); public ZUGFeRDImporter(String pdfFilename) { try { @@ -175,189 +155,112 @@ public class ZUGFeRDImporter { } } - public HashMap getAdditionalData() { - return additionalXMLs; + private void prettyPrint(Document document) throws TransformerException { + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = null; + try { + transformer = tf.newTransformer(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + StringWriter writer = new StringWriter(); + transformer.transform(new DOMSource(document), new StreamResult(writer)); + String output = writer.getBuffer().toString();//.replaceAll("\n|\r", ""); + System.err.println(output); + } + + private Document getDocument() throws ParserConfigurationException, IOException, SAXException, TransformerException { + DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); + xmlFact.setNamespaceAware(false); + DocumentBuilder builder = xmlFact.newDocumentBuilder(); + Document doc = builder.parse(new ByteArrayInputStream(rawXML)); + //prettyPrint(doc); + return doc; + } + + private String extractString(String xpathStr) { + if (!containsMeta) { + throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); + } + String result; + try { + Document document = getDocument(); + XPathFactory xpathFact = XPathFactory.newInstance(); + XPath xpath = xpathFact.newXPath(); + result = xpath.evaluate(xpathStr, document); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + throw new ZUGFeRDExportException(e); + } catch (IOException | SAXException | TransformerException | XPathExpressionException e) { + e.printStackTrace(); + throw new ZUGFeRDExportException(e); + } + return result; } /** - * needs to be called to be able to call the getters + * @return the reference (purpose) the sender specified for this invoice */ - protected void parse() { - DocumentBuilderFactory factory = null; - DocumentBuilder builder = null; - Document document = null; + public String getForeignReference() { + String result = extractString("//ApplicableHeaderTradeSettlement/PaymentReference"); + if(result == null || result.isEmpty()) + result = extractString("//ApplicableSupplyChainTradeSettlement/PaymentReference"); + return result; + } - if (!containsMeta) { - throw new RuntimeException("No suitable data/ZUGFeRD file could be found."); - } + /** + * @return the sender's bank's BLZ code + */ + public String getBLZ() { + return extractString("//PayeeSpecifiedCreditorFinancialInstitution/GermanBankleitzahlID"); + } - factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use - // document.getElementsByTagNameNS("*",... - try { - builder = factory.newDocumentBuilder(); - } catch (ParserConfigurationException ex3) { - // TODO Auto-generated catch block - ex3.printStackTrace(); - } + /** + * @return the sender's bank's BIC code + */ + public String getBIC() { + return extractString("//PayeeSpecifiedCreditorFinancialInstitution/BICID"); + } - try { - InputStream bais = new ByteArrayInputStream(rawXML); - document = builder.parse(bais); - } catch (SAXException ex1) { - ex1.printStackTrace(); - } catch (IOException ex2) { - ex2.printStackTrace(); - } - NodeList ndList; + /** + * @return the sender's bankname + */ + public String getBankName() { + return extractString("/CrossIndustryInvoice/SupplyChainTradeTransaction/ApplicableHeaderTradeSettlement/SpecifiedTradeSettlementPaymentMeans/PayeeSpecifiedCreditorFinancialInstitution/Name"); + } - // rootNode = document.getDocumentElement(); - // ApplicableSupplyChainTradeSettlement - ndList = document.getDocumentElement().getElementsByTagNameNS("*", "PaymentReference"); //$NON-NLS-1$ + public String getIBAN() { + return extractString("//PayeePartyCreditorFinancialAccount/IBANID"); + } - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - Node booking = ndList.item(bookingIndex); - // if there is a attribute in the tag number:value + public String getKTO() { + return extractString("//PayeePartyCreditorFinancialAccount/ProprietaryID"); + } - setForeignReference(booking.getTextContent()); + public String getHolder() { + return extractString("//SellerTradeParty/Name"); + } - } - /* - * ndList = document .getElementsByTagName("GermanBankleitzahlID"); - * //$NON-NLS-1$ - * - * for (int bookingIndex = 0; bookingIndex < ndList .getLength(); - * bookingIndex++) { Node booking = ndList.item(bookingIndex); // if there is a - * attribute in the tag number:value setBIC(booking.getTextContent()); - * - * } - * - * ndList = document.getElementsByTagName("ProprietaryID"); //$NON-NLS-1$ - * - * for (int bookingIndex = 0; bookingIndex < ndList .getLength(); - * bookingIndex++) { Node booking = ndList.item(bookingIndex); // if there is a - * attribute in the tag number:value setIBAN(booking.getTextContent()); - * - * } DE1234 - * - * - * DE5656565 Commerzbank - * - * - */ + /** + * @return the total payable amount + */ + public String getAmount() { + String result = extractString("//SpecifiedTradeSettlementHeaderMonetarySummation/DuePayableAmount"); + if(result == null || result.isEmpty()) + result = extractString("//SpecifiedTradeSettlementMonetarySummation/GrandTotalAmount"); + return result; + } - /*** - * we should switch to xpath like this // Create XPathFactory object - * XPathFactory xpathFactory = XPathFactory.newInstance(); - * - * // Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression - * expr = - * xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]"); - * //evaluate expression result on XML document ndList = (NodeList) - * expr.evaluate(doc, XPathConstants.NODESET); - * - */ + /** + * @return when the payment is due + */ + public String getDueDate() { + return extractString("//SpecifiedTradePaymentTerms/DueDateDateTime/DateTimeString"); + } - ndList = document.getElementsByTagNameNS("*", "PayeePartyCreditorFinancialAccount"); //$NON-NLS-1$ - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - - Node booking = ndList.item(bookingIndex); - // there are many "name" elements, so get the one below - // SellerTradeParty - NodeList bookingDetails = booking.getChildNodes(); - - for (int detailIndex = 0; detailIndex < bookingDetails.getLength(); detailIndex++) { - Node detail = bookingDetails.item(detailIndex); - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("IBANID"))) { //$NON-NLS-1$ - setIBAN(detail.getTextContent()); - } - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("ProprietaryID"))) { //$NON-NLS-1$ - setKTO(detail.getTextContent()); - - } - } - - } - ndList = document.getElementsByTagNameNS("*", "PayeeSpecifiedCreditorFinancialInstitution");// ZF1 //$NON-NLS-1$ - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - Node booking = ndList.item(bookingIndex); - // there are many "name" elements, so get the one below - // SellerTradeParty - NodeList bookingDetails = booking.getChildNodes(); - for (int detailIndex = 0; detailIndex < bookingDetails.getLength(); detailIndex++) { - Node detail = bookingDetails.item(detailIndex); - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("BICID"))) { //$NON-NLS-1$ - setBIC(detail.getTextContent()); - } - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("GermanBankleitzahlID"))) { //$NON-NLS-1$ - setBLZ(detail.getTextContent()); - } - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("Name"))) { //$NON-NLS-1$ - setBankName(detail.getTextContent()); - } - } - - } - - ndList = document.getElementsByTagNameNS("*", "SellerTradeParty"); //$NON-NLS-1$ - - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - Node booking = ndList.item(bookingIndex); - // there are many "name" elements, so get the one below - // SellerTradeParty - NodeList bookingDetails = booking.getChildNodes(); - for (int detailIndex = 0; detailIndex < bookingDetails.getLength(); detailIndex++) { - Node detail = bookingDetails.item(detailIndex); - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("Name"))) { //$NON-NLS-1$ - setHolder(detail.getTextContent()); - } - } - - } - - ndList = document.getElementsByTagNameNS("*", "DuePayableAmount"); //$NON-NLS-1$ - - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - Node booking = ndList.item(bookingIndex); - // if there is a attribute in the tag number:value - amountFound = true; - setAmount(booking.getTextContent()); - - } - - if (!amountFound) { - /* - * there is apparently no requirement to mention DuePayableAmount,, if it's not - * there, check for GrandTotalAmount - */ - ndList = document.getElementsByTagNameNS("*", "GrandTotalAmount"); //$NON-NLS-1$ - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - Node booking = ndList.item(bookingIndex); - // if there is a attribute in the tag number:value - amountFound = true; - setAmount(booking.getTextContent()); - - } - - } - - ndList = document.getElementsByTagNameNS("*", "SpecifiedTradePaymentTerms"); //$NON-NLS-1$ - - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - Node booking = ndList.item(bookingIndex); - // there are many "name" elements, so get the one below - // SellerTradeParty - NodeList bookingDetails = booking.getChildNodes(); - for (int detailIndex = 0; detailIndex < bookingDetails.getLength(); detailIndex++) { - Node detail = bookingDetails.item(detailIndex); - if ((detail.getLocalName() != null) && (detail.getLocalName().equals("DueDateDateTime"))) { //$NON-NLS-1$ - setDueDate(detail.getTextContent().trim()); - } - } - - } - - parsed = true; + public HashMap getAdditionalData() { + return additionalXMLs; } /** @@ -377,159 +280,6 @@ public class ZUGFeRDImporter { return containsMeta; } - /** - * @return the reference (purpose) the sender specified for this invoice - */ - public String getForeignReference() { - if (!parsed) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (foreignReference == null) { - parse(); - } - return foreignReference; - } - - private void setForeignReference(String foreignReference) { - this.foreignReference = foreignReference; - } - - /** - * @return the sender's bank's BLZ code - */ - public String getBLZ() { - if (!parsed) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (BLZ == null) { - parse(); - } - return BLZ; - } - - private void setBLZ(String blz) { - this.BLZ = blz; - } - - /** - * @return the sender's bank's BIC code - */ - public String getBIC() { - if (!parsed) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (BIC == null) { - parse(); - } - return BIC; - } - - private void setBIC(String bic) { - this.BIC = bic; - } - - private void setDueDate(String dueDate) { - this.dueDate = dueDate; - } - - private void setBankName(String bankname) { - this.bankName = bankname; - } - - /** - * @return the sender's IBAN - */ - public String getIBAN() { - if (!parsed) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (IBAN == null) { - parse(); - } - return IBAN; - } - - /** - * @return the sender's KTO - */ - public String getKTO() { - if (!parsed) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (KTO == null) { - parse(); - } - return KTO; - } - - /** - * @return the sender's bank name - */ - public String getBankName() { - if (!parsed) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (bankName == null) { - parse(); - } - return bankName; - } - - private void setIBAN(String IBAN) { - this.IBAN = IBAN; - } - - private void setKTO(String KTO) { - this.KTO = KTO; - } - - /** - * @return the name of the owner of the sender's bank account - */ - public String getHolder() { - if (rawXML == null) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (holder == null) { - parse(); - } - return holder; - } - - private void setHolder(String holder) { - this.holder = holder; - } - - /** - * @return the total payable amount - */ - public String getAmount() { - if (rawXML == null) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (amount == null) { - parse(); - } - return amount; - } - - /** - * @return when the payment is due - */ - public String getDueDate() { - if (rawXML == null) { - throw new RuntimeException("use extract() before requesting a value"); - } - if (dueDate == null) { - parse(); - } - return dueDate; - } - - private void setAmount(String amount) { - this.amount = amount; - } - /** * @param meta raw XML to be set */ diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java index 44474c38..07b03609 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterCustomXMLTest.java @@ -55,14 +55,12 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { // the writing part try { - InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931) .load(SOURCE_PDF); - final byte[] UTF8ByteOrderMark = new byte[]{(byte) 0xef, (byte) 0xbb, - (byte) 0xbf}; + final byte[] UTF8ByteOrderMark = new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf}; /* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */ String ownZUGFeRDXML = new String(UTF8ByteOrderMark) + "\n" + "\n" + @@ -267,7 +265,6 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { assertFalse(pdfContent.indexOf("EN 16931") == -1); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } @@ -275,32 +272,13 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); // Reading ZUGFeRD - String amount = null; - String bic = null; - String blz = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - - if (zi.canParse()) { - zi.parse(); - amount = zi.getAmount(); - blz = zi.getBLZ(); - bic = zi.getBIC(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - ref = zi.getForeignReference(); - } - - assertEquals(amount, "571.04"); - assertEquals(blz, "41441604"); - assertEquals(bic, "COBADEFFXXX"); - assertEquals(iban, "DE88 2008 0000 0970 3757 00"); - assertEquals(kto, "44421800"); - assertEquals(holder, "Bei Spiel GmbH"); - assertEquals(ref, "RE-20171118/506"); + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBLZ(), "41441604"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getKTO(), "44421800"); + assertEquals(zi.getHolder(), "Bei Spiel GmbH"); + assertEquals(zi.getForeignReference(), "RE-20171118/506"); } /** @@ -317,8 +295,7 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { // the writing part try { - InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.BASIC) .load(SOURCE_PDF); @@ -468,7 +445,6 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { assertFalse(pdfContent.indexOf("BASIC") == -1); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } @@ -476,32 +452,13 @@ public class MustangReaderWriterCustomXMLTest extends TestCase { ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); // Reading ZUGFeRD - String amount = null; - String bic = null; - String blz = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - - if (zi.canParse()) { - zi.parse(); - amount = zi.getAmount(); - bic = zi.getBIC(); - blz = zi.getBLZ(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - ref = zi.getForeignReference(); - } - - assertEquals(amount, "571.04"); - assertEquals(bic, "COBADEFFXXX"); - assertEquals(blz, "41441604"); - assertEquals(iban, "DE88 2008 0000 0970 3757 00"); - assertEquals(kto, "44421800"); - assertEquals(holder, "Bei Spiel GmbH"); - assertEquals(ref, "RE-20170509/505"); + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getBLZ(), "41441604"); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getKTO(), "44421800"); + assertEquals(zi.getHolder(), "Bei Spiel GmbH"); + assertEquals(zi.getForeignReference(), "RE-20170509/505"); } } diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index 6af0cfe8..01b99312 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -340,36 +340,14 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); // Reading ZUGFeRD - String amount = null; - String bic = null; - String blz = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - String dueDate = null; - - if (zi.canParse()) { - zi.parse(); - amount = zi.getAmount(); - bic = zi.getBIC(); - blz = zi.getBLZ(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - dueDate = zi.getDueDate(); - ref = zi.getForeignReference(); - } - - assertEquals(amount, "571.04"); - assertEquals(bic, getOwnBIC()); - assertEquals(blz, getOwnBLZ()); - assertEquals(iban, getOwnIBAN()); - assertEquals(kto, getOwnKto()); - assertEquals(holder, getOwnOrganisationName()); - - assertEquals(dueDate, "20170530"); - assertEquals(ref, getNumber()); + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getOwnBIC()); + assertEquals(zi.getBLZ(), getOwnBLZ()); + assertEquals(zi.getIBAN(), getOwnIBAN()); + assertEquals(zi.getKTO(), getOwnKto()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getDueDate(), "20170530"); + assertEquals(zi.getForeignReference(), getNumber()); } @@ -404,33 +382,13 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); // Reading ZUGFeRD - String amount = null; - String bic = null; - String blz = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - - if (zi.canParse()) { - zi.parse(); - amount = zi.getAmount(); - bic = zi.getBIC(); - blz = zi.getBLZ(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - ref = zi.getForeignReference(); - } - - assertEquals(amount, "571.04"); - assertEquals(bic, getOwnBIC()); - assertEquals(blz, getOwnBLZ()); - assertEquals(iban, getOwnIBAN()); - assertEquals(kto, getOwnKto()); - assertEquals(holder, getOwnOrganisationName()); - assertEquals(ref, getNumber()); - + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getOwnBIC()); + assertEquals(zi.getBLZ(), getOwnBLZ()); + assertEquals(zi.getIBAN(), getOwnIBAN()); + assertEquals(zi.getKTO(), getOwnKto()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); } } diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index 320e853d..c6f98cf7 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -359,7 +359,6 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta String ref = null; if (zi.canParse()) { - zi.parse(); amount = zi.getAmount(); blz = zi.getBLZ(); bic = zi.getBIC(); @@ -517,29 +516,12 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); // Reading ZUGFeRD - String amount = null; - String bic = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - if (zi.canParse()) { - zi.parse(); - amount = zi.getAmount(); - bic = zi.getBIC(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - ref = zi.getForeignReference(); - } - - assertEquals(amount, "571.04"); - assertEquals(bic, getOwnBIC()); - assertEquals(iban, getOwnIBAN()); - assertEquals(kto, getOwnKto()); - assertEquals(holder, getOwnOrganisationName()); - assertEquals(ref, getNumber()); - + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getOwnBIC()); + assertEquals(zi.getIBAN(), getOwnIBAN()); + assertEquals(zi.getKTO(), getOwnKto()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); } /** From 1b015d3cee6db8af7cf8c3178beaeb24854b5cfb Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Tue, 9 Apr 2019 23:35:44 +0200 Subject: [PATCH 4/8] merge master --- .../ZUGFeRD/MustangReaderWriterTest.java | 35 +++++-------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index e2fdc9f1..066863c3 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -514,34 +514,17 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta } // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.extract(TARGET_PDF); + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // Reading ZUGFeRD - - String amount = null; - String bic = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - if (zi.canParse()) { - zi.parse(); - amount = zi.getAmount(); - bic = zi.getBIC(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - ref = zi.getForeignReference(); - } - - assertEquals(amount, "571.04"); - assertEquals(bic, getOwnBIC()); - assertEquals(iban, getOwnIBAN()); - assertEquals(kto, getOwnKto()); - assertEquals(holder, getOwnOrganisationName()); - assertEquals(ref, getNumber()); - + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getOwnBIC()); + assertEquals(zi.getIBAN(), getOwnIBAN()); + assertEquals(zi.getKTO(), getOwnKto()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); } + /* public void testFXExport() throws Exception { From 283e028d9e6183bc38a6abdea8465545dca485c1 Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Wed, 10 Apr 2019 15:10:53 +0200 Subject: [PATCH 5/8] use java8 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index e3773f75..650c1728 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ github -Xdoclint:none - 1.7 + 1.8 1.8 1.8 @@ -134,8 +134,8 @@ - 1.7 - 1.7 + 1.8 + 1.8 From 5ddd6f745eeff96e610dc66599d96aeb0a1d8c0c Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Wed, 10 Apr 2019 15:11:09 +0200 Subject: [PATCH 6/8] add document code --- .../IZUGFeRDExportableTransaction.java | 11 +++++++ .../ZUGFeRD/ZUGFeRDImporter.java | 7 ++++ .../ZUGFeRDTransactionModelConverter.java | 2 +- .../ZUGFeRD/MustangReaderWriterEdgeTest.java | 1 + .../ZUGFeRD/MustangReaderWriterTest.java | 33 ++++--------------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java index 44057afc..1c4c4dbc 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java @@ -27,10 +27,21 @@ package org.mustangproject.ZUGFeRD; * */ +import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; + import java.util.Date; public interface IZUGFeRDExportableTransaction { + /** + * + * + * @return Code of Document + */ + default String getDocumentCode() { + return DocumentCodeTypeConstants.INVOICE; + } + /** * Number, typically invoice number of the invoice * diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 9ea0b067..6b2a1acb 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -209,6 +209,13 @@ public class ZUGFeRDImporter { return result; } + /** + * @return the document code + */ + public String getDocumentCode() { + return extractString("//HeaderExchangedDocument/TypeCode"); + } + /** * @return the sender's bank's BLZ code */ diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java index e21fed1d..265c6f98 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java @@ -94,7 +94,7 @@ class ZUGFeRDTransactionModelConverter { document.setIssueDateTime(issueDateTime); DocumentCodeType documentCodeType = xmlFactory.createDocumentCodeType(); - documentCodeType.setValue(DocumentCodeTypeConstants.INVOICE); + documentCodeType.setValue(trans.getDocumentCode()); document.setTypeCode(documentCodeType); TextType name = xmlFactory.createTextType(); diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index 01b99312..84fd2fa3 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -348,6 +348,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getDueDate(), "20170530"); assertEquals(zi.getForeignReference(), getNumber()); + assertEquals(zi.getDocumentCode(), "380"); } diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index 066863c3..a041a7e8 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -350,32 +350,13 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); // Reading ZUGFeRD - String amount = null; - String blz = null; - String bic = null; - String iban = null; - String kto = null; - String holder = null; - String ref = null; - - if (zi.canParse()) { - amount = zi.getAmount(); - blz = zi.getBLZ(); - bic = zi.getBIC(); - iban = zi.getIBAN(); - kto = zi.getKTO(); - holder = zi.getHolder(); - ref = zi.getForeignReference(); - } - // this resembles the data written in MustangReaderWriterCustomXMLTest - assertEquals(amount, "571.04"); - assertEquals(blz, "41441604"); - assertEquals(bic, "COBADEFFXXX"); - assertEquals(iban, "DE88 2008 0000 0970 3757 00"); - assertEquals(kto, "44421800"); - assertEquals(holder, "Bei Spiel GmbH"); - assertEquals(ref, "RE-20170509/505"); - + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBLZ(), getOwnBLZ()); + assertEquals(zi.getBIC(), getOwnBIC()); + assertEquals(zi.getIBAN(), getOwnIBAN()); + assertEquals(zi.getKTO(), getOwnKto()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), "RE-20170509/505"); } public void testForeignImport() throws IOException { From 11bc7680fc7746e5f94ac72474b1213a5c3342fc Mon Sep 17 00:00:00 2001 From: Andre Kemper Date: Thu, 11 Apr 2019 07:44:09 +0200 Subject: [PATCH 7/8] use DocumentCode --- .../ZUGFeRD/IZUGFeRDAllowanceCharge.java | 7 ++ .../ZUGFeRD/IZUGFeRDExportableItem.java | 5 + .../org/mustangproject/ZUGFeRD/VATAmount.java | 17 +++- .../ZUGFeRD/ZUGFeRD2PullProvider.java | 6 +- .../ZUGFeRDTransactionModelConverter.java | 92 +++++++------------ 5 files changed, 62 insertions(+), 65 deletions(-) diff --git a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java index 36f0d428..667a4c78 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java @@ -15,16 +15,23 @@ */ package org.mustangproject.ZUGFeRD; +import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; + import java.math.BigDecimal; /** * @author AlexanderSchmidt */ public interface IZUGFeRDAllowanceCharge { + BigDecimal getTotalAmount(); String getReason(); BigDecimal getTaxPercent(); + default String getCategoryCode() { + return TaxCategoryCodeTypeConstants.STANDARDRATE; + } + } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java index d1b30732..85b0577d 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java @@ -26,6 +26,8 @@ package org.mustangproject.ZUGFeRD; * @author jstaerk * */ +import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; + import java.math.BigDecimal; public interface IZUGFeRDExportableItem { @@ -51,5 +53,8 @@ public interface IZUGFeRDExportableItem { */ BigDecimal getQuantity(); + default String getCategoryCode() { + return TaxCategoryCodeTypeConstants.STANDARDRATE; + } } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java b/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java index 32d180ca..408ea69f 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java @@ -31,14 +31,17 @@ import java.math.BigDecimal; */ public class VATAmount { - public VATAmount(BigDecimal basis, BigDecimal calculated) { + public VATAmount(BigDecimal basis, BigDecimal calculated, String documentCode) { super(); this.basis = basis; this.calculated = calculated; + this.documentCode = documentCode; } BigDecimal basis, calculated; + String documentCode; + public BigDecimal getBasis() { return basis; } @@ -55,12 +58,20 @@ public class VATAmount { this.calculated = calculated; } + public String getDocumentCode() { + return documentCode; + } + + public void setDocumentCode(String documentCode) { + this.documentCode = documentCode; + } + public VATAmount add(VATAmount v) { - return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated())); + return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.documentCode); } public VATAmount subtract(VATAmount v) { - return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated())); + return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated()), this.documentCode); } } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 2fb91343..52a77fe5 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -134,8 +134,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); res = res.add(amount.getCalculated()); } - - return res; } @@ -162,16 +160,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { BigDecimal percent = currentItem.getProduct().getVATPercent(); LineCalc lc = new LineCalc(currentItem); - VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount()); + VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), trans.getDocumentCode()); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); } else { hm.put(percent, current.add(itemVATAmount)); - } } - return hm; } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java index 265c6f98..8d087e8a 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java @@ -113,7 +113,7 @@ class ZUGFeRDTransactionModelConverter { document.getIncludedNote().add(regularInfo); } - if (trans.getReferenceNumber() != null && !new String().equals(trans.getReferenceNumber())) { + if (trans.getReferenceNumber() != null && !"".equals(trans.getReferenceNumber())) { NoteType referenceInfo = xmlFactory.createNoteType(); TextType referenceInfoContent = xmlFactory.createTextType(); referenceInfoContent.setValue("Ursprungsbeleg: " + trans.getReferenceNumber()); @@ -336,10 +336,9 @@ class ZUGFeRDTransactionModelConverter { } private Collection getTradeTax() { - List tradeTaxTypes = new ArrayList(); + List tradeTaxTypes = new ArrayList<>(); - HashMap VATPercentAmountMap = this - .getVATPercentAmountMap(); + HashMap VATPercentAmountMap = this.getVATPercentAmountMap(); for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); @@ -347,9 +346,9 @@ class ZUGFeRDTransactionModelConverter { taxTypeCode.setValue(TaxTypeCodeTypeConstants.SALESTAX); tradeTax.setTypeCode(taxTypeCode); - TaxCategoryCodeType taxCategoryCode = xmlFactory - .createTaxCategoryCodeType(); - taxCategoryCode.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE); + TaxCategoryCodeType taxCategoryCode = xmlFactory.createTaxCategoryCodeType(); + VATAmount vatAmount = VATPercentAmountMap.get(currentTaxPercent); + taxCategoryCode.setValue(vatAmount.getDocumentCode()); tradeTax.setCategoryCode(taxCategoryCode); VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); @@ -360,8 +359,7 @@ class ZUGFeRDTransactionModelConverter { AmountType calculatedTaxAmount = xmlFactory.createAmountType(); calculatedTaxAmount.setCurrencyID(currency); - calculatedTaxAmount - .setValue(currencyFormat(amount.getCalculated())); + calculatedTaxAmount.setValue(currencyFormat(amount.getCalculated())); tradeTax.getCalculatedAmount().add(calculatedTaxAmount); AmountType basisTaxAmount = xmlFactory.createAmountType(); @@ -376,13 +374,11 @@ class ZUGFeRDTransactionModelConverter { } private Collection getHeaderAllowances() { - List headerAllowances = new ArrayList(); + List headerAllowances = new ArrayList<>(); for (IZUGFeRDAllowanceCharge iAllowance : trans.getZFAllowances()) { - TradeAllowanceChargeType allowance = xmlFactory - .createTradeAllowanceChargeType(); - + TradeAllowanceChargeType allowance = xmlFactory.createTradeAllowanceChargeType(); IndicatorType chargeIndicator = xmlFactory.createIndicatorType(); chargeIndicator.setIndicator(false); allowance.setChargeIndicator(chargeIndicator); @@ -397,7 +393,6 @@ class ZUGFeRDTransactionModelConverter { allowance.setReason(reason); TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); - PercentType vatPercent = xmlFactory.createPercentType(); vatPercent.setValue(currencyFormat(iAllowance.getTaxPercent())); tradeTax.setApplicablePercent(vatPercent); @@ -409,9 +404,8 @@ class ZUGFeRDTransactionModelConverter { * basisAmount.setValue(amount.getBasis()); * allowance.setBasisAmount(basisAmount); */ - TaxCategoryCodeType taxType = xmlFactory - .createTaxCategoryCodeType(); - taxType.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE); + TaxCategoryCodeType taxType = xmlFactory.createTaxCategoryCodeType(); + taxType.setValue(iAllowance.getCategoryCode()); tradeTax.setCategoryCode(taxType); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); @@ -420,20 +414,17 @@ class ZUGFeRDTransactionModelConverter { allowance.getCategoryTradeTax().add(tradeTax); headerAllowances.add(allowance); - } return headerAllowances; } private Collection getHeaderCharges() { - List headerCharges = new ArrayList(); + List headerCharges = new ArrayList<>(); for (IZUGFeRDAllowanceCharge iCharge : trans.getZFCharges()) { - TradeAllowanceChargeType charge = xmlFactory - .createTradeAllowanceChargeType(); - + TradeAllowanceChargeType charge = xmlFactory.createTradeAllowanceChargeType(); IndicatorType chargeIndicator = xmlFactory.createIndicatorType(); chargeIndicator.setIndicator(true); charge.setChargeIndicator(chargeIndicator); @@ -448,7 +439,6 @@ class ZUGFeRDTransactionModelConverter { charge.setReason(reason); TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); - PercentType vatPercent = xmlFactory.createPercentType(); vatPercent.setValue(currencyFormat(iCharge.getTaxPercent())); tradeTax.setApplicablePercent(vatPercent); @@ -460,9 +450,8 @@ class ZUGFeRDTransactionModelConverter { * basisAmount.setValue(amount.getBasis()); * allowance.setBasisAmount(basisAmount); */ - TaxCategoryCodeType taxType = xmlFactory - .createTaxCategoryCodeType(); - taxType.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE); + TaxCategoryCodeType taxType = xmlFactory.createTaxCategoryCodeType(); + taxType.setValue(iCharge.getCategoryCode()); tradeTax.setCategoryCode(taxType); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); @@ -478,18 +467,15 @@ class ZUGFeRDTransactionModelConverter { } private Collection getHeaderLogisticsServiceCharges() { - List headerServiceCharge = new ArrayList(); + List headerServiceCharge = new ArrayList<>(); - for (IZUGFeRDAllowanceCharge iServiceCharge : trans - .getZFLogisticsServiceCharges()) { + for (IZUGFeRDAllowanceCharge iServiceCharge : trans.getZFLogisticsServiceCharges()) { - LogisticsServiceChargeType serviceCharge = xmlFactory - .createLogisticsServiceChargeType(); + LogisticsServiceChargeType serviceCharge = xmlFactory.createLogisticsServiceChargeType(); AmountType actualAmount = xmlFactory.createAmountType(); actualAmount.setCurrencyID(currency); - actualAmount.setValue(currencyFormat(iServiceCharge - .getTotalAmount())); + actualAmount.setValue(currencyFormat(iServiceCharge.getTotalAmount())); serviceCharge.getAppliedAmount().add(actualAmount); TextType reason = xmlFactory.createTextType(); @@ -509,9 +495,8 @@ class ZUGFeRDTransactionModelConverter { * basisAmount.setValue(amount.getBasis()); * allowance.setBasisAmount(basisAmount); */ - TaxCategoryCodeType taxType = xmlFactory - .createTaxCategoryCodeType(); - taxType.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE); + TaxCategoryCodeType taxType = xmlFactory.createTaxCategoryCodeType(); + taxType.setValue(iServiceCharge.getCategoryCode()); tradeTax.setCategoryCode(taxType); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); @@ -527,7 +512,7 @@ class ZUGFeRDTransactionModelConverter { } private Collection getPaymentTerms() { - List paymentTerms = new ArrayList(); + List paymentTerms = new ArrayList<>(); TradePaymentTermsType paymentTerm = xmlFactory .createTradePaymentTermsType(); @@ -632,7 +617,7 @@ class ZUGFeRDTransactionModelConverter { private Collection getLineItems() { - ArrayList lineItems = new ArrayList(); + ArrayList lineItems = new ArrayList<>(); int lineID = 0; for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { lineID++; @@ -734,9 +719,8 @@ class ZUGFeRDTransactionModelConverter { .createSupplyChainTradeSettlementType(); TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); - TaxCategoryCodeType taxCategoryCode = xmlFactory - .createTaxCategoryCodeType(); - taxCategoryCode.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE); + TaxCategoryCodeType taxCategoryCode = xmlFactory.createTaxCategoryCodeType(); + taxCategoryCode.setValue(currentItem.getCategoryCode()); tradeTax.setCategoryCode(taxCategoryCode); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); @@ -849,15 +833,13 @@ class ZUGFeRDTransactionModelConverter { return getVATPercentAmountMap(false); } - private HashMap getVATPercentAmountMap( - Boolean itemOnly) { - HashMap hm = new HashMap(); + private HashMap getVATPercentAmountMap(Boolean itemOnly) { + HashMap hm = new HashMap<>(); for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { BigDecimal percent = currentItem.getProduct().getVATPercent(); LineCalc lc = new LineCalc(currentItem); - VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), - lc.getItemTotalVATAmount()); + VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), trans.getDocumentCode()); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); @@ -869,13 +851,12 @@ class ZUGFeRDTransactionModelConverter { return hm; } if (trans.getZFAllowances() != null) { - for (IZUGFeRDAllowanceCharge headerAllowance : trans - .getZFAllowances()) { + for (IZUGFeRDAllowanceCharge headerAllowance : trans.getZFAllowances()) { BigDecimal percent = headerAllowance.getTaxPercent(); VATAmount itemVATAmount = new VATAmount( headerAllowance.getTotalAmount(), headerAllowance .getTotalAmount().multiply(percent) - .divide(new BigDecimal(100))); + .divide(new BigDecimal(100)), trans.getDocumentCode()); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); @@ -892,7 +873,7 @@ class ZUGFeRDTransactionModelConverter { VATAmount itemVATAmount = new VATAmount( logisticsServiceCharge.getTotalAmount(), logisticsServiceCharge.getTotalAmount() - .multiply(percent).divide(new BigDecimal(100))); + .multiply(percent).divide(new BigDecimal(100)), trans.getDocumentCode()); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); @@ -907,7 +888,7 @@ class ZUGFeRDTransactionModelConverter { BigDecimal percent = charge.getTaxPercent(); VATAmount itemVATAmount = new VATAmount( charge.getTotalAmount(), charge.getTotalAmount() - .multiply(percent).divide(new BigDecimal(100))); + .multiply(percent).divide(new BigDecimal(100)), trans.getDocumentCode()); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); @@ -1026,17 +1007,14 @@ class ZUGFeRDTransactionModelConverter { // Set total net amount this.totalNetAmount = res; - HashMap VATPercentAmountMap = getVATPercentAmountMap(); - for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); + HashMap vatAmountHashMap = getVATPercentAmountMap(); + for (VATAmount amount : vatAmountHashMap.values()) { res = res.add(amount.getCalculated()); } // Set total gross amount this.totalGrossAmount = res; - - this.totalTaxAmount = this.totalGrossAmount - .subtract(this.totalNetAmount); + this.totalTaxAmount = this.totalGrossAmount.subtract(this.totalNetAmount); } public BigDecimal getTotalNet() { From 9090095300c61ff57e8a6e50f07e241239bc2fd3 Mon Sep 17 00:00:00 2001 From: Pierre Barke Date: Thu, 11 Apr 2019 15:11:45 +0200 Subject: [PATCH 8/8] IZUGFeRDExportableTransaction: Interface-Methodes switched to default, so they don't have to be implementend in inheriting classes when not needed IZUGFeRDExportableContact: added getID() to return a unique customer ID assigned by the seller > BuyerTradeParty.ID ZUGFeRDTransactionModelConverter: getBuyer() and getSeller() adjusted. add ID to XML if available removed unnecessary this. and typecast --- .../ZUGFeRD/IZUGFeRDExportableContact.java | 19 +- .../IZUGFeRDExportableTransaction.java | 133 +++++++++---- .../ZUGFeRDTransactionModelConverter.java | 181 +++++++++++++----- 3 files changed, 252 insertions(+), 81 deletions(-) diff --git a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java index f03d7e5a..125852c8 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java @@ -19,9 +19,7 @@ package org.mustangproject.ZUGFeRD; /** - * Mustangproject's ZUGFeRD implementation - * Neccessary interface for ZUGFeRD exporter - * Licensed under the APLv2 + * Mustangproject's ZUGFeRD implementation Neccessary interface for ZUGFeRD exporter Licensed under the APLv2 * * @author jstaerk * @version 1.2.0 @@ -31,6 +29,16 @@ package org.mustangproject.ZUGFeRD; public interface IZUGFeRDExportableContact { + /** + * customer identification assigned by the seller + * + * @return customer identification + */ + default String getID() { + return null; + } + + /** * First and last name of the recipient * @@ -38,6 +46,7 @@ public interface IZUGFeRDExportableContact { */ String getName(); + /** * Postal code of the recipient * @@ -45,6 +54,7 @@ public interface IZUGFeRDExportableContact { */ String getZIP(); + /** * VAT ID (Umsatzsteueridentifikationsnummer) of the contact * @@ -52,6 +62,7 @@ public interface IZUGFeRDExportableContact { */ String getVATID(); + /** * two-letter country code of the contact * @@ -59,6 +70,7 @@ public interface IZUGFeRDExportableContact { */ String getCountry(); + /** * Returns the city of the contact * @@ -66,6 +78,7 @@ public interface IZUGFeRDExportableContact { */ String getLocation(); + /** * Returns the street address (street+number) of the contact * diff --git a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java index 44057afc..19bf8d98 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java @@ -36,46 +36,55 @@ public interface IZUGFeRDExportableTransaction { * * @return invoice number */ - String getNumber(); + default String getNumber() { + return null; + } + /** * the date when the invoice was created * * @return when the invoice was created */ - Date getIssueDate(); + default Date getIssueDate() { + return null; + } + /** - * this should be the full sender institution name, details, manager and tax registration. - * It is one of the few functions which may return null. - * e.g. + * this should be the full sender institution name, details, manager and tax registration. It is one of the few functions which may return null. e.g. *

- * Lieferant GmbH - * Lieferantenstraße 20 - * 80333 München - * Deutschland - * Geschäftsführer: Hans Muster - * Handelsregisternummer: H A 123 + * Lieferant GmbH Lieferantenstraße 20 80333 München Deutschland Geschäftsführer: Hans Muster Handelsregisternummer: H A 123 * * @return null or full sender institution name, details, manager and tax registration */ - String getOwnOrganisationFullPlaintextInfo(); + default String getOwnOrganisationFullPlaintextInfo() { + return null; + } + /** * when the invoice is to be paid * * @return when the invoice is to be paid */ - Date getDueDate(); + default Date getDueDate() { + return null; + } + IZUGFeRDAllowanceCharge[] getZFAllowances(); + IZUGFeRDAllowanceCharge[] getZFCharges(); + IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges(); + IZUGFeRDExportableItem[] getZFItems(); + /** * the recipient * @@ -83,89 +92,136 @@ public interface IZUGFeRDExportableTransaction { */ IZUGFeRDExportableContact getRecipient(); + /** * BIC of the sender * * @return the BIC code of the recipient sender's bank */ - String getOwnBIC(); + default String getOwnBIC() { + return null; + } + /** * BLZ of the sender * * @return the BLZ code of the recipient sender's bank */ - String getOwnBLZ(); + default String getOwnBLZ() { + return null; + } + /** * Bank name of the sender * * @return the name of the sender's bank */ - String getOwnBankName(); + default String getOwnBankName() { + return null; + } + /** * IBAN of the sender * * @return the IBAN of the invoice sender's bank account */ - String getOwnIBAN(); + default String getOwnIBAN() { + return null; + } + /** * IBAN of the sender * * @return the Account Number of the invoice sender's bank account */ - String getOwnKto(); + default String getOwnKto() { + return null; + } + /** * Tax ID (not VAT ID) of the sender * * @return Tax ID (not VAT ID) of the sender */ - String getOwnTaxID(); + default String getOwnTaxID() { + return null; + } + /** * VAT ID (Umsatzsteueridentifikationsnummer) of the sender * * @return VAT ID (Umsatzsteueridentifikationsnummer) of the sender */ - String getOwnVATID(); + default String getOwnVATID() { + return null; + } + + + /** + * supplier identification assigned by the costumer + * + * @return the sender's identification + */ + default String getOwnForeignOrganisationID() { + return null; + } + /** * own name * * @return the sender's organisation name */ - String getOwnOrganisationName(); + default String getOwnOrganisationName() { + return null; + } + /** * own street address * * @return sender street address */ - String getOwnStreet(); + default String getOwnStreet() { + return null; + } + /** * own street postal code * * @return sender postal code */ - String getOwnZIP(); + default String getOwnZIP() { + return null; + } + /** * own city * * @return the invoice sender's city */ - String getOwnLocation(); + default String getOwnLocation() { + return null; + } + /** * own two digit country code * * @return the invoice senders two character country iso code */ - String getOwnCountry(); + default String getOwnCountry() { + return null; + } + /** * get delivery date @@ -174,35 +230,44 @@ public interface IZUGFeRDExportableTransaction { */ Date getDeliveryDate(); + /** * get main invoice currency used on the invoice * * @return three character currency of this invoice */ - String getCurrency(); + default String getCurrency() { + return null; + } + /** * get payment information text. e.g. Bank transfer * * @return payment information text */ - String getOwnPaymentInfoText(); + default String getOwnPaymentInfoText() { + return null; + } + /** - * get payment term descriptional text - * e.g. Bis zum 22.10.2015 ohne Abzug + * get payment term descriptional text e.g. Bis zum 22.10.2015 ohne Abzug * * @return get payment terms */ - String getPaymentTermDescription(); + default String getPaymentTermDescription() { + return null; + } + /** - * get reference document number - * typically used for Invoice Corrections - * Will be added as IncludedNote in comfort profile + * get reference document number typically used for Invoice Corrections Will be added as IncludedNote in comfort profile * * @return the ID of the document this document refers to */ - String getReferenceNumber(); + default String getReferenceNumber() { + return null; + } } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java index e21fed1d..8fbc9b10 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java @@ -18,14 +18,65 @@ *********************************************************************** */ package org.mustangproject.ZUGFeRD; -import org.mustangproject.ZUGFeRD.model.*; - -import javax.xml.bind.JAXBElement; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +import javax.xml.bind.JAXBElement; + +import org.mustangproject.ZUGFeRD.model.AmountType; +import org.mustangproject.ZUGFeRD.model.CodeType; +import org.mustangproject.ZUGFeRD.model.CountryIDType; +import org.mustangproject.ZUGFeRD.model.CreditorFinancialAccountType; +import org.mustangproject.ZUGFeRD.model.CreditorFinancialInstitutionType; +import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType; +import org.mustangproject.ZUGFeRD.model.DateTimeType; +import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants; +import org.mustangproject.ZUGFeRD.model.DocumentCodeType; +import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; +import org.mustangproject.ZUGFeRD.model.DocumentContextParameterType; +import org.mustangproject.ZUGFeRD.model.DocumentContextParameterTypeConstants; +import org.mustangproject.ZUGFeRD.model.DocumentLineDocumentType; +import org.mustangproject.ZUGFeRD.model.ExchangedDocumentContextType; +import org.mustangproject.ZUGFeRD.model.ExchangedDocumentType; +import org.mustangproject.ZUGFeRD.model.IDType; +import org.mustangproject.ZUGFeRD.model.IndicatorType; +import org.mustangproject.ZUGFeRD.model.LogisticsServiceChargeType; +import org.mustangproject.ZUGFeRD.model.NoteType; +import org.mustangproject.ZUGFeRD.model.NoteTypeConstants; +import org.mustangproject.ZUGFeRD.model.ObjectFactory; +import org.mustangproject.ZUGFeRD.model.PaymentMeansCodeType; +import org.mustangproject.ZUGFeRD.model.PaymentMeansCodeTypeConstants; +import org.mustangproject.ZUGFeRD.model.PercentType; +import org.mustangproject.ZUGFeRD.model.QuantityType; +import org.mustangproject.ZUGFeRD.model.SupplyChainEventType; +import org.mustangproject.ZUGFeRD.model.SupplyChainTradeAgreementType; +import org.mustangproject.ZUGFeRD.model.SupplyChainTradeDeliveryType; +import org.mustangproject.ZUGFeRD.model.SupplyChainTradeLineItemType; +import org.mustangproject.ZUGFeRD.model.SupplyChainTradeSettlementType; +import org.mustangproject.ZUGFeRD.model.SupplyChainTradeTransactionType; +import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeType; +import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; +import org.mustangproject.ZUGFeRD.model.TaxRegistrationType; +import org.mustangproject.ZUGFeRD.model.TaxRegistrationTypeConstants; +import org.mustangproject.ZUGFeRD.model.TaxTypeCodeType; +import org.mustangproject.ZUGFeRD.model.TaxTypeCodeTypeConstants; +import org.mustangproject.ZUGFeRD.model.TextType; +import org.mustangproject.ZUGFeRD.model.TradeAddressType; +import org.mustangproject.ZUGFeRD.model.TradeAllowanceChargeType; +import org.mustangproject.ZUGFeRD.model.TradePartyType; +import org.mustangproject.ZUGFeRD.model.TradePaymentTermsType; +import org.mustangproject.ZUGFeRD.model.TradePriceType; +import org.mustangproject.ZUGFeRD.model.TradeProductType; +import org.mustangproject.ZUGFeRD.model.TradeSettlementMonetarySummationType; +import org.mustangproject.ZUGFeRD.model.TradeSettlementPaymentMeansType; +import org.mustangproject.ZUGFeRD.model.TradeTaxType; class ZUGFeRDTransactionModelConverter { private static final SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); @@ -36,10 +87,11 @@ class ZUGFeRDTransactionModelConverter { private boolean isTest; private String currency = "EUR"; + ZUGFeRDTransactionModelConverter(IZUGFeRDExportableTransaction trans) { this.trans = trans; totals = new Totals(); - this.currency = trans.getCurrency() != null ? trans.getCurrency() : currency; + currency = trans.getCurrency() != null ? trans.getCurrency() : currency; } @@ -47,15 +99,15 @@ class ZUGFeRDTransactionModelConverter { CrossIndustryDocumentType invoice = xmlFactory .createCrossIndustryDocumentType(); - invoice.setSpecifiedExchangedDocumentContext(this.getDocumentContext()); - invoice.setHeaderExchangedDocument(this.getDocument()); - invoice.setSpecifiedSupplyChainTradeTransaction(this - .getTradeTransaction()); + invoice.setSpecifiedExchangedDocumentContext(getDocumentContext()); + invoice.setHeaderExchangedDocument(getDocument()); + invoice.setSpecifiedSupplyChainTradeTransaction(getTradeTransaction()); return xmlFactory .createCrossIndustryDocument(invoice); } + private ExchangedDocumentContextType getDocumentContext() { ExchangedDocumentContextType context = xmlFactory @@ -75,6 +127,7 @@ class ZUGFeRDTransactionModelConverter { return context; } + private ExchangedDocumentType getDocument() { ExchangedDocumentType document = xmlFactory @@ -124,36 +177,44 @@ class ZUGFeRDTransactionModelConverter { return document; } + private SupplyChainTradeTransactionType getTradeTransaction() { SupplyChainTradeTransactionType transaction = xmlFactory .createSupplyChainTradeTransactionType(); transaction.getApplicableSupplyChainTradeAgreement().add( - this.getTradeAgreement()); - transaction.setApplicableSupplyChainTradeDelivery(this - .getTradeDelivery()); - transaction.setApplicableSupplyChainTradeSettlement(this - .getTradeSettlement()); + getTradeAgreement()); + transaction.setApplicableSupplyChainTradeDelivery(getTradeDelivery()); + transaction.setApplicableSupplyChainTradeSettlement(getTradeSettlement()); transaction.getIncludedSupplyChainTradeLineItem().addAll( - this.getLineItems()); + getLineItems()); return transaction; } + private SupplyChainTradeAgreementType getTradeAgreement() { SupplyChainTradeAgreementType tradeAgreement = xmlFactory .createSupplyChainTradeAgreementType(); - tradeAgreement.setBuyerTradeParty(this.getBuyer()); - tradeAgreement.setSellerTradeParty(this.getSeller()); + tradeAgreement.setBuyerTradeParty(getBuyer()); + tradeAgreement.setSellerTradeParty(getSeller()); return tradeAgreement; } + private TradePartyType getBuyer() { TradePartyType buyerTradeParty = xmlFactory.createTradePartyType(); + + if (trans.getRecipient().getID() != null) { + IDType buyerID = xmlFactory.createIDType(); + buyerID.setValue(trans.getRecipient().getID()); + buyerTradeParty.getID().add(buyerID); + } + TextType buyerName = xmlFactory.createTextType(); buyerName.setValue(trans.getRecipient().getName()); buyerTradeParty.setName(buyerName); @@ -189,9 +250,17 @@ class ZUGFeRDTransactionModelConverter { return buyerTradeParty; } + private TradePartyType getSeller() { TradePartyType sellerTradeParty = xmlFactory.createTradePartyType(); + + if (trans.getOwnForeignOrganisationID() != null) { + IDType sellerID = xmlFactory.createIDType(); + sellerID.setValue(trans.getOwnForeignOrganisationID()); + sellerTradeParty.getID().add(sellerID); + } + TextType sellerName = xmlFactory.createTextType(); sellerName.setValue(trans.getOwnOrganisationName()); sellerTradeParty.setName(sellerName); @@ -238,6 +307,7 @@ class ZUGFeRDTransactionModelConverter { return sellerTradeParty; } + private SupplyChainTradeDeliveryType getTradeDelivery() { SupplyChainTradeDeliveryType tradeDelivery = xmlFactory @@ -257,6 +327,7 @@ class ZUGFeRDTransactionModelConverter { return tradeDelivery; } + private SupplyChainTradeSettlementType getTradeSettlement() { SupplyChainTradeSettlementType tradeSettlement = xmlFactory .createSupplyChainTradeSettlementType(); @@ -270,29 +341,29 @@ class ZUGFeRDTransactionModelConverter { tradeSettlement.setInvoiceCurrencyCode(currencyCode); tradeSettlement.getSpecifiedTradeSettlementPaymentMeans().add( - this.getPaymentData()); - tradeSettlement.getApplicableTradeTax().addAll(this.getTradeTax()); + getPaymentData()); + tradeSettlement.getApplicableTradeTax().addAll(getTradeTax()); tradeSettlement.getSpecifiedTradePaymentTerms().addAll( - this.getPaymentTerms()); + getPaymentTerms()); if (trans.getZFAllowances() != null) { tradeSettlement.getSpecifiedTradeAllowanceCharge().addAll( - this.getHeaderAllowances()); + getHeaderAllowances()); } if (trans.getZFLogisticsServiceCharges() != null) { tradeSettlement.getSpecifiedLogisticsServiceCharge().addAll( - this.getHeaderLogisticsServiceCharges()); + getHeaderLogisticsServiceCharges()); } if (trans.getZFCharges() != null) { tradeSettlement.getSpecifiedTradeAllowanceCharge().addAll( - this.getHeaderCharges()); + getHeaderCharges()); } - tradeSettlement.setSpecifiedTradeSettlementMonetarySummation(this - .getMonetarySummation()); + tradeSettlement.setSpecifiedTradeSettlementMonetarySummation(getMonetarySummation()); return tradeSettlement; } + private TradeSettlementPaymentMeansType getPaymentData() { TradeSettlementPaymentMeansType paymentData = xmlFactory .createTradeSettlementPaymentMeansType(); @@ -335,8 +406,9 @@ class ZUGFeRDTransactionModelConverter { return paymentData; } + private Collection getTradeTax() { - List tradeTaxTypes = new ArrayList(); + List tradeTaxTypes = new ArrayList<>(); HashMap VATPercentAmountMap = this .getVATPercentAmountMap(); @@ -375,8 +447,9 @@ class ZUGFeRDTransactionModelConverter { return tradeTaxTypes; } + private Collection getHeaderAllowances() { - List headerAllowances = new ArrayList(); + List headerAllowances = new ArrayList<>(); for (IZUGFeRDAllowanceCharge iAllowance : trans.getZFAllowances()) { @@ -426,8 +499,9 @@ class ZUGFeRDTransactionModelConverter { return headerAllowances; } + private Collection getHeaderCharges() { - List headerCharges = new ArrayList(); + List headerCharges = new ArrayList<>(); for (IZUGFeRDAllowanceCharge iCharge : trans.getZFCharges()) { @@ -477,8 +551,9 @@ class ZUGFeRDTransactionModelConverter { return headerCharges; } + private Collection getHeaderLogisticsServiceCharges() { - List headerServiceCharge = new ArrayList(); + List headerServiceCharge = new ArrayList<>(); for (IZUGFeRDAllowanceCharge iServiceCharge : trans .getZFLogisticsServiceCharges()) { @@ -526,8 +601,9 @@ class ZUGFeRDTransactionModelConverter { return headerServiceCharge; } + private Collection getPaymentTerms() { - List paymentTerms = new ArrayList(); + List paymentTerms = new ArrayList<>(); TradePaymentTermsType paymentTerm = xmlFactory .createTradePaymentTermsType(); @@ -553,6 +629,7 @@ class ZUGFeRDTransactionModelConverter { return paymentTerms; } + private TradeSettlementMonetarySummationType getMonetarySummation() { TradeSettlementMonetarySummationType monetarySummation = xmlFactory .createTradeSettlementMonetarySummationType(); @@ -630,9 +707,10 @@ class ZUGFeRDTransactionModelConverter { return monetarySummation; } + private Collection getLineItems() { - ArrayList lineItems = new ArrayList(); + ArrayList lineItems = new ArrayList<>(); int lineID = 0; for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { lineID++; @@ -777,22 +855,27 @@ class ZUGFeRDTransactionModelConverter { return lineItems; } + private BigDecimal vatFormat(BigDecimal value) { return nDigitFormat(value, 2); } + private BigDecimal currencyFormat(BigDecimal value) { return nDigitFormat(value, 2); } + private BigDecimal priceFormat(BigDecimal value) { return nDigitFormat(value, 4); } + private BigDecimal quantityFormat(BigDecimal value) { return nDigitFormat(value, 4); } + private BigDecimal nDigitFormat(BigDecimal value, int scale) { /* * I needed 123,45, locale independent.I tried @@ -837,11 +920,10 @@ class ZUGFeRDTransactionModelConverter { } + /** - * which taxes have been used with which amounts in this transaction, empty - * for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable to - * 19% VAT (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) - * 190 Eur + * which taxes have been used with which amounts in this transaction, empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable to 19% VAT + * (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) 190 Eur * * @return HashMap which taxes have been used with which amounts */ @@ -849,9 +931,10 @@ class ZUGFeRDTransactionModelConverter { return getVATPercentAmountMap(false); } + private HashMap getVATPercentAmountMap( Boolean itemOnly) { - HashMap hm = new HashMap(); + HashMap hm = new HashMap<>(); for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { BigDecimal percent = currentItem.getProduct().getVATPercent(); @@ -874,8 +957,8 @@ class ZUGFeRDTransactionModelConverter { BigDecimal percent = headerAllowance.getTaxPercent(); VATAmount itemVATAmount = new VATAmount( headerAllowance.getTotalAmount(), headerAllowance - .getTotalAmount().multiply(percent) - .divide(new BigDecimal(100))); + .getTotalAmount().multiply(percent) + .divide(new BigDecimal(100))); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); @@ -907,7 +990,7 @@ class ZUGFeRDTransactionModelConverter { BigDecimal percent = charge.getTaxPercent(); VATAmount itemVATAmount = new VATAmount( charge.getTotalAmount(), charge.getTotalAmount() - .multiply(percent).divide(new BigDecimal(100))); + .multiply(percent).divide(new BigDecimal(100))); VATAmount current = hm.get(percent); if (current == null) { hm.put(percent, itemVATAmount); @@ -920,6 +1003,7 @@ class ZUGFeRDTransactionModelConverter { return hm; } + ZUGFeRDTransactionModelConverter withTest(boolean isTest) { this.isTest = isTest; return this; @@ -932,6 +1016,7 @@ class ZUGFeRDTransactionModelConverter { private BigDecimal itemTotalVATAmount; private BigDecimal itemNetAmount; + public LineCalc(IZUGFeRDExportableItem currentItem) { BigDecimal totalAllowance = BigDecimal.ZERO; BigDecimal totalCharge = BigDecimal.ZERO; @@ -974,14 +1059,17 @@ class ZUGFeRDTransactionModelConverter { BigDecimal.ROUND_HALF_UP); } + public BigDecimal getItemTotalNetAmount() { return itemTotalNetAmount; } + public BigDecimal getItemTotalVATAmount() { return itemTotalVATAmount; } + public BigDecimal getItemNetAmount() { return itemNetAmount; } @@ -994,6 +1082,7 @@ class ZUGFeRDTransactionModelConverter { private BigDecimal lineTotalAmount; private BigDecimal totalTaxAmount; + public Totals() { BigDecimal res = BigDecimal.ZERO; for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { @@ -1001,7 +1090,7 @@ class ZUGFeRDTransactionModelConverter { res = res.add(lc.getItemTotalNetAmount()); } // Set line total - this.lineTotalAmount = res; + lineTotalAmount = res; if (trans.getZFAllowances() != null) { for (IZUGFeRDAllowanceCharge headerAllowance : trans @@ -1024,7 +1113,7 @@ class ZUGFeRDTransactionModelConverter { } // Set total net amount - this.totalNetAmount = res; + totalNetAmount = res; HashMap VATPercentAmountMap = getVATPercentAmountMap(); for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { @@ -1033,24 +1122,28 @@ class ZUGFeRDTransactionModelConverter { } // Set total gross amount - this.totalGrossAmount = res; + totalGrossAmount = res; - this.totalTaxAmount = this.totalGrossAmount - .subtract(this.totalNetAmount); + totalTaxAmount = totalGrossAmount + .subtract(totalNetAmount); } + public BigDecimal getTotalNet() { return totalNetAmount; } + public BigDecimal getTotalGross() { return totalGrossAmount; } + public BigDecimal getLineTotal() { return lineTotalAmount; } + public BigDecimal getTaxTotal() { return totalTaxAmount; }