Merge pull request #217 from weclapp-dev/dev/SellerOrderReferencedDocument

Dev/seller order referenced document
This commit is contained in:
Jochen Staerk
2021-01-21 15:42:55 +01:00
committed by GitHub
5 changed files with 209 additions and 147 deletions

View File

@@ -39,6 +39,7 @@ public class Invoice implements IExportableTransaction {
protected TradeParty sender = null, recipient = null, deliveryAddress = null; protected TradeParty sender = null, recipient = null, deliveryAddress = null;
protected ArrayList<IZUGFeRDExportableItem> ZFItems = null; protected ArrayList<IZUGFeRDExportableItem> ZFItems = null;
protected ArrayList<String> notes = null; protected ArrayList<String> notes = null;
private String sellerOrderReferencedDocumentID;
protected String contractReferencedDocument = null; protected String contractReferencedDocument = null;
protected ArrayList<FileAttachment> xmlEmbeddedFiles=null; protected ArrayList<FileAttachment> xmlEmbeddedFiles=null;
@@ -50,7 +51,7 @@ public class Invoice implements IExportableTransaction {
protected IZUGFeRDPaymentTerms paymentTerms = null; protected IZUGFeRDPaymentTerms paymentTerms = null;
public Invoice() { public Invoice() {
ZFItems = new ArrayList<IZUGFeRDExportableItem>(); ZFItems = new ArrayList<IZUGFeRDExportableItem>();
setCurrency("EUR"); setCurrency("EUR");
} }
@@ -60,7 +61,8 @@ public class Invoice implements IExportableTransaction {
return documentName; return documentName;
} }
public String getContractReferencedDocument() { @Override
public String getContractReferencedDocument() {
return contractReferencedDocument; return contractReferencedDocument;
} }
@@ -81,13 +83,14 @@ public class Invoice implements IExportableTransaction {
public Invoice embedFileInXML(FileAttachment fa) { public Invoice embedFileInXML(FileAttachment fa) {
if (xmlEmbeddedFiles == null) { if (xmlEmbeddedFiles == null) {
xmlEmbeddedFiles=new ArrayList<FileAttachment>(); xmlEmbeddedFiles= new ArrayList<>();
} }
xmlEmbeddedFiles.add(fa); xmlEmbeddedFiles.add(fa);
return this; return this;
} }
public FileAttachment[] getAdditionalReferencedDocuments() { @Override
public FileAttachment[] getAdditionalReferencedDocuments() {
if (xmlEmbeddedFiles == null) { if (xmlEmbeddedFiles == null) {
return null; return null;
} }
@@ -209,7 +212,16 @@ public class Invoice implements IExportableTransaction {
public String getBuyerOrderReferencedDocumentID() { public String getBuyerOrderReferencedDocumentID() {
return buyerOrderReferencedDocumentID; return buyerOrderReferencedDocumentID;
} }
@Override
public String getSellerOrderReferencedDocumentID() {
return sellerOrderReferencedDocumentID;
}
public Invoice setSellerOrderReferencedDocumentID(String sellerOrderReferencedDocumentID) {
this.sellerOrderReferencedDocumentID = sellerOrderReferencedDocumentID;
return this;
}
/*** /***
* usually the order number or in case of a correction the original invoice number * usually the order number or in case of a correction the original invoice number
* @param buyerOrderReferencedDocumentID string with number * @param buyerOrderReferencedDocumentID string with number
@@ -310,12 +322,14 @@ public class Invoice implements IExportableTransaction {
} }
public String getOwnLocation() { @Override
public String getOwnLocation() {
return sender.getLocation(); return sender.getLocation();
} }
public String getOwnCountry() { @Override
public String getOwnCountry() {
return sender.getCountry(); return sender.getCountry();
} }
@@ -405,7 +419,8 @@ public class Invoice implements IExportableTransaction {
return this; return this;
} }
public IZUGFeRDExportableTradeParty getRecipient() { @Override
public IZUGFeRDExportableTradeParty getRecipient() {
return recipient; return recipient;
} }
@@ -439,8 +454,9 @@ public class Invoice implements IExportableTransaction {
public IZUGFeRDAllowanceCharge[] getZFAllowances() { public IZUGFeRDAllowanceCharge[] getZFAllowances() {
if (Allowances.isEmpty()) { if (Allowances.isEmpty()) {
return null; return null;
} else } else {
return Allowances.toArray(new IZUGFeRDAllowanceCharge[0]); return Allowances.toArray(new IZUGFeRDAllowanceCharge[0]);
}
} }
@@ -448,8 +464,9 @@ public class Invoice implements IExportableTransaction {
public IZUGFeRDAllowanceCharge[] getZFCharges() { public IZUGFeRDAllowanceCharge[] getZFCharges() {
if (Charges.isEmpty()) { if (Charges.isEmpty()) {
return null; return null;
} else } else {
return Charges.toArray(new IZUGFeRDAllowanceCharge[0]); return Charges.toArray(new IZUGFeRDAllowanceCharge[0]);
}
} }
@@ -457,8 +474,9 @@ public class Invoice implements IExportableTransaction {
public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() {
if (LogisticsServiceCharges.isEmpty()) { if (LogisticsServiceCharges.isEmpty()) {
return null; return null;
} else } else {
return LogisticsServiceCharges.toArray(new IZUGFeRDAllowanceCharge[0]); return LogisticsServiceCharges.toArray(new IZUGFeRDAllowanceCharge[0]);
}
} }
@@ -599,7 +617,7 @@ public class Invoice implements IExportableTransaction {
*/ */
public Invoice addNote(String text) { public Invoice addNote(String text) {
if (notes == null) { if (notes == null) {
notes = new ArrayList<String>(); notes = new ArrayList<>();
} }
notes.add(text); notes.add(text);
return this; return this;

View File

@@ -398,6 +398,14 @@ public interface IExportableTransaction {
} }
/**
* get the ID of the SellerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement/ApplicableHeaderTradeAgreement
*
* @return the ID of the document
*/
default String getSellerOrderReferencedDocumentID() {
return null;
}
/** /**
* get the ID of the BuyerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement * get the ID of the BuyerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement
* *

View File

@@ -20,13 +20,6 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.XMLTools;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@@ -37,6 +30,13 @@ import java.util.HashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.XMLTools;
public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLProvider { public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLProvider {
@@ -82,20 +82,20 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
byte[] res = zugferdData; byte[] res = zugferdData;
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
Document document = null; Document document = null;
try { try {
document = DocumentHelper.parseText(new String(zugferdData)); document = DocumentHelper.parseText(new String(zugferdData));
} catch (DocumentException e1) { } catch (final DocumentException e1) {
Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e1); Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e1);
} }
try { try {
OutputFormat format = OutputFormat.createPrettyPrint(); final OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(sw, format); final XMLWriter writer = new XMLWriter(sw, format);
writer.write(document); writer.write(document);
res = sw.toString().getBytes("UTF-8"); res = sw.toString().getBytes("UTF-8");
} catch (IOException e) { } catch (final IOException e) {
Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e);
} }
@@ -110,7 +110,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
this.calc = new TransactionCalculator(trans); this.calc = new TransactionCalculator(trans);
boolean hasDueDate = false; boolean hasDueDate = false;
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
String exemptionReason = ""; String exemptionReason = "";
if (trans.getPaymentTermDescription() != null) { if (trans.getPaymentTermDescription() != null) {
@@ -199,6 +199,12 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
xml += " </ram:BuyerTradeParty>\n"; xml += " </ram:BuyerTradeParty>\n";
if (trans.getSellerOrderReferencedDocumentID() != null) {
xml = xml + " <ram:SellerOrderReferencedDocument>\n"
+ " <ram:IssuerAssignedID>"
+ XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "</ram:IssuerAssignedID>\n"
+ " </ram:SellerOrderReferencedDocument>\n";
}
if (trans.getBuyerOrderReferencedDocumentID() != null) { if (trans.getBuyerOrderReferencedDocumentID() != null) {
xml = xml + " <ram:BuyerOrderReferencedDocument>\n" xml = xml + " <ram:BuyerOrderReferencedDocument>\n"
+ " <ram:IssuerAssignedID>" + " <ram:IssuerAssignedID>"
@@ -235,7 +241,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
+ " <ram:InvoiceCurrencyCode>" + trans.getCurrency() + "</ram:InvoiceCurrencyCode>\n"; + " <ram:InvoiceCurrencyCode>" + trans.getCurrency() + "</ram:InvoiceCurrencyCode>\n";
if (trans.getTradeSettlementPayment() != null) { if (trans.getTradeSettlementPayment() != null) {
for (IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) {
if (payment != null) { if (payment != null) {
hasDueDate = true; hasDueDate = true;
xml += payment.getSettlementXML(); xml += payment.getSettlementXML();
@@ -243,7 +249,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
} }
} }
if (trans.getTradeSettlement() != null) { if (trans.getTradeSettlement() != null) {
for (IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if (payment != null) { if (payment != null) {
if (payment instanceof IZUGFeRDTradeSettlementPayment) { if (payment instanceof IZUGFeRDTradeSettlementPayment) {
hasDueDate = true; hasDueDate = true;
@@ -253,9 +259,9 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
} }
} }
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap(); final HashMap<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) { if (amount != null) {
xml += " <ram:ApplicableTradeTax>\n" xml += " <ram:ApplicableTradeTax>\n"
+ " <ram:CalculatedAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(amount.getCalculated()) + " <ram:CalculatedAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(amount.getCalculated())
@@ -275,7 +281,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
+ " <ram:Description>" + paymentTermsDescription + "</ram:Description>\n"; + " <ram:Description>" + paymentTermsDescription + "</ram:Description>\n";
if (trans.getTradeSettlement() != null) { if (trans.getTradeSettlement() != null) {
for (IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) {
xml += payment.getPaymentXML(); xml += payment.getPaymentXML();
} }
@@ -318,14 +324,14 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
int lineID = 0; int lineID = 0;
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
lineID++; lineID++;
if (currentItem.getProduct().getTaxExemptionReason() != null) { if (currentItem.getProduct().getTaxExemptionReason() != null) {
exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>"; exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
} }
LineCalculator lc = new LineCalculator(currentItem); final LineCalculator lc = new LineCalculator(currentItem);
xml = xml + " <ram:IncludedSupplyChainTradeLineItem>\n" + xml = xml + " <ram:IncludedSupplyChainTradeLineItem>\n" +
" <ram:AssociatedDocumentLineDocument>\n" " <ram:AssociatedDocumentLineDocument>\n"
+ " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-2$ + " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-2$
@@ -404,11 +410,11 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
xml = xml + " </rsm:SpecifiedSupplyChainTradeTransaction>\n" xml = xml + " </rsm:SpecifiedSupplyChainTradeTransaction>\n"
+ "</rsm:CrossIndustryDocument>"; + "</rsm:CrossIndustryDocument>";
byte[] zugferdRaw; final byte[] zugferdRaw;
try { try {
zugferdRaw = xml.getBytes("UTF-8"); zugferdRaw = xml.getBytes("UTF-8");
zugferdData = XMLTools.removeBOM(zugferdRaw); zugferdData = XMLTools.removeBOM(zugferdRaw);
} catch (UnsupportedEncodingException e) { } catch (final UnsupportedEncodingException e) {
Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e);
} }
} }
@@ -421,9 +427,9 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
private String buildPaymentTermsXml() { private String buildPaymentTermsXml() {
String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>"; String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>";
IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
Date dueDate = paymentTerms.getDueDate(); final Date dueDate = paymentTerms.getDueDate();
if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) {
throw new IllegalStateException( throw new IllegalStateException(
"if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified"); "if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified");
@@ -438,14 +444,14 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
if (discountTerms != null) { if (discountTerms != null) {
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>"; paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
String currency = trans.getCurrency(); final String currency = trans.getCurrency();
String basisAmount = currencyFormat(calc.getGrandTotal()); final String basisAmount = currencyFormat(calc.getGrandTotal());
paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>"; paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>";
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString() paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>"; + "</ram:CalculationPercent>";
if (discountTerms.getBaseDate() != null) { if (discountTerms.getBaseDate() != null) {
Date baseDate = discountTerms.getBaseDate(); final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>"; paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(baseDate) + "</udt:DateTimeString>"; paymentTermsXml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(baseDate) + "</udt:DateTimeString>";
paymentTermsXml += "</ram:BasisDateTime>"; paymentTermsXml += "</ram:BasisDateTime>";

View File

@@ -20,17 +20,18 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.Base64;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentException; import org.dom4j.DocumentException;
@@ -39,9 +40,6 @@ import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import org.mustangproject.FileAttachment; import org.mustangproject.FileAttachment;
import org.mustangproject.XMLTools; import org.mustangproject.XMLTools;
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE;
public class ZUGFeRD2PullProvider implements IXMLProvider { public class ZUGFeRD2PullProvider implements IXMLProvider {
@@ -82,20 +80,20 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
byte[] res = zugferdData; byte[] res = zugferdData;
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
Document document = null; Document document = null;
try { try {
document = DocumentHelper.parseText(new String(zugferdData)); document = DocumentHelper.parseText(new String(zugferdData));
} catch (DocumentException e1) { } catch (final DocumentException e1) {
Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e1); Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e1);
} }
try { try {
OutputFormat format = OutputFormat.createPrettyPrint(); final OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(sw, format); final XMLWriter writer = new XMLWriter(sw, format);
writer.write(document); writer.write(document);
res = sw.toString().getBytes("UTF-8"); res = sw.toString().getBytes("UTF-8");
} catch (IOException e) { } catch (final IOException e) {
Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e);
} }
@@ -210,7 +208,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
// only in extended profile // only in extended profile
reason = "<ram:Reason>" + XMLTools.encodeXML(allowance.getReason()) + "</ram:Reason>"; reason = "<ram:Reason>" + XMLTools.encodeXML(allowance.getReason()) + "</ram:Reason>";
} }
String allowanceChargeStr = "<ram:AppliedTradeAllowanceCharge><ram:ChargeIndicator><udt:Indicator>" + final String allowanceChargeStr = "<ram:AppliedTradeAllowanceCharge><ram:ChargeIndicator><udt:Indicator>" +
chargeIndicator + "</udt:Indicator></ram:ChargeIndicator>" + percentage + chargeIndicator + "</udt:Indicator></ram:ChargeIndicator>" + percentage +
"<ram:ActualAmount>" + priceFormat(allowance.getTotalAmount(item)) + "</ram:ActualAmount>" + "<ram:ActualAmount>" + priceFormat(allowance.getTotalAmount(item)) + "</ram:ActualAmount>" +
reason + reason +
@@ -224,7 +222,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
this.calc = new TransactionCalculator(trans); this.calc = new TransactionCalculator(trans);
boolean hasDueDate = false; boolean hasDueDate = false;
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
String exemptionReason = ""; String exemptionReason = "";
@@ -265,7 +263,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
String notes = ""; String notes = "";
if (trans.getNotes() != null) { if (trans.getNotes() != null) {
for (String currentNote : trans.getNotes()) { for (final String currentNote : trans.getNotes()) {
notes = notes + "<ram:IncludedNote><ram:Content>" + XMLTools.encodeXML(currentNote) + "</ram:Content></ram:IncludedNote>"; notes = notes + "<ram:IncludedNote><ram:Content>" + XMLTools.encodeXML(currentNote) + "</ram:Content></ram:IncludedNote>";
} }
@@ -301,19 +299,19 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ " </rsm:ExchangedDocument>\n" + " </rsm:ExchangedDocument>\n"
+ " <rsm:SupplyChainTradeTransaction>\n"; + " <rsm:SupplyChainTradeTransaction>\n";
int lineID = 0; int lineID = 0;
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
lineID++; lineID++;
if (currentItem.getProduct().getTaxExemptionReason() != null) { if (currentItem.getProduct().getTaxExemptionReason() != null) {
exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>"; exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
} }
notes = ""; notes = "";
if (currentItem.getNotes() != null) { if (currentItem.getNotes() != null) {
for (String currentNote : currentItem.getNotes()) { for (final String currentNote : currentItem.getNotes()) {
notes = notes + "<ram:IncludedNote><ram:Content>" + XMLTools.encodeXML(currentNote) + "</ram:Content></ram:IncludedNote>"; notes = notes + "<ram:IncludedNote><ram:Content>" + XMLTools.encodeXML(currentNote) + "</ram:Content></ram:IncludedNote>";
} }
} }
LineCalculator lc = new LineCalculator(currentItem); final LineCalculator lc = new LineCalculator(currentItem);
xml = xml + " <ram:IncludedSupplyChainTradeLineItem>\n" + xml = xml + " <ram:IncludedSupplyChainTradeLineItem>\n" +
" <ram:AssociatedDocumentLineDocument>\n" " <ram:AssociatedDocumentLineDocument>\n"
+ " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-2$ + " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-2$
@@ -332,12 +330,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
String allowanceChargeStr = ""; String allowanceChargeStr = "";
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) {
for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
} }
} }
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) {
for (IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);
} }
@@ -423,6 +421,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml += getTradePartyAsXML(trans.getRecipient(), false, false); xml += getTradePartyAsXML(trans.getRecipient(), false, false);
xml += " </ram:BuyerTradeParty>\n"; xml += " </ram:BuyerTradeParty>\n";
if (trans.getSellerOrderReferencedDocumentID() != null) {
xml = xml + " <ram:SellerOrderReferencedDocument>\n"
+ " <ram:IssuerAssignedID>"
+ XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "</ram:IssuerAssignedID>\n"
+ " </ram:SellerOrderReferencedDocument>\n";
}
if (trans.getBuyerOrderReferencedDocumentID() != null) { if (trans.getBuyerOrderReferencedDocumentID() != null) {
xml = xml + " <ram:BuyerOrderReferencedDocument>\n" xml = xml + " <ram:BuyerOrderReferencedDocument>\n"
+ " <ram:IssuerAssignedID>" + " <ram:IssuerAssignedID>"
@@ -438,7 +442,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
// Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung)
if (trans.getAdditionalReferencedDocuments() != null) { if (trans.getAdditionalReferencedDocuments() != null) {
for (FileAttachment f : trans.getAdditionalReferencedDocuments()) { for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) {
final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData()));
xml = xml + " <ram:AdditionalReferencedDocument>\n" xml = xml + " <ram:AdditionalReferencedDocument>\n"
+ " <ram:IssuerAssignedID>" + f.getFilename() + "</ram:IssuerAssignedID>\n" + " <ram:IssuerAssignedID>" + f.getFilename() + "</ram:IssuerAssignedID>\n"
@@ -480,7 +484,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ " <ram:InvoiceCurrencyCode>" + trans.getCurrency() + "</ram:InvoiceCurrencyCode>\n"; + " <ram:InvoiceCurrencyCode>" + trans.getCurrency() + "</ram:InvoiceCurrencyCode>\n";
if (trans.getTradeSettlementPayment() != null) { if (trans.getTradeSettlementPayment() != null) {
for (IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) {
if (payment != null) { if (payment != null) {
hasDueDate = true; hasDueDate = true;
xml += payment.getSettlementXML(); xml += payment.getSettlementXML();
@@ -488,7 +492,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
} }
if (trans.getTradeSettlement() != null) { if (trans.getTradeSettlement() != null) {
for (IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if (payment != null) { if (payment != null) {
if (payment instanceof IZUGFeRDTradeSettlementPayment) { if (payment instanceof IZUGFeRDTradeSettlementPayment) {
hasDueDate = true; hasDueDate = true;
@@ -501,9 +505,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
hasDueDate = false; hasDueDate = false;
} }
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap(); final HashMap<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) { if (amount != null) {
xml += " <ram:ApplicableTradeTax>\n" xml += " <ram:ApplicableTradeTax>\n"
+ " <ram:CalculatedAmount>" + currencyFormat(amount.getCalculated()) + " <ram:CalculatedAmount>" + currencyFormat(amount.getCalculated())
@@ -532,7 +536,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) {
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) {
@@ -555,7 +559,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) {
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) {
xml = xml + " <ram:SpecifiedTradeAllowanceCharge>\n" + xml = xml + " <ram:SpecifiedTradeAllowanceCharge>\n" +
" <ram:ChargeIndicator>\n" + " <ram:ChargeIndicator>\n" +
@@ -582,7 +586,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
if (trans.getTradeSettlement() != null) { if (trans.getTradeSettlement() != null) {
for (IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) {
xml += payment.getPaymentXML(); xml += payment.getPaymentXML();
} }
@@ -601,9 +605,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
String allowanceTotalLine = "<ram:AllowanceTotalAmount>" + currencyFormat(calc.getAllowancesForPercent(null)) + "</ram:AllowanceTotalAmount>"; final String allowanceTotalLine = "<ram:AllowanceTotalAmount>" + currencyFormat(calc.getAllowancesForPercent(null)) + "</ram:AllowanceTotalAmount>";
String chargesTotalLine = "<ram:ChargeTotalAmount>" + currencyFormat(calc.getChargesForPercent(null)) + "</ram:ChargeTotalAmount>"; final String chargesTotalLine = "<ram:ChargeTotalAmount>" + currencyFormat(calc.getChargesForPercent(null)) + "</ram:ChargeTotalAmount>";
xml = xml + " <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n" xml = xml + " <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n"
+ " <ram:LineTotalAmount>" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-2$ + " <ram:LineTotalAmount>" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-2$
@@ -635,12 +639,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml = xml + " </rsm:SupplyChainTradeTransaction>\n" xml = xml + " </rsm:SupplyChainTradeTransaction>\n"
+ "</rsm:CrossIndustryInvoice>"; + "</rsm:CrossIndustryInvoice>";
byte[] zugferdRaw; final byte[] zugferdRaw;
try { try {
zugferdRaw = xml.getBytes("UTF-8"); zugferdRaw = xml.getBytes("UTF-8");
zugferdData = XMLTools.removeBOM(zugferdRaw); zugferdData = XMLTools.removeBOM(zugferdRaw);
} catch (UnsupportedEncodingException e) { } catch (final UnsupportedEncodingException e) {
Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e);
} }
} }
@@ -652,14 +656,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
private String buildPaymentTermsXml() { private String buildPaymentTermsXml() {
IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
if (paymentTerms==null) { if (paymentTerms==null) {
return ""; return "";
} }
String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>"; String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>";
IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
Date dueDate = paymentTerms.getDueDate(); final Date dueDate = paymentTerms.getDueDate();
if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) {
throw new IllegalStateException( throw new IllegalStateException(
"if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified"); "if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified");
@@ -674,14 +678,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if (discountTerms != null) { if (discountTerms != null) {
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>"; paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
String currency = trans.getCurrency(); final String currency = trans.getCurrency();
String basisAmount = currencyFormat(calc.getGrandTotal()); final String basisAmount = currencyFormat(calc.getGrandTotal());
paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>"; paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>";
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString() paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>"; + "</ram:CalculationPercent>";
if (discountTerms.getBaseDate() != null) { if (discountTerms.getBaseDate() != null) {
Date baseDate = discountTerms.getBaseDate(); final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>"; paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(baseDate) + "</udt:DateTimeString>"; paymentTermsXml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(baseDate) + "</udt:DateTimeString>";
paymentTermsXml += "</ram:BasisDateTime>"; paymentTermsXml += "</ram:BasisDateTime>";

View File

@@ -21,23 +21,31 @@ import java.math.BigDecimal;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.mustangproject.Item;
import org.mustangproject.Product;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.mustangproject.Item;
import org.mustangproject.Product;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@@ -74,7 +82,7 @@ public class ZUGFeRDImporter {
public ZUGFeRDImporter(String pdfFilename) { public ZUGFeRDImporter(String pdfFilename) {
try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) {
extractLowLevel(bis); extractLowLevel(bis);
} catch (IOException e) { } catch (final IOException e) {
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
@@ -84,7 +92,7 @@ public class ZUGFeRDImporter {
public ZUGFeRDImporter(InputStream pdfStream) { public ZUGFeRDImporter(InputStream pdfStream) {
try { try {
extractLowLevel(pdfStream); extractLowLevel(pdfStream);
} catch (IOException e) { } catch (final IOException e) {
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
@@ -99,7 +107,7 @@ public class ZUGFeRDImporter {
private void extractLowLevel(InputStream pdfStream) throws IOException { private void extractLowLevel(InputStream pdfStream) throws IOException {
try (PDDocument doc = PDDocument.load(pdfStream)) { try (PDDocument doc = PDDocument.load(pdfStream)) {
// PDDocumentInformation info = doc.getDocumentInformation(); // PDDocumentInformation info = doc.getDocumentInformation();
PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
//start //start
if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) { if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) {
@@ -107,15 +115,15 @@ public class ZUGFeRDImporter {
return; return;
} }
InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata();
xmpString = convertStreamToString(XMP); xmpString = convertStreamToString(XMP);
PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles();
if (etn == null) { if (etn == null) {
return; return;
} }
Map<String, PDComplexFileSpecification> efMap = etn.getNames(); final Map<String, PDComplexFileSpecification> efMap = etn.getNames();
// String filePath = "/tmp/"; // String filePath = "/tmp/";
if (efMap != null) { if (efMap != null) {
@@ -123,9 +131,9 @@ public class ZUGFeRDImporter {
// https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/
} else { } else {
List<PDNameTreeNode<PDComplexFileSpecification>> kids = etn.getKids(); final List<PDNameTreeNode<PDComplexFileSpecification>> kids = etn.getKids();
for (PDNameTreeNode<PDComplexFileSpecification> node : kids) { for (final PDNameTreeNode<PDComplexFileSpecification> node : kids) {
Map<String, PDComplexFileSpecification> namesL = node.getNames(); final Map<String, PDComplexFileSpecification> namesL = node.getNames();
extractFiles(namesL); extractFiles(namesL);
} }
} }
@@ -134,17 +142,17 @@ public class ZUGFeRDImporter {
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException { private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
for (String alias : names.keySet()) { for (final String alias : names.keySet()) {
PDComplexFileSpecification fileSpec = names.get(alias); final PDComplexFileSpecification fileSpec = names.get(alias);
String filename = fileSpec.getFilename(); final String filename = fileSpec.getFilename();
/** /**
* filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X)
*/ */
if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml")) { if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml")) {
containsMeta = true; containsMeta = true;
PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
// String embeddedFilename = filePath + filename; // String embeddedFilename = filePath + filename;
// File file = new File(filePath + filename); // File file = new File(filePath + filename);
// System.out.println("Writing " + embeddedFilename); // System.out.println("Writing " + embeddedFilename);
@@ -158,7 +166,7 @@ public class ZUGFeRDImporter {
// fos.close(); // fos.close();
} }
if (filename.startsWith("additional_data")) { if (filename.startsWith("additional_data")) {
PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
additionalXMLs.put(filename, embeddedFile.toByteArray()); additionalXMLs.put(filename, embeddedFile.toByteArray());
} }
} }
@@ -171,10 +179,10 @@ public class ZUGFeRDImporter {
private void setDocument() throws ParserConfigurationException, IOException, SAXException { private void setDocument() throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
xmlFact.setNamespaceAware(false); xmlFact.setNamespaceAware(false);
DocumentBuilder builder = xmlFact.newDocumentBuilder(); final DocumentBuilder builder = xmlFact.newDocumentBuilder();
ByteArrayInputStream is = new ByteArrayInputStream(rawXML); final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
/// is.skip(guessBOMSize(is)); /// is.skip(guessBOMSize(is));
document = builder.parse(is); document = builder.parse(is);
} }
@@ -197,13 +205,13 @@ public class ZUGFeRDImporter {
if (!containsMeta) { if (!containsMeta) {
throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found.");
} }
String result; final String result;
try { try {
Document document = getDocument(); final Document document = getDocument();
XPathFactory xpathFact = XPathFactory.newInstance(); final XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath(); final XPath xpath = xpathFact.newXPath();
result = xpath.evaluate(xpathStr, document); result = xpath.evaluate(xpathStr, document);
} catch (XPathExpressionException e) { } catch (final XPathExpressionException e) {
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
@@ -263,7 +271,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ApplicableHeaderTradeSettlement//InvoiceCurrencyCode"); return extractString("//ApplicableHeaderTradeSettlement//InvoiceCurrencyCode");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -273,13 +281,31 @@ public class ZUGFeRDImporter {
* @return the IssuerAssigned ID * @return the IssuerAssigned ID
*/ */
public String getIssuerAssignedID() { public String getIssuerAssignedID() {
return extractIssuerAssignedID("BuyerOrderReferencedDocument");
}
/**
* @return the SellerOrderReferencedDocument IssuerAssigned ID
*/
public String getSellerOrderReferencedDocumentIssuerAssignedID() {
return extractIssuerAssignedID("SellerOrderReferencedDocument");
}
/**
* @return the IssuerAssigned ID
*/
public String getContractOrderReferencedDocumentIssuerAssignedID() {
return extractIssuerAssignedID("ContractReferencedDocument");
}
private String extractIssuerAssignedID(String propertyName) {
try { try {
if (getVersion() == 1) { if (getVersion() == 1) {
return extractString("//BuyerOrderReferencedDocument//ID"); return extractString("//BuyerOrderReferencedDocument//ID");
} else { } else {
return extractString("//BuyerOrderReferencedDocument//IssuerAssignedID"); return extractString("//BuyerOrderReferencedDocument//IssuerAssignedID");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -302,7 +328,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ExchangedDocument//IssueDateTime//DateTimeString"); return extractString("//ExchangedDocument//IssueDateTime//DateTimeString");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -318,7 +344,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxBasisTotalAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxBasisTotalAmount");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -334,7 +360,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxTotalAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxTotalAmount");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -350,7 +376,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//RoundingAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//RoundingAmount");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -366,7 +392,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TotalPrepaidAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TotalPrepaidAmount");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -404,7 +430,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ExchangedDocument//IncludedNote"); return extractString("//ExchangedDocument//IncludedNote");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -429,7 +455,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//LineTotalAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//LineTotalAmount");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -452,7 +478,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ActualDeliverySupplyChainEvent//OccurrenceDateTime//DateTimeString"); return extractString("//ActualDeliverySupplyChainEvent//OccurrenceDateTime//DateTimeString");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -468,7 +494,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ExchangedDocument//ID"); return extractString("//ExchangedDocument//ID");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -486,7 +512,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ExchangedDocument/TypeCode"); return extractString("//ExchangedDocument/TypeCode");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -503,7 +529,7 @@ public class ZUGFeRDImporter {
} else { } else {
return extractString("//ApplicableHeaderTradeAgreement/BuyerReference"); return extractString("//ApplicableHeaderTradeAgreement/BuyerReference");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
@@ -628,7 +654,7 @@ public class ZUGFeRDImporter {
} }
byte[] bomlessData; final byte[] bomlessData;
if ((rawXML[0] == (byte) 0xEF) if ((rawXML[0] == (byte) 0xEF)
&& (rawXML[1] == (byte) 0xBB) && (rawXML[1] == (byte) 0xBB)
@@ -664,7 +690,7 @@ public class ZUGFeRDImporter {
// SpecifiedExchangedDocumentContext is in the schema, so a relatively good // SpecifiedExchangedDocumentContext is in the schema, so a relatively good
// indication if zugferd is present - better than just invoice // indication if zugferd is present - better than just invoice
String meta = getMeta(); final String meta = getMeta();
return (meta != null) && (meta.length() > 0) && ((meta.contains("SpecifiedExchangedDocumentContext") return (meta != null) && (meta.length() > 0) && ((meta.contains("SpecifiedExchangedDocumentContext")
/* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */)); /* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */));
} }
@@ -673,7 +699,7 @@ public class ZUGFeRDImporter {
static String convertStreamToString(java.io.InputStream is) { static String convertStreamToString(java.io.InputStream is) {
// source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to // source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to
// https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks // https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks
Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A"); final Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A");
return s.hasNext() ? s.next() : ""; return s.hasNext() ? s.next() : "";
} }
@@ -691,7 +717,7 @@ public class ZUGFeRDImporter {
} else { } else {
nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//BuyerTradeParty//PostalTradeAddress"); nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//BuyerTradeParty//PostalTradeAddress");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
@@ -706,7 +732,7 @@ public class ZUGFeRDImporter {
public PostalTradeAddress getSellerTradePartyAddress() { public PostalTradeAddress getSellerTradePartyAddress() {
NodeList nl = null; NodeList nl = null;
PostalTradeAddress address = new PostalTradeAddress(); final PostalTradeAddress address = new PostalTradeAddress();
try { try {
if (getVersion() == 1) { if (getVersion() == 1) {
@@ -714,7 +740,7 @@ public class ZUGFeRDImporter {
} else { } else {
nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//SellerTradeParty//PostalTradeAddress"); nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//SellerTradeParty//PostalTradeAddress");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
@@ -723,15 +749,15 @@ public class ZUGFeRDImporter {
} }
private PostalTradeAddress getAddressFromNodeList(NodeList nl) { private PostalTradeAddress getAddressFromNodeList(NodeList nl) {
PostalTradeAddress address = new PostalTradeAddress(); final PostalTradeAddress address = new PostalTradeAddress();
if (nl != null) { if (nl != null) {
for (int i = 0; i < nl.getLength(); i++) { for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i); Node n = nl.item(i);
NodeList nodes = n.getChildNodes(); final NodeList nodes = n.getChildNodes();
for (int j = 0; j < nodes.getLength(); j++) { for (int j = 0; j < nodes.getLength(); j++) {
n = nodes.item(j); n = nodes.item(j);
short nodeType = n.getNodeType(); final short nodeType = n.getNodeType();
if (nodeType==Node.ELEMENT_NODE){ if (nodeType==Node.ELEMENT_NODE){
switch (n.getNodeName()) { switch (n.getNodeName()) {
case "ram:PostcodeCode": case "ram:PostcodeCode":
@@ -789,16 +815,16 @@ public class ZUGFeRDImporter {
* @return a List of LineItem instances * @return a List of LineItem instances
*/ */
public List<Item> getLineItemList() { public List<Item> getLineItemList() {
List<Node> nodeList = getLineItemNodes(); final List<Node> nodeList = getLineItemNodes();
List<Item> lineItemList = new ArrayList<>(); final List<Item> lineItemList = new ArrayList<>();
for (Node n: nodeList) { for (final Node n: nodeList) {
Item lineItem = new Item(null, null, null); final Item lineItem = new Item(null, null, null);
lineItem.setProduct(new Product(null,null,null,null)); lineItem.setProduct(new Product(null,null,null,null));
NodeList nl = n.getChildNodes(); final NodeList nl = n.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) { for (int i = 0; i < nl.getLength(); i++) {
Node nn = nl.item(i); final Node nn = nl.item(i);
Node node = null; Node node = null;
switch (nn.getNodeName()) { switch (nn.getNodeName()) {
case "ram:SpecifiedLineTradeAgreement": case "ram:SpecifiedLineTradeAgreement":
@@ -806,12 +832,12 @@ public class ZUGFeRDImporter {
node = getNodeByName(nn.getChildNodes(), "ram:NetPriceProductTradePrice"); node = getNodeByName(nn.getChildNodes(), "ram:NetPriceProductTradePrice");
if (node != null) { if (node != null) {
NodeList tradeAgreementChildren = node.getChildNodes(); final NodeList tradeAgreementChildren = node.getChildNodes();
node = getNodeByName(tradeAgreementChildren, "ram:ChargeAmount"); node = getNodeByName(tradeAgreementChildren, "ram:ChargeAmount");
lineItem.setPrice(tryBigDecimal(getNodeValue(node))); lineItem.setPrice(tryBigDecimal(getNodeValue(node)));
node = getNodeByName(tradeAgreementChildren, "ram:BasisQuantity"); node = getNodeByName(tradeAgreementChildren, "ram:BasisQuantity");
if(node != null && node.getAttributes()!=null) { if(node != null && node.getAttributes()!=null) {
Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode"); final Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode");
if(unitCodeAttribute != null) { if(unitCodeAttribute != null) {
lineItem.getProduct().setUnit(unitCodeAttribute.getNodeValue()); lineItem.getProduct().setUnit(unitCodeAttribute.getNodeValue());
} }
@@ -905,7 +931,7 @@ public class ZUGFeRDImporter {
* @return a List of Node instances * @return a List of Node instances
*/ */
public List<Node> getLineItemNodes() { public List<Node> getLineItemNodes() {
List<Node> lineItemNodes = new ArrayList<>(); final List<Node> lineItemNodes = new ArrayList<>();
NodeList nl = null; NodeList nl = null;
try { try {
if (getVersion() == 1) { if (getVersion() == 1) {
@@ -913,12 +939,12 @@ public class ZUGFeRDImporter {
} else { } else {
nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//IncludedSupplyChainTradeLineItem"); nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//IncludedSupplyChainTradeLineItem");
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
for (int i = 0; i < nl.getLength(); i++) { for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i); final Node n = nl.item(i);
lineItemNodes.add(n); lineItemNodes.add(n);
} }
return lineItemNodes; return lineItemNodes;
@@ -935,7 +961,7 @@ public class ZUGFeRDImporter {
if (nl.item(i).getNodeName() == name) { if (nl.item(i).getNodeName() == name) {
return nl.item(i); return nl.item(i);
} else if (nl.item(i).getChildNodes().getLength() > 0) { } else if (nl.item(i).getChildNodes().getLength() > 0) {
Node node = getNodeByName(nl.item(i).getChildNodes(), name); final Node node = getNodeByName(nl.item(i).getChildNodes(), name);
if (node != null) { if (node != null) {
return node; return node;
} }
@@ -951,14 +977,14 @@ public class ZUGFeRDImporter {
*/ */
public NodeList getNodeListByPath(String path) { public NodeList getNodeListByPath(String path) {
XPathFactory xpathFact = XPathFactory.newInstance(); final XPathFactory xpathFact = XPathFactory.newInstance();
XPath xPath = xpathFact.newXPath(); final XPath xPath = xpathFact.newXPath();
String s = path; final String s = path;
try { try {
XPathExpression xpr = xPath.compile(s); final XPathExpression xpr = xPath.compile(s);
return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
@@ -986,10 +1012,10 @@ public class ZUGFeRDImporter {
private BigDecimal tryBigDecimal(String nodeValue) { private BigDecimal tryBigDecimal(String nodeValue) {
try { try {
return new BigDecimal(nodeValue); return new BigDecimal(nodeValue);
} catch (Exception e) { } catch (final Exception e) {
try { try {
return new BigDecimal(Float.valueOf(nodeValue)); return new BigDecimal(Float.valueOf(nodeValue));
} catch (Exception ex) { } catch (final Exception ex) {
return new BigDecimal("0.00"); return new BigDecimal("0.00");
} }
} }