diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 716f9019..28635a2f 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -634,8 +634,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if(trans.getTenderReferencedDocument() != null){ xml += "" + "" + XMLTools.encodeXML(trans.getTenderReferencedDocument().getID()) + "" - + "" + 50 + "" - + ""; + + "" + 50 + ""; + if (trans.getTenderReferencedDocument().getDate()!=null) { + final SimpleDateFormat dateFormat102 = new SimpleDateFormat("yyyyMMdd"); + xml += ""+XMLTools.encodeXML(dateFormat102.format(trans.getTenderReferencedDocument().getDate()))+""; + } + + + xml += ""; } if (trans.getSpecifiedProcuringProjectID() != null) { xml += "" diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 45ad9ad1..855384b0 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -606,6 +606,11 @@ public class ZUGFeRDInvoiceImporter { if (!issueDateStr.isEmpty()) { issueDate = parseDate(issueDateStr, "yyyy-MM-dd"); } + + String tenderReference = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"OriginatorDocumentReference\"]/*[local-name()=\"ID\"]").trim(); + String tenderReferenceDate = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"OriginatorDocumentReference\"]/*[local-name()=\"ID\"]").trim(); + //if (tenderReference!=null) zpp... @todo bt-17 create a ubl with a date and set up an according xpath and if only tenderReference!=null only set that but if tenderReference!=null&&date!=null set both in zpp + String dueDt = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"DueDate\"]").trim(); if (!dueDt.isEmpty()) { dueDate = parseDate(dueDt, "yyyy-MM-dd"); @@ -672,6 +677,7 @@ public class ZUGFeRDInvoiceImporter { String buyerOrderIssuerAssignedID = null; String sellerOrderIssuerAssignedID = null; String additionalReferencedDocument = null; + Date additionalReferencedDocumentDate = null; for (int i = 0; i < headerTradeAgreementNodes.getLength(); i++) { // XMLTools.trimOrNull(nodes.item(i)))) { Node headerTradeAgreementNode = headerTradeAgreementNodes.item(i); @@ -702,9 +708,20 @@ public class ZUGFeRDInvoiceImporter { NodeList additionalChilds = headerTradeAgreementChilds.item(agreementChildIndex).getChildNodes(); for (int additionalChildIndex = 0; additionalChildIndex < additionalChilds.getLength(); additionalChildIndex++){ if((additionalChilds.item(additionalChildIndex).getLocalName() != null) - && (additionalChilds.item(additionalChildIndex).getLocalName().equals("IssuerAssignedID"))) { + && (additionalChilds.item(additionalChildIndex).getLocalName().equals("IssuerAssignedID"))) { additionalReferencedDocument = XMLTools.trimOrNull(additionalChilds.item(additionalChildIndex)); } + if((additionalChilds.item(additionalChildIndex).getLocalName() != null) + && (additionalChilds.item(additionalChildIndex).getLocalName().equals("FormattedIssueDateTime"))) { + NodeList FormattedIssueDateTimeChilds = headerTradeAgreementChilds.item(agreementChildIndex).getChildNodes(); + for (int dateChildIndex = 0; dateChildIndex < FormattedIssueDateTimeChilds.getLength(); dateChildIndex++){ + if((FormattedIssueDateTimeChilds.item(dateChildIndex).getLocalName() != null) + && (FormattedIssueDateTimeChilds.item(dateChildIndex).getLocalName().equals("DateTimeString"))) { + additionalReferencedDocumentDate = XMLTools.tryDate(FormattedIssueDateTimeChilds.item(dateChildIndex)); + } + + } + } } } } @@ -948,7 +965,11 @@ public class ZUGFeRDInvoiceImporter { } } if (additionalReferencedDocument != null){ - zpp.setTenderReferencedDocument(additionalReferencedDocument); + if (additionalReferencedDocumentDate!=null) { + zpp.setTenderReferencedDocument(new DatedReference(additionalReferencedDocument, additionalReferencedDocumentDate)); + } else { + zpp.setTenderReferencedDocument(additionalReferencedDocument); + } } String invoiceReferencedDocumentID = extractString("//*[local-name()=\"InvoiceReferencedDocument\"]/*[local-name()=\"IssuerAssignedID\"]|//*[local-name()=\"BillingReference\"]/*[local-name()=\"InvoiceDocumentReference\"]/*[local-name()=\"ID\"]"); if (!invoiceReferencedDocumentID.isEmpty()) { diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java index a9c6b188..ec744ec8 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java @@ -191,6 +191,38 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { } + public void testBT17InvoiceImport() { + boolean hasExceptions = false; + Invoice invoice = null; +/* + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushEdge.pdf"); + + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + SimpleDateFormat sdf=new SimpleDateFormat("YYYY-mm-dd"); + // Reading ZUGFeRD + assertEquals("90-kl-98798-C", invoice.getTenderReferencedDocument().getID()); + assertNotNull(invoice.getTenderReferencedDocument().getDate()); + assertEquals("2025", sdf.format(invoice.getTenderReferencedDocument().getDate())); +*/ + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + try { + zii.setInputStream(new FileInputStream(getResourceAsFile("bt17/response_1760553749128.xml"))); + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException | FileNotFoundException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + // Reading ZUGFeRD + assertEquals("Testing1", invoice.getTenderReferencedDocument().getID()); + + } + + public void testZF1Import() { ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"); diff --git a/library/src/test/resources/bt17/factur-x.xml b/library/src/test/resources/bt17/factur-x.xml new file mode 100644 index 00000000..592bff46 --- /dev/null +++ b/library/src/test/resources/bt17/factur-x.xml @@ -0,0 +1,230 @@ + + + + + + + + urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended + + + + 123 + Rechnung + 380 + + 20251017 + + + document level 1/2 + + + document level 2/2 + + + + + + a123 + + item level 1/1 + + + + 2001015001325 + 4711 + Testprodukt + + + + orderId + xxx + + + 1.0000 + 1.0000 + + + + 1.0000 + + + + VAT + S + 16.00 + + + + 20200113 + + + 20200115 + + + + + false + + 0.02 + item discount + + + 0.98 + + + + + + 0009845 + Test company + + 55232 + teststr + teststadt + DE + + + sender@test.org + + + DE0815 + + + 9990815 + + + + 4304171000002 + Franz Müller + + Franz Müller + + 01779999999 + + + ++49555123456 + + + franz@mueller.de + + + + 55232 + teststr.12 + Hinterhaus 3 + Entenhausen + DE + + + recipient@test.org + + + DE4711 + + + + 9384 + + + 28934 + + + 376zreurzu0983 + + + 90-kl-98798-C + 50 + + + + + just the other side of the street + + 55232 + teststr.12a + Entenhausen + DE + + + + + 20201102 + + + + + Verwendungszweck + CHF + + 0.20 + VAT + 1.28 + S + 72 + 16.00 + + + + 20201001 + + + 20201005 + + + + + true + + 0.50 + quick delivery charge + + VAT + S + 16.00 + + + + + false + + 0.20 + discount + + VAT + S + 16.00 + + + + Please remit until 17.10.2025 + + 20251017 + + + + Cash Discount + + 14 + 2.000 + + + + 0.98 + 0.50 + 0.20 + 1.28 + 0.20 + 1.48 + 0.00 + 1.48 + + + abc123 + + + abcd1234 + + + + diff --git a/library/src/test/resources/bt17/response_1760553749128.xml b/library/src/test/resources/bt17/response_1760553749128.xml new file mode 100644 index 00000000..a54da434 --- /dev/null +++ b/library/src/test/resources/bt17/response_1760553749128.xml @@ -0,0 +1,181 @@ + + + urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended + RE-20170509/505 + 2017-05-09 + 2022-02-28 + 380 + USD + AB321 + + 123 + + + Testing1 + + + + + Ecke 12 + Stadthausen + 12345 + + DE + + + + DE0815 + + VAT + + + + 0815 + + FC + + + + Bei Spiel GmbH + + + + + + + Bahnstr. 42 + Hinterhaus + Spielkreis + 88802 + + Zweiter Stock + + + DE + + + + DE999999999 + + VAT + + + + Theodor Est + + + + + 2017-05-07 + + + Bahnstr. 42 + Hinterhaus + Spielkreis + 88802 + + Zweiter Stock + + + DE + + + + + + Theodor Est + + + + + 54 + + + 14 Tage 2% Skonto, 30 Tage rein netto + + + 0 + + 337.6 + 0 + + K + 0 + Intra-community supply + + VAT + + + + + + 337.6 + 337.6 + 337.6 + 0 + 0 + 0 + 337.6 + + + 1 + 1 + 1.6 + + 1825 + 130 + + + Künstlerische Gestaltung (Stunde): Einer Beispielrechnung + + K + 0 + + VAT + + + + + 160 + 100 + + + + 2 + 400 + 316 + + Bestellerweiterung für E&F Umbau + + K + 0 + + VAT + + + + + 0.79 + 1 + + + + 3 + 200 + 20 + + Heiße Luft pro Liter + + K + 0 + + VAT + + + + + 0.1 + 1 + + + \ No newline at end of file