Add optional Invoicer and Invoicee for Extended profile.

This commit is contained in:
Frank Langelage
2025-10-19 12:25:49 +02:00
parent be72952865
commit 401b568353
5 changed files with 81 additions and 3 deletions

View File

@@ -41,7 +41,7 @@ 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, 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 Date issueDate = null, dueDate = null, deliveryDate = null;
protected TradeParty sender = null, recipient = null, deliveryAddress = null, payee = null; protected TradeParty sender = null, recipient = null, deliveryAddress = null, payee = null, invoicer = null, invoicee = null;
protected ArrayList<CashDiscount> cashDiscounts = null; protected ArrayList<CashDiscount> cashDiscounts = null;
@JsonDeserialize(contentAs = Item.class) @JsonDeserialize(contentAs = Item.class)
protected ArrayList<IZUGFeRDExportableItem> ZFItems = null; protected ArrayList<IZUGFeRDExportableItem> ZFItems = null;
@@ -722,6 +722,36 @@ public class Invoice implements IExportableTransaction {
return this; return this;
} }
@Override
public TradeParty getInvoicer() {
return this.invoicer;
}
/***
* if the invoicer is not the seller, it can be specified here
* @param invoicer the invoice issuing organisation
* @return fluent setter
*/
public Invoice setInvoicer(TradeParty invoicer) {
this.invoicer = invoicer;
return this;
}
@Override
public TradeParty getInvoicee() {
return this.invoicee;
}
/***
* if the invoicee is not the buyer, it can be specified here
* @param invoicee the invoice receiving organisation
* @return fluent setter
*/
public Invoice setInvoicee(TradeParty invoicee) {
this.invoicee = invoicee;
return this;
}
/*** /***
* Adds a cash discount (skonto) * Adds a cash discount (skonto)
* @param c the CashDiscount percent/period combination * @param c the CashDiscount percent/period combination

View File

@@ -38,6 +38,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import org.mustangproject.FileAttachment; import org.mustangproject.FileAttachment;
import org.mustangproject.IncludedNote; import org.mustangproject.IncludedNote;
import org.mustangproject.ReferencedDocument; import org.mustangproject.ReferencedDocument;
import org.mustangproject.TradeParty;
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
/*** /***
@@ -493,12 +494,30 @@ public interface IExportableTransaction {
/*** /***
* payee / payment receiver, if different from seller, ram:Payee (only supported for zf2) * payee / payment receiver, if different from seller, ram:Payee (only supported for zf2)
* *
* @return the IZUGFeRDExportableTradeParty payment receiver, if different from sellver * @return the IZUGFeRDExportableTradeParty payment receiver, if different from seller
*/ */
default IZUGFeRDExportableTradeParty getPayee() { default IZUGFeRDExportableTradeParty getPayee() {
return null; return null;
} }
/***
* invoicer / invoice sender, if different from seller, ram:InvoicerTradeParty
*
* @return the IZUGFeRDExportableTradeParty invoice sender, if different from seller
*/
default IZUGFeRDExportableTradeParty getInvoicer() {
return null;
}
/***
* invoicee / invoice receiver, if different from buyer, ram:InvoiceeTradeParty
*
* @return the IZUGFeRDExportableTradeParty invoice receiver, if different from buyer
*/
default IZUGFeRDExportableTradeParty getInvoicee() {
return null;
}
/*** /***
* specifies the document level delivery period, will be included in a * specifies the document level delivery period, will be included in a
* BillingSpecifiedPeriod element * BillingSpecifiedPeriod element

View File

@@ -677,6 +677,17 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml += "<ram:PaymentReference>" + XMLTools.encodeXML(trans.getPaymentReference()) + "</ram:PaymentReference>"; xml += "<ram:PaymentReference>" + XMLTools.encodeXML(trans.getPaymentReference()) + "</ram:PaymentReference>";
} }
xml += "<ram:InvoiceCurrencyCode>" + trans.getCurrency() + "</ram:InvoiceCurrencyCode>"; xml += "<ram:InvoiceCurrencyCode>" + trans.getCurrency() + "</ram:InvoiceCurrencyCode>";
if (this.trans.getInvoicer() != null && getProfile() == Profiles.getByName("Extended")) {
xml += "<ram:InvoicerTradeParty>" +
getTradePartyAsXML(this.trans.getInvoicer(), false, false) +
"</ram:InvoicerTradeParty>";
}
if (this.trans.getInvoicee() != null && getProfile() == Profiles.getByName("Extended")) {
xml += "<ram:InvoiceeTradeParty>" +
getTradePartyAsXML(this.trans.getInvoicee(), false, false) +
"</ram:InvoiceeTradeParty>";
}
if (this.trans.getPayee() != null) { if (this.trans.getPayee() != null) {
xml += "<ram:PayeeTradeParty>" + xml += "<ram:PayeeTradeParty>" +
getTradePartyPayeeAsXML(this.trans.getPayee()) + getTradePartyPayeeAsXML(this.trans.getPayee()) +

View File

@@ -315,7 +315,7 @@ public class ZUGFeRDInvoiceImporter {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//REDHAT //REDHAT
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf //https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
dbf.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true); dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
@@ -436,6 +436,12 @@ public class ZUGFeRDInvoiceImporter {
xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*"); xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*");
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile("//*[local-name()=\"InvoicerTradeParty\"]");
NodeList invoicerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile("//*[local-name()=\"InvoiceeTradeParty\"]");
NodeList invoiceeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]"); xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]");
NodeList payeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); NodeList payeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
@@ -908,6 +914,14 @@ public class ZUGFeRDInvoiceImporter {
} }
if (invoicerNodes.getLength() > 0) {
zpp.setInvoicer(new TradeParty(invoicerNodes));
}
if (invoiceeNodes.getLength() > 0) {
zpp.setInvoicee(new TradeParty(invoiceeNodes));
}
if (payeeNodes.getLength() > 0) { if (payeeNodes.getLength() > 0) {
zpp.setPayee(new TradeParty(payeeNodes)); zpp.setPayee(new TradeParty(payeeNodes));
} }

View File

@@ -604,6 +604,8 @@ public class ZF2PushTest extends TestCase {
.setContractReferencedDocument(contractID) .setContractReferencedDocument(contractID)
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711") .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711")
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3")) .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3"))
.setInvoicer( new TradeParty("Abweichender Rechnungssteller", "Teststr.12", "04711", "Entenhausen", "DE") )
.setInvoicee( new TradeParty("Abweichender Rechnungsempfänger", "Teststr.42", "00815", "Entenhausen", "DE") )
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addBuyerOrderReferencedDocumentID("orderId").addBuyerOrderReferencedDocumentLineID("xxx").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15"))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addBuyerOrderReferencedDocumentID("orderId").addBuyerOrderReferencedDocumentLineID("xxx").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15")))
.addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16))) .addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16)))
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16))) .addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
@@ -669,6 +671,8 @@ public class ZF2PushTest extends TestCase {
assertEquals("++49555123456",i.getRecipient().getContact().getFax()); assertEquals("++49555123456",i.getRecipient().getContact().getFax());
assertNotNull(i.getInvoicer());
assertNotNull(i.getInvoicee());
} catch (XPathExpressionException e) { } catch (XPathExpressionException e) {
fail("XPathExpressionException should not be raised"); fail("XPathExpressionException should not be raised");
} catch (ParseException e) { } catch (ParseException e) {