Skip to content

Commit

Permalink
secondd UBL test
Browse files Browse the repository at this point in the history
  • Loading branch information
jstaerk committed Sep 12, 2023
1 parent 98fbd36 commit 6f0139d
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,8 @@ public static void main(String[] args) {
} else if ((action != null) && (action.equals("a3only"))) {
performConvert(sourceName, outName);
optionsRecognized = true;
} else if ((action != null) && (action.equals("pdf"))) {
performVisualization(sourceName, lang, outName, true);
optionsRecognized = true;
} else if ((action != null) && (action.equals("visualize"))) {
performVisualization(sourceName, lang, outName, false);
performVisualization(sourceName, lang, outName);
optionsRecognized = true;
} else if ((action != null) && (action.equals("upgrade"))) {
performUpgrade(sourceName, outName);
Expand Down
33 changes: 31 additions & 2 deletions library/src/main/java/org/mustangproject/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,49 @@ public Item(NodeList itemChilds, boolean recalcPrice) {
}
}
}
if ((currentUBLItemChildNode.getLocalName() != null) && (currentUBLItemChildNode.getLocalName().equals("SellersItemIdentification"))) {
for (Node currentUBLSellerIDNodes : XMLTools.asList(currentUBLItemChildNode.getChildNodes())) {
if ((currentUBLSellerIDNodes.getLocalName() != null) && (currentUBLSellerIDNodes.getLocalName().equals("ID"))) {
sellerAssignedID = currentUBLSellerIDNodes.getTextContent();
}
}
}
}
}

if ((lineTrade != null) && (lineTrade.equals("Price"))) {
// ubl
// PriceAmount with currencyID and BaseQuantity with unitCode
NodeList UBLpriceChilds = itemChilds.item(itemChildIndex).getChildNodes();
boolean isAllowance=true;
String allowanceCharge="";
for (Node currentUBLPriceChildNode : XMLTools.asList(UBLpriceChilds)) {

if ((currentUBLPriceChildNode.getLocalName() != null) && (currentUBLPriceChildNode.getLocalName().equals("PriceAmount"))) {
price = currentUBLPriceChildNode.getTextContent();
}
if ((currentUBLPriceChildNode.getLocalName() != null) && (currentUBLPriceChildNode.getLocalName().equals("BaseQuantity"))) {
basisQuantity = currentUBLPriceChildNode.getTextContent();
}
}/* not needed because already reflected in net price
if ((currentUBLPriceChildNode.getLocalName() != null) && (currentUBLPriceChildNode.getLocalName().equals("AllowanceCharge"))) {
for (Node currentUBLAllowanceChildNode : XMLTools.asList(currentUBLPriceChildNode.getChildNodes())) {
if ((currentUBLAllowanceChildNode.getLocalName()!=null)&&(currentUBLAllowanceChildNode.getLocalName().equals("ChargeIndicator"))) {
if (currentUBLAllowanceChildNode.getTextContent().equalsIgnoreCase("true")) {
isAllowance=false;
}
}
if ((currentUBLAllowanceChildNode.getLocalName()!=null)&&(currentUBLAllowanceChildNode.getLocalName().equals("Amount"))) {
allowanceCharge=currentUBLAllowanceChildNode.getTextContent();
}
}
if (isAllowance) {
// addAllowance(new Allowance(new BigDecimal(allowanceCharge)));
} else {
// addAllowance(new Charge(new BigDecimal(allowanceCharge)));
}
}*/
}

}
Expand Down Expand Up @@ -187,7 +216,7 @@ public Item(NodeList itemChilds, boolean recalcPrice) {
}
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null)
&& (tradeProductChilds.item(tradeProductChildIndex).getLocalName()
.equals("SellerAssignedID"))) {
.equals("SellerAssignedID") ) ) {
sellerAssignedID = tradeProductChilds.item(tradeProductChildIndex).getTextContent();
}
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,30 @@ public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseEx
{
// UBL...
number = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"ID\"]").trim();
issueDate=new SimpleDateFormat("yyyy-MM-dd")
.parse(extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim());
dueDate=new SimpleDateFormat("yyyy-MM-dd")
.parse(extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim());
deliveryDate=new SimpleDateFormat("yyyy-MM-dd")
.parse(extractString("//*[local-name()=\"Delivery\"]/*[local-name()=\"ActualDeliveryDate\"]").trim());
String issueDateStr=extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim();
if (!issueDateStr.equals("")) {
issueDate=new SimpleDateFormat("yyyy-MM-dd")
.parse(issueDateStr);
}
// else there is hopefully a invoice period
String issuePeriodFrom=extractString("//*[local-name()=\"InvoicePeriod\"]/*[local-name()=\"StartDate\"]").trim();
String issuePeriodTo=extractString("//*[local-name()=\"InvoicePeriod\"]/*[local-name()=\"EndDate\"]").trim();
if (!issuePeriodFrom.equals("")&&!issuePeriodTo.equals("")) {
zpp.setDetailedDeliveryPeriod(new SimpleDateFormat("yyyy-MM-dd").parse(issuePeriodFrom), new SimpleDateFormat("yyyy-MM-dd").parse(issuePeriodTo));

}


