IN ARBEIT - issue QMT-1461: Rechnungseingang - ZUGFeRD-Rechnungen

importieren
http://sws-jira/browse/QMT-1461
This commit is contained in:
Stefan Schmaltz
2022-10-13 09:17:15 +02:00
parent 524165b1ba
commit 589e94af8f
4 changed files with 167 additions and 102 deletions

View File

@@ -7,10 +7,10 @@ import java.math.BigDecimal;
* @see TransactionCalculator * @see TransactionCalculator
*/ */
public class LineCalculator { public class LineCalculator {
private BigDecimal price; private final BigDecimal price;
private BigDecimal priceGross; private final BigDecimal priceGross;
private BigDecimal itemTotalNetAmount; private final BigDecimal itemTotalNetAmount;
private BigDecimal itemTotalVATAmount; private final BigDecimal itemTotalVATAmount;
private BigDecimal allowance = BigDecimal.ZERO; private BigDecimal allowance = BigDecimal.ZERO;
private BigDecimal charge = BigDecimal.ZERO; private BigDecimal charge = BigDecimal.ZERO;
private BigDecimal allowanceItemTotal = BigDecimal.ZERO; private BigDecimal allowanceItemTotal = BigDecimal.ZERO;
@@ -33,7 +33,10 @@ public class LineCalculator {
} }
} }
BigDecimal multiplicator = currentItem.getProduct().getVATPercent().divide(BigDecimal.valueOf(100)); BigDecimal vatPercent = currentItem.getProduct().getVATPercent();
if (vatPercent == null)
vatPercent = BigDecimal.ZERO;
BigDecimal multiplicator = vatPercent.divide(BigDecimal.valueOf(100));
priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159 priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159
price = priceGross.subtract(allowance).add(charge); price = priceGross.subtract(allowance).add(charge);
itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity()) itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity())

View File

@@ -167,14 +167,16 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent(); BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalculator lc = new LineCalculator(currentItem); if (percent != null) {
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), LineCalculator lc = new LineCalculator(currentItem);
currentItem.getProduct().getTaxCategoryCode()); VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
VATAmount current = hm.get(percent.stripTrailingZeros()); currentItem.getProduct().getTaxCategoryCode());
if (current == null) { VATAmount current = hm.get(percent.stripTrailingZeros());
hm.put(percent.stripTrailingZeros(), itemVATAmount); if (current == null) {
} else { hm.put(percent.stripTrailingZeros(), itemVATAmount);
hm.put(percent.stripTrailingZeros(), current.add(itemVATAmount)); } else {
hm.put(percent.stripTrailingZeros(), current.add(itemVATAmount));
}
} }
} }
@@ -199,16 +201,18 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
if ((allowances != null) && (allowances.length > 0)) { if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) { for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
BigDecimal taxPercent = currentAllowance.getTaxPercent(); BigDecimal taxPercent = currentAllowance.getTaxPercent();
VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); if (taxPercent != null) {
if (theAmount == null) { VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros());
theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, if (theAmount == null) {
currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S"); theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO,
} currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S");
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this))); }
BigDecimal factor = taxPercent.divide(new BigDecimal(100)); theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this)));
theAmount.setCalculated(theAmount.getBasis().multiply(factor)); BigDecimal factor = taxPercent.divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(taxPercent.stripTrailingZeros(), theAmount); hm.put(taxPercent.stripTrailingZeros(), theAmount);
}
} }
} }
@@ -220,4 +224,12 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
return getTotal(); return getTotal();
} }
public BigDecimal getChargeTotal() {
return getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP);
}
public BigDecimal getAllowanceTotal() {
return getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP);
}
} }

View File

