diff --git a/History.md b/History.md index 1a5f7fc3..fa2e51df 100644 --- a/History.md +++ b/History.md @@ -1,7 +1,17 @@ +2.0.3 +======= + + +- #201 correct embedded files in XRechnung + 2.0.2 ======= +2020-11-25 + - #197 file attachments - Charges/Allowances CategoryCode improvement PR #198 Thanks to weclapp-dev +- support reverse charge +- support intra community supply also in product class, not only interface 2.0.1 ===== diff --git a/Mustang-CLI/pom.xml b/Mustang-CLI/pom.xml index 0df1b88d..c4fd177a 100644 --- a/Mustang-CLI/pom.xml +++ b/Mustang-CLI/pom.xml @@ -3,14 +3,14 @@ org.mustangproject core - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT 4.0.0 org.mustangproject Mustang-CLI Mustang commandline tool jar - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT @@ -31,7 +31,7 @@ org.mustangproject validator - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT diff --git a/README.md b/README.md index c39a9eee..bcea4a64 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ If you setup a Maven project, you can grab the artifacts using org.mustangproject library - 2.0.0 + 2.0.2 ``` diff --git a/doc/development_documentation.md b/doc/development_documentation.md index afe475c1..6dc8c7a9 100644 --- a/doc/development_documentation.md +++ b/doc/development_documentation.md @@ -171,7 +171,6 @@ Change to the project directory and run * clean the release with `mvn release:clean` and prepare the release with * `mvn release:prepare -DignoreSnapshots=true` and enter the version numbers. * After that is through you can create a new release via `mvn release:perform -Dmaven.java.skip=True`.This will also update the maven repo. - * Experimental: mvn deploy -Dregistry=https://maven.pkg.github.com/ZUGFeRD -Dtoken=GH_TOKEN ![screenshot](development_documentation_screenshot_release.png "Screenshot Release") diff --git a/library/pom.xml b/library/pom.xml index a6e19a95..fe73205a 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -3,13 +3,13 @@ org.mustangproject core - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT 4.0.0 org.mustangproject library - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT jar Library to write and read FacturX and ZUGFeRD e-invoices. The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs. To write files, a provided PDF/A will be combined with generated or provided XML. diff --git a/library/src/main/java/org/mustangproject/Invoice.java b/library/src/main/java/org/mustangproject/Invoice.java index 68c49339..1d0c121f 100644 --- a/library/src/main/java/org/mustangproject/Invoice.java +++ b/library/src/main/java/org/mustangproject/Invoice.java @@ -40,6 +40,7 @@ public class Invoice implements IExportableTransaction { protected ArrayList ZFItems = null; protected ArrayList notes = null; protected String contractReferencedDocument = null; + protected ArrayList xmlEmbeddedFiles=null; protected Date detailedDeliveryDateStart = null; protected Date detailedDeliveryPeriodEnd = null; @@ -78,6 +79,22 @@ public class Invoice implements IExportableTransaction { return this; } + public Invoice embedFileInXML(FileAttachment fa) { + if (xmlEmbeddedFiles == null) { + xmlEmbeddedFiles=new ArrayList(); + } + xmlEmbeddedFiles.add(fa); + return this; + } + + public FileAttachment[] getAdditionalReferencedDocuments() { + if (xmlEmbeddedFiles == null) { + return null; + } + return xmlEmbeddedFiles.toArray(new FileAttachment[0]); + + } + @Override public String getNumber() { diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java index 241e82d8..29d15c78 100644 --- a/library/src/main/java/org/mustangproject/Product.java +++ b/library/src/main/java/org/mustangproject/Product.java @@ -10,6 +10,8 @@ import java.math.BigDecimal; public class Product implements IZUGFeRDExportableProduct { protected String unit, name, description, sellerAssignedID, buyerAssignedID; protected BigDecimal VATPercent; + protected boolean isReverseCharge=false; + protected boolean isIntraCommunitySupply=false; /*** * default constructor @@ -54,6 +56,37 @@ public class Product implements IZUGFeRDExportableProduct { return this; } + @Override + public boolean isReverseCharge() { + return isReverseCharge; + } + + @Override + public boolean isIntraCommunitySupply() { + return isIntraCommunitySupply; + } + + /*** + * sets reverse charge(=delivery to outside EU) + * @return fluent setter + */ + public Product setReverseCharge() { + isReverseCharge=true; + setVATPercent(BigDecimal.ZERO); + return this; + } + + + /*** + * sets intra community supply(=delivery outside the country inside the EU) + * @return fluent setter + */ + public Product setIntraCommunitySupply() { + isIntraCommunitySupply=true; + setVATPercent(BigDecimal.ZERO); + return this; + } + @Override public String getUnit() { return unit; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java index 55af8ee1..efab767d 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java @@ -108,10 +108,16 @@ public interface IZUGFeRDExportableProduct { return false; } + default boolean isReverseCharge() { + return false; + } + default String getTaxCategoryCode() { if (isIntraCommunitySupply()) { - return "K"; - } else if (getVATPercent().equals(new BigDecimal(0))) { + return "K"; // within europe + } else if (isReverseCharge()) { + return "AE"; // to out of europe... + } else if (getVATPercent().equals(BigDecimal.ZERO)) { return "Z"; // zero rated goods } else { return "S"; // one of the "standard" rates (not neccessarily a default rate, even a deducted VAT is standard calculation) @@ -119,8 +125,11 @@ public interface IZUGFeRDExportableProduct { } default String getTaxExemptionReason() { - if (isIntraCommunitySupply()) + if (isIntraCommunitySupply()) { return "Intra-community supply"; + } else if (isReverseCharge()) { + return "Reverse Charge"; + } 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 f31176df..54d1c169 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -442,7 +442,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + " 916\n" + " " + f.getDescription() + "\n" + " " + documentContent + "\n" + + " filename=\"" + f.getFilename() + "\">" + documentContent + "\n" + " \n"; } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java index 6166dd51..ac94775d 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java @@ -39,6 +39,7 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class XRTest extends TestCase { final String TARGET_XML = "./target/testout-XR.xml"; + final String TARGET_EDGE_XML = "./target/testout-XR-Edge.xml"; public void testXRExport() { // the writing part @@ -76,5 +77,48 @@ public class XRTest extends TestCase { } } + public void testXREdgeExport() { + + // the writing part + + String orgname = "Test company"; + String number = "123"; + String amountStr = "1.00"; + BigDecimal amount = new BigDecimal(amountStr); + byte[] b = {12, 13}; + FileAttachment fe1=new FileAttachment("one.pdf", "application/pdf", "Alternative", b); + FileAttachment fe2=new FileAttachment("two.pdf", "application/pdf", "Alternative", b); + Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + .setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890","COBADEFXXX"))) + .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) + .setReferenceNumber("991-01484-64")//leitweg-id + // not using any VAT, this is also a test of zero-rated goods: + .setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), amount, new BigDecimal(1.0))) + .embedFileInXML(fe1).embedFileInXML(fe2); + + + ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); + + zf2p.setProfile(Profiles.getByName("XRechnung")); + zf2p.generateXML(i); + String theXML = new String(zf2p.getXML()); + assertTrue(theXML.contains("4.0.0 org.mustangproject core - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT pom Mustang diff --git a/validator/pom.xml b/validator/pom.xml index bd74cd8b..0868f732 100644 --- a/validator/pom.xml +++ b/validator/pom.xml @@ -3,7 +3,7 @@ org.mustangproject core - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT 4.0.0 org.mustangproject @@ -11,7 +11,7 @@ Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung) jar - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT @@ -75,7 +75,7 @@ org.mustangproject library - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT org.xmlunit diff --git a/validator/src/test/java/org/mustangproject/validator/LibraryTest.java b/validator/src/test/java/org/mustangproject/validator/LibraryTest.java index 977d85d3..f780b390 100644 --- a/validator/src/test/java/org/mustangproject/validator/LibraryTest.java +++ b/validator/src/test/java/org/mustangproject/validator/LibraryTest.java @@ -157,7 +157,7 @@ public class LibraryTest extends ResourceCase { * automatically test the xrechnung */ public void testXRValidation() { - File tempFile = new File("../library/target/testout-XR.xml"); + File tempFile = new File("../library/target/testout-XR-Edge.xml"); ZUGFeRDValidator zfv = new ZUGFeRDValidator(); String res = zfv.validate(tempFile.getAbsolutePath());