Add list of invoice referenced documents (BG-3) to invoice
This commit is contained in:
@@ -38,7 +38,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public class Invoice implements IExportableTransaction {
|
||||
|
||||
protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, invoiceReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null;
|
||||
protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null;
|
||||
protected Date issueDate = null, dueDate = null, deliveryDate = null;
|
||||
protected TradeParty sender = null, recipient = null, deliveryAddress = null, payee = null;
|
||||
protected ArrayList<CashDiscount> cashDiscounts = null;
|
||||
@@ -57,7 +57,12 @@ public class Invoice implements IExportableTransaction {
|
||||
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>(),
|
||||
Charges = new ArrayList<>(), LogisticsServiceCharges = new ArrayList<>();
|
||||
protected IZUGFeRDPaymentTerms paymentTerms = null;
|
||||
|
||||
protected String invoiceReferencedDocumentID = null;
|
||||
protected Date invoiceReferencedIssueDate;
|
||||
// New field for storing Invoiced Object Identifier (BG-3)
|
||||
protected ArrayList<ReferencedDocument> invoiceReferencedDocuments = null;
|
||||
|
||||
protected String specifiedProcuringProjectID = null;
|
||||
protected String specifiedProcuringProjectName = null;
|
||||
protected String despatchAdviceReferencedDocumentID = null;
|
||||
@@ -148,6 +153,7 @@ public class Invoice implements IExportableTransaction {
|
||||
*/
|
||||
public Invoice setCorrection(String number) {
|
||||
setInvoiceReferencedDocumentID(number);
|
||||
addInvoiceReferencedDocument(new ReferencedDocument(number));
|
||||
documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE;
|
||||
return this;
|
||||
}
|
||||
@@ -546,6 +552,26 @@ public class Invoice implements IExportableTransaction {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Getter for BG-3
|
||||
@Override
|
||||
public ArrayList<ReferencedDocument> getInvoiceReferencedDocuments() {
|
||||
return invoiceReferencedDocuments;
|
||||
}
|
||||
|
||||
// Setter for BG-3
|
||||
public void setInvoiceReferencedDocuments(ArrayList<ReferencedDocument> invoiceReferencedDocuments) {
|
||||
this.invoiceReferencedDocuments = invoiceReferencedDocuments;
|
||||
}
|
||||
|
||||
// Method to add a single ReferencedDocument for BG-3
|
||||
public Invoice addInvoiceReferencedDocument(ReferencedDocument doc) {
|
||||
if (invoiceReferencedDocuments == null) {
|
||||
invoiceReferencedDocuments = new ArrayList<>();
|
||||
}
|
||||
invoiceReferencedDocuments.add(doc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IZUGFeRDAllowanceCharge[] getZFAllowances() {
|
||||
if (Allowances.isEmpty()) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.mustangproject;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import java.util.Date;
|
||||
|
||||
import org.mustangproject.ZUGFeRD.IReferencedDocument;
|
||||
import org.mustangproject.util.NodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
@@ -13,20 +15,33 @@ public class ReferencedDocument implements IReferencedDocument {
|
||||
String issuerAssignedID;
|
||||
String typeCode;
|
||||
String referenceTypeCode;
|
||||
Date formattedIssueDateTime;
|
||||
|
||||
public ReferencedDocument(String issuerAssignedID, String typeCode, String referenceTypeCode) {
|
||||
this.issuerAssignedID = issuerAssignedID;
|
||||
this(issuerAssignedID);
|
||||
this.typeCode = typeCode;
|
||||
this.referenceTypeCode = referenceTypeCode;
|
||||
}
|
||||
|
||||
public ReferencedDocument(String issuerAssignedID, String referenceTypeCode) {
|
||||
this.issuerAssignedID = issuerAssignedID;
|
||||
this.typeCode = "916"; // additional invoice related document
|
||||
this.referenceTypeCode = referenceTypeCode;
|
||||
public ReferencedDocument(String issuerAssignedID, String typeCode, String referenceTypeCode, Date formattedIssueDateTime) {
|
||||
this(issuerAssignedID, typeCode, referenceTypeCode);
|
||||
this.formattedIssueDateTime = formattedIssueDateTime;
|
||||
}
|
||||
|
||||
/***
|
||||
public ReferencedDocument(String issuerAssignedID, String referenceTypeCode) {
|
||||
this(issuerAssignedID, "916", referenceTypeCode); // additional invoice related document
|
||||
}
|
||||
|
||||
public ReferencedDocument(String issuerAssingedID, Date formattedIssueDateTime) {
|
||||
this(issuerAssingedID);
|
||||
this.formattedIssueDateTime = formattedIssueDateTime;
|
||||
}
|
||||
|
||||
public ReferencedDocument(String issuerAssignedID) {
|
||||
this.issuerAssignedID = issuerAssignedID;
|
||||
}
|
||||
|
||||
/***
|
||||
* sets an ID assigned by the sender
|
||||
* @param issuerAssignedID the ID as a string :-)
|
||||
*/
|
||||
@@ -50,6 +65,15 @@ public class ReferencedDocument implements IReferencedDocument {
|
||||
this.referenceTypeCode = referenceTypeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* issue date of this line
|
||||
*
|
||||
* @param formattedIssueDateTime as Date
|
||||
*/
|
||||
public void setFormattedIssueDateTime(Date formattedIssueDateTime) {
|
||||
this.formattedIssueDateTime = formattedIssueDateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIssuerAssignedID() {
|
||||
return issuerAssignedID;
|
||||
@@ -65,6 +89,12 @@ public class ReferencedDocument implements IReferencedDocument {
|
||||
return referenceTypeCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getFormattedIssueDateTime()
|
||||
{
|
||||
return formattedIssueDateTime;
|
||||
}
|
||||
|
||||
public static ReferencedDocument fromNode(Node node) {
|
||||
if (!node.hasChildNodes()) {
|
||||
return null;
|
||||
@@ -72,6 +102,7 @@ public class ReferencedDocument implements IReferencedDocument {
|
||||
NodeMap nodes = new NodeMap(node);
|
||||
return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID", "ID"),
|
||||
nodes.getAsStringOrNull("TypeCode", "DocumentTypeCode"),
|
||||
nodes.getAsStringOrNull("ReferenceTypeCode"));
|
||||
nodes.getAsStringOrNull("ReferenceTypeCode"),
|
||||
XMLTools.tryDate(nodes.getAsStringOrNull("FormattedIssueDateTime")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,13 @@ package org.mustangproject.ZUGFeRD;
|
||||
* */
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.mustangproject.FileAttachment;
|
||||
import org.mustangproject.IncludedNote;
|
||||
import org.mustangproject.ReferencedDocument;
|
||||
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
||||
|
||||
/***
|
||||
@@ -424,13 +426,23 @@ public interface IExportableTransaction {
|
||||
*
|
||||
* @return the ID of the document
|
||||
*/
|
||||
@Deprecated
|
||||
default String getInvoiceReferencedDocumentID() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
default Date getInvoiceReferencedIssueDate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for BG-3
|
||||
* @return list of documents
|
||||
*/
|
||||
default ArrayList<ReferencedDocument> getInvoiceReferencedDocuments() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the issue timestamp of the BuyerOrderReferencedDocument, which sits in
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface IReferencedDocument {
|
||||
|
||||
/***
|
||||
@@ -20,4 +22,12 @@ public interface IReferencedDocument {
|
||||
*/
|
||||
String getReferenceTypeCode();
|
||||
|
||||
/***
|
||||
*
|
||||
* issue date of this line
|
||||
*
|
||||
* @return date of the issue
|
||||
*/
|
||||
Date getFormattedIssueDateTime();
|
||||
|
||||
}
|
||||
|
||||
@@ -459,6 +459,19 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
|
||||
}
|
||||
xml += "</ram:InvoiceReferencedDocument>";
|
||||
}
|
||||
if (trans.getInvoiceReferencedDocuments() != null) {
|
||||
for (var doc : trans.getInvoiceReferencedDocuments()) {
|
||||
xml += "<ram:InvoiceReferencedDocument>"
|
||||
+ "<ram:IssuerAssignedID>"
|
||||
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
||||
if (doc.getFormattedIssueDateTime() != null) {
|
||||
xml += "<ram:FormattedIssueDateTime>"
|
||||
+ DATE.qdtFormat(doc.getFormattedIssueDateTime())
|
||||
+ "</ram:FormattedIssueDateTime>";
|
||||
}
|
||||
xml += "</ram:InvoiceReferencedDocument>";
|
||||
}
|
||||
}
|
||||
|
||||
xml += "</ram:ApplicableHeaderTradeSettlement>";
|
||||
// + " <IncludedSupplyChainTradeLineItem>"
|
||||
|
||||
@@ -893,6 +893,19 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
||||
}
|
||||
xml += "</ram:InvoiceReferencedDocument>";
|
||||
}
|
||||
if (trans.getInvoiceReferencedDocuments() != null) {
|
||||
for (var doc : trans.getInvoiceReferencedDocuments()) {
|
||||
xml += "<ram:InvoiceReferencedDocument>"
|
||||
+ "<ram:IssuerAssignedID>"
|
||||
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
||||
if (doc.getFormattedIssueDateTime() != null) {
|
||||
xml += "<ram:FormattedIssueDateTime>"
|
||||
+ DATE.qdtFormat(doc.getFormattedIssueDateTime())
|
||||
+ "</ram:FormattedIssueDateTime>";
|
||||
}
|
||||
xml += "</ram:InvoiceReferencedDocument>";
|
||||
}
|
||||
}
|
||||
|
||||
xml += "</ram:ApplicableHeaderTradeSettlement>";
|
||||
// + "<IncludedSupplyChainTradeLineItem>\n"
|
||||
|
||||
@@ -816,6 +816,23 @@ public class ZUGFeRDInvoiceImporter {
|
||||
}
|
||||
zpp.setInvoiceReferencedDocumentID(extractString("//*[local-name()=\"InvoiceReferencedDocument\"]/*[local-name()=\"IssuerAssignedID\"]|//*[local-name()=\"BillingReference\"]/*[local-name()=\"InvoiceDocumentReference\"]/*[local-name()=\"ID\"]"));
|
||||
|
||||
xpr = xpath.compile("//*[local-name()=\"InvoiceReferencedDocument\"]");
|
||||
NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||
|
||||
if (nodes.getLength() != 0) {
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
|
||||
Node currentItemNode = nodes.item(i);
|
||||
ReferencedDocument doc = ReferencedDocument.fromNode(currentItemNode);
|
||||
if (doc != null
|
||||
&& (!Objects.equals(zpp.getInvoiceReferencedDocumentID(), doc.getIssuerAssignedID())
|
||||
|| !Objects.equals(zpp.getInvoiceReferencedIssueDate(), doc.getFormattedIssueDateTime())))
|
||||
{
|
||||
zpp.addInvoiceReferencedDocument(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim());
|
||||
|
||||
String rounding = extractString("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"RoundingAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"Party\"]/*[local-name()=\"PayableRoundingAmount\"]");
|
||||
@@ -834,7 +851,7 @@ public class ZUGFeRDInvoiceImporter {
|
||||
}
|
||||
|
||||
xpr = xpath.compile("//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]|//*[local-name()=\"InvoiceLine\"]");
|
||||
NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||
nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||
|
||||
if (nodes.getLength() != 0) {
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
|
||||
@@ -542,7 +542,7 @@ public class ZF2PushTest extends TestCase {
|
||||
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
|
||||
.addCashDiscount(new CashDiscount(new BigDecimal(2), 14))
|
||||
.setDeliveryDate(sdf.parse("2020-11-02")).setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE)
|
||||
.setInvoiceReferencedDocumentID("abc123")
|
||||
.setInvoiceReferencedDocumentID("abc123").addInvoiceReferencedDocument(new ReferencedDocument("abcd1234"))
|
||||
);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
@@ -587,6 +587,8 @@ public class ZF2PushTest extends TestCase {
|
||||
Invoice i = zii.extractInvoice();
|
||||
|
||||
assertEquals("abc123", i.getInvoiceReferencedDocumentID());
|
||||
assertEquals(1, i.getInvoiceReferencedDocuments().size());
|
||||
assertEquals("abcd1234", i.getInvoiceReferencedDocuments().get(0).getIssuerAssignedID());
|
||||
assertEquals("4304171000002", i.getRecipient().getGlobalID());
|
||||
assertEquals("2001015001325", i.getZFItems()[0].getProduct().getGlobalID());
|
||||
assertEquals(orgID, i.getSender().getID());
|
||||
|
||||
Reference in New Issue
Block a user