diff --git a/History.md b/History.md index f4f94f14..55f0a4e2 100644 --- a/History.md +++ b/History.md @@ -1,16 +1,23 @@ -- #420 -- #441 -- #431 support reasoncodes +2.13.0 +======= +2024-08-27 + +- Item Attributes and Country of Origin missing on Product. #420 +- Avoid NullPointerException if dueDate is not set. #441 +- support reasoncodes #431 - Enhance Charges/Allowances with reasonCode. #432 - Fix build warnings from editing and building. #415 - ZUGFeRDVisualizer.toPDF(): generate PDF/A-3b. #400 - allow access to invoice attachments via ZUGFeRDInvoiceImporter zii.getFileAttachmentsPDF() and XML (zii.getFileAttachmentsXML) -- #436 and #370. (langfr) +- No interface for required field CreditorReferenceID #436 and +- X-Rechnung direct-debit missing mandatory field BT-90 #370. (langfr) - refactor(ZUGFeRDVisualizer): improve PDF visualization performance #438 -- trying to default product on empty description -- #452 -- +- product creation without description now possible empty description +- filename of embedded file was not xrechnung.xml when using profile xrechnung #452 +- allow legalorganisation to have a tradingbusinessname #447 +- JSon deserialization does not work with BankDetails #455 + 2.12.0 ======= 2024-07-20 diff --git a/library/src/main/java/org/mustangproject/BankDetails.java b/library/src/main/java/org/mustangproject/BankDetails.java index b72817ca..c6edcc86 100644 --- a/library/src/main/java/org/mustangproject/BankDetails.java +++ b/library/src/main/java/org/mustangproject/BankDetails.java @@ -1,5 +1,7 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementPayment; /** @@ -18,6 +20,10 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { * the "name" of the bank account (holder) */ protected String accountName=null; + /*** + * bean constructor + */ + public BankDetails() { } /*** * constructor for IBAN only :-) @@ -80,12 +86,14 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { * */ @Override @Deprecated + @JsonIgnore public String getOwnBIC() { return getBIC(); } @Override @Deprecated + @JsonIgnore public String getOwnIBAN() { return getIBAN(); } diff --git a/library/src/main/java/org/mustangproject/Charge.java b/library/src/main/java/org/mustangproject/Charge.java index c1810c57..a16f5e66 100644 --- a/library/src/main/java/org/mustangproject/Charge.java +++ b/library/src/main/java/org/mustangproject/Charge.java @@ -116,12 +116,20 @@ public class Charge implements IZUGFeRDAllowanceCharge { @Override public BigDecimal getTotalAmount(IAbsoluteValueProvider currentItem) { + if (percent!=null) { + return currentItem.getValue().multiply(getPercent().divide(new BigDecimal(100))); + } else if(totalAmount != null) { + return totalAmount; + } else { + throw new RuntimeException("percent must be set"); + } + } + + public BigDecimal getTotalAmount() { if (totalAmount!=null) { return totalAmount; - } else if (percent!=null) { - return currentItem.getValue().multiply(getPercent().divide(new BigDecimal(100))); } else { - throw new RuntimeException("Either totalAmount or percent must be set"); + throw new RuntimeException("totalAmount must be set"); } } diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java index b90a70cd..df5e329f 100644 --- a/library/src/main/java/org/mustangproject/Product.java +++ b/library/src/main/java/org/mustangproject/Product.java @@ -11,7 +11,8 @@ import java.util.HashMap; */ @JsonIgnoreProperties(ignoreUnknown = true) public class Product implements IZUGFeRDExportableProduct { - protected String unit, name, description, sellerAssignedID, buyerAssignedID; + protected String unit, name, sellerAssignedID, buyerAssignedID; + protected String description=""; protected BigDecimal VATPercent; protected boolean isReverseCharge = false; protected boolean isIntraCommunitySupply = false; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java index 038c5d36..3dd18d74 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java @@ -18,12 +18,15 @@ *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import com.fasterxml.jackson.annotation.JsonIgnore; + public interface IZUGFeRDTradeSettlement { /*** * gets the applicableHeaderTradeSettlement * @return zf2 xml */ + @JsonIgnore String getSettlementXML(); @@ -31,6 +34,7 @@ public interface IZUGFeRDTradeSettlement { * gets the applicableHeaderTradePayment * @return zf2 xml */ + @JsonIgnore default String getPaymentXML() { return null; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java index 2247ae06..9731a9a5 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java @@ -18,6 +18,7 @@ *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.mustangproject.XMLTools; public interface IZUGFeRDTradeSettlementPayment extends IZUGFeRDTradeSettlement { @@ -27,6 +28,7 @@ public interface IZUGFeRDTradeSettlementPayment extends IZUGFeRDTradeSettlement * * @return payment information text */ + @JsonIgnore default String getOwnPaymentInfoText() { return null; } @@ -59,6 +61,7 @@ public interface IZUGFeRDTradeSettlementPayment extends IZUGFeRDTradeSettlement @Override + @JsonIgnore default String getSettlementXML() { String accountNameStr=""; if (getAccountName()!=null) { diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java index 185e8ba8..5223b31b 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java @@ -96,6 +96,7 @@ public class ZUGFeRDVisualizer { private TransformerFactory mFactory = null; private Templates mXsltXRTemplate = null; private Templates mXsltUBLTemplate = null; + private Templates mXsltCIOTemplate = null; private Templates mXsltHTMLTemplate = null; private Templates mXsltPDFTemplate = null; private Templates mXsltZF1HTMLTemplate = null; @@ -151,6 +152,8 @@ public class ZUGFeRDVisualizer { String zf2Signature = "CrossIndustryInvoice"; String ublSignature = "Invoice"; String ublCreditNoteSignature = "CreditNote"; + String cioSignature = "SCRDMCCBDACIOMessageStructure" + + ""; boolean doPostProcessing = false; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); @@ -173,6 +176,10 @@ public class ZUGFeRDVisualizer { //zf2 or fx applyUBLCreditNote2XSLT(fis, iaos); doPostProcessing = true; + } else if (root.getLocalName().equals(cioSignature)) { + //zf2 or fx + applyCIO2XSLT(fis, iaos); + doPostProcessing = true; } else { throw new IllegalArgumentException("File does not look like CII or UBL"); } @@ -277,20 +284,6 @@ public class ZUGFeRDVisualizer { } catch (FileNotFoundException | TransformerException e) { LOGGER.error("Failed to apply FOP", e); } - /* - FopConfParser parser = null; - try { - //parsing configuration - parser = new FopConfParser(CLASS_LOADER.getResourceAsStream("fop-config.xconf"), new URI("file:///")); - - } catch (SAXException e) { - throw new UncheckedIOException(new IOException(e)); - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (URISyntaxException e) { - Logger.getLogger(ZUGFeRDVisualizer.class.getName()).log(Level.SEVERE, null, e); - }*/ -// FopFactoryBuilder builder = parser.getFopFactoryBuilder(); DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); Configuration cfg = null; @@ -351,6 +344,17 @@ public class ZUGFeRDVisualizer { transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); } + protected void applyCIO2XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) + throws TransformerException { + if (mXsltCIOTemplate == null) { + mXsltCIOTemplate = mFactory.newTemplates( + new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/cio-xr.xsl"))); + } + Transformer transformer = mXsltCIOTemplate.newTransformer(); + + transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + } + protected void applyUBL2XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) throws TransformerException { if (mXsltUBLTemplate == null) { diff --git a/library/src/main/resources/stylesheets/cio-xr.xsl b/library/src/main/resources/stylesheets/cio-xr.xsl new file mode 100644 index 00000000..415e2dfe --- /dev/null +++ b/library/src/main/resources/stylesheets/cio-xr.xsl @@ -0,0 +1,2225 @@ + + + + + + Author: KoSIT Bremen (kosit@finanzen.bremen.de) + Fassung vom: 2020-06-30+02:00 + Überführt eine zur EN 16931 konforme elektronische Rechnung in der konkreten Syntax UNCEFACT.CII.D16B in eine Instanz gemäß des Schemas für den Namensraum urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1. + Das Skript setzt voraus, dass das zu verarbeitende Dokument valide bzgl. des XML Schemas und der Schematron-Regeln der Quelle ist. Für nicht valide Dokumente ist das Ergebnis nicht definiert. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ILLEGAL DATE FORMAT: <para>Mit diesem Datentyp wird ein kalendarisches Datum abgebildet, wie es in der ISO 8601 Spezifikation <quote>Calendar date complete representation</quote> beschrieben ist (siehe ISO 8601:2004, Abschnitt 5.2.1.1). Das Datum beinhaltet keine Zeitangabe. Das konkret zu verwendende Format ist abhängig von der genutzten Syntax.</para> +<para>Der Datentyp basiert auf dem Typ <quote>Date Time. Type</quote>, wie in ISO 15000-5:2014 Anhang B definiert.</para> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Liefert einen XPath-Pfad, welches $n eindeutig identifiziert. + + + + + + + + + + + Liefert einen XPath-Pfad, welches $n eindeutig identifiziert. + + + + + / + + + [ + + ] + + + + /@ + + + diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java index 4b9bbb34..d6a425d4 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java @@ -36,7 +36,7 @@ public class DeSerializationTest extends TestCase { public void testJackson() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); - Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty("some org", "teststr", "55232", "teststadt", "DE").addTaxID("taxID")).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber("0185").addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal("1"), new BigDecimal(1.0))); + Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty("some org", "teststr", "55232", "teststadt", "DE").addTaxID("taxID").addBankDetails(new BankDetails("DE3600000123456", "ABCDEFG1001").setAccountName("Donald Duck"))).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber("0185").addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal("1"), new BigDecimal(1.0))); String jsonArray = mapper.writeValueAsString(i); // [{"stringValue":"a","intValue":1,"booleanValue":true},