diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 1297b1e8..82822da9 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -48,6 +48,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -1272,6 +1273,25 @@ public class ZUGFeRDInvoiceImporter { //appliedAmount //AppliedTradeTax } + + if (cd.getDays() == null) { + NodeList siblingNodes = cashdiscountNodes.item(i).getParentNode().getChildNodes(); + for (int siblingIndex = 0; siblingIndex < siblingNodes.getLength(); siblingIndex++) { + if (siblingNodes.item(siblingIndex).getLocalName() != null && siblingNodes.item(siblingIndex).getLocalName().equals("DueDateDateTime")) { + NodeList dueDateChilds = siblingNodes.item(siblingIndex).getChildNodes(); + for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) { + if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) { + String dueDateString = XMLTools.trimOrNull(dueDateChilds.item(dueDateChildIndex)); + dueDate = parseDate(dueDateString, "yyyyMMdd"); + long diffInMillies = Math.abs(dueDate.getTime() - zpp.getIssueDate().getTime()); + long diffInDays = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); + cd.setDays((int) diffInDays); + } + } + } + } + } + if ((cd.getPercent() != null)&&(cd.getDays() != null)) { zpp.addCashDiscount(cd); } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/CashDiscountFacturXTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/CashDiscountFacturXTest.java new file mode 100644 index 00000000..b2631802 --- /dev/null +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/CashDiscountFacturXTest.java @@ -0,0 +1,178 @@ +package org.mustangproject.ZUGFeRD; + +import junit.framework.TestCase; +import org.mustangproject.Invoice; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.text.ParseException; +import javax.xml.xpath.XPathExpressionException; + +/* https://github.com/ZUGFeRD/mustangproject/issues/993 */ +public class CashDiscountFacturXTest extends TestCase { + String XMLString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended\n" + + " \n" + + " \n" + + " \n" + + " 471102\n" + + " 380\n" + + " \n" + + " 20260201\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " Trennblätter A4\n" + + " \n" + + " \n" + + " \n" + + " 9.9000\n" + + " 1.0000\n" + + " \n" + + " \n" + + " \n" + + " 20.0000\n" + + " \n" + + " \n" + + " \n" + + " VAT\n" + + " S\n" + + " 19.00\n" + + " \n" + + " \n" + + " 198.00\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " \n" + + " Joghurt Banane\n" + + " \n" + + " \n" + + " \n" + + " 5.5000\n" + + " 1.0000\n" + + " \n" + + " \n" + + " \n" + + " 50.0000\n" + + " \n" + + " \n" + + " \n" + + " VAT\n" + + " S\n" + + " 7.00\n" + + " \n" + + " \n" + + " 275.00\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Lieferant GmbH\n" + + " \n" + + " 80333\n" + + " Lieferantenstraße 20\n" + + " München\n" + + " DE\n" + + " \n" + + " \n" + + " DE123456789\n" + + " \n" + + " \n" + + " 201/113/40209\n" + + " \n" + + " \n" + + " \n" + + " Kunden AG Mitte\n" + + " \n" + + " 69876\n" + + " Kundenstraße 15\n" + + " Frankfurt\n" + + " DE\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 20180304\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 471102\n" + + " EUR\n" + + " \n" + + " 19.25\n" + + " VAT\n" + + " 275.00\n" + + " S\n" + + " 7.00\n" + + " \n" + + " \n" + + " 37.62\n" + + " VAT\n" + + " 198.00\n" + + " S\n" + + " 19.00\n" + + " \n" + + " \n" + + " Please remit until 04.03.2018\n" + + " \n" + + " 20180304\n" + + " \n" + + " \n" + + " \n" + + " Bis zum 15.02.2026 erhalten Sie 4,000 % Skonto, 21.19 EUR\n" + + " \n" + + " 20260215\n" + + " \n" + + " \n" + + " 529.8700\n" + + " 4.00\n" + + " 21.19\n" + + " \n" + + " \n" + + " \n" + + " Bis zum 16.02.2026 ohne Abzug\n" + + " \n" + + " 20260216\n" + + " \n" + + " \n" + + " \n" + + " 473.00\n" + + " 0.00\n" + + " 0.00\n" + + " 473.00\n" + + " 56.87\n" + + " 529.87\n" + + " 0.00\n" + + " 529.87\n" + + " \n" + + " \n" + + " \n" + + " "; + + public void testCashDiscount() throws XPathExpressionException, ParseException { + InputStream inputStream = new ByteArrayInputStream(XMLString.getBytes(StandardCharsets.UTF_8)); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(inputStream); + Invoice invoice = zii.extractInvoice(); + assertEquals(new BigDecimal("4.00"), invoice.getCashDiscounts()[0].getPercent()); + } +}