diff --git a/History.md b/History.md index b54d369a..ffa54fec 100644 --- a/History.md +++ b/History.md @@ -6,7 +6,8 @@ - 997 - 1000 - deprecate itemTotalAllowances instead of itemAllowances oder itemCharges -- +- #1011 + 2.21.0 ======= 2025-12-18 diff --git a/library/src/main/java/org/mustangproject/CalculatedInvoice.java b/library/src/main/java/org/mustangproject/CalculatedInvoice.java index d496744f..3698a52a 100644 --- a/library/src/main/java/org/mustangproject/CalculatedInvoice.java +++ b/library/src/main/java/org/mustangproject/CalculatedInvoice.java @@ -5,6 +5,7 @@ package org.mustangproject; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.TransactionCalculator; +import org.mustangproject.ZUGFeRD.VATAmount; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,6 +20,7 @@ public class CalculatedInvoice extends Invoice implements Serializable { protected BigDecimal duePayable=null; protected BigDecimal grandTotal=null; protected BigDecimal taxBasis=null; + protected BigDecimal VATtotal=null; protected TransactionCalculator tc=null; public void calculate() { @@ -27,6 +29,10 @@ public class CalculatedInvoice extends Invoice implements Serializable { lineTotalAmount=tc.getValue(); duePayable=tc.getDuePayable(); taxBasis= tc.getTaxBasis(); + VATtotal=BigDecimal.ZERO; + for (VATAmount vam:getCalculation().getTaxDetails()) { + VATtotal=VATtotal.add(vam.getCalculated()); + } } public BigDecimal getGrandTotal() { if (grandTotal==null) { @@ -88,6 +94,28 @@ public class CalculatedInvoice extends Invoice implements Serializable { return lineTotalAmount; } + /*** + * usually one would use calculate, use only if the invoice is parsed + * BT-110 + * @param parsedValue the gross total minus net + * @return fluent setter + */ + public CalculatedInvoice setVATtotal(BigDecimal parsedValue) { + VATtotal=parsedValue; + return this; + } + + /*** + * + * @return expect a value close to getGrandTotal-LineTotalAmount + */ + public BigDecimal getVATtotal() { + if (VATtotal==null) { + calculate(); + } + return VATtotal; + } + /*** * usually one would use calculate, use only if the invoice is parsed * @param total the net total diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 09803e59..4b8d5580 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -514,6 +514,14 @@ public class ZUGFeRDInvoiceImporter { } } + xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"TaxTotalAmount\"]|//*[local-name()=\"TaxTotal\"]/*[local-name()=\"TaxAmount\"]"); + NodeList taxTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + if (taxTotalNodes.getLength() > 0) { + if (zpp instanceof CalculatedInvoice) { + ((CalculatedInvoice) zpp).setVATtotal(new BigDecimal(XMLTools.trimOrNull(taxTotalNodes.item(0)))); + } + } + xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"DuePayableAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"PayableAmount\"]"); NodeList lineDueNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); BigDecimal duePayableAmount = null; diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java index 36877696..7e692c15 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java @@ -718,6 +718,7 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { zii.extractInto(i); assertEquals("123", i.getNumber()); assertEquals("1.48", i.getGrandTotal().toString()); + assertEquals("0.20", i.getVATtotal().toString()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); assertEquals("2020-10-01", sdf.format(i.getDetailedDeliveryPeriodFrom())); @@ -751,13 +752,16 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { BigDecimal expectedPrepaid=new BigDecimal(50); BigDecimal expectedLineTotal=new BigDecimal("180.76"); BigDecimal expectedDue=new BigDecimal("147.65"); + BigDecimal expectedTax=new BigDecimal("20.16"); if (isBD) { BigDecimal amread=invoice.getTotalPrepaidAmount(); BigDecimal importedLineTotal=invoice.getLineTotalAmount(); BigDecimal importedDuePayable=invoice.getDuePayable(); + BigDecimal importedTaxAmount=invoice.getVATtotal(); assertTrue(amread.compareTo(expectedPrepaid) == 0); assertTrue(importedLineTotal.compareTo(expectedLineTotal) == 0); assertTrue(importedDuePayable.compareTo(expectedDue) == 0); + assertTrue(importedTaxAmount.compareTo(expectedTax) == 0); } }