diff --git a/History.md b/History.md index a940a217..97088002 100644 --- a/History.md +++ b/History.md @@ -1,10 +1,14 @@ 2.0.3 ======= +2020-12-06 - #201 correct embedded files in XRechnung - transaction calculator getGrandTotal now public - corrected sample in docs thanks to tweimer PR #204 - don't write "null" as paymentDescription if no Bank account is specified +- generic and unitcode/categorycode improvements (thanks to weclapp-dev) PR #207 +- programmatically switch to XRechnung 2.0 if invoked next year +- support Credit Notes (additionally to corrected invoices) 2.0.2 ======= diff --git a/Mustang-CLI/pom.xml b/Mustang-CLI/pom.xml index c4fd177a..274d1f1c 100644 --- a/Mustang-CLI/pom.xml +++ b/Mustang-CLI/pom.xml @@ -3,14 +3,14 @@ org.mustangproject core - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT 4.0.0 org.mustangproject Mustang-CLI Mustang commandline tool jar - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT @@ -31,7 +31,7 @@ org.mustangproject validator - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT diff --git a/doc/konikmustangvergleich.odt b/doc/konikmustangvergleich.odt deleted file mode 100644 index 99c02ed5..00000000 Binary files a/doc/konikmustangvergleich.odt and /dev/null differ diff --git a/library/pom.xml b/library/pom.xml index fe73205a..d1c0b4bf 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -3,13 +3,13 @@ org.mustangproject core - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT 4.0.0 org.mustangproject library - 2.0.3-SNAPSHOT + 2.0.4-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 1d0c121f..7562f41a 100644 --- a/library/src/main/java/org/mustangproject/Invoice.java +++ b/library/src/main/java/org/mustangproject/Invoice.java @@ -119,6 +119,10 @@ public class Invoice implements IExportableTransaction { documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE; return this; } + public Invoice setCreditNote() { + documentCode = DocumentCodeTypeConstants.CREDITNOTE; + return this; + } @Override public String getOwnOrganisationFullPlaintextInfo() { diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java index 2496e801..515e9505 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java @@ -20,6 +20,7 @@ */ package org.mustangproject.ZUGFeRD; +import java.time.Year; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -31,7 +32,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.0")} + {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_"+((Year.now().getValue()<=2020)?"1.2":"2.0"))} //intentionally switch to XRechnung 2.0 on 01.01.2021 }).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 3129943e..5980cbf9 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -40,6 +40,8 @@ import org.mustangproject.FileAttachment; import org.mustangproject.XMLTools; import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; +import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE; + public class ZUGFeRD2PullProvider implements IXMLProvider { //// MAIN CLASS @@ -229,7 +231,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { paymentTermsDescription = trans.getPaymentTermDescription(); } - if ((paymentTermsDescription == null) && (trans.getDocumentCode() != org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE)) { + if ((paymentTermsDescription == null) && (trans.getDocumentCode() != CORRECTEDINVOICE)/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) { paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); } @@ -494,7 +496,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } } } - if (trans.getDocumentCode() == DocumentCodeTypeConstants.CORRECTEDINVOICE) { + if ((trans.getDocumentCode() == CORRECTEDINVOICE)/*||(trans.getDocumentCode() == DocumentCodeTypeConstants.CREDITNOTE)*/) { hasDueDate = false; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java index 96855ea4..bbc2a7ac 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java @@ -20,7 +20,7 @@ package org.mustangproject.ZUGFeRD.model; public class DocumentCodeTypeConstants { public static final String INVOICE = "380"; + public static final String CREDITNOTE = "381"; public static final String DEBITNOTE = "84"; public static final String CORRECTEDINVOICE = "384"; - public static final String CREDITNOTE = "389"; } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java index c19cf0c7..ea0daf27 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java @@ -39,6 +39,7 @@ import junit.framework.TestCase; public class ZF2PushTest extends TestCase { final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20201121_508.pdf"; final String TARGET_ALLOWANCESPDF = "./target/testout-ZF2PushAllowances.pdf"; + final String TARGET_CREDITNOTEPDF = "./target/testout-ZF2PushCreditNote.pdf"; final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf"; final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf"; final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf"; @@ -501,6 +502,11 @@ public class ZF2PushTest extends TestCase { } + /*** + * German Stornorechnung/Rechnungskorrektur: + * quantities have to be negative! + * official example: zugferd_2p1_EXTENDED_Rechnungskorrektur.pdf + */ public void testCorrectionExport() { String orgname = "Test company"; @@ -545,5 +551,54 @@ public class ZF2PushTest extends TestCase { } + /*** + * UNTDID 1001 says 381 as typecode for credit notes and + * the Factur-X 1.0.50 has examples like Avoir_FR_type381_EN16931.pdf + * along with a documentation in chapter 7.1.6 (where they also tackle + * negative TypeCode 380 invoices) + */ + public void testCreditNoteExport() { + + String orgname = "Test company"; + String number = "123"; + String priceStr = "1.00"; + BigDecimal price = new BigDecimal(priceStr); + BigDecimal qty = new BigDecimal(1.0); + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + + ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application") + .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).ignorePDFAErrors() + .load(SOURCE_PDF)) { + Invoice i = new Invoice().setIssueDate(new Date()).setDueDate(new Date()).setDetailedDeliveryPeriod(new Date(), new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX"))).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815")).setNumber(number) + .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)) + .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)) + .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)).setCreditNote(); + ze.setTransaction(i); + String theXML = new String(ze.getProvider().getXML()); + assertTrue(theXML.contains("4.0.0 org.mustangproject core - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT pom Mustang diff --git a/validator/pom.xml b/validator/pom.xml index 0868f732..16990f77 100644 --- a/validator/pom.xml +++ b/validator/pom.xml @@ -3,7 +3,7 @@ org.mustangproject core - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT 4.0.0 org.mustangproject @@ -11,7 +11,7 @@ Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung) jar - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT @@ -75,7 +75,7 @@ org.mustangproject library - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT org.xmlunit