write support for referenceddocument

This commit is contained in:
jstaerk
2021-10-21 13:58:10 +02:00
parent d0e3fb1876
commit cfee4b3c31
6 changed files with 184 additions and 73 deletions

View File

@@ -1,5 +1,6 @@
package org.mustangproject;
import org.mustangproject.ZUGFeRD.IReferencedDocument;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
@@ -17,6 +18,7 @@ public class Item implements IZUGFeRDExportableItem {
protected String referencedLineID=null;
protected Product product;
protected ArrayList<String> notes = null;
protected ArrayList<ReferencedDocument> referencedDocuments = null;
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<IZUGFeRDAllowanceCharge>(),
Charges = new ArrayList<IZUGFeRDAllowanceCharge>();
@@ -189,6 +191,26 @@ public class Item implements IZUGFeRDExportableItem {
return this;
}
/***
* adds item level Referenced documents along with their typecodes and issuerassignedIDs
* @param doc the ReferencedDocument to add
* @return fluent setter
*/
public Item addReferencedDocument(ReferencedDocument doc) {
if (referencedDocuments==null) {
referencedDocuments=new ArrayList<ReferencedDocument>();
}
referencedDocuments.add(doc);
return this;
}
@Override
public IReferencedDocument[] getReferencedDocuments() {
if (referencedDocuments==null) {
return null;
}
return referencedDocuments.toArray(new IReferencedDocument[0]);
}
/***
* specify a item level delivery period
* (apart from the document level delivery period, and the document level

View File

@@ -0,0 +1,38 @@
package org.mustangproject;
import org.mustangproject.ZUGFeRD.IReferencedDocument;
public class ReferencedDocument implements IReferencedDocument {
String issuerAssignedID;
String typeCode;
String referenceTypeCode;
public void setIssuerAssignedID(String issuerAssignedID) {
this.issuerAssignedID = issuerAssignedID;
}
public void setTypeCode(String typeCode) {
this.typeCode = typeCode;
}
public void setReferenceTypeCode(String referenceTypeCode) {
this.referenceTypeCode = referenceTypeCode;
}
@Override
public String getIssuerAssignedID() {
return issuerAssignedID;
}
@Override
public String getTypeCode() {
return typeCode;
}
@Override
public String getReferenceTypeCode() {
return referenceTypeCode;
}
}

View File

@@ -0,0 +1,8 @@
package org.mustangproject.ZUGFeRD;
public interface IReferencedDocument {
String getIssuerAssignedID();
String getTypeCode();
String getReferenceTypeCode();
}

View File

@@ -94,6 +94,14 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
return null;
}
/***
* allows to specify multiple(!) referenced documents along with e.g. their typecodes
* @return
*/
default IReferencedDocument[] getReferencedDocuments() {
return null;
}
/***
* descriptive texts
* @return an array of strings of item specific "includedNotes", text values

View File

@@ -351,9 +351,21 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ " </ram:SpecifiedTradeProduct>\n"
+ " <ram:SpecifiedLineTradeAgreement>\n";
if (currentItem.getReferencedDocuments() != null) {
for (IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) {
xml = xml + "<ram:AdditionalReferencedDocument>\n" +
"<ram:IssuerAssignedID>" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "</ram:IssuerAssignedID>\n" +
"<ram:TypeCode>" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "</ram:TypeCode>\n" +
"<ram:ReferenceTypeCode>" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "</ram:ReferenceTypeCode>\n" +
"</ram:AdditionalReferencedDocument>\n";
}
}
if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) {
xml = xml + " <ram:BuyerOrderReferencedDocument> \n"
+ " <ram:LineID>"+XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID())+"</ram:LineID>\n"
+ " <ram:LineID>" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "</ram:LineID>\n"
+ " </ram:BuyerOrderReferencedDocument>\n";
}

View File

@@ -18,6 +18,8 @@ import java.util.Date;
public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDInvoiceImporter.class.getCanonicalName()); // log
private boolean recalcPrice = false;
private boolean ignoreCalculationErrors = false;
public ZUGFeRDInvoiceImporter() {
super();
@@ -84,7 +86,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((exchangedDocumentChilds.item(documentChildIndex).getLocalName() != null) && (exchangedDocumentChilds.item(documentChildIndex).getLocalName().equals("IssueDateTime"))) {
NodeList issueDateTimeChilds = exchangedDocumentChilds.item(documentChildIndex).getChildNodes();
for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) {
if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName()!=null)&&(issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) {
if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null) && (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) {
issueDate = new SimpleDateFormat("yyyyMMdd").parse(issueDateTimeChilds.item(issueDateChildIndex).getTextContent());
}
}
@@ -160,6 +162,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
String description = "";
String quantity = "0";
String vatPercent = "0";
String lineTotal = "0";
String unitCode = "0";
//nodes.item(i).getTextContent())) {
@@ -169,7 +172,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((itemChilds.item(itemChildIndex).getLocalName() != null) && (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedLineTradeAgreement"))) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) {
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();
for (int netIndex = 0; netIndex < netChilds.getLength(); netIndex++) {
if ((netChilds.item(netIndex).getLocalName() != null) && (netChilds.item(netIndex).getLocalName().equals("ChargeAmount"))) {
@@ -192,8 +195,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((itemChilds.item(itemChildIndex).getLocalName() != null) && (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedTradeProduct"))) {
NodeList tradeProductChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeProductChildIndex = 0; tradeProductChildIndex < tradeProductChilds.getLength(); tradeProductChildIndex++) {
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null) && (tradeProductChilds.item(tradeProductChildIndex).getLocalName().equals("Name")))
{
if ((tradeProductChilds.item(tradeProductChildIndex).getLocalName() != null) && (tradeProductChilds.item(tradeProductChildIndex).getLocalName().equals("Name"))) {
name = tradeProductChilds.item(tradeProductChildIndex).getTextContent();
}
}
@@ -201,7 +203,9 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
if ((itemChilds.item(itemChildIndex).getLocalName() != null) && (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedLineTradeSettlement"))) {
NodeList tradeSettlementChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeSettlementChildIndex = 0; tradeSettlementChildIndex < tradeSettlementChilds.getLength(); tradeSettlementChildIndex++) {
if ((tradeSettlementChilds.item(tradeSettlementChildIndex).getLocalName() != null) && (tradeSettlementChilds.item(tradeSettlementChildIndex).getLocalName().equals("ApplicableTradeTax"))) {
if (tradeSettlementChilds.item(tradeSettlementChildIndex).getLocalName() != null) {
if (tradeSettlementChilds.item(tradeSettlementChildIndex).getLocalName().equals("ApplicableTradeTax")) {
NodeList taxChilds = tradeSettlementChilds.item(tradeSettlementChildIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
if ((taxChilds.item(taxChildIndex).getLocalName() != null) && (taxChilds.item(taxChildIndex).getLocalName().equals("RateApplicablePercent"))) {
@@ -209,13 +213,26 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
}
}
}
}
}
if (tradeSettlementChilds.item(tradeSettlementChildIndex).getLocalName().equals("SpecifiedTradeSettlementLineMonetarySummation")) {
NodeList totalChilds = tradeSettlementChilds.item(tradeSettlementChildIndex).getChildNodes();
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();
}
}
}
}
}
}
}
BigDecimal prc = new BigDecimal(price.trim());
BigDecimal qty = new BigDecimal(quantity.trim());
if ((recalcPrice) && (!qty.equals(BigDecimal.ZERO))) {
prc = new BigDecimal(lineTotal.trim()).divide(qty,4, RoundingMode.HALF_UP);
}
zpp.addItem(new Item(new Product(name, description, unitCode, new BigDecimal(vatPercent.trim())), prc, qty));
}
zpp.addItem(new Item(new Product(name, description, unitCode, new BigDecimal(vatPercent.trim())), new BigDecimal(price.trim()), new BigDecimal(quantity.trim())));
}
}
@@ -248,15 +265,12 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
} else if (chargeNodeChilds.item(chargeChildIndex).getLocalName().equals("CategoryTradeTax")) {
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
if ((taxChilds.item(taxChildIndex).getLocalName() != null) && (taxChilds.item(taxChildIndex).getLocalName().equals("RateApplicablePercent")))
{
if ((taxChilds.item(taxChildIndex).getLocalName() != null) && (taxChilds.item(taxChildIndex).getLocalName().equals("RateApplicablePercent"))) {
taxPercent = taxChilds.item(taxChildIndex).getTextContent();
}
}
}
}
}
@@ -285,11 +299,20 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
TransactionCalculator tc = new TransactionCalculator(zpp);
String expectedStringTotalGross = tc.getGrandTotal().toPlainString();
if (!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2))) {
if ((!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;
}
public void doRecalculateItemPricesFromLineTotals() {
recalcPrice = true;
}
public void doIgnoreCalculationErrors() {
ignoreCalculationErrors = true;
}
}