diff --git a/History.md b/History.md index 4a4c67a6..21dc49d3 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,30 @@ -- #678 -- #679 -- #681 +#705 +#707 +-#708 +-#709 +607 +649 +650 +665 +684 +703 +701 +691 + + + + + +2.16.1 +======= +2025-01-21 +- #678 some ubl creditnote attributes are not parsed +- #679 validation of a XR does not ignore whitespace +- #681 IBAN assigned to invoice sender not recipient on direct debit +- #689 incorrect element order when both charge reason and reasoncode are specified +- be able to set detailedDeliveryPeriodFrom, detailedDeliveryPeriodTo MS188 +- updated verapdf from 1.26.1 to 1.26.2 +- cashDiscount JSON now corrently ignores values for cii and xr methods 2.16.0 ======= diff --git a/Mustang-CLI/pom.xml b/Mustang-CLI/pom.xml index 9d83688f..d5b924e9 100644 --- a/Mustang-CLI/pom.xml +++ b/Mustang-CLI/pom.xml @@ -3,7 +3,7 @@ org.mustangproject core - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT 4.0.0 org.mustangproject @@ -12,7 +12,7 @@ should also work for XRechnung/CII. jar - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT UTF-8 11 @@ -23,7 +23,7 @@ org.mustangproject validator - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT diff --git a/library/pom.xml b/library/pom.xml index 81a1716f..91695791 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -3,13 +3,13 @@ org.mustangproject core - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT 4.0.0 org.mustangproject library - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT jar Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII) FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT @@ -59,6 +59,12 @@ slf4j-api 2.0.9 + + net.sf.offo + fop-hyph + 2.0 + runtime + net.sf.saxon diff --git a/library/src/main/java/org/mustangproject/CashDiscount.java b/library/src/main/java/org/mustangproject/CashDiscount.java index 2151489a..b1993a02 100644 --- a/library/src/main/java/org/mustangproject/CashDiscount.java +++ b/library/src/main/java/org/mustangproject/CashDiscount.java @@ -1,5 +1,6 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDCashDiscount; @@ -63,6 +64,7 @@ public class CashDiscount implements IZUGFeRDCashDiscount { /*** * @return this particular cash discount as cross industry invoice XML */ + @JsonIgnore public String getAsCII() { return ""+ "Cash Discount"+ @@ -78,6 +80,7 @@ public class CashDiscount implements IZUGFeRDCashDiscount { * XRechnung CIUS defined it's own proprietary format for a freetext field * @return this particular cash discount in proprietary xrechnung format */ + @JsonIgnore public String getAsXRechnung() { return "#SKONTO#TAGE="+days+"#PROZENT="+XMLTools.nDigitFormat(percent,2)+"#\n"; } diff --git a/library/src/main/java/org/mustangproject/Invoice.java b/library/src/main/java/org/mustangproject/Invoice.java index 04c8b5dc..a03487ae 100644 --- a/library/src/main/java/org/mustangproject/Invoice.java +++ b/library/src/main/java/org/mustangproject/Invoice.java @@ -69,6 +69,7 @@ public class Invoice implements IExportableTransaction { protected String vatDueDateTypeCode = null; protected String creditorReferenceID; // required when direct debit is used. private BigDecimal roundingAmount=null; + private String paymentReference; // Remittance information / Verwendungszweck, BT-83 public Invoice() { ZFItems = new ArrayList<>(); @@ -650,6 +651,16 @@ public class Invoice implements IExportableTransaction { return this; } + @Override + public String getPaymentReference() { + return paymentReference; + } + + public Invoice setPaymentReference(String paymentReference) { + this.paymentReference = paymentReference; + return this; + } + @Override public TradeParty getDeliveryAddress() { return deliveryAddress; @@ -783,11 +794,20 @@ public class Invoice implements IExportableTransaction { return detailedDeliveryDateStart; } + public Invoice setDetailedDeliveryPeriodFrom(Date dt) { + detailedDeliveryDateStart=dt; + return this; + } + @Override public Date getDetailedDeliveryPeriodTo() { return detailedDeliveryPeriodEnd; } + public Invoice setDetailedDeliveryPeriodTo(Date dt) { + detailedDeliveryPeriodEnd=dt; + return this; + } /** * adds a free text paragraph, which will become an includedNote element diff --git a/library/src/main/java/org/mustangproject/Item.java b/library/src/main/java/org/mustangproject/Item.java index 94562ca5..0688530a 100644 --- a/library/src/main/java/org/mustangproject/Item.java +++ b/library/src/main/java/org/mustangproject/Item.java @@ -172,6 +172,9 @@ public class Item implements IZUGFeRDExportableItem { icnm.getAsNodeMap("ApplicableTradeTax") .flatMap(cnm -> cnm.getAsBigDecimal("RateApplicablePercent", "ApplicablePercent")) .ifPresent(product::setVATPercent); + icnm.getAsNodeMap("ApplicableTradeTax") + .flatMap(cnm -> cnm.getAsString("ExemptionReason")) + .ifPresent(product::setTaxExemptionReason); icnm.getAsNodeMap("SpecifiedTradeAllowanceCharge").ifPresent(stac -> { stac.getAsNodeMap("ChargeIndicator").ifPresent(ci -> { String isChargeString=ci.getAsString("Indicator").get(); @@ -187,8 +190,12 @@ public class Item implements IZUGFeRDExportableItem { if (amountString!=null) { izac.setTotalAmount(new BigDecimal(amountString)); } + if(percentString!=null) { izac.setPercent(new BigDecimal(percentString)); + } + if(reason!=null) { izac.setReason(reason); + } if (isChargeString.equalsIgnoreCase("false")) { addAllowance(izac); diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java index 0a013ba3..686afd44 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java @@ -314,6 +314,10 @@ public interface IExportableTransaction { return null; } + default String getPaymentReference() { + return null; + } + /** * returns if a rebate agreements exists * diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 2903d81d..6958bb61 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -288,8 +288,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { final String allowanceChargeStr = "" + chargeIndicator + "" + percentage + "" + priceFormat(allowance.getTotalAmount(item)) + "" + - reason + reasonCode + + reason + ""; return allowanceChargeStr; } @@ -323,8 +323,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { final String itemTotalAllowanceChargeStr = "" + chargeIndicator + "" + percentage + "" + currencyFormat(allowance.getTotalAmount(item)) + "" + - reason + reasonCode + + reason + ""; return itemTotalAllowanceChargeStr; } @@ -388,14 +388,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + "" + "" + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - // + "RECHNUNG" - // + "380" - + "" + typecode + "" - + "" - + DATE.udtFormat(trans.getIssueDate()) + "" // date + + "" + XMLTools.encodeXML(trans.getNumber()) + ""; + if (profile == Profiles.getByName("Extended") && trans.getDocumentName() != null) { + xml += "" + XMLTools.encodeXML(trans.getDocumentName()) + ""; + } + xml += "" + typecode + "" + + "" + DATE.udtFormat(trans.getIssueDate()) + "" // date + buildNotes(trans) - + "" + ""; int lineID = 0; @@ -662,8 +661,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if ((trans.getCreditorReferenceID() != null) && (getProfile() != Profiles.getByName("Minimum"))) { xml += "" + XMLTools.encodeXML(trans.getCreditorReferenceID()) + ""; } - if ((trans.getNumber() != null) && (getProfile() != Profiles.getByName("Minimum"))) { - xml += "" + XMLTools.encodeXML(trans.getNumber()) + ""; + if ((trans.getPaymentReference() != null) && (getProfile() != Profiles.getByName("Minimum"))) { + xml += "" + XMLTools.encodeXML(trans.getPaymentReference()) + ""; } xml += "" + trans.getCurrency() + ""; if (this.trans.getPayee() != null) { @@ -744,12 +743,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { "true" + "" + "" + currencyFormat(charge.getTotalAmount(calc)) + ""; - if (charge.getReason() != null) { - xml += "" + XMLTools.encodeXML(charge.getReason()) + ""; - } if (charge.getReasonCode() != null) { xml += "" + charge.getReasonCode() + ""; } + if (charge.getReason() != null) { + xml += "" + XMLTools.encodeXML(charge.getReason()) + ""; + } xml += "" + "VAT" + "" + charge.getCategoryCode() + ""; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 9115feb4..734f5f0c 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -288,6 +288,7 @@ public class ZUGFeRDInvoiceImporter { public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseException { String number = ""; + String documentName = null; String typeCode = null; String deliveryPeriodStart = null; String deliveryPeriodEnd = null; @@ -496,6 +497,9 @@ public class ZUGFeRDInvoiceImporter { if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) { number = XMLTools.trimOrNull(item); } + if ((item.getLocalName() != null) && (item.getLocalName().equals("Name"))) { + documentName = XMLTools.trimOrNull(item); + } if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) { typeCode = XMLTools.trimOrNull(item); } @@ -556,13 +560,13 @@ public class ZUGFeRDInvoiceImporter { } zpp.addNotes(includedNotes); String rootNode = extractString("local-name(/*)"); - if (rootNode.equals("Invoice")||rootNode.equals("CreditNote")) { + if (rootNode.equals("Invoice") || rootNode.equals("CreditNote")) { // UBL... // //*[local-name()="Invoice" or local-name()="CreditNote"] number = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"ID\"]").trim(); typeCode = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"InvoiceTypeCode\"]").trim(); String issueDateStr = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"IssueDate\"]").trim(); - if (issueDateStr.length()>0) { + if (issueDateStr.length() > 0) { issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(issueDateStr); } String dueDt = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"DueDate\"]").trim(); @@ -651,7 +655,7 @@ public class ZUGFeRDInvoiceImporter { zpp.setCurrency(currency); String paymentTermsDescription = extractString("//*[local-name()=\"SpecifiedTradePaymentTerms\"]/*[local-name()=\"Description\"]|//*[local-name()=\"PaymentTerms\"]/*[local-name()=\"Note\"]"); - if ((paymentTermsDescription!=null)&&(!paymentTermsDescription.isEmpty())) { + if ((paymentTermsDescription != null) && (!paymentTermsDescription.isEmpty())) { zpp.setPaymentTermDescription(paymentTermsDescription); } @@ -668,6 +672,12 @@ public class ZUGFeRDInvoiceImporter { NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes(); for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) { + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) + && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("PaymentReference"))) { + String paymentReference = headerTradeSettlementChilds.item(settlementChildIndex).getTextContent(); + zpp.setPaymentReference(paymentReference); + } + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradePaymentTerms"))) { NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); @@ -802,7 +812,7 @@ public class ZUGFeRDInvoiceImporter { } - zpp.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode); + zpp.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentName(documentName).setDocumentCode(typeCode); if ((directDebitMandateID != null) && (IBAN != null)) { DirectDebit d = new DirectDebit(IBAN, directDebitMandateID); @@ -848,15 +858,14 @@ public class ZUGFeRDInvoiceImporter { Node currentItemNode = nodes.item(i); ReferencedDocument doc = ReferencedDocument.fromNode(currentItemNode); - if (doc != null - && (!Objects.equals(zpp.getInvoiceReferencedDocumentID(), doc.getIssuerAssignedID()) - || !Objects.equals(zpp.getInvoiceReferencedIssueDate(), doc.getFormattedIssueDateTime()))) - { + if (doc != null + && (!Objects.equals(zpp.getInvoiceReferencedDocumentID(), doc.getIssuerAssignedID()) + || !Objects.equals(zpp.getInvoiceReferencedIssueDate(), doc.getFormattedIssueDateTime()))) { zpp.addInvoiceReferencedDocument(doc); } } } - + zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim()); String rounding = extractString("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"RoundingAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"Party\"]/*[local-name()=\"PayableRoundingAmount\"]"); @@ -890,7 +899,7 @@ public class ZUGFeRDInvoiceImporter { xpr = xpath.compile("//*[local-name()=\"AttachmentBinaryObject\"]|//*[local-name()=\"EmbeddedDocumentBinaryObject\"]"); NodeList attachmentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); for (int i = 0; i < attachmentNodes.getLength(); i++) { - FileAttachment fa = new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(), attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(), "Data", Base64.getDecoder().decode(XMLTools.trimOrNull(attachmentNodes.item(i)))); + FileAttachment fa = new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(), attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(), "Data", Base64.getMimeDecoder().decode(XMLTools.trimOrNull(attachmentNodes.item(i)))); zpp.embedFileInXML(fa); // filename = "Aufmass.png" mimeCode = "image/png" //EmbeddedDocumentBinaryObject cbc:EmbeddedDocumentBinaryObject mimeCode="image/png" filename="Aufmass.png" @@ -976,6 +985,38 @@ public class ZUGFeRDInvoiceImporter { } } + xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"SpecifiedLogisticsServiceCharge\"]");// UBL unknown + chargeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + for (int i = 0; i < chargeNodes.getLength(); i++) { + NodeList chargeNodeChilds = chargeNodes.item(i).getChildNodes(); + String chargeAmount = null; + String taxPercent = null; + for (int chargeChildIndex = 0; chargeChildIndex < chargeNodeChilds.getLength(); chargeChildIndex++) { + String chargeChildName = chargeNodeChilds.item(chargeChildIndex).getLocalName(); + if (chargeChildName != null) { + if (chargeChildName.equals("AppliedAmount")) { + chargeAmount = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } else if (chargeChildName.equals("AppliedTradeTax")) { + NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); + for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { + String taxItemName = taxChilds.item(taxChildIndex).getLocalName(); + if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent"))) { + taxPercent = XMLTools.trimOrNull(taxChilds.item(taxChildIndex)); + } + } + } + } + //appliedAmount + //AppliedTradeTax + } + if (chargeAmount != null) { + Charge c = new Charge(new BigDecimal(chargeAmount)); + if (taxPercent != null) { + c.setTaxPercent(new BigDecimal(taxPercent)); + } + zpp.addCharge(c); + } + } TransactionCalculator tc = new TransactionCalculator(zpp); @@ -1040,7 +1081,7 @@ public class ZUGFeRDInvoiceImporter { } else if (rootNode.equals("Invoice")) { return EStandard.ubl; } else if (rootNode.equals("CreditNote")) { - return EStandard.ubl; + return EStandard.ubl_creditnote; } else if (rootNode.equals("CrossIndustryInvoice")) { return EStandard.facturx; } else if (rootNode.equals("SCRDMCCBDACIDAMessageStructure")) { @@ -1085,11 +1126,17 @@ public class ZUGFeRDInvoiceImporter { * * @return the file attachments embedded in XML (using base64) decoded as byte array, * for PDF embedded files in FX use getFileAttachmentsPDF() + * may return empty array * @deprecated use invoice.getAdditionalReferencedDocuments */ @Deprecated public List getFileAttachmentsXML() { - return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments())); + if (importedInvoice.getAdditionalReferencedDocuments()!=null) { + return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments())); + } else { + return new ArrayList<>(); + } + } /*** diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java index 9b5c1e73..8795b478 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java @@ -45,6 +45,9 @@ import javax.xml.transform.stream.StreamSource; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.function.Supplier; public class ZUGFeRDVisualizer { @@ -254,16 +257,61 @@ public class ZUGFeRDVisualizer { // the writing part File XMLinputFile = new File(xmlFilename); - String result = null; + String fopInput = null; /* remove file endings so that tests can also pass after checking out from git with arbitrary options (which may include CSRF changes) */ try { - result = this.toFOP(XMLinputFile.getAbsolutePath()); + fopInput = this.toFOP(XMLinputFile.getAbsolutePath()); } catch (TransformerException | IOException e) { LOGGER.error("Failed to apply FOP", e); } + + toPDFfromFOP(fopInput, () -> { + try { + return new FileOutputStream(pdfFilename); + } catch (FileNotFoundException e) { + LOGGER.error("Failed to create PDF", e); + } + return null; + }, (OutputStream out) -> {}); + } + + public byte[] toPDF(String xmlContent) { + + String fopInput = null; + + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + try { + ByteArrayInputStream fis = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8)); + EStandard theStandard = findOutStandardFromRootNode(fis); + fis = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8));//rewind :-( + + fopInput = toFOP(fis, theStandard); + } catch (TransformerException | IOException e) { + LOGGER.error("Failed to apply FOP", e); + } + + AtomicReference byteHolder = new AtomicReference<>(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + toPDFfromFOP(fopInput, () -> new BufferedOutputStream(os), (OutputStream out) -> { + + try { + out.flush(); + } catch (IOException e) { + LOGGER.error("Failed to create PDF", e); + } + byteHolder.set(os.toByteArray()); + }); + + return byteHolder.get(); + } + + private void toPDFfromFOP(String fopInput, Supplier outputStreamDelegate, Consumer consumerDelegate) { + DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); Configuration cfg = null; @@ -291,7 +339,7 @@ public class ZUGFeRDVisualizer { // Step 2: Set up output stream. // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). - try (OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFilename))) { + try (OutputStream out = new BufferedOutputStream(outputStreamDelegate.get())) { // Step 3: Construct fop with desired output format Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); @@ -302,13 +350,15 @@ public class ZUGFeRDVisualizer { // Step 5: Setup input and output for XSLT transformation // Setup input stream - Source src = new StreamSource(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8))); + Source src = new StreamSource(new ByteArrayInputStream(fopInput.getBytes(StandardCharsets.UTF_8))); // Resulting SAX events (the generated FO) must be piped through to FOP Result res = new SAXResult(fop.getDefaultHandler()); // Step 6: Start XSLT transformation and FOP processing transformer.transform(src, res); + + consumerDelegate.accept(out); } catch (FOPException | IOException | TransformerException e) { LOGGER.error("Failed to create PDF", e); diff --git a/library/src/main/resources/stylesheets/result-pdf.xsl b/library/src/main/resources/stylesheets/result-pdf.xsl index 0dfa7c95..f3e2e0d4 100644 --- a/library/src/main/resources/stylesheets/result-pdf.xsl +++ b/library/src/main/resources/stylesheets/result-pdf.xsl @@ -28,6 +28,14 @@ red + + + Das XML ist valide. + + + Das XML ist nicht valide. + + green @@ -37,18 +45,26 @@ - + Das ZUGFeRD-PDF ist valide. - + Das ZUGFeRD-PDF ist nicht valide. + + + green + + + red + + - + Es wird empfohlen, das Dokument anzunehmen und es weiterzuverarbeiten. - + Es wird empfohlen, das Dokument zurückzuweisen. @@ -118,6 +134,7 @@ + + + + + + + + + true + + + urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended + + + + R87654321012345 + WARENRECHNUNG + 380 + + 20180806 + + + ST3 + Es bestehen Rabatt- oder Bonusvereinbarungen. + AAK + + + EEV + Der Verkäufer bleibt Eigentümer der Waren bis zu vollständigen Erfüllung der Kaufpreisforderung. + AAJ + + + MUSTERLIEFERANT GMBH +BAHNHOFSTRASSE 99 +99199 MUSTERHAUSEN +Geschäftsführung: +Max Mustermann +USt-IdNr: DE123456789 +Telefon: +49 932 431 0 +www.musterlieferant.de +HRB Nr. 372876 +Amtsgericht Musterstadt +GLN 4304171000002 +WEEE-Reg-Nr.: DE87654321 + + REG + + + Leergutwert: 46,50 + + + Wichtige Information: Bei Bestellungen bis zum 19.12. ist die Auslieferung bis spätestens 23.12. garantiert. + + + + + + 1 + + + 4123456000014 + ZS997 + Zitronensäure 100ml + + Verpackungsart + BO + + + + + 1.0000 + + + 1.0000 + + + + 100.0000 + 4.0000 + + + + VAT + S + 19.00 + + + 100.00 + + + + + + 2 + + + 4123456000021 + GZ250 + Gelierzucker Extra 250g + + + + 1.5000 + + + false + + 0.0300 + Artikelrabatt 1 + + + + false + + 0.0200 + Artikelrabatt 2 + + + + 1.4500 + + + + 50.0000 + 1.0000 + + + + VAT + S + 7.00 + + + 72.50 + + + + + + 3 + + + 4123456000021 + GZ250 + Gelierzucker Extra 250g + Artikel wie vereinbart ohne Berechnung + + + + 0.0000 + + + 0.0000 + + + + 10.0000 + 1.0000 + + + + VAT + S + 7.00 + + + 0.00 + + + + + + 4 + + + 4100130013294 + 2031 + + Bierbrau Pils 20/0500 + EAN-VKE: 4100130913297 + + Verpackung + Kiste + + + + + 12.0000 + + + 12.0000 + + + + 15.0000 + 20.0000 + + + + VAT + S + 19.00 + + + 180.00 + + + + + + 5 + + + 2001015001325 + 1805 + + Leergutpfand 20 x 0,5l + + Verpackung + unverpackt + + + + + 3.1000 + + + 3.1000 + + + + 15.0000 + 1.0000 + + + + VAT + S + 19.00 + + + 46.50 + + + + + + 6 + + + 4123456000038 + MP107 + Mischpalette Joghurt Karton 3 x 20 + + Verpackung + Karton + + + 4123456001035 + JOG103 + Erdbeer 20 x 150g Becher + 20.0000 + + + 4123456002032 + JOG203 + Banane 20 x 150g Becher + 20.0000 + + + 4123456003039 + JOG303 + Schoko 20 x 150g Becher + 20.0000 + + + + + 30.0000 + + + false + + 0.9000 + Artikelrabatt 1 + + + + 29.1000 + + + + 2.0000 + 1.0000 + + + + VAT + S + 7.00 + + + 58.20 + + + + + + 549910 + 4333741000005 + MUSTERLIEFERANT GMBH + + + +49 932 431 500 + + + max.mustermann@musterlieferant.de + + + + 99199 + BAHNHOFSTRASSE 99 + MUSTERHAUSEN + DE + + + DE123456789 + + + + 009420 + 4304171000002 + MUSTER-KUNDE GMBH + + 40235 + KUNDENWEG 88 + DUESSELDORF + DE + + + + B123456789 + + + A456123 + 130 + + + + + 4304171088093 + MUSTER-MARKT + + 8211 + + + 31157 + HAUPTSTRASSE 44 + SARSTEDT + DE + + + + + 20180805 + + + + L87654321012345 + + + + EUR + + 009420 + 4304171000002 + MUSTER-KUNDE GMBH + + 40235 + KUNDENWEG 88 + DUESSELDORF + DE + + + + 61.07 + VAT + 321.40 + 326.50 + -5.10 + S + 19.00 + + + 8.93 + VAT + 127.59 + 130.70 + -3.11 + S + 7.00 + + + + false + + 2.00 + 280.00 + 5.60 + Rechnungsrabatt 1 + + VAT + S + 19.00 + + + + + false + + 2.00 + 130.70 + 2.61 + Rechnungsrabatt 1 + + VAT + S + 7.00 + + + + + false + + 280.00 + 2.50 + Rechnungsrabatt 2 + + VAT + S + 19.00 + + + + + false + + 130.70 + 0.50 + Rechnungsrabatt 2 + + VAT + S + 7.00 + + + + Transportkosten + 3.00 + + VAT + S + 19.00 + + + + Bei Zahlung innerhalb 14 Tagen gewähren wir 2,0% Skonto. + + 14 + 2.00 + + + + 457.20 + 3.00 + 11.21 + 448.99 + 70.00 + 518.99 + 0.00 + 518.99 + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 03f326a5..7346b012 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.mustangproject core - 2.16.1-SNAPSHOT pom + 2.16.2-SNAPSHOT pom Mustang diff --git a/validator/pom.xml b/validator/pom.xml index d8820ab1..6c94fd9e 100644 --- a/validator/pom.xml +++ b/validator/pom.xml @@ -3,7 +3,7 @@ org.mustangproject core - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT 4.0.0 org.mustangproject @@ -11,7 +11,7 @@ Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung) jar - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT @@ -38,7 +38,7 @@ ${project.groupId} library - 2.16.1-SNAPSHOT + 2.16.2-SNAPSHOT org.dom4j @@ -73,7 +73,7 @@ org.verapdf validation-model-jakarta - 1.26.1 + 1.26.2