Merge branch 'master' of https://github.com/ZUGFeRD/mustangproject into master
This commit is contained in:
@@ -54,13 +54,11 @@ switch
|
|||||||
|
|
||||||
### 2.0 still todo
|
### 2.0 still todo
|
||||||
- dont show empty tax number field
|
- dont show empty tax number field
|
||||||
- new sample invoice
|
- fail when no bankverbindung?
|
||||||
- *visualizer to work with Extended profile
|
- fail when xr attrs missing?
|
||||||
- *visualizer tests
|
- build xr skonto???
|
||||||
- *validator not to XR error on ZF files (only notices)
|
- *validator not to XR error on ZF files (only notices)
|
||||||
- *from A3 does not seem tow ork see mustangreaderwriteredgetest:testedgeexport
|
|
||||||
- xmp errors may not show correctly in log
|
- xmp errors may not show correctly in log
|
||||||
- finalize invoiceimporter
|
|
||||||
Alpha3 2020-10-24
|
Alpha3 2020-10-24
|
||||||
Alpha2 2020-09-15
|
Alpha2 2020-09-15
|
||||||
Alpha1 2020-08-06
|
Alpha1 2020-08-06
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ but there is also the new invoiceImporter
|
|||||||
assertEquals("Spielkreis", invoice.getRecipient().getLocation());
|
assertEquals("Spielkreis", invoice.getRecipient().getLocation());
|
||||||
|
|
||||||
TransactionCalculator tc=new TransactionCalculator(invoice);
|
TransactionCalculator tc=new TransactionCalculator(invoice);
|
||||||
assertEquals(new BigDecimal("571.040000"),tc.getTotalGross());
|
assertEquals(new BigDecimal("571.04"),tc.getTotalGross());
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.mustangproject.ZUGFeRD;
|
package org.mustangproject.ZUGFeRD;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -30,7 +31,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
|
|||||||
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
|
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
|
||||||
res = res.add(amount.getCalculated());
|
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\"]");
|
"//*[local-name()=\"ExchangedDocument\"]");
|
||||||
NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
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 issueDate = null;
|
||||||
Date dueDate = 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;
|
return zpp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,10 @@ import java.util.GregorianCalendar;
|
|||||||
* used for this import, testout-ZF2New.pdf
|
* used for this import, testout-ZF2New.pdf
|
||||||
*/
|
*/
|
||||||
public class ZF2ZInvoiceImporterTest extends TestCase {
|
public class ZF2ZInvoiceImporterTest extends TestCase {
|
||||||
final String TARGET_PDF = "./target/testout-ZF2new.pdf";
|
|
||||||
|
|
||||||
public void testInvoiceImport() {
|
public void testInvoiceImport() {
|
||||||
|
|
||||||
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
|
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter("./target/testout-ZF2new.pdf");
|
||||||
|
|
||||||
boolean hasExceptions=false;
|
boolean hasExceptions=false;
|
||||||
Invoice invoice=null;
|
Invoice invoice=null;
|
||||||
@@ -82,7 +81,44 @@ public class ZF2ZInvoiceImporterTest extends TestCase {
|
|||||||
assertEquals("Stadthausen", invoice.getSender().getLocation());
|
assertEquals("Stadthausen", invoice.getSender().getLocation());
|
||||||
|
|
||||||
TransactionCalculator tc=new TransactionCalculator(invoice);
|
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
|
// 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