@@ -310,16 +310,19 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
xml += "<ram:SpecifiedTradeSettlementMonetarySummation>" xml += "<ram:SpecifiedTradeSettlementMonetarySummation>"
+ "<ram:LineTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>" + "<ram:LineTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>"
// currencyID=\"EUR\" // currencyID=\"EUR\"
+ "<ram:ChargeTotalAmount currencyID=\"" + trans.getCurrency() + "\">0.00</ram:ChargeTotalAmount>" // currencyID=\"EUR\" + "<ram:ChargeTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
+ "<ram:AllowanceTotalAmount currencyID=\"" + trans.getCurrency() + "\">0.00</ram:AllowanceTotalAmount>" // + currencyFormat(calc.getChargeTotal()) + "</ram:ChargeTotalAmount>" // currencyID=\"EUR\"
+ "<ram:AllowanceTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
+ currencyFormat(calc.getAllowanceTotal()) + "</ram:AllowanceTotalAmount>" //
// currencyID=\"EUR\" // currencyID=\"EUR\"
// + " <ChargeTotalAmount currencyID=\"EUR\">5.80</ChargeTotalAmount>" // + " <ChargeTotalAmount currencyID=\"EUR\">5.80</ChargeTotalAmount>"
// + " <AllowanceTotalAmount currencyID=\"EUR\">14.73</AllowanceTotalAmount>" // + " <AllowanceTotalAmount currencyID=\"EUR\">14.73</AllowanceTotalAmount>"
+ "<ram:TaxBasisTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotal()) + "</ram:TaxBasisTotalAmount>" + "<ram:TaxBasisTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
+ currencyFormat(calc.getTaxBasis()) + "</ram:TaxBasisTotalAmount>"
// // // //
// currencyID=\"EUR\" // currencyID=\"EUR\"
+ "<ram:TaxTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + "<ram:TaxTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
+ currencyFormat(calc.getGrandTotal().subtract(calc.getTotal())) + "</ram:TaxTotalAmount>" + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "</ram:TaxTotalAmount>"
+ "<ram:GrandTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getGrandTotal()) + "</ram:GrandTotalAmount>" + "<ram:GrandTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getGrandTotal()) + "</ram:GrandTotalAmount>"
// // // //
// currencyID=\"EUR\" // currencyID=\"EUR\"

View File

