From a9bce8669c6f2e1d41a43d96349a06e74c839d7e Mon Sep 17 00:00:00 2001 From: jstaerk Date: Mon, 7 Jul 2025 15:23:17 +0200 Subject: [PATCH] working on #887 --- .../java/org/mustangproject/Allowance.java | 2 +- .../ZUGFeRD/LineCalculator.java | 2 +- .../ZUGFeRD/CalculationTest.java | 66 ++++++++++++++++--- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/org/mustangproject/Allowance.java b/library/src/main/java/org/mustangproject/Allowance.java index d8b5f3fe..cca2033a 100644 --- a/library/src/main/java/org/mustangproject/Allowance.java +++ b/library/src/main/java/org/mustangproject/Allowance.java @@ -38,7 +38,7 @@ public class Allowance extends Charge { if(totalAmount != null) { return totalAmount; } else if (percent!=null) { - BigDecimal singlePrice=currentItem.getValue().divide(BigDecimal.ONE.add(getPercent().divide(new BigDecimal(100))), 18, RoundingMode.HALF_UP); + BigDecimal singlePrice=currentItem.getValue().multiply(BigDecimal.ONE.subtract(getPercent().divide(new BigDecimal(100)))); // BigDecimal singlePrice=currentItem.getValue().multiply(BigDecimal.ONE.subtract(getPercent().divide(new BigDecimal(100)))); BigDecimal singlePriceDiff=currentItem.getValue().subtract(singlePrice); return singlePriceDiff; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java b/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java index a0566f3e..a78a72df 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java @@ -94,7 +94,7 @@ public class LineCalculator { ? BigDecimal.ONE.setScale(4) : currentItem.getBasisQuantity(); itemTotalNetAmount = quantity.multiply(price).divide(basisQuantity, 18, RoundingMode.HALF_UP) - .add(lineCharge).subtract(lineAllowance).subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP); + .add(lineCharge).subtract(lineAllowance).subtract(allowanceItemTotal.setScale(2, RoundingMode.HALF_UP)).setScale(2, RoundingMode.HALF_UP); itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator);//.setScale(2, RoundingMode.HALF_UP); } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java index 7fc94f5f..f7f1ce72 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java @@ -79,6 +79,56 @@ public class CalculationTest extends ResourceCase { assertEquals(valueOf(287.9408).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); } + @Test + public void testAllowanceAndChargeEx4() { + /** numbers from en16931 example 4 */ + SimpleDateFormat sqlDate = new SimpleDateFormat("yyyy-MM-dd"); + + Invoice invoice = new Invoice(); + invoice.setDocumentName("Rechnung"); + invoice.setNumber("777777"); + try { + invoice.setIssueDate(sqlDate.parse("2020-12-31")); + } catch (Exception e) { + LOGGER.error("Failed to set dates", e); + + } + + /* trade party (sender) */ + TradeParty sender = new TradeParty("Maier GmbH", "Musterweg 5", "11111", "Testung", "DE"); + sender.addVATID("DE2222222222"); + invoice.setSender(sender); + + /* trade party (recipient) */ + TradeParty recipient = new TradeParty("Teston GmbH" + " " + "Zentrale" + " " + "", "Testweg 5", "11111", "Testung", "DE"); + invoice.setRecipient(recipient); + + /* item */ + Product product; + Item item; + + product = new Product("Pens", "", "H84", new BigDecimal(25)); + product.addAllowance(new Allowance(new BigDecimal(1))); + item = new Item(product, new BigDecimal("9.50"), new BigDecimal(25)); + item.addCharge(new Charge(new BigDecimal(10)).setReasonCode("ZZZ").setReason("Zuschlag")); + LineCalculator lc = new LineCalculator(item); + assertEquals(new BigDecimal("222.50"), lc.getItemTotalNetAmount()); + invoice.addItem(item); + product = new Product("Paper", "", "H84", new BigDecimal(25)); + item = new Item(product, new BigDecimal("4.50"), new BigDecimal(15)); + item.addAllowance(new Allowance().setPercent(new BigDecimal(5)).setReasonCode("ZZZ").setReason("Zuschlag")); + lc = new LineCalculator(item); + assertEquals(new BigDecimal("64.12"), lc.getItemTotalNetAmount()); + invoice.addItem(item); + invoice.addAllowance(new Allowance().setPercent(new BigDecimal(10)).setTaxPercent(new BigDecimal(25)).setReasonCode("ZZZ").setReason("Mengenrabatt")); + invoice.addCharge(new Charge(new BigDecimal(15)).setReasonCode("ZZZ").setReason("Frachtkosten")); + + TransactionCalculator calculator = new TransactionCalculator(invoice); + assertEquals(valueOf(286.62).stripTrailingZeros(), calculator.getTotal());// interestingly, EN16931-1 has 286.63 here? + assertEquals(valueOf(272.96).stripTrailingZeros(), calculator.getTaxBasis()); // and 272.97 here + assertEquals(valueOf(337.45).stripTrailingZeros(), calculator.getDuePayable()); // and 337.46 here??? + } + @Test public void testLineCalculatorForeignCurrencyExample() { /*** xml of official fx sample with allowances and charges @@ -88,19 +138,19 @@ public class CalculationTest extends ResourceCase { */ File inputCII = getResourceAsFile("Extended_fremdwaehrung.xml"); - ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(); - Invoice invoice=null; + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + Invoice invoice = null; zii.doIgnoreCalculationErrors(); - boolean hasExceptions=false; + boolean hasExceptions = false; try { zii.setInputStream(new FileInputStream(inputCII)); - invoice=zii.extractInvoice(); + invoice = zii.extractInvoice(); } catch (XPathExpressionException | ParseException e) { // handle Exceptions - hasExceptions=true; + hasExceptions = true; } catch (FileNotFoundException e) { - hasExceptions=true; + hasExceptions = true; } assertFalse(hasExceptions); // Reading ZUGFeRD @@ -266,7 +316,7 @@ public class CalculationTest extends ResourceCase { invoice.addItem(item); TransactionCalculator calculator = new TransactionCalculator(invoice); - assertEquals(new BigDecimal(5), calculator.getGrandTotal().stripTrailingZeros()); + assertEquals(new BigDecimal("4.95"), calculator.getGrandTotal().stripTrailingZeros()); } public void testSimpleItemTotalAllowance() { @@ -314,7 +364,7 @@ public class CalculationTest extends ResourceCase { /** * LineCalculator should not throw an exception when calculating a non-terminating decimal expansion - * */ + */ @Test public void testNonTerminatingDecimalExpansion() { final Product product = new Product();