String dueDateStr=extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim();
if (!dueDateStr.equals("")) {
dueDate = new SimpleDateFormat("yyyy-MM-dd")
.parse(dueDateStr);
}
String deliveryDateStr=extractString("//*[local-name()=\"Delivery\"]/*[local-name()=\"ActualDeliveryDate\"]").trim();
if (!deliveryDateStr.equals("")) {
deliveryDate = new SimpleDateFormat("yyyy-MM-dd")
.parse(deliveryDateStr);
}
}
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]");
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
Expand Down Expand Up @@ -157,7 +175,7 @@ public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseEx
}
}

xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeAgreement\"]");
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeAgreement\"]|//*[local-name()=\"OrderReference\"]");
NodeList headerTradeAgreementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
String buyerOrderIssuerAssignedID = null;
String sellerOrderIssuerAssignedID = null;
Expand Down Expand Up @@ -197,6 +215,15 @@ public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseEx

}

if (sellerOrderIssuerAssignedID==null) {
//UBL?
sellerOrderIssuerAssignedID=extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"SalesOrderID\"]");
}

if (buyerOrderIssuerAssignedID==null) {
//UBL?
buyerOrderIssuerAssignedID=extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"ID\"]");
}

xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]");
NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
Expand Down Expand Up @@ -269,11 +296,11 @@ public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseEx
// be read,
// so the invoice remains arithmetically correct
// -> parse document level charges+allowances
xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]");
xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]|//*[local-name()=\"Invoice\"]/*[local-name()=\"AllowanceCharge\"]");
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;
Boolean isCharge = null;
String chargeAmount = null;
String reason = null;
String taxPercent = null;
Expand All @@ -288,28 +315,42 @@ public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseEx
if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null)
&& (indicatorChilds.item(indicatorChildIndex).getLocalName()
.equals("Indicator"))) {
isCharge = indicatorChilds.item(indicatorChildIndex).getTextContent()
.equalsIgnoreCase("true");
if (indicatorChilds.item(indicatorChildIndex).getTextContent()
.equalsIgnoreCase("true")) {
isCharge=Boolean.TRUE;
} else {
isCharge=Boolean.FALSE;
}
}
}
if (isCharge==null) {
// ubl (has no indicator)
if (chargeNodeChilds.item(chargeChildIndex).getTextContent()
.equalsIgnoreCase("true")) {
isCharge=Boolean.TRUE;
} else {
isCharge=Boolean.FALSE;
}
}
} else if (chargeChildName.equals("ActualAmount")) {
} else if ((chargeChildName.equals("ActualAmount"))||(chargeChildName.equals("Amount"))) {
// ActualAmount is CII, Amount is UBL
chargeAmount = chargeNodeChilds.item(chargeChildIndex).getTextContent();
} else if (chargeChildName.equals("Reason")) {
reason = chargeNodeChilds.item(chargeChildIndex).getTextContent();
} else if (chargeChildName.equals("CategoryTradeTax")) {
} else if (chargeChildName.equals("CategoryTradeTax")||chargeChildName.equals("TaxCategory")/*UBL*/) {
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
String taxItemName = taxChilds.item(taxChildIndex).getLocalName();
if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent")
|| taxItemName.equals("ApplicablePercent"))) {
|| taxItemName.equals("ApplicablePercent")|| taxItemName.equals("Percent"/*UBL*/))) {
taxPercent = taxChilds.item(taxChildIndex).getTextContent();
}
}
}
}
}

if (isCharge) {
if (isCharge.booleanValue()) {
Charge c = new Charge(new BigDecimal(chargeAmount));
if (reason != null) {
c.setReason(reason);
Expand Down Expand Up @@ -346,7 +387,7 @@ public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseEx
&& ((!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);
"Could not reproduce the invoice (would have expected a grand total of "+expectedStringTotalGross+" instead of "+XMLTools.nDigitFormat(expectedGrandTotal, 2)+"), this could mean that it could not be read properly", 0);
}
}
return zpp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,31 @@ public void testEdgeInvoiceImport() {

}

public void testEdgeInvoiceImportUBL() {

boolean hasExceptions=false;
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
File expectedResult = getResourceAsFile("testout-ZF2PushEdge.ubl.xml");

Invoice invoice = null;
try {
String xml = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", "");

zii.fromXML(xml);

invoice = zii.extractInvoice();
} catch (XPathExpressionException | ParseException | IOException e) {
hasExceptions = true;
}

assertFalse(hasExceptions);
// Reading ZUGFeRD
assertEquals("4711", invoice.getZFItems()[0].getProduct().getSellerAssignedID());
assertEquals("9384", invoice.getSellerOrderReferencedDocumentID());
assertEquals("28934", invoice.getBuyerOrderReferencedDocumentID());

}

public void testZF1Import() {

ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf");
Expand Down Expand Up @@ -235,6 +260,27 @@ public void testItemAllowancesChargesImport() {
assertEquals(new BigDecimal("18.33"), tc.getGrandTotal());
}

public void testItemAllowancesChargesImportUBL() {

boolean hasExceptions=false;
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
File expectedResult = getResourceAsFile("testout-ZF2PushItemChargesAllowances.ubl.xml");

Invoice invoice = null;
try {
String xml = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", "");

zii.fromXML(xml);

invoice = zii.extractInvoice();
} catch (XPathExpressionException | ParseException | IOException e) {
hasExceptions = true;
}
assertFalse(hasExceptions);
TransactionCalculator tc = new TransactionCalculator(invoice);
assertEquals(new BigDecimal("18.33"), tc.getGrandTotal());
}

public void testBasisQuantityImport() {

ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2newEdge.pdf");
Expand Down

0 comments on commit 6f0139d

Please sign in to comment.