From 3ca078a10c13bb4a3e582fea127fbae94ccfdb35 Mon Sep 17 00:00:00 2001 From: Matthias Kilian Date: Thu, 27 Jun 2024 13:19:46 +0200 Subject: [PATCH 1/6] ZUGFeRDVisualizer.toPDF(): generate PDF/A-3b. PDF/A-1b doesn't support embedded files, but when converting e.g. an XRechnung with an attached document, the visualizer tries (and fails) to attach it to the generated PDF. --- .../main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java index c9431b2b..4aa8a374 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java @@ -332,7 +332,7 @@ public class ZUGFeRDVisualizer { FOUserAgent userAgent = fopFactory.newFOUserAgent(); - userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-1b"); + userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-3b"); // Step 2: Set up output stream. // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). From 93e7a394fc592755388f9316b942843736644994 Mon Sep 17 00:00:00 2001 From: langfr Date: Mon, 15 Jul 2024 22:00:03 +0100 Subject: [PATCH 2/6] Fix build warnings --- Mustang-CLI/pom.xml | 27 --------------------------- library/pom.xml | 25 ++----------------------- pom.xml | 8 ++------ validator/pom.xml | 27 ++------------------------- 4 files changed, 6 insertions(+), 81 deletions(-) diff --git a/Mustang-CLI/pom.xml b/Mustang-CLI/pom.xml index 247cd494..81520e27 100644 --- a/Mustang-CLI/pom.xml +++ b/Mustang-CLI/pom.xml @@ -7,16 +7,13 @@ 2.12.0-SNAPSHOT 4.0.0 - org.mustangproject Mustang-CLI e-invoices commandline tool, allowing to create(embed), split and validate Factur-X/ZUGFeRD files. Validation should also work for XRechnung/CII. jar - 2.12.0-SNAPSHOT UTF-8 - 11 11 11 @@ -111,18 +108,6 @@ maven-compiler-plugin 2.3.2 - - - true - org.mustangproject.commandline.main - - - - jar-with-dependencies - - - 11 11 @@ -150,24 +135,12 @@ META-INF/*.RSA - - log4j:log4j - - ** - - commons-logging:commons-logging ** - - com.sun.xml.bind:jaxb-impl - - ** - - diff --git a/library/pom.xml b/library/pom.xml index 76b7e8b7..5ada8d65 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -8,9 +8,7 @@ 4.0.0 - org.mustangproject library - 2.12.0-SNAPSHOT jar Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII) FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT @@ -47,11 +45,9 @@ github -Xdoclint:none - 11 11 11 - true - + true @@ -170,12 +166,6 @@ maven-compiler-plugin 3.13.0 - - jar-with-dependencies - - - 11 11 @@ -234,10 +224,8 @@ 3.5.3 true - false - + false - *:* @@ -246,12 +234,6 @@ META-INF/*.RSA - - log4j:log4j - - ** - - commons-logging:commons-logging @@ -269,9 +251,6 @@ - diff --git a/pom.xml b/pom.xml index 0c747e0d..15983ee6 100644 --- a/pom.xml +++ b/pom.xml @@ -63,8 +63,7 @@ maven-deploy-plugin 3.0.0-M1 - internal.repo::default::file://${project.build.directory}/mvn-repo - + internal.repo::default::file://${project.build.directory}/mvn-repo @@ -82,6 +81,7 @@ org.apache.maven.plugins maven-surefire-plugin + 3.3.1 alphabetical @@ -90,9 +90,6 @@ org.apache.maven.plugins maven-source-plugin 3.2.1 - - UTF-8 - attach-javadoc @@ -118,7 +115,6 @@ github -Xdoclint:none - 11 11 11 true @@ -27,18 +25,15 @@ UTF-8 - false - - 11 + false 11 11 - ${project.groupId} library - 2.12.0-SNAPSHOT + ${project.version} jakarta.xml.bind @@ -134,12 +129,6 @@ maven-compiler-plugin 2.3.2 - - jar-with-dependencies - - - 11 11 @@ -163,24 +152,12 @@ META-INF/*.RSA - - log4j:log4j - - ** - - commons-logging:commons-logging ** - - com.sun.xml.bind:jaxb-impl - - ** - - From 71d2b98702f7f695574a1353ad1c4e2ff5c6ef8c Mon Sep 17 00:00:00 2001 From: langfr Date: Sun, 21 Jul 2024 10:13:32 +0100 Subject: [PATCH 3/6] Add ApplicableProductCharacteristic (BG-32:BT-160/BT-161) and OriginTradeCountry (BT-159) to Product. --- .../main/java/org/mustangproject/Product.java | 33 +++++++++++++++++++ .../ZUGFeRD/IZUGFeRDExportableProduct.java | 9 +++++ .../ZUGFeRD/ZUGFeRD2PullProvider.java | 13 ++++++++ 3 files changed, 55 insertions(+) diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java index 3d21f588..b90a70cd 100644 --- a/library/src/main/java/org/mustangproject/Product.java +++ b/library/src/main/java/org/mustangproject/Product.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct; import java.math.BigDecimal; +import java.util.HashMap; /*** * describes a product, good or service used in an invoice item line @@ -15,6 +16,8 @@ public class Product implements IZUGFeRDExportableProduct { protected boolean isReverseCharge = false; protected boolean isIntraCommunitySupply = false; protected SchemedID globalId = null; + protected String countryOfOrigin = null; + protected HashMap attributes = null; /*** * default constructor @@ -63,6 +66,7 @@ public class Product implements IZUGFeRDExportableProduct { } + @Override public String getSellerAssignedID() { return sellerAssignedID; } @@ -77,6 +81,7 @@ public class Product implements IZUGFeRDExportableProduct { return this; } + @Override public String getBuyerAssignedID() { return buyerAssignedID; } @@ -183,4 +188,32 @@ public class Product implements IZUGFeRDExportableProduct { this.VATPercent = VATPercent; return this; } + + @Override + public String getCountryOfOrigin() { + return this.countryOfOrigin; + } + + public Product setCountryOfOrigin(String countryOfOrigin) { + this.countryOfOrigin = countryOfOrigin; + return this; + } + + @Override + public HashMap getAttributes() { + return this.attributes; + } + + public Product setAttributes(HashMap attributes) { + this.attributes = attributes; + return this; + } + + public Product addAttribute(String name, String value ) { + if ( this.attributes == null ) { + this.attributes = new HashMap<>(); + } + this.attributes.put(name, value); + return this; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java index 3b82786e..049bb546 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java @@ -21,6 +21,7 @@ package org.mustangproject.ZUGFeRD; import java.math.BigDecimal; +import java.util.HashMap; import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; @@ -156,4 +157,12 @@ public interface IZUGFeRDExportableProduct { } return null; } + + default String getCountryOfOrigin() { + return null; + } + + default HashMap getAttributes() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 06a6ab28..c937f87a 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -34,6 +34,7 @@ import java.util.Base64; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.stream.Collectors; @@ -397,6 +398,18 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { XMLTools.encodeXML(currentItem.getProduct().getDescription()) + ""; } + if (currentItem.getProduct().getAttributes() != null) { + xml += ""; + for ( Entry entry : currentItem.getProduct().getAttributes().entrySet() ) { + xml += "" + XMLTools.encodeXML(entry.getKey()) + "" + "" + XMLTools.encodeXML(entry.getValue()) + ""; + } + xml += ""; + } + if (currentItem.getProduct().getCountryOfOrigin() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getCountryOfOrigin()) + + ""; + } xml += "" + ""; From d50a66e8d605279f02feb49e008c605ef843571e Mon Sep 17 00:00:00 2001 From: langfr Date: Thu, 25 Jul 2024 20:10:15 +0100 Subject: [PATCH 4/6] Correction on Item Attributes, related to #420. --- .../org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index c937f87a..e1111220 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -399,11 +399,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { ""; } if (currentItem.getProduct().getAttributes() != null) { - xml += ""; for ( Entry entry : currentItem.getProduct().getAttributes().entrySet() ) { - xml += "" + XMLTools.encodeXML(entry.getKey()) + "" + "" + XMLTools.encodeXML(entry.getValue()) + ""; + xml += "" + + "" + XMLTools.encodeXML(entry.getKey()) + "" + + "" + XMLTools.encodeXML(entry.getValue()) + "" + + ""; } - xml += ""; } if (currentItem.getProduct().getCountryOfOrigin() != null) { xml += "" + From ac9b88693627380a3171b2016690a4ec92361c05 Mon Sep 17 00:00:00 2001 From: langfr Date: Thu, 25 Jul 2024 20:19:08 +0100 Subject: [PATCH 5/6] Read Item.referencedLineID. --- library/src/main/java/org/mustangproject/Item.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/src/main/java/org/mustangproject/Item.java b/library/src/main/java/org/mustangproject/Item.java index 8d9b0d0e..321b4723 100644 --- a/library/src/main/java/org/mustangproject/Item.java +++ b/library/src/main/java/org/mustangproject/Item.java @@ -60,6 +60,7 @@ public class Item implements IZUGFeRDExportableItem { String vatPercent = null; String lineTotal = "0"; String unitCode = "0"; + String referencedLineID = null; ArrayList rdocs = null; @@ -142,6 +143,16 @@ public class Item implements IZUGFeRDExportableItem { } + if ((tradeLineChilds.item(tradeLineChildIndex).getLocalName() != null) && tradeLineChilds.item(tradeLineChildIndex).getLocalName().equals("BuyerOrderReferencedDocument")) { + NodeList docChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes(); + for (int docIndex = 0; docIndex < docChilds.getLength(); docIndex++) { + String localName = docChilds.item(docIndex).getLocalName(); + if ((localName != null) && (localName.equals("LineID"))) { + referencedLineID = docChilds.item(docIndex).getTextContent(); + } + } + } + if ((tradeLineChilds.item(tradeLineChildIndex).getLocalName() != null) && tradeLineChilds .item(tradeLineChildIndex).getLocalName().equals("NetPriceProductTradePrice")) { NodeList netChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes(); @@ -263,6 +274,7 @@ public class Item implements IZUGFeRDExportableItem { addReferencedDocument(rdoc); } } + addReferencedLineID( referencedLineID ); } From 77ddc7627d5c193af6e1223c831bdd85935e46f8 Mon Sep 17 00:00:00 2001 From: langfr Date: Tue, 30 Jul 2024 15:37:57 +0100 Subject: [PATCH 6/6] Enhance Charges/Allowances with reasonCode. --- .../main/java/org/mustangproject/Charge.java | 22 +- .../ZUGFeRD/IZUGFeRDAllowanceCharge.java | 6 + .../ZUGFeRD/ZUGFeRD2PullProvider.java | 198 ++++++++++++------ .../ZUGFeRD/ZUGFeRDInvoiceImporter.java | 10 +- .../ZUGFeRD/IZUGFeRDAllowanceChargeImpl.java | 11 + 5 files changed, 178 insertions(+), 69 deletions(-) diff --git a/library/src/main/java/org/mustangproject/Charge.java b/library/src/main/java/org/mustangproject/Charge.java index 93335a13..c1810c57 100644 --- a/library/src/main/java/org/mustangproject/Charge.java +++ b/library/src/main/java/org/mustangproject/Charge.java @@ -26,6 +26,10 @@ public class Charge implements IZUGFeRDAllowanceCharge { * a simple human readable description */ protected String reason; + /** + * Code from list UNTDID 5189 + */ + protected String reasonCode; /** * the category ID why this charge has been applied */ @@ -94,6 +98,22 @@ public class Charge implements IZUGFeRDAllowanceCharge { } + @Override + public String getReasonCode() { + return reasonCode; + } + + /*** + * Reason code for the charge + * @param reasonCode from list UNTDID 5189 + * @return fluid setter + */ + public Charge setReasonCode(String reasonCode) { + this.reasonCode = reasonCode; + return this; + } + + @Override public BigDecimal getTotalAmount(IAbsoluteValueProvider currentItem) { if (totalAmount!=null) { @@ -137,7 +157,7 @@ public class Charge implements IZUGFeRDAllowanceCharge { /*** - * machine readable reason for this allowance/charge + * the category ID why this has been applied * @param categoryCode usually S * @return fluid setter */ diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java index 75b01a67..0c61ba5b 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java @@ -44,6 +44,12 @@ public interface IZUGFeRDAllowanceCharge { */ String getReason(); + /*** + * get the code for the allowance/charge + * @return the code + */ + String getReasonCode(); + /*** * get the applicable tax percentage for the allowance/charge * @return the percentage diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index e1111220..345fed91 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -141,7 +141,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if (party.getLegalOrganisation() != null) { xml += " "; - xml += " " + XMLTools.encodeXML(party.getLegalOrganisation().getID()) + ""; + xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getID()) + ""; xml += ""; } @@ -244,10 +244,16 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { // only in extended profile reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; } + String reasonCode = ""; + if ((allowance.getReasonCode() != null) && (profile == Profiles.getByName("XRechnung"))) { + // only in XRechnung profile + reasonCode = "" + allowance.getReasonCode() + ""; + } final String allowanceChargeStr = "" + chargeIndicator + "" + percentage + "" + priceFormat(allowance.getTotalAmount(item)) + "" + reason + + reasonCode + ""; return allowanceChargeStr; } @@ -269,10 +275,21 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { chargeIndicator = "true"; } + String reason = ""; + if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended"))) { + // only in extended profile + reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; + } + String reasonCode = ""; + if ((allowance.getReasonCode() != null) && (profile == Profiles.getByName("XRechnung"))) { + // only in XRechnung profile + reasonCode = "" + allowance.getReasonCode() + ""; + } final String itemTotalAllowanceChargeStr = "" + chargeIndicator + "" + percentage + "" + currencyFormat(allowance.getTotalAmount(item)) + "" + - "" + XMLTools.encodeXML(allowance.getReason()) + "" + + reason + + reasonCode + ""; return itemTotalAllowanceChargeStr; } @@ -325,9 +342,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { // if (getProfile() == Profiles.getByName("XRechnung")) { - xml += " \n" - + " urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\n" - + " \n"; + xml += "\n" + + "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\n" + + "\n"; } xml += "" @@ -336,7 +353,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + "" + "" + "" + XMLTools.encodeXML(trans.getNumber()) + "" - // + " RECHNUNG" + // + "RECHNUNG" // + "380" + "" + typecode + "" + "" @@ -436,11 +453,11 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + allowanceChargeStr - // + " " - // + " false" - // + " 0.6667" - // + " Rabatt" - // + " " + // + "" + // + "false" + // + "0.6667" + // + "Rabatt" + // + "" + ""; } @@ -499,53 +516,53 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + getTradePartyAsXML(trans.getSender(), true, false) + "" + ""; - // + " GE2020211" - // + " 4000001987658" + // + "GE2020211" + // + "4000001987658" xml += getTradePartyAsXML(trans.getRecipient(), false, false); xml += ""; if (trans.getSellerOrderReferencedDocumentID() != null) { - xml += " " - + " " + xml += "" + + "" + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" - + " "; + + ""; } if (trans.getBuyerOrderReferencedDocumentID() != null) { - xml += " " - + " " + xml += "" + + "" + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" - + " "; + + ""; } if (trans.getContractReferencedDocument() != null) { - xml += " " - + " " + xml += "" + + "" + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" - + " "; + + ""; } // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) if (trans.getAdditionalReferencedDocuments() != null) { for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); - xml += " " - + " " + f.getFilename() + "" - + " 916" - + " " + f.getDescription() + "" - + " " + documentContent + "" - + " "; + xml += "" + + "" + f.getFilename() + "" + + "916" + + "" + f.getDescription() + "" + + "" + documentContent + "" + + ""; } } if (trans.getSpecifiedProcuringProjectID() != null) { - xml += " " - + " " + xml += "" + + "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; if (trans.getSpecifiedProcuringProjectName() != null) { - xml += " " + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; + xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; } - xml += " "; + xml += ""; } xml += ""; xml += ""; @@ -562,7 +579,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + ""; xml += DATE.udtFormat(trans.getDeliveryDate()); xml += ""; - xml += " "; + xml += ""; } /* @@ -581,9 +598,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { xml += ""; xml += ""; if ((trans.getNumber() != null) && (getProfile() != Profiles.getByName("Minimum"))) { - xml += " " + XMLTools.encodeXML(trans.getNumber()) + ""; + xml += "" + XMLTools.encodeXML(trans.getNumber()) + ""; } - xml += " " + trans.getCurrency() + ""; + xml += "" + trans.getCurrency() + ""; if (trans.getTradeSettlementPayment() != null) { for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { @@ -645,40 +662,87 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { - - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - xml += " " + + if (profile == Profiles.getByName("XRechnung")) { + for(IZUGFeRDAllowanceCharge charge : trans.getZFCharges()) { + xml += "" + "" + "true" + "" + - "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + - "" + + "" + currencyFormat(charge.getTotalAmount(calc)) + ""; + if (charge.getReason() != null) { + xml += "" + XMLTools.encodeXML(charge.getReason()) + ""; + } + if (charge.getReasonCode() != null) { + xml += "" + charge.getReasonCode() + ""; + } + xml += "" + "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - " "; + "" + charge.getCategoryCode() + ""; + if (charge.getTaxPercent() != null) { + xml += "" + vatFormat(charge.getTaxPercent()) + ""; + } + xml += "" + + ""; + } + } else { + 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) + "" + + "" + + ""; + } } } } if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { + if (profile == Profiles.getByName("XRechnung")) { + for(IZUGFeRDAllowanceCharge allowance : trans.getZFAllowances()) { xml += "" + "" + "false" + "" + - "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + - "" + + "" + currencyFormat(allowance.getTotalAmount(calc)) + ""; + if (allowance.getReason() != null) { + xml += "" + XMLTools.encodeXML(allowance.getReason()) + ""; + } + if (allowance.getReasonCode() != null) { + xml += "" + allowance.getReasonCode() + ""; + } + xml += "" + "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - " "; + "" + allowance.getCategoryCode() + ""; + if (allowance.getTaxPercent() != null) { + xml += "" + vatFormat(allowance.getTaxPercent()) + ""; + } + xml += "" + + ""; + } + } else { + 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) + "" + + "" + + ""; + } } } } @@ -736,31 +800,31 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { // // // currencyID=\"EUR\" if (getProfile() != Profiles.getByName("Minimum")) { - xml += " " + currencyFormat(calc.getTotalPrepaid()) + ""; + xml += "" + currencyFormat(calc.getTotalPrepaid()) + ""; } xml += "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" + ""; if (trans.getInvoiceReferencedDocumentID() != null) { - xml += " " - + " " + xml += "" + + "" + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; if (trans.getInvoiceReferencedIssueDate() != null) { xml += "" + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) + ""; } - xml += " "; + xml += ""; } xml += ""; - // + " \n" - // + " \n" - // + " \n" - // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. + // + "\n" + // + "\n" + // + "\n" + // + "Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. // 2013-51112 in Rechnung zu stellen:\n" - // + " \n" - // + " \n" - // + " \n"; + // + "\n" + // + "\n" + // + "\n"; xml += "" + ""; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index d2921474..5207bcf2 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -357,6 +357,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { boolean isCharge = true; String chargeAmount = null; String reason = null; + String reasonCode = null; String taxPercent = null; for (int chargeChildIndex = 0; chargeChildIndex < chargeNodeChilds.getLength(); chargeChildIndex++) { String chargeChildName = chargeNodeChilds.item(chargeChildIndex).getLocalName(); @@ -377,6 +378,8 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { chargeAmount = chargeNodeChilds.item(chargeChildIndex).getTextContent(); } else if (chargeChildName.equals("Reason")) { reason = chargeNodeChilds.item(chargeChildIndex).getTextContent(); + } else if (chargeChildName.equals("ReasonCode")) { + reasonCode = chargeNodeChilds.item(chargeChildIndex).getTextContent(); } else if (chargeChildName.equals("CategoryTradeTax")) { NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { @@ -395,16 +398,21 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { if (reason != null) { c.setReason(reason); } + if (reasonCode != null) { + c.setReasonCode(reasonCode); + } if (taxPercent != null) { c.setTaxPercent(new BigDecimal(taxPercent)); } - zpp.addCharge(c); } else { Allowance a = new Allowance(new BigDecimal(chargeAmount)); if (reason != null) { a.setReason(reason); } + if (reasonCode != null) { + a.setReasonCode(reasonCode); + } if (taxPercent != null) { a.setTaxPercent(new BigDecimal(taxPercent)); } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceChargeImpl.java b/library/src/test/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceChargeImpl.java index 899e5adc..ea25c9b2 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceChargeImpl.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceChargeImpl.java @@ -23,6 +23,7 @@ import java.math.BigDecimal; public class IZUGFeRDAllowanceChargeImpl implements IZUGFeRDAllowanceCharge { private BigDecimal totalAmount; private String reason; + private String reasonCode; private BigDecimal taxPercent; boolean isCharge=true; @@ -36,6 +37,11 @@ public class IZUGFeRDAllowanceChargeImpl implements IZUGFeRDAllowanceCharge { return reason; } + @Override + public String getReasonCode() { + return reasonCode; + } + @Override public BigDecimal getTaxPercent() { return taxPercent; @@ -61,6 +67,11 @@ public class IZUGFeRDAllowanceChargeImpl implements IZUGFeRDAllowanceCharge { return this; } + public IZUGFeRDAllowanceChargeImpl setReasonCode(String reasonCode) { + this.reasonCode = reasonCode; + return this; + } + public IZUGFeRDAllowanceChargeImpl setTaxPercent(BigDecimal taxPercent) { this.taxPercent = taxPercent; return this;