@@ -54,31 +54,29 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
/*** /***
* This will parse a XML into a invoice object * This will parse a XML into a invoice object
*
* @return the parsed invoice object * @return the parsed invoice object
*/ */
public Invoice extractInvoice() throws XPathExpressionException, ParseException { public Invoice extractInvoice() throws XPathExpressionException, ParseException {
String number = ""; String number = "";
/* /*
* dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate setSender setRecipient setnumber * dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate
* bspw. due date //ExchangedDocument//IssueDateTime//DateTimeString : due date optional * setSender setRecipient setnumber bspw. due date
* //ExchangedDocument//IssueDateTime//DateTimeString : due date optional
*/ */
XPathFactory xpathFact = XPathFactory.newInstance(); XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath(); XPath xpath = xpathFact.newXPath();
Invoice zpp = null; Invoice zpp = null;
XPathExpression xpr = xpath.compile( XPathExpression xpr = xpath.compile("//*[local-name()=\"SellerTradeParty\"]");
"//*[local-name()=\"SellerTradeParty\"]");
NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile( xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]");
"//*[local-name()=\"BuyerTradeParty\"]");
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile( xpr = xpath.compile("//*[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( xpr = xpath.compile("//*[local-name()=\"GrandTotalAmount\"]");
"//*[local-name()=\"GrandTotalAmount\"]");
BigDecimal expectedGrandTotal = null; BigDecimal expectedGrandTotal = null;
NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (totalNodes.getLength() > 0) { if (totalNodes.getLength() > 0) {
@@ -90,43 +88,57 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
Date deliveryDate = null; Date deliveryDate = null;
for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) { for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) {
//nodes.item(i).getTextContent())) { // nodes.item(i).getTextContent())) {
Node exchangedDocumentNode = ExchangedDocumentNodes.item(i); Node exchangedDocumentNode = ExchangedDocumentNodes.item(i);
NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes(); NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes();
for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) { for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds
.getLength(); documentChildIndex++) {
Node item = exchangedDocumentChilds.item(documentChildIndex); Node item = exchangedDocumentChilds.item(documentChildIndex);
if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) { if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) {
number = item.getTextContent(); number = item.getTextContent();
} }
if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) { if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) {
NodeList issueDateTimeChilds = item.getChildNodes(); NodeList issueDateTimeChilds = item.getChildNodes();
for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) { for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds
if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null) && (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) { .getLength(); issueDateChildIndex++) {
issueDate = new SimpleDateFormat("yyyyMMdd").parse(issueDateTimeChilds.item(issueDateChildIndex).getTextContent()); if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null)
&& (issueDateTimeChilds.item(issueDateChildIndex).getLocalName()
.equals("DateTimeString"))) {
issueDate = new SimpleDateFormat("yyyyMMdd")
.parse(issueDateTimeChilds.item(issueDateChildIndex).getTextContent());
} }
} }
} }
} }
} }
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]");
xpr = xpath.compile(
"//*[local-name()=\"ApplicableHeaderTradeDelivery\"]");
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) { for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) {
//nodes.item(i).getTextContent())) { // nodes.item(i).getTextContent())) {
Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i); Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i);
NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes(); NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes();
for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) { for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds
if ((headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName() != null) && (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName().equals("ActualDeliverySupplyChainEvent"))) { .getLength(); deliveryChildIndex++) {
if ((headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName() != null)
&& (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName()
.equals("ActualDeliverySupplyChainEvent"))) {
NodeList actualDeliveryChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes(); NodeList actualDeliveryChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes();
for (int actualDeliveryChildIndex = 0; actualDeliveryChildIndex < actualDeliveryChilds.getLength(); actualDeliveryChildIndex++) { for (int actualDeliveryChildIndex = 0; actualDeliveryChildIndex < actualDeliveryChilds
if ((actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName() != null) && (actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName().equals("OccurrenceDateTime"))) { .getLength(); actualDeliveryChildIndex++) {
NodeList occurenceChilds = actualDeliveryChilds.item(actualDeliveryChildIndex).getChildNodes(); if ((actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName() != null)
for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) { && (actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName()
if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null) && (occurenceChilds.item(occurenceChildIndex).getLocalName().equals("DateTimeString"))) { .equals("OccurrenceDateTime"))) {
deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(occurenceChilds.item(occurenceChildIndex).getTextContent()); NodeList occurenceChilds = actualDeliveryChilds.item(actualDeliveryChildIndex)
.getChildNodes();
for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds
.getLength(); occurenceChildIndex++) {
if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null)
&& (occurenceChilds.item(occurenceChildIndex).getLocalName()
.equals("DateTimeString"))) {
deliveryDate = new SimpleDateFormat("yyyyMMdd")
.parse(occurenceChilds.item(occurenceChildIndex).getTextContent());
} }
} }
} }
@@ -135,24 +147,30 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
} }
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]");
xpr = xpath.compile(
"//*[local-name()=\"ApplicableHeaderTradeSettlement\"]");
NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) { for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) {
//nodes.item(i).getTextContent())) { // nodes.item(i).getTextContent())) {
Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i); Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i);
NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes(); NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes();
for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) { for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradePaymentTerms"))) { .getLength(); settlementChildIndex++) {
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null)
&& (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName()
.equals("SpecifiedTradePaymentTerms"))) {
NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes();
for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds
if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DueDateDateTime"))) { .getLength(); paymentTermChildIndex++) {
if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds
.item(paymentTermChildIndex).getLocalName().equals("DueDateDateTime"))) {
NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes(); NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes();
for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) { for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds
if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) { .getLength(); dueDateChildIndex++) {
dueDate = new SimpleDateFormat("yyyyMMdd").parse(dueDateChilds.item(dueDateChildIndex).getTextContent()); if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds
.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) {
dueDate = new SimpleDateFormat("yyyyMMdd")
.parse(dueDateChilds.item(dueDateChildIndex).getTextContent());
} }
} }
} }
@@ -161,11 +179,11 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
} }
zpp = new Invoice().setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number); zpp = new Invoice().setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate)
.setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number);
//.addItem(new Item(new Product("Testprodukt","","C62",BigDecimal.ZERO),amount,new BigDecimal(1.0))) //.addItem(new Item(new Product("Testprodukt","","C62",BigDecimal.ZERO),amount,new BigDecimal(1.0)))
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]")); zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]"));
xpr = xpath.compile( xpr = xpath.compile("//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]");
"//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]");
NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (nodes.getLength() == 0) { if (nodes.getLength() == 0) {
@@ -177,13 +195,13 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
String description = ""; String description = "";
SchemedID gid = null; SchemedID gid = null;
String quantity = "0"; String quantity = "0";
String vatPercent = "0"; String vatPercent = null;
String lineTotal = "0"; String lineTotal = "0";
String unitCode = "0"; String unitCode = "0";
ArrayList<ReferencedDocument> rdocs = null; ArrayList<ReferencedDocument> rdocs = null;
//nodes.item(i).getTextContent())) { // nodes.item(i).getTextContent())) {
Node currentItemNode = nodes.item(i); Node currentItemNode = nodes.item(i);
NodeList itemChilds = currentItemNode.getChildNodes(); NodeList itemChilds = currentItemNode.getChildNodes();
for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) { for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) {
@@ -191,9 +209,11 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((lineTrade != null) && (lineTrade.equals("SpecifiedLineTradeAgreement") if ((lineTrade != null) && (lineTrade.equals("SpecifiedLineTradeAgreement")
|| lineTrade.equals("SpecifiedSupplyChainTradeAgreement"))) { || lineTrade.equals("SpecifiedSupplyChainTradeAgreement"))) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes(); NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) { for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds
.getLength(); tradeLineChildIndex++) {
if ((tradeLineChilds.item(tradeLineChildIndex).getLocalName() != null) && tradeLineChilds.item(tradeLineChildIndex).getLocalName().equals("AdditionalReferencedDocument")) { if ((tradeLineChilds.item(tradeLineChildIndex).getLocalName() != null) && tradeLineChilds
.item(tradeLineChildIndex).getLocalName().equals("AdditionalReferencedDocument")) {
String IssuerAssignedID = ""; String IssuerAssignedID = "";
String TypeCode = ""; String TypeCode = "";
String ReferenceTypeCode = ""; String ReferenceTypeCode = "";
@@ -212,7 +232,8 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
} }
ReferencedDocument rd = new ReferencedDocument(IssuerAssignedID, TypeCode, ReferenceTypeCode); ReferencedDocument rd = new ReferencedDocument(IssuerAssignedID, TypeCode,
ReferenceTypeCode);
if (rdocs == null) { if (rdocs == null) {
rdocs = new ArrayList<ReferencedDocument>(); rdocs = new ArrayList<ReferencedDocument>();
} }
@@ -220,11 +241,13 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
if ((tradeLineChilds.item(tradeLineChildIndex).getLocalName() != null) && tradeLineChilds.item(tradeLineChildIndex).getLocalName().equals("NetPriceProductTradePrice")) { if ((tradeLineChilds.item(tradeLineChildIndex).getLocalName() != null) && tradeLineChilds
.item(tradeLineChildIndex).getLocalName().equals("NetPriceProductTradePrice")) {
NodeList netChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes(); NodeList netChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes();
for (int netIndex = 0; netIndex < netChilds.getLength(); netIndex++) { for (int netIndex = 0; netIndex < netChilds.getLength(); netIndex++) {
if ((netChilds.item(netIndex).getLocalName() != null) && (netChilds.item(netIndex).getLocalName().equals("ChargeAmount"))) { if ((netChilds.item(netIndex).getLocalName() != null)
price = netChilds.item(netIndex).getTextContent();//ChargeAmount && (netChilds.item(netIndex).getLocalName().equals("ChargeAmount"))) {
price = netChilds.item(netIndex).getTextContent();// ChargeAmount
} }
} }
@@ -234,26 +257,37 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((lineTrade != null) && (lineTrade.equals("SpecifiedLineTradeDelivery") if ((lineTrade != null) && (lineTrade.equals("SpecifiedLineTradeDelivery")
|| lineTrade.equals("SpecifiedSupplyChainTradeDelivery"))) { || lineTrade.equals("SpecifiedSupplyChainTradeDelivery"))) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes(); NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) { for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds
.getLength(); tradeLineChildIndex++) {
String tradeName = tradeLineChilds.item(tradeLineChildIndex).getLocalName(); String tradeName = tradeLineChilds.item(tradeLineChildIndex).getLocalName();
if ((tradeName != null) if ((tradeName != null)
&& (tradeName.equals("BilledQuantity") || tradeName.equals("RequestedQuantity") && (tradeName.equals("BilledQuantity") || tradeName.equals("RequestedQuantity")
|| tradeName.equals("DespatchedQuantity"))) { || tradeName.equals("DespatchedQuantity"))) {
//RequestedQuantity is for Order-X, BilledQuantity for FX and ZF // RequestedQuantity is for Order-X, BilledQuantity for FX and ZF
quantity = tradeLineChilds.item(tradeLineChildIndex).getTextContent(); quantity = tradeLineChilds.item(tradeLineChildIndex).getTextContent();
unitCode = tradeLineChilds.item(tradeLineChildIndex).getAttributes().getNamedItem("unitCode").getNodeValue(); unitCode = tradeLineChilds.item(tradeLineChildIndex).getAttributes()
.getNamedItem("unitCode").getNodeValue();
} }
} }
} }
if ((lineTrade != null) && (lineTrade.equals("SpecifiedTradeProduct"))) { if ((lineTrade != null) && (lineTrade.equals("SpecifiedTradeProduct"))) {
NodeList tradeProductChilds = itemChilds.item(itemChildIndex).getChildNodes(); NodeList tradeProductChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeProductChildIndex = 0; tradeProductChildIndex < tradeProductChilds.getLength(); tradeProductChildIndex++) { for (int tradeProductChildIndex = 0; tradeProductChildIndex < tradeProductChilds
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null) && (tradeProductChilds.item(tradeProductChildIndex).getLocalName().equals("Name"))) { .getLength(); tradeProductChildIndex++) {
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null)
&& (tradeProductChilds.item(tradeProductChildIndex).getLocalName()
.equals("Name"))) {
name = tradeProductChilds.item(tradeProductChildIndex).getTextContent(); name = tradeProductChilds.item(tradeProductChildIndex).getTextContent();
} }
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null) && (tradeProductChilds.item(tradeProductChildIndex).getLocalName().equals("GlobalID"))) { if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null)
if (tradeProductChilds.item(tradeProductChildIndex).getAttributes().getNamedItem("schemeID") != null) { && (tradeProductChilds.item(tradeProductChildIndex).getLocalName()
gid = new SchemedID().setScheme(tradeProductChilds.item(tradeProductChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(tradeProductChilds.item(tradeProductChildIndex).getTextContent()); .equals("GlobalID"))) {
if (tradeProductChilds.item(tradeProductChildIndex).getAttributes()
.getNamedItem("schemeID") != null) {
gid = new SchemedID()
.setScheme(tradeProductChilds.item(tradeProductChildIndex).getAttributes()
.getNamedItem("schemeID").getNodeValue())
.setId(tradeProductChilds.item(tradeProductChildIndex).getTextContent());
} }
} }
@@ -262,14 +296,17 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((lineTrade != null) && (lineTrade.equals("SpecifiedLineTradeSettlement") if ((lineTrade != null) && (lineTrade.equals("SpecifiedLineTradeSettlement")
|| lineTrade.equals("SpecifiedSupplyChainTradeSettlement"))) { || lineTrade.equals("SpecifiedSupplyChainTradeSettlement"))) {
NodeList tradeSettlementChilds = itemChilds.item(itemChildIndex).getChildNodes(); NodeList tradeSettlementChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeSettlementChildIndex = 0; tradeSettlementChildIndex < tradeSettlementChilds.getLength(); tradeSettlementChildIndex++) { for (int tradeSettlementChildIndex = 0; tradeSettlementChildIndex < tradeSettlementChilds
.getLength(); tradeSettlementChildIndex++) {
String tradeSettlementName = tradeSettlementChilds.item(tradeSettlementChildIndex) String tradeSettlementName = tradeSettlementChilds.item(tradeSettlementChildIndex)
.getLocalName(); .getLocalName();
if (tradeSettlementName != null) { if (tradeSettlementName != null) {
if (tradeSettlementName.equals("ApplicableTradeTax")) { if (tradeSettlementName.equals("ApplicableTradeTax")) {
NodeList taxChilds = tradeSettlementChilds.item(tradeSettlementChildIndex).getChildNodes(); NodeList taxChilds = tradeSettlementChilds.item(tradeSettlementChildIndex)
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { .getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds
.getLength(); taxChildIndex++) {
String taxChildName = taxChilds.item(taxChildIndex).getLocalName(); String taxChildName = taxChilds.item(taxChildIndex).getLocalName();
if ((taxChildName != null) && (taxChildName.equals("RateApplicablePercent") if ((taxChildName != null) && (taxChildName.equals("RateApplicablePercent")
|| taxChildName.equals("ApplicablePercent"))) { || taxChildName.equals("ApplicablePercent"))) {
@@ -279,9 +316,12 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
if (tradeSettlementName.equals("SpecifiedTradeSettlementLineMonetarySummation")) { if (tradeSettlementName.equals("SpecifiedTradeSettlementLineMonetarySummation")) {
NodeList totalChilds = tradeSettlementChilds.item(tradeSettlementChildIndex).getChildNodes(); NodeList totalChilds = tradeSettlementChilds.item(tradeSettlementChildIndex)
for (int totalChildIndex = 0; totalChildIndex < totalChilds.getLength(); totalChildIndex++) { .getChildNodes();
if ((totalChilds.item(totalChildIndex).getLocalName() != null) && (totalChilds.item(totalChildIndex).getLocalName().equals("LineTotalAmount"))) { for (int totalChildIndex = 0; totalChildIndex < totalChilds
.getLength(); totalChildIndex++) {
if ((totalChilds.item(totalChildIndex).getLocalName() != null) && (totalChilds
.item(totalChildIndex).getLocalName().equals("LineTotalAmount"))) {
lineTotal = totalChilds.item(totalChildIndex).getTextContent(); lineTotal = totalChilds.item(totalChildIndex).getTextContent();
} }
} }
@@ -295,7 +335,8 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((recalcPrice) && (!qty.equals(BigDecimal.ZERO))) { if ((recalcPrice) && (!qty.equals(BigDecimal.ZERO))) {
prc = new BigDecimal(lineTotal.trim()).divide(qty, 4, RoundingMode.HALF_UP); prc = new BigDecimal(lineTotal.trim()).divide(qty, 4, RoundingMode.HALF_UP);
} }
Product p = new Product(name, description, unitCode, new BigDecimal(vatPercent.trim())); Product p = new Product(name, description, unitCode,
vatPercent == null ? null : new BigDecimal(vatPercent.trim()));
if (gid != null) { if (gid != null) {
p.addGlobalID(gid); p.addGlobalID(gid);
} }
@@ -307,14 +348,13 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
zpp.addItem(it); zpp.addItem(it);
} }
// item level charges+allowances are not yet handled but a lower item price will be read, // item level charges+allowances are not yet handled but a lower item price will
// be read,
// so the invoice remains arithmetically correct // so the invoice remains arithmetically correct
// -> parse document level charges+allowances // -> parse document level charges+allowances
xpr = xpath.compile( xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]");
"//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]");
NodeList chargeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList chargeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < chargeNodes.getLength(); i++) { for (int i = 0; i < chargeNodes.getLength(); i++) {
NodeList chargeNodeChilds = chargeNodes.item(i).getChildNodes(); NodeList chargeNodeChilds = chargeNodes.item(i).getChildNodes();
@@ -328,9 +368,13 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if (chargeChildName.equals("ChargeIndicator")) { if (chargeChildName.equals("ChargeIndicator")) {
NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) { for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds
if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null) && (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) { .getLength(); indicatorChildIndex++) {
isCharge = indicatorChilds.item(indicatorChildIndex).getTextContent().equalsIgnoreCase("true"); if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null)
&& (indicatorChilds.item(indicatorChildIndex).getLocalName()
.equals("Indicator"))) {
isCharge = indicatorChilds.item(indicatorChildIndex).getTextContent()
.equalsIgnoreCase("true");
} }
} }
} else if (chargeChildName.equals("ActualAmount")) { } else if (chargeChildName.equals("ActualAmount")) {
@@ -340,7 +384,9 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} else if (chargeChildName.equals("CategoryTradeTax")) { } else if (chargeChildName.equals("CategoryTradeTax")) {
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
if ((taxChilds.item(taxChildIndex).getLocalName() != null) && (taxChilds.item(taxChildIndex).getLocalName().equals("RateApplicablePercent"))) { String taxItemName = taxChilds.item(taxChildIndex).getLocalName();
if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent")
|| taxItemName.equals("ApplicablePercent"))) {
taxPercent = taxChilds.item(taxChildIndex).getTextContent(); taxPercent = taxChilds.item(taxChildIndex).getTextContent();
} }
} }
@@ -348,7 +394,6 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
} }
if (isCharge) { if (isCharge) {
Charge c = new Charge(new BigDecimal(chargeAmount)); Charge c = new Charge(new BigDecimal(chargeAmount));
if (reason != null) { if (reason != null) {
@@ -385,13 +430,15 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} }
if ((whichType != EStandard.despatchadvice) && ((!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2))) && (!ignoreCalculationErrors))) { if ((whichType != EStandard.despatchadvice)
throw new ParseException("Could not reproduce the invoice, this could mean that it could not be read properly", 0); && ((!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2)))
&& (!ignoreCalculationErrors))) {
throw new ParseException(
"Could not reproduce the invoice, this could mean that it could not be read properly", 0);
} }
} }
return zpp; return zpp;
} }
public void doRecalculateItemPricesFromLineTotals() { public void doRecalculateItemPricesFromLineTotals() {