diff --git a/History.md b/History.md index ce13e64b9..2878cf75b 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,11 @@ +2.10.0 +- - also accept pdf/a3 from inputstream - closes #354 factur-x 1 from commandline +- support XR 3.0.1 (#343), + - i.e. processid + - set email in tradeparty class + - empty description remove 2.9.0 ======= diff --git a/doc/development_documentation.md b/doc/development_documentation.md index 30a27c9b3..447763201 100644 --- a/doc/development_documentation.md +++ b/doc/development_documentation.md @@ -69,15 +69,6 @@ mvnw clean package -P generateXSLTFromSchematron `package -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001 -Xnoagent -Djava.compiler=NONE"` can be used as debug configuration goal in Eclipse. In that case you can set breakpoints in tests. -## Validate - -The former ZUGFeRD VeraPDF [ZUV](https://github.com/ZUGFeRD/ZUV/) validator -is now part of Mustangproject. -The JUnit tests of the validator component will also run through a couple of -test files of the library component. - - - ## Deployment diff --git a/library/src/main/java/org/mustangproject/TradeParty.java b/library/src/main/java/org/mustangproject/TradeParty.java index 9a6d3f8d7..51c20f90c 100644 --- a/library/src/main/java/org/mustangproject/TradeParty.java +++ b/library/src/main/java/org/mustangproject/TradeParty.java @@ -31,7 +31,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { protected Contact contact = null; protected LegalOrganisation legalOrg = null; protected SchemedID globalId=null; - protected SchemedID uriUniversalCommunicationId=null; + protected SchemedID uriUniversalCommunicationId=null; //e.g. the email address of the organization /** * Default constructor. @@ -411,7 +411,31 @@ public String getUriUniversalCommunicationIDScheme() { } - + + /*** + * sets the email of the organization (not the one of the contact person) + * @return fluent setter + */ + public TradeParty setEmail(String eMail) { + SchemedID theSchemedID=new SchemedID("EM", eMail); + addUriUniversalCommunicationID(theSchemedID); + return this; + } + + /*** + * gets the email of the organization (not the one of the contact person) + * will return null if not set or if the provided UriUniversalCommunicationID + * is not a email address + * + * @return String the email, or null + */ + public String getEmail() { + if (uriUniversalCommunicationId.getScheme().equals("EM")) { + return uriUniversalCommunicationId.getID(); + } + return null; + } + /** * if it's a customer, this can e.g. be the customer ID diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java index 553890b80..1e70462f1 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java @@ -33,7 +33,7 @@ public class Profiles { {"BASIC", new Profile("BASIC", "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")}, {"EN16931", new Profile("EN16931", "urn:cen.eu:en16931:2017")}, {"EXTENDED", new Profile("EXTENDED", "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")}, - {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.3")} // up next: urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 + {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0")} // up next: urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); static Map zf1Map = Stream.of(new Object[][]{ diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index dd7eb3d30..bd133558f 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -134,7 +134,7 @@ protected String getTradePartyAsXML(IZUGFeRDExportableTradeParty party, boolean } if ((party.getGlobalIDScheme() != null) && (party.getGlobalID() != null)) { xml += "" - + XMLTools.encodeXML(party.getGlobalID()) + ""; + + XMLTools.encodeXML(party.getGlobalID()) + ""; } xml += "" + XMLTools.encodeXML(party.getName()) + ""; @@ -148,24 +148,24 @@ protected String getTradePartyAsXML(IZUGFeRDExportableTradeParty party, boolean xml += ""; if (party.getContact().getName() != null) { xml += "" + XMLTools.encodeXML(party.getContact().getName()) - + ""; + + ""; } if (party.getContact().getPhone() != null) { xml += "" - + XMLTools.encodeXML(party.getContact().getPhone()) + "" - + ""; + + XMLTools.encodeXML(party.getContact().getPhone()) + "" + + ""; } if ((party.getContact().getFax() != null) && (profile == Profiles.getByName("Extended"))) { xml += "" - + XMLTools.encodeXML(party.getContact().getFax()) + "" - + ""; + + XMLTools.encodeXML(party.getContact().getFax()) + "" + + ""; } if (party.getContact().getEMail() != null) { xml += "" - + XMLTools.encodeXML(party.getContact().getEMail()) + "" - + ""; + + XMLTools.encodeXML(party.getContact().getEMail()) + "" + + ""; } xml += ""; } @@ -173,47 +173,47 @@ protected String getTradePartyAsXML(IZUGFeRDExportableTradeParty party, boolean xml += ""; if (party.getZIP() != null) { xml += "" + XMLTools.encodeXML(party.getZIP()) - + ""; + + ""; } if (party.getStreet() != null) { xml += "" + XMLTools.encodeXML(party.getStreet()) - + ""; + + ""; } if (party.getAdditionalAddress() != null) { xml += "" + XMLTools.encodeXML(party.getAdditionalAddress()) - + ""; + + ""; } if (party.getAdditionalAddressExtension() != null) { xml += "" + XMLTools.encodeXML(party.getAdditionalAddressExtension()) - + ""; + + ""; } if (party.getLocation() != null) { xml += "" + XMLTools.encodeXML(party.getLocation()) - + ""; + + ""; } - + //country IS mandatory xml += "" + XMLTools.encodeXML(party.getCountry()) - + "" - + ""; - if (party.getUriUniversalCommunicationID() != null && party.getUriUniversalCommunicationIDScheme()!=null) { - xml += "" + - "" + - XMLTools.encodeXML(party.getUriUniversalCommunicationID()) - + ""; - } + + "" + + ""; + if (party.getUriUniversalCommunicationID() != null && party.getUriUniversalCommunicationIDScheme() != null) { + xml += "" + + "" + + XMLTools.encodeXML(party.getUriUniversalCommunicationID()) + + ""; + } if ((party.getVATID() != null) && (!isShipToTradeParty)) { xml += "" - + "" + XMLTools.encodeXML(party.getVATID()) - + "" - + ""; + + "" + XMLTools.encodeXML(party.getVATID()) + + "" + + ""; } if ((party.getTaxID() != null) && (!isShipToTradeParty)) { xml += "" - + "" + XMLTools.encodeXML(party.getTaxID()) - + "" - + ""; + + "" + XMLTools.encodeXML(party.getTaxID()) + + "" + + ""; } return xml; @@ -244,10 +244,10 @@ protected String getAllowanceChargeStr(IZUGFeRDAllowanceCharge allowance, IAbsol reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; } final String allowanceChargeStr = "" + - chargeIndicator + "" + percentage + - "" + priceFormat(allowance.getTotalAmount(item)) + "" + - reason + - ""; + chargeIndicator + "" + percentage + + "" + priceFormat(allowance.getTotalAmount(item)) + "" + + reason + + ""; return allowanceChargeStr; } @@ -269,10 +269,10 @@ protected String getItemTotalAllowanceChargeStr(IZUGFeRDAllowanceCharge allowanc } final String itemTotalAllowanceChargeStr = "" + - chargeIndicator + "" + percentage + - "" + currencyFormat(allowance.getTotalAmount(item)) + "" + - "" + XMLTools.encodeXML(allowance.getReason()) + "" + - ""; + chargeIndicator + "" + percentage + + "" + currencyFormat(allowance.getTotalAmount(item)) + "" + + "" + XMLTools.encodeXML(allowance.getReason()) + "" + + ""; return itemTotalAllowanceChargeStr; } @@ -283,7 +283,7 @@ public void generateXML(IExportableTransaction trans) { boolean hasDueDate = false; final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - + String exemptionReason = ""; if (trans.getPaymentTermDescription() != null) { @@ -294,25 +294,32 @@ public void generateXML(IExportableTransaction trans) { paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); } - + String typecode = "380"; if (trans.getDocumentCode() != null) { typecode = trans.getDocumentCode(); } - String xml = "" - + "" - + "" - + "" - // + " - // "+testBooleanStr+"" - // - + "" + String xml = "" + + "" + + "" + + "\n"; + // + " + // "+testBooleanStr+"" + // + + if (getProfile() == Profiles.getByName("XRechnung")) { + xml += " \n" + + " urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\n" + + " \n"; + } + xml += + "" + "" + getProfile().getID() + "" + "" + "" @@ -334,25 +341,25 @@ public void generateXML(IExportableTransaction trans) { exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; } final LineCalculator lc = new LineCalculator(currentItem); - if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) { - xml += "" + - "" - + "" + lineID + "" - + buildItemNotes(currentItem) - + "" - - + ""; + if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) { + xml += "" + + "" + + "" + lineID + "" + + buildItemNotes(currentItem) + + "" + + + ""; if ((currentItem.getProduct().getGlobalIDScheme() != null) && (currentItem.getProduct().getGlobalID() != null)) { xml += "" + XMLTools.encodeXML(currentItem.getProduct().getGlobalID()) + ""; } if (currentItem.getProduct().getSellerAssignedID() != null) { xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; + + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; } if (currentItem.getProduct().getBuyerAssignedID() != null) { xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; + + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; } String allowanceChargeStr = ""; if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { @@ -374,57 +381,60 @@ public void generateXML(IExportableTransaction trans) { } } - xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" - + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) - + "" - + "" + xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + ""; + if (currentItem.getProduct().getDescription().length() > 0) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getDescription()) + + ""; + } + xml += "" - + ""; + + ""; if (currentItem.getReferencedDocuments() != null) { for (final IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) { xml += "" + - "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "" + - "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "" + - "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "" + - ""; + "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "" + + "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "" + + "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "" + + ""; } } if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) { xml += " " - + "" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "" - + ""; + + "" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "" + + ""; } xml += "" - + "" + priceFormat(lc.getPriceGross()) - + "" //currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + allowanceChargeStr - // + " " - // + " false" - // + " 0.6667" - // + " Rabatt" - // + " " - + "" - + "" - + "" + priceFormat(lc.getPrice()) - + "" // currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + "" - + "" - + "" - + "" - + quantityFormat(currentItem.getQuantity()) + "" - + "" - + "" - + "" - + "VAT" - + exemptionReason - + "" + currentItem.getProduct().getTaxCategoryCode() + "" - + "" - + vatFormat(currentItem.getProduct().getVATPercent()) + "" - + ""; + + "" + priceFormat(lc.getPriceGross()) + + "" //currencyID=\"EUR\" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + allowanceChargeStr + // + " " + // + " false" + // + " 0.6667" + // + " Rabatt" + // + " " + + "" + + "" + + "" + priceFormat(lc.getPrice()) + + "" // currencyID=\"EUR\" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + "" + + "" + + "" + + "" + + quantityFormat(currentItem.getQuantity()) + "" + + "" + + "" + + "" + + "VAT" + + exemptionReason + + "" + currentItem.getProduct().getTaxCategoryCode() + "" + + "" + + vatFormat(currentItem.getProduct().getVATPercent()) + "" + + ""; if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { xml += ""; if (currentItem.getDetailedDeliveryPeriodFrom() != null) { @@ -439,15 +449,15 @@ public void generateXML(IExportableTransaction trans) { xml += itemTotalAllowanceChargeStr; xml += "" - + "" + currencyFormat(lc.getItemTotalNetAmount()) - + "" // currencyID=\"EUR\" - + ""; + + "" + currencyFormat(lc.getItemTotalNetAmount()) + + "" // currencyID=\"EUR\" + + ""; if (currentItem.getAdditionalReferencedDocumentID() != null) { xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; } xml += "" - + ""; + + ""; } } @@ -458,9 +468,9 @@ public void generateXML(IExportableTransaction trans) { } xml += "" - + getTradePartyAsXML(trans.getSender(), true, false) - + "" - + ""; + + getTradePartyAsXML(trans.getSender(), true, false) + + "" + + ""; // + " GE2020211" // + " 4000001987658" @@ -469,21 +479,21 @@ public void generateXML(IExportableTransaction trans) { if (trans.getSellerOrderReferencedDocumentID() != null) { xml += " " - + " " - + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" - + " "; + + " " + + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" + + " "; } if (trans.getBuyerOrderReferencedDocumentID() != null) { xml += " " - + " " - + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" - + " "; + + " " + + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" + + " "; } if (trans.getContractReferencedDocument() != null) { xml += " " - + " " - + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" - + " "; + + " " + + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" + + " "; } // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) @@ -491,19 +501,19 @@ public void generateXML(IExportableTransaction trans) { for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); xml += " " - + " " + f.getFilename() + "" - + " 916" - + " " + f.getDescription() + "" - + " " + documentContent + "" - + " "; + + " " + f.getFilename() + "" + + " 916" + + " " + f.getDescription() + "" + + " " + documentContent + "" + + " "; } } if (trans.getSpecifiedProcuringProjectID() != null) { xml += " " - + " " - + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; + + " " + + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; if (trans.getSpecifiedProcuringProjectName() != null) { xml += " " + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; } @@ -514,20 +524,20 @@ public void generateXML(IExportableTransaction trans) { if (this.trans.getDeliveryAddress() != null) { xml += "" + - getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + - ""; + getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + + ""; } if (trans.getDeliveryDate() != null) { xml += "" - + ""; + + ""; xml += DATE.udtFormat(trans.getDeliveryDate()); xml += ""; xml += " "; } else { - if ((trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)&&(getProfile() != Profiles.getByName("Minimum"))) { + if ((trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE) && (getProfile() != Profiles.getByName("Minimum"))) { throw new IllegalStateException("No delivery date provided"); } } @@ -587,15 +597,15 @@ public void generateXML(IExportableTransaction trans) { if (getProfile() != Profiles.getByName("Minimum")) { xml += "" - + "" + currencyFormat(amount.getCalculated()) - + "" //currencyID=\"EUR\" - + "VAT" - + (displayExemptionReason ? exemptionReason : "") - + "" + currencyFormat(amount.getBasis()) + "" // currencyID=\"EUR\" - + "" + amountCategoryCode + "" - + (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + "" : "") - + "" - + vatFormat(currentTaxPercent) + ""; + + "" + currencyFormat(amount.getCalculated()) + + "" //currencyID=\"EUR\" + + "VAT" + + (displayExemptionReason ? exemptionReason : "") + + "" + currencyFormat(amount.getBasis()) + "" // currencyID=\"EUR\" + + "" + amountCategoryCode + "" + + (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + "" : "") + + "" + + vatFormat(currentTaxPercent) + ""; } } } @@ -615,17 +625,17 @@ public void generateXML(IExportableTransaction trans) { for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { xml += " " + - "" + - "true" + - "" + - "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + - "" + - "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - " "; + "" + + "true" + + "" + + "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + + "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + + "" + + "VAT" + + "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + + "" + vatFormat(currentTaxPercent) + "" + + "" + + " "; } } } @@ -634,17 +644,17 @@ public void generateXML(IExportableTransaction trans) { for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { xml += "" + - "" + - "false" + - "" + - "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + - "" + - "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - " "; + "" + + "false" + + "" + + "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + + "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + + "" + + "VAT" + + "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + + "" + vatFormat(currentTaxPercent) + "" + + "" + + " "; } } } @@ -667,8 +677,8 @@ public void generateXML(IExportableTransaction trans) { if (hasDueDate && (trans.getDueDate() != null)) { xml += "" // $NON-NLS-2$ - + DATE.udtFormat(trans.getDueDate()) - + "";// 20130704 + + DATE.udtFormat(trans.getDueDate()) + + "";// 20130704 } xml += ""; @@ -685,29 +695,29 @@ public void generateXML(IExportableTransaction trans) { if (getProfile() != Profiles.getByName("Minimum")) { xml += "" + currencyFormat(calc.getTotal()) + ""; xml += chargesTotalLine - + allowanceTotalLine; + + allowanceTotalLine; } xml += "" + currencyFormat(calc.getTaxBasis()) + "" - // // - // currencyID=\"EUR\" - + "" - + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" - + "" + currencyFormat(calc.getGrandTotal()) + ""; - // // - // currencyID=\"EUR\" - if (getProfile() != Profiles.getByName("Minimum")) { - xml+=" " + currencyFormat(calc.getTotalPrepaid()) + ""; - } - xml+= "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" - + ""; + // // + // currencyID=\"EUR\" + + "" + + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" + + "" + currencyFormat(calc.getGrandTotal()) + ""; + // // + // currencyID=\"EUR\" + if (getProfile() != Profiles.getByName("Minimum")) { + xml += " " + currencyFormat(calc.getTotalPrepaid()) + ""; + } + xml += "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" + + ""; if (trans.getInvoiceReferencedDocumentID() != null) { xml += " " - + " " - + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; + + " " + + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; if (trans.getInvoiceReferencedIssueDate() != null) { xml += "" - + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) - + ""; + + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) + + ""; } xml += " "; } @@ -723,7 +733,7 @@ public void generateXML(IExportableTransaction trans) { // + " \n"; xml += "" - + ""; + + ""; final byte[] zugferdRaw; try { @@ -735,37 +745,37 @@ public void generateXML(IExportableTransaction trans) { } } - protected String buildItemNotes(IZUGFeRDExportableItem currentItem) { - if (currentItem.getNotes() == null) { - return ""; - } - return Arrays.stream(currentItem.getNotes()) - .map(IncludedNote::unspecifiedNote) - .map(IncludedNote::toCiiXml) - .collect(Collectors.joining()); - } - - protected String buildNotes(IExportableTransaction exportableTransaction) { - final List includedNotes = Optional.ofNullable(exportableTransaction.getNotesWithSubjectCode()) - .orElse(new ArrayList<>()); - if (exportableTransaction.getNotes() != null) { - for (final String currentNote : exportableTransaction.getNotes()) { - includedNotes.add(IncludedNote.unspecifiedNote(currentNote)); - } - } - if (exportableTransaction.rebateAgreementExists()) { - includedNotes.add(IncludedNote.discountBonusNote("Es bestehen Rabatt- und Bonusvereinbarungen.")); - } - Optional.ofNullable(exportableTransaction.getOwnOrganisationFullPlaintextInfo()) - .ifPresent(info -> includedNotes.add(IncludedNote.regulatoryNote(info))); - - Optional.ofNullable(exportableTransaction.getSubjectNote()) - .ifPresent(note -> includedNotes.add(IncludedNote.unspecifiedNote(note))); - - return includedNotes.stream().map(IncludedNote::toCiiXml).collect(Collectors.joining("")); - } - - @Override + protected String buildItemNotes(IZUGFeRDExportableItem currentItem) { + if (currentItem.getNotes() == null) { + return ""; + } + return Arrays.stream(currentItem.getNotes()) + .map(IncludedNote::unspecifiedNote) + .map(IncludedNote::toCiiXml) + .collect(Collectors.joining()); + } + + protected String buildNotes(IExportableTransaction exportableTransaction) { + final List includedNotes = Optional.ofNullable(exportableTransaction.getNotesWithSubjectCode()) + .orElse(new ArrayList<>()); + if (exportableTransaction.getNotes() != null) { + for (final String currentNote : exportableTransaction.getNotes()) { + includedNotes.add(IncludedNote.unspecifiedNote(currentNote)); + } + } + if (exportableTransaction.rebateAgreementExists()) { + includedNotes.add(IncludedNote.discountBonusNote("Es bestehen Rabatt- und Bonusvereinbarungen.")); + } + Optional.ofNullable(exportableTransaction.getOwnOrganisationFullPlaintextInfo()) + .ifPresent(info -> includedNotes.add(IncludedNote.regulatoryNote(info))); + + Optional.ofNullable(exportableTransaction.getSubjectNote()) + .ifPresent(note -> includedNotes.add(IncludedNote.unspecifiedNote(note))); + + return includedNotes.stream().map(IncludedNote::toCiiXml).collect(Collectors.joining("")); + } + + @Override public void setProfile(Profile p) { profile = p; } @@ -781,7 +791,7 @@ private String buildPaymentTermsXml() { final Date dueDate = paymentTerms.getDueDate(); if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { 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"); } paymentTermsXml += "" + paymentTerms.getDescription() + ""; @@ -805,7 +815,7 @@ private String buildPaymentTermsXml() { final String basisAmount = currencyFormat(calc.getGrandTotal()); paymentTermsXml += "" + basisAmount + ""; paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() - + ""; + + ""; if (discountTerms.getBaseDate() != null) { final Date baseDate = discountTerms.getBaseDate(); @@ -814,7 +824,7 @@ private String buildPaymentTermsXml() { paymentTermsXml += ""; paymentTermsXml += "" - + discountTerms.getBasePeriodMeasure() + ""; + + discountTerms.getBasePeriodMeasure() + ""; } paymentTermsXml += ""; diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java index 6b5cccba7..ac5f2aaf7 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java @@ -48,6 +48,7 @@ public void testXRExport() { // the writing part TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + recipient.setEmail("quack@ducktown.org"); Invoice i = createInvoice(recipient); ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); @@ -153,7 +154,7 @@ private org.mustangproject.Invoice createInvoice(TradeParty recipient) { String amountStr = "1.00"; BigDecimal amount = new BigDecimal(amountStr); return new Invoice().setDueDate(new java.util.Date()).setIssueDate(new java.util.Date()).setDeliveryDate(new java.util.Date()) - .setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new org.mustangproject.Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new org.mustangproject.BankDetails("DE12500105170648489890","COBADEFXXX"))) + .setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setEmail("info@example.org").setContact(new org.mustangproject.Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new org.mustangproject.BankDetails("DE12500105170648489890","COBADEFXXX"))) .setRecipient(recipient) .setReferenceNumber("991-01484-64")//leitweg-id // not using any VAT, this is also a test of zero-rated goods: