diff --git a/History.md b/History.md index fa2e51df..a940a217 100644 --- a/History.md +++ b/History.md @@ -1,8 +1,10 @@ 2.0.3 ======= - - #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 2.0.2 ======= diff --git a/doc/Mustang-Architecture.graphml b/doc/Mustang-Architecture.graphml new file mode 100644 index 00000000..b8aa411e --- /dev/null +++ b/doc/Mustang-Architecture.graphml @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + PDF/A-1 + + + + + + + + + + PDF/A-3 Factur-X file + + + + + + + + + + XRechnung + + + + + + + + + + XML Report + + + + + + + + + + XRechnung + + + + + + + + + + + + + + Mustang + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + Command line tool + + + + + + + + + + Library + + + + + + + + + + Validator Component + + + + + + + + + + Java Interfaces + + + + + + + + + + Java Classes + + + + + + + + + + + + + Shell + + + + + + + + + + + Your Java software + + + + + + + + + + PDF/A-3 Factur-X file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/Mustang-Architecture.svg b/doc/Mustang-Architecture.svg new file mode 100644 index 00000000..0e8196c8 --- /dev/null +++ b/doc/Mustang-Architecture.svg @@ -0,0 +1,1926 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PDF/A-1 + + + + + + + + + + + + + + + PDF/A-3 Factur-X file + + + + + + + + + + + + + + + XRechnung + + + + + + + + + + + + + + + XML Report + + + + + + + + + + + + + + + XRechnung + + + + + + + + + Mustang + + + + + + + + + + + + + + + + Command line tool + + + + + + + + + + + + + + + Library + + + + + + + + + + + + + + + Validator Component + + + + + + + + + + + + + + + Java Interfaces + + + + + + + + + + + + + + + Java Classes + + + + + + + + + + + + + + + + + + + Shell + + + + + + + + + + + + + + + + + + + Your Java software + + + + + + + + + + + + + + + PDF/A-3 Factur-X file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/MustangWriter.java b/doc/MustangWriter.java index bedd367e..6cf8670b 100644 --- a/doc/MustangWriter.java +++ b/doc/MustangWriter.java @@ -6,15 +6,15 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import org.mustangproject.ZUGFeRD.IExportableTransaction; import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge; -import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct; -import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTransaction; -import org.mustangproject.ZUGFeRD.ZUGFeRDExporter; -import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA1Factory; +import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty; +import org.mustangproject.ZUGFeRD.IZUGFeRDExporter; +import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA1; -class Contact implements IZUGFeRDExportableContact { +class Contact implements IZUGFeRDExportableTradeParty { public String getCountry() { return "DE"; @@ -132,16 +132,16 @@ class Product implements IZUGFeRDExportableProduct { } } -public class MustangWriter implements IZUGFeRDExportableTransaction { +public class MustangWriter implements IExportableTransaction { private void apply() { try { System.out.println("Reading Blanko-PDF"); - ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setProducer("My Application") + IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setProducer("My Application") .setCreator(System.getProperty("user.name")) .load("./MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); System.out.println("Generating and attaching ZUGFeRD-Data"); - ze.PDFattachZugferdFile(this); + ze.setTransaction(this); System.out.println("Writing ZUGFeRD-PDF"); ze.export("./MustangGnuaccountingBeispielRE-20170509_505new.pdf"); System.out.println("Done."); @@ -238,7 +238,7 @@ public class MustangWriter implements IZUGFeRDExportableTransaction { return null; } - public IZUGFeRDExportableContact getRecipient() { + public IZUGFeRDExportableTradeParty getRecipient() { return new Contact(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java b/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java index 187adc97..d714e4c1 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java @@ -11,10 +11,18 @@ import java.util.HashMap; public class TransactionCalculator implements IAbsoluteValueProvider { protected IExportableTransaction trans; + /*** + * + * @param trans the invoice (or IExportableTransaction) to be calculated + */ public TransactionCalculator(IExportableTransaction trans) { this.trans=trans; } + /*** + * if something had already been paid in advance, this will get it from the transaction + * @return prepaid amount + */ protected BigDecimal getTotalPrepaid() { if (trans.getTotalPrepaidAmount() == null) { return BigDecimal.ZERO; @@ -23,7 +31,11 @@ public class TransactionCalculator implements IAbsoluteValueProvider { } } - protected BigDecimal getTotalGross() { + /*** + * the invoice total with VAT, corrected by prepaid amount, allowances and charges + * @return the invoice total including taxes + */ + public BigDecimal getGrandTotal() { BigDecimal res = getTaxBasis(); HashMap VATPercentAmountMap = getVATPercentAmountMap(); @@ -31,7 +43,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider { VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); res = res.add(amount.getCalculated()); } - return res; + return res.setScale(2, RoundingMode.HALF_UP); } /*** @@ -119,6 +131,10 @@ public class TransactionCalculator implements IAbsoluteValueProvider { return res; } + /*** + * returns the total net value of all items, without document level charges/allowances + * @return item sum + */ protected BigDecimal getTotal() { BigDecimal res = BigDecimal.ZERO; for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { @@ -128,6 +144,11 @@ public class TransactionCalculator implements IAbsoluteValueProvider { return res; } + /*** + * returns the total net value of the invoice, including charges/allowances on document + * level + * @return item sum +- charges/allowances + */ protected BigDecimal getTaxBasis() { BigDecimal res = getTotal().add(getChargesForPercent(null)).subtract(getAllowancesForPercent(null)); return res; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java index d627d0a4..2a55d93b 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java @@ -305,12 +305,12 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr // // // currencyID=\"EUR\" + " " - + currencyFormat(calc.getTotalGross().subtract(calc.getTotal())) + "\n" - + " " + currencyFormat(calc.getTotalGross()) + "\n" //$NON-NLS-2$ + + currencyFormat(calc.getGrandTotal().subtract(calc.getTotal())) + "\n" + + " " + currencyFormat(calc.getGrandTotal()) + "\n" //$NON-NLS-2$ // // // currencyID=\"EUR\" + " " + currencyFormat(calc.getTotalPrepaid()) + "\n" - + " " + currencyFormat(calc.getTotalGross().subtract(calc.getTotalPrepaid())) + "\n" //$NON-NLS-2$ + + " " + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "\n" //$NON-NLS-2$ // // // currencyID=\"EUR\" + " \n" @@ -439,7 +439,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr if (discountTerms != null) { paymentTermsXml += ""; String currency = trans.getCurrency(); - String basisAmount = currencyFormat(calc.getTotalGross()); + String basisAmount = currencyFormat(calc.getGrandTotal()); paymentTermsXml += "" + basisAmount + ""; paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() + ""; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 54d1c169..3129943e 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -571,9 +571,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } - if (trans.getPaymentTerms() == null) { - xml = xml + " \n" - + " " + paymentTermsDescription + "\n"; + if ((trans.getPaymentTerms() == null)&&((paymentTermsDescription!=null)||(trans.getTradeSettlement()!=null)||(hasDueDate))) { + xml = xml + "\n"; + + if (paymentTermsDescription!=null) { + xml = xml + "" + paymentTermsDescription + "\n"; + } if (trans.getTradeSettlement() != null) { for (IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { @@ -607,12 +610,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { // // // currencyID=\"EUR\" + " " - + currencyFormat(calc.getTotalGross().subtract(calc.getTaxBasis())) + "\n" - + " " + currencyFormat(calc.getTotalGross()) + "\n" //$NON-NLS-2$ + + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "\n" + + " " + currencyFormat(calc.getGrandTotal()) + "\n" //$NON-NLS-2$ // // // currencyID=\"EUR\" + " " + currencyFormat(calc.getTotalPrepaid()) + "\n" - + " " + currencyFormat(calc.getTotalGross().subtract(calc.getTotalPrepaid())) + "\n" //$NON-NLS-2$ + + " " + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "\n" //$NON-NLS-2$ // // // currencyID=\"EUR\" + " \n" @@ -645,9 +648,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } private String buildPaymentTermsXml() { - String paymentTermsXml = ""; IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); + if (paymentTerms==null) { + return ""; + } + String paymentTermsXml = ""; + IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); Date dueDate = paymentTerms.getDueDate(); if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { @@ -665,7 +672,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if (discountTerms != null) { paymentTermsXml += ""; String currency = trans.getCurrency(); - String basisAmount = currencyFormat(calc.getTotalGross()); + String basisAmount = currencyFormat(calc.getGrandTotal()); paymentTermsXml += "" + basisAmount + ""; paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() + ""; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 9334ffe1..172cc6cb 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -260,7 +260,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { } TransactionCalculator tc = new TransactionCalculator(zpp); - String expectedStringTotalGross = tc.getTotalGross().setScale(2, RoundingMode.HALF_UP).toPlainString(); + String expectedStringTotalGross = tc.getGrandTotal().toPlainString(); if (!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2))) { throw new ParseException("Could not reproduce the invoice, this could mean that it could not be read properly", 0); } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java index add87e7e..668b8094 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java @@ -20,21 +20,13 @@ package org.mustangproject.ZUGFeRD; import org.mustangproject.Invoice; -import org.mustangproject.XMLTools; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; import junit.framework.TestCase; -import junit.framework.Test; -import junit.framework.TestSuite; import javax.xml.xpath.XPathExpressionException; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; /*** @@ -82,7 +74,7 @@ public class ZF2ZInvoiceImporterTest extends TestCase { assertEquals("Stadthausen", invoice.getSender().getLocation()); TransactionCalculator tc=new TransactionCalculator(invoice); - assertEquals("571.04", XMLTools.nDigitFormat(tc.getTotalGross(),2)); + assertEquals(new BigDecimal("571.04"),tc.getGrandTotal()); // name street location zip country, contact name phone email, total amount @@ -103,7 +95,7 @@ public class ZF2ZInvoiceImporterTest extends TestCase { } assertFalse(hasExceptions); TransactionCalculator tc=new TransactionCalculator(invoice); - assertEquals("18.33", XMLTools.nDigitFormat(tc.getTotalGross(),2)); + assertEquals(new BigDecimal("18.33"),tc.getGrandTotal()); } public void testAllowancesChargesImport() { @@ -119,7 +111,7 @@ public class ZF2ZInvoiceImporterTest extends TestCase { } assertFalse(hasExceptions); TransactionCalculator tc=new TransactionCalculator(invoice); - assertEquals("11.07", XMLTools.nDigitFormat(tc.getTotalGross(),2)); + assertEquals(new BigDecimal("11.07"),tc.getGrandTotal()); // name street location zip country, contact name phone email, total amount