diff --git a/library/src/main/java/org/mustangproject/Invoice.java b/library/src/main/java/org/mustangproject/Invoice.java index 639663b9..a03487ae 100644 --- a/library/src/main/java/org/mustangproject/Invoice.java +++ b/library/src/main/java/org/mustangproject/Invoice.java @@ -69,6 +69,7 @@ public class Invoice implements IExportableTransaction { protected String vatDueDateTypeCode = null; protected String creditorReferenceID; // required when direct debit is used. private BigDecimal roundingAmount=null; + private String paymentReference; // Remittance information / Verwendungszweck, BT-83 public Invoice() { ZFItems = new ArrayList<>(); @@ -650,6 +651,16 @@ public class Invoice implements IExportableTransaction { return this; } + @Override + public String getPaymentReference() { + return paymentReference; + } + + public Invoice setPaymentReference(String paymentReference) { + this.paymentReference = paymentReference; + return this; + } + @Override public TradeParty getDeliveryAddress() { return deliveryAddress; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java index 0a013ba3..686afd44 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java @@ -314,6 +314,10 @@ public interface IExportableTransaction { return null; } + default String getPaymentReference() { + return null; + } + /** * returns if a rebate agreements exists * diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 192582f4..6958bb61 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -388,14 +388,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + "" + "" + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - // + "RECHNUNG" - // + "380" - + "" + typecode + "" - + "" - + DATE.udtFormat(trans.getIssueDate()) + "" // date + + "" + XMLTools.encodeXML(trans.getNumber()) + ""; + if (profile == Profiles.getByName("Extended") && trans.getDocumentName() != null) { + xml += "" + XMLTools.encodeXML(trans.getDocumentName()) + ""; + } + xml += "" + typecode + "" + + "" + DATE.udtFormat(trans.getIssueDate()) + "" // date + buildNotes(trans) - + "" + ""; int lineID = 0; @@ -662,8 +661,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if ((trans.getCreditorReferenceID() != null) && (getProfile() != Profiles.getByName("Minimum"))) { xml += "" + XMLTools.encodeXML(trans.getCreditorReferenceID()) + ""; } - if ((trans.getNumber() != null) && (getProfile() != Profiles.getByName("Minimum"))) { - xml += "" + XMLTools.encodeXML(trans.getNumber()) + ""; + if ((trans.getPaymentReference() != null) && (getProfile() != Profiles.getByName("Minimum"))) { + xml += "" + XMLTools.encodeXML(trans.getPaymentReference()) + ""; } xml += "" + trans.getCurrency() + ""; if (this.trans.getPayee() != null) { diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 3f2231d1..1fa95600 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -288,6 +288,7 @@ public class ZUGFeRDInvoiceImporter { public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseException { String number = ""; + String documentName = null; String typeCode = null; String deliveryPeriodStart = null; String deliveryPeriodEnd = null; @@ -496,6 +497,9 @@ public class ZUGFeRDInvoiceImporter { if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) { number = XMLTools.trimOrNull(item); } + if ((item.getLocalName() != null) && (item.getLocalName().equals("Name"))) { + documentName = XMLTools.trimOrNull(item); + } if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) { typeCode = XMLTools.trimOrNull(item); } @@ -668,6 +672,12 @@ public class ZUGFeRDInvoiceImporter { NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes(); for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) { + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) + && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("PaymentReference"))) { + String paymentReference = headerTradeSettlementChilds.item(settlementChildIndex).getTextContent(); + zpp.setPaymentReference(paymentReference); + } + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradePaymentTerms"))) { NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); @@ -802,7 +812,7 @@ public class ZUGFeRDInvoiceImporter { } - zpp.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode); + zpp.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentName(documentName).setDocumentCode(typeCode); if ((directDebitMandateID != null) && (IBAN != null)) { DirectDebit d = new DirectDebit(IBAN, directDebitMandateID); diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java index 412d334a..b1b61257 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java @@ -531,7 +531,7 @@ public class ZF2PushTest extends TestCase { try { SchemedID gtin = new SchemedID("0160", "2001015001325"); SchemedID gln = new SchemedID("0088", "4304171000002"); - ze.setTransaction(new Invoice().setCurrency("CHF").addNote("document level 1/2").addNote("document level 2/2").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + ze.setTransaction(new Invoice().setCurrency("CHF").addNote("document level 1/2").addNote("document level 2/2").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setPaymentReference("Verwendungszweck").setDocumentName("Rechnung") .setSellerOrderReferencedDocumentID("9384").setBuyerOrderReferencedDocumentID("28934") .setDetailedDeliveryPeriod(new SimpleDateFormat("yyyyMMdd").parse(occurrenceFrom), new SimpleDateFormat("yyyyMMdd").parse(occurrenceTo)) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID).setEmail("sender@test.org").setID(orgID).addVATID("DE0815")) @@ -583,6 +583,7 @@ public class ZF2PushTest extends TestCase { assertTrue(zi.getUTF8().contains("++49555123456")); assertTrue(zi.getUTF8().contains("Cash Discount")); // default description for cash discounts assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='ApplicableTradeTax']/*[local-name()='DueDateTypeCode']").asString().isEqualTo(EventTimeCodeTypeConstants.PAYMENT_DATE); + assertTrue(zi.getUTF8().contains("Rechnung")); ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PUSHEDGE); try { @@ -594,6 +595,8 @@ public class ZF2PushTest extends TestCase { assertEquals("4304171000002", i.getRecipient().getGlobalID()); assertEquals("2001015001325", i.getZFItems()[0].getProduct().getGlobalID()); assertEquals(orgID, i.getSender().getID()); + assertEquals("Verwendungszweck", i.getPaymentReference()); + assertEquals("Rechnung", i.getDocumentName()); } catch (XPathExpressionException e) { fail("XPathExpressionException should not be raised");