support document level charges/allowances in invoiceimporter
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
|
||||
/***
|
||||
@@ -30,7 +31,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
|
||||
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
|
||||
res = res.add(amount.getCalculated());
|
||||
}
|
||||
return res;
|
||||
return res.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/***
|
||||
|
||||
@@ -40,6 +40,13 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
||||
"//*[local-name()=\"ExchangedDocument\"]");
|
||||
NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||
|
||||
xpr = xpath.compile(
|
||||
"//*[local-name()=\"GrandTotalAmount\"]");
|
||||
BigDecimal expectedGrandTotal = null;
|
||||
NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||
if (totalNodes.getLength() > 0) {
|
||||
expectedGrandTotal = new BigDecimal(totalNodes.item(0).getTextContent());
|
||||
}
|
||||
|
||||
Date issueDate = null;
|
||||
Date dueDate = null;
|
||||
@@ -192,6 +199,70 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
||||
|
||||
}
|
||||
|
||||
// item level charges+allowances are not yet handled but a lower item price will be read,
|
||||
// so the invoice remains arithmetically correct
|
||||
// -> parse document level charges+allowances
|
||||
xpr = xpath.compile(
|
||||
"//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]");
|
||||
NodeList chargeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||
for (int i = 0; i < chargeNodes.getLength(); i++) {
|
||||
NodeList chargeNodeChilds = chargeNodes.item(i).getChildNodes();
|
||||
boolean isCharge = true;
|
||||
String chargeAmount = null;
|
||||
String reason = null;
|
||||
String taxPercent = null;
|
||||
for (int chargeChildIndex = 0; chargeChildIndex < chargeNodeChilds.getLength(); chargeChildIndex++) {
|
||||
if (chargeNodeChilds.item(chargeChildIndex).getNodeName().equals("ram:ChargeIndicator")) {
|
||||
NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
|
||||
for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) {
|
||||
if (indicatorChilds.item(indicatorChildIndex).getNodeName().equals("udt:Indicator")) {
|
||||
isCharge = indicatorChilds.item(indicatorChildIndex).getTextContent().equalsIgnoreCase("true");
|
||||
}
|
||||
}
|
||||
} else if (chargeNodeChilds.item(chargeChildIndex).getNodeName().equals("ram:ActualAmount")) {
|
||||
chargeAmount = chargeNodeChilds.item(chargeChildIndex).getTextContent();
|
||||
} else if (chargeNodeChilds.item(chargeChildIndex).getNodeName().equals("ram:Reason")) {
|
||||
reason = chargeNodeChilds.item(chargeChildIndex).getTextContent();
|
||||
} else if (chargeNodeChilds.item(chargeChildIndex).getNodeName().equals("ram:CategoryTradeTax")) {
|
||||
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
|
||||
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
|
||||
if (taxChilds.item(taxChildIndex).getNodeName().equals("ram:RateApplicablePercent")) {
|
||||
taxPercent = taxChilds.item(taxChildIndex).getTextContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (isCharge) {
|
||||
Charge c = new Charge(new BigDecimal(chargeAmount));
|
||||
if (reason != null) {
|
||||
c.setReason(reason);
|
||||
}
|
||||
if (taxPercent != null) {
|
||||
c.setTaxPercent(new BigDecimal(taxPercent));
|
||||
}
|
||||
|
||||
zpp.addCharge(c);
|
||||
} else {
|
||||
Allowance a = new Allowance(new BigDecimal(chargeAmount));
|
||||
if (reason != null) {
|
||||
a.setReason(reason);
|
||||
}
|
||||
if (taxPercent != null) {
|
||||
a.setTaxPercent(new BigDecimal(taxPercent));
|
||||
}
|
||||
zpp.addAllowance(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TransactionCalculator tc = new TransactionCalculator(zpp);
|
||||
String expectedStringTotalGross = tc.getTotalGross().toPlainString();
|
||||
if (!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2))) {
|
||||
throw new ParseException("Could not reproduce the invoice, this could mean that it could not be read properly", 0);
|
||||
}
|
||||
|
||||
return zpp;
|
||||
}
|
||||
|
||||
@@ -41,11 +41,10 @@ import java.util.GregorianCalendar;
|
||||
* used for this import, testout-ZF2New.pdf
|
||||
*/
|
||||
public class ZF2ZInvoiceImporterTest extends TestCase {
|
||||
final String TARGET_PDF = "./target/testout-ZF2new.pdf";
|
||||
|
||||
public void testInvoiceImport() {
|
||||
|
||||
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
|
||||
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter("./target/testout-ZF2new.pdf");
|
||||
|
||||
boolean hasExceptions=false;
|
||||
Invoice invoice=null;
|
||||
@@ -82,7 +81,44 @@ public class ZF2ZInvoiceImporterTest extends TestCase {
|
||||
assertEquals("Stadthausen", invoice.getSender().getLocation());
|
||||
|
||||
TransactionCalculator tc=new TransactionCalculator(invoice);
|
||||
assertEquals(new BigDecimal("571.040000"),tc.getTotalGross());
|
||||
assertEquals(new BigDecimal("571.04"),tc.getTotalGross());
|
||||
|
||||
|
||||
// name street location zip country, contact name phone email, total amount
|
||||
|
||||
|
||||
|
||||
}
|
||||
public void testItemAllowancesChargesImport() {
|
||||
|
||||
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushItemChargesAllowances.pdf");
|
||||
|
||||
boolean hasExceptions=false;
|
||||
Invoice invoice=null;
|
||||
try {
|
||||
invoice=zii.extractInvoice();
|
||||
} catch (XPathExpressionException | ParseException e) {
|
||||
hasExceptions=true;
|
||||
}
|
||||
assertFalse(hasExceptions);
|
||||
TransactionCalculator tc=new TransactionCalculator(invoice);
|
||||
assertEquals(new BigDecimal("18.33"),tc.getTotalGross());
|
||||
}
|
||||
|
||||
public void testAllowancesChargesImport() {
|
||||
|
||||
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushChargesAllowances.pdf");
|
||||
|
||||
boolean hasExceptions=false;
|
||||
Invoice invoice=null;
|
||||
try {
|
||||
invoice=zii.extractInvoice();
|
||||
} catch (XPathExpressionException | ParseException e) {
|
||||
hasExceptions=true;
|
||||
}
|
||||
assertFalse(hasExceptions);
|
||||
TransactionCalculator tc=new TransactionCalculator(invoice);
|
||||
assertEquals(new BigDecimal("11.07"),tc.getTotalGross());
|
||||
|
||||
|
||||
// name street location zip country, contact name phone email, total amount
|
||||
@@ -91,4 +127,5 @@ public class ZF2ZInvoiceImporterTest extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user