From 74900ebe69fc69a481a72576108f7a4b2409e364 Mon Sep 17 00:00:00 2001 From: Jens Heise Date: Tue, 2 Jun 2020 14:41:59 +0200 Subject: [PATCH] ZUGFeRD2PullProvider: Added several properties to be written to the ZUGFeRD-XML and if necessary corresponding methods in the IZUGFeRDExportable... interface objects of Transaction, Item and Product: Properties with new methods: - SubjectNote for 'ExchangedDocument.IncludedNote' (human readable document subject) - RebateAgreementExists for 'ExchangedDocument.IncludedNote' (Note that there are rebate agreements) - BasisQuantity (number of item units per price) - SellerAssignedID (seller identification of product) - BuyerAssignedID (buyer identification of product) - TaxExemptionReason (explanatory statement why no tax gets applied) enhancement to support other exemptions than "IC-supply" Properties for existing methods that did not get written to the XML up to now: - SellerTradeParty.ID (buyer assigned ID of seller) - SellerTradeParty.GlobalID of seller (e.g. DUNS) - BuyerOrderReferencedDocumentID (order number of buyer) --- .../ZUGFeRD/IZUGFeRDExportableItem.java | 11 ++- .../ZUGFeRD/IZUGFeRDExportableProduct.java | 25 +++++- .../IZUGFeRDExportableTransaction.java | 18 ++++ .../ZUGFeRD/ZUGFeRD2PullProvider.java | 86 ++++++++++++------- 4 files changed, 106 insertions(+), 34 deletions(-) diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java index a4dfcc80..c4362443 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java @@ -47,12 +47,21 @@ public interface IZUGFeRDExportableItem { BigDecimal getPrice(); /** - * how many + * how many get billed * * @return the quantity of the item */ BigDecimal getQuantity(); + /** + * how many items units per price + * + * @return item units per price + */ + default BigDecimal getBasisQuantity() { + return BigDecimal.ONE.setScale(4); + } + default String getCategoryCode() { return TaxCategoryCodeTypeConstants.STANDARDRATE; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java index ab441e74..197bbac9 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java @@ -75,6 +75,25 @@ public interface IZUGFeRDExportableProduct { */ String getDescription(); + /** + * Get the ID that had been assigned by the seller to + * identify the product + * + * @return seller assigned product ID + */ + default String getSellerAssignedID() { + return null; + } + + /** + * Get the ID that had been assigned by the buyer to + * identify the product + * + * @return buyer assigned product ID + */ + default String getBuyerAssignedID() { + return null; + } /** * VAT percent of the product (e.g. 19, or 5.1 if you like) * @@ -95,5 +114,9 @@ public interface IZUGFeRDExportableProduct { } } - + default String getTaxExemptionReason() { + if (isIntraCommunitySupply()) + return "Intra-community supply"; + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java index 920ab7d2..7cdbbe04 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTransaction.java @@ -106,6 +106,16 @@ public interface IZUGFeRDExportableTransaction { } + /** + * subject of the document e.g. invoice and order + * number as human readable text + * + * @return string with document subject + */ + default String getSubjectNote() { + return null; + } + IZUGFeRDAllowanceCharge[] getZFAllowances(); @@ -272,6 +282,14 @@ public interface IZUGFeRDExportableTransaction { return null; } + /** + * returns if a rebate agreements exists + * + * @return + */ + default boolean rebateAgreementExists() { + return false; + } /** * get reference document number typically used for Invoice Corrections Will be added as IncludedNote in comfort profile diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 76c43125..d51a4b43 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -48,9 +48,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { BigDecimal multiplicator = currentItem.getProduct().getVATPercent().divide(new BigDecimal(100)) .add(new BigDecimal(1)); priceGross = currentItem.getPrice().multiply(multiplicator); - totalGross = currentItem.getPrice().multiply(multiplicator).multiply(currentItem.getQuantity()); - itemTotalNetAmount = currentItem.getQuantity().multiply(currentItem.getPrice()).setScale(2, - BigDecimal.ROUND_HALF_UP); + totalGross = currentItem.getQuantity().multiply(currentItem.getPrice()).divide(currentItem.getBasisQuantity()) + .multiply(multiplicator); + itemTotalNetAmount = currentItem.getQuantity().multiply(currentItem.getPrice()).divide(currentItem.getBasisQuantity()) + .setScale(2, BigDecimal.ROUND_HALF_UP); itemTotalVATAmount = totalGross.subtract(itemTotalNetAmount); } @@ -268,6 +269,20 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { } + String rebateAgreement = ""; + if (trans.rebateAgreementExists()) { + rebateAgreement = "\n" + " " + + "Es bestehen Rabatt- und Bonusvereinbarungen.\n" + + "AAK\n" + "\n"; + } + + String subjectNote = ""; + if (trans.getSubjectNote()!=null) { + subjectNote = "\n" + " " + + XMLTools.encodeXML(trans.getSubjectNote())+ "\n" + + "\n"; + } + String xml = "\n" //$NON-NLS-1$ + "\n" - // + " \n" - // + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n" - // + "\n" - // + " \n" - // + " \n" - // + " \n" - // + " \n" - // + "Es bestehen Rabatt- und Bonusvereinbarungen.\n" - // + " \n" - // + " AAK\n" - // + " \n" + + " \n" //$NON-NLS-1$ + " \n"; //$NON-NLS-1$ int lineID = 0; for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { lineID++; taxCategoryCode=currentItem.getProduct().getTaxCategoryCode(); - if (currentItem.getProduct().isIntraCommunitySupply()) { - exemptionReason="Intra-community supply"; + if (currentItem.getProduct().getTaxExemptionReason() != null) { + exemptionReason="" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; } LineCalc lc = new LineCalc(currentItem); @@ -321,11 +327,17 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { " \n" //$NON-NLS-1$ + " " + lineID + "\n" //$NON-NLS-1$ //$NON-NLS-2$ + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ // + " 4012345001235\n" - // + " KR3M\n" - // + " 55T01\n" - + " " + XMLTools.encodeXML(currentItem.getProduct().getName()) + "\n" //$NON-NLS-1$ //$NON-NLS-2$ + if (currentItem.getProduct().getSellerAssignedID() != null) { + xml = xml + " " + + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + "\n"; + } + if (currentItem.getProduct().getBuyerAssignedID() != null) { + xml = xml + " " + + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "\n"; + } + xml = xml + " " + XMLTools.encodeXML(currentItem.getProduct().getName()) + "\n" //$NON-NLS-1$ //$NON-NLS-2$ + " " + XMLTools.encodeXML(currentItem.getProduct().getDescription()) //$NON-NLS-1$ + "\n" //$NON-NLS-1$ + " \n" //$NON-NLS-1$ @@ -335,7 +347,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { + " " + priceFormat(lc.getPriceGross()) //$NON-NLS-1$ + "\n" //$NON-NLS-1$ //currencyID=\"EUR\" + " 1.0000\n" //$NON-NLS-1$ + + "\">" + quantityFormat(currentItem.getBasisQuantity()) +"\n" //$NON-NLS-1$ // + " \n" // + " false\n" // + " 0.6667\n" @@ -346,7 +358,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { + " " + priceFormat(currentItem.getPrice()) //$NON-NLS-1$ + "\n" //$NON-NLS-1$ // currencyID=\"EUR\" + " 1.0000\n" //$NON-NLS-1$ + + "\">" + quantityFormat(currentItem.getBasisQuantity()) +"\n" //$NON-NLS-1$ + " \n" //$NON-NLS-1$ + " \n" //$NON-NLS-1$ @@ -381,9 +393,16 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { xml = xml + " " + XMLTools.encodeXML(trans.getReferenceNumber()) + "\n"; } - xml = xml + " \n" //$NON-NLS-1$ - // + " 4000001123452\n" - + " " + XMLTools.encodeXML(trans.getOwnOrganisationName()) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ + xml = xml + " \n"; //$NON-NLS-1$ + if (trans.getOwnForeignOrganisationID()!=null) { + xml = xml + " " + XMLTools.encodeXML(trans.getOwnForeignOrganisationID()) + "\n"; + } + + if ((trans.getOwnContact()!=null)&&(trans.getOwnContact().getGlobalID()!=null)&&(trans.getOwnContact().getGlobalIDScheme()!=null)) { + xml = xml + " " + + XMLTools.encodeXML(trans.getOwnContact().getGlobalID()) + "\n"; + } + xml = xml + " " + XMLTools.encodeXML(trans.getOwnOrganisationName()) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ if ((trans.getOwnVATID()!=null)&&(trans.getOwnOrganisationName()!=null)) { @@ -429,12 +448,15 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider { // + " 4000001987658\n" xml+=getContactAsXML(trans.getRecipient()); - xml += " \n" //$NON-NLS-1$ - // + " \n" - // + " 20130301\n" - // + " 2013-471331\n" - // + " \n" - + " \n" //$NON-NLS-1$ + xml += " \n"; //$NON-NLS-1$ + + if (trans.getBuyerOrderReferencedDocumentID()!=null) { + xml = xml + " \n" //$NON-NLS-1$ + + " " //$NON-NLS-1$ + + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "\n" //$NON-NLS-1$ + + " \n"; + } + xml = xml + " \n" //$NON-NLS-1$ + " \n" ; if (this.trans.getDeliveryAddress()!=null) { xml += ""+