diff --git a/library/src/main/java/org/mustangproject/CashDiscount.java b/library/src/main/java/org/mustangproject/CashDiscount.java
index b1993a02..d27b3dcb 100644
--- a/library/src/main/java/org/mustangproject/CashDiscount.java
+++ b/library/src/main/java/org/mustangproject/CashDiscount.java
@@ -21,7 +21,9 @@ public class CashDiscount implements IZUGFeRDCashDiscount {
/***
* the period (usually days) count how long the percent apply
*/
- protected Integer days=null;
+ protected Integer days;
+
+ protected BigDecimal basisAmount;
/***
* Create a cash discount (skonto) with the specified height in the specified period.
@@ -61,18 +63,31 @@ public class CashDiscount implements IZUGFeRDCashDiscount {
return this;
}
+ public BigDecimal getBasisAmount() {
+ return basisAmount;
+ }
+
+ public CashDiscount setBasisAmount(BigDecimal basisAmount) {
+ this.basisAmount = basisAmount;
+ return this;
+ }
+
/***
* @return this particular cash discount as cross industry invoice XML
*/
@JsonIgnore
public String getAsCII() {
- return ""+
- "Cash Discount"+
- " "+
- " "+days+""+
- " "+XMLTools.nDigitFormat(percent,3)+""+
- " "+
- "";
+ String s = ""
+ + " Cash Discount"
+ + " "
+ + " " + days + "";
+ if (basisAmount != null) {
+ s += " " + XMLTools.nDigitFormat(basisAmount, 2) + "";
+ }
+ s += " "+XMLTools.nDigitFormat(percent,3)+""+
+ " "+
+ "";
+ return s;
}
/***
@@ -84,8 +99,4 @@ public class CashDiscount implements IZUGFeRDCashDiscount {
public String getAsXRechnung() {
return "#SKONTO#TAGE="+days+"#PROZENT="+XMLTools.nDigitFormat(percent,2)+"#\n";
}
-
-
-
-
}
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java
index 86462375..b94a763a 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java
@@ -41,28 +41,6 @@ public class DXExporterFromA1 extends DXExporterFromA3 {
private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser (dataSource));
}
- /***
- * internal helper function: get namespace for order-x
- * @param ver the delivery-x version
- * @return the URN of the namespace
- */
- @Override
- public String getNamespaceForVersion(int ver) {
- // As of late 2022 the Delivery-X standard is not yet published. See specification:
- // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022
- // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3
- // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html
- return "urn:factur-x:pdfa:CrossIndustryDocument:despatchadvice:1p0#";
- }
- /***
- * internal helper: returns the namespace prefix for the given order-x version number
- * @param ver the ox version
- * @return the namespace prefix as string, without colon
- */
- @Override
- public String getPrefixForVersion(int ver) {
- return "fx";
- }
private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException {
/*
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java
index bc0189e8..9b6a95cf 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java
@@ -130,6 +130,29 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
private boolean attachZUGFeRDHeaders = true;
+ /***
+ * internal helper function: get namespace for order-x
+ * @param ver the delivery-x version
+ * @return the URN of the namespace
+ */
+ @Override
+ public String getNamespaceForVersion(int ver) {
+ // As of late 2022 the Delivery-X standard is not yet published. See specification:
+ // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022
+ // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3
+ // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html
+ return "urn:factur-x:pdfa:CrossIndustryDocument:despatchadvice:1p0#";
+ }
+ /***
+ * internal helper: returns the namespace prefix for the given order-x version number
+ * @param ver the ox version
+ * @return the namespace prefix as string, without colon
+ */
+ @Override
+ public String getPrefixForVersion(int ver) {
+ return "fx";
+ }
+
/**
* Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the
* metadata level, this will not e.g. convert graphics to JPG-2000)
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java
index 33f95aea..6b4b7e6c 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java
@@ -41,24 +41,6 @@ public class OXExporterFromA1 extends OXExporterFromA3 {
private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource));
}
- /***
- * internal helper function: get namespace for order-x
- * @param ver the order-x version
- * @return the URN of the namespace
- */
- @Override
- public String getNamespaceForVersion(int ver) {
- return "urn:factur-x:pdfa:CrossIndustryDocument:1p0#";
- }
- /***
- * internal helper: returns the namespace prefix for the given order-x version number
- * @param ver the ox version
- * @return the namespace prefix as string, without colon
- */
- @Override
- public String getPrefixForVersion(int ver) {
- return "fx";
- }
private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException {
/*
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java
index 542b4249..a38eec1c 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java
@@ -126,9 +126,27 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*/
protected String orderXDocumentType = "ORDER";
-
private boolean attachZUGFeRDHeaders = true;
+ /***
+ * internal helper function: get namespace for order-x
+ * @param ver the order-x version
+ * @return the URN of the namespace
+ */
+ @Override
+ public String getNamespaceForVersion(int ver) {
+ return "urn:factur-x:pdfa:CrossIndustryDocument:1p0#";
+ }
+ /***
+ * internal helper: returns the namespace prefix for the given order-x version number
+ * @param ver the ox version
+ * @return the namespace prefix as string, without colon
+ */
+ @Override
+ public String getPrefixForVersion(int ver) {
+ return "fx";
+ }
+
/** Defines whether attachments to the PDF should be using FLATE compression */
private boolean compressionEnabled = false;
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java
index c9f53282..1dba311c 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java
@@ -711,6 +711,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ "";
}
+ if (trans.getDespatchAdviceReferencedDocumentID() != null && !trans.getDespatchAdviceReferencedDocumentID().trim().isEmpty()) {
+ xml += "";
+ xml += "" + XMLTools.encodeXML(trans.getDespatchAdviceReferencedDocumentID()) + "";
+ xml += "";
+ }
+
if (trans.getDeliveryNoteReferencedDocumentID() != null && !trans.getDeliveryNoteReferencedDocumentID().trim().isEmpty()) {
xml += "";
xml += "" + XMLTools.encodeXML(trans.getDeliveryNoteReferencedDocumentID()) + "";
@@ -719,14 +725,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml += ""+XMLTools.encodeXML(dateFormat102.format(trans.getDeliveryNoteReferencedDocumentDate()))+"";
}
xml += "";
-
- }
-
- if (trans.getDespatchAdviceReferencedDocumentID() != null && !trans.getDespatchAdviceReferencedDocumentID().trim().isEmpty()) {
- xml += "";
- xml += "" + XMLTools.encodeXML(trans.getDespatchAdviceReferencedDocumentID()) + "";
- xml += "";
-
}
xml += "";
@@ -822,8 +820,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml += "" +
"" +
"true" +
- "" +
- "" + currencyFormat(charge.getTotalAmount(calc)) + "";
+ "";
+ if (charge.getPercent() != null && (profile == Profiles.getByName("EN16931") || (profile == Profiles.getByName("EXTENDED")))) {
+ xml += "" + vatFormat(charge.getPercent()) + "";
+ }
+ if (charge.getBasisAmount() != null && (profile == Profiles.getByName("EN16931") || (profile == Profiles.getByName("EXTENDED")))) {
+ xml += "" + currencyFormat(charge.getBasisAmount()) + "";
+ }
+ xml += "" + currencyFormat(charge.getTotalAmount(calc)) + "";
if (charge.getReasonCode() != null) {
xml += "" + charge.getReasonCode() + "";
}
@@ -866,14 +870,20 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml += "" +
"" +
"false" +
- "" +
- "" + currencyFormat(allowance.getTotalAmount(calc)) + "";
- if (allowance.getReason() != null) {
- xml += "" + XMLTools.encodeXML(allowance.getReason()) + "";
+ "";
+ if (allowance.getPercent() != null) {
+ xml += "" + vatFormat(allowance.getPercent()) + "";
}
+ if (allowance.getBasisAmount() != null) {
+ xml += "" + currencyFormat(allowance.getBasisAmount()) + "";
+ }
+ xml += "" + currencyFormat(allowance.getTotalAmount(calc)) + "";
if (allowance.getReasonCode() != null) {
xml += "" + allowance.getReasonCode() + "";
}
+ if (allowance.getReason() != null) {
+ xml += "" + XMLTools.encodeXML(allowance.getReason()) + "";
+ }
xml += "" +
"VAT" +
"" + allowance.getCategoryCode() + "";
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java
index 5a232747..437e0979 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java
@@ -78,6 +78,8 @@ import jakarta.activation.FileDataSource;
public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter {
+ private static final String XML_DESCRIPTION = "Invoice metadata conforming to ZUGFeRD standard (https://www.ferd-net.de/en/standards/zugferd/factur-x)";
+
private boolean isFacturX = true;
public static final int DefaultZUGFeRDVersion = 2;
@@ -684,8 +686,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
}
PDFAttachGenericFile(doc, filename, relationship,
- "Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)",
- "text/xml", xmlProvider.getXML());
+ XML_DESCRIPTION, "text/xml", xmlProvider.getXML());
for (FileAttachment attachment : fileAttachments) {
PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData());
diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java
index 0d354bb8..3408b9a0 100644
--- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java
+++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java
@@ -764,8 +764,9 @@ public class ZF2PushTest extends TestCase {
.setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
- .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0))).addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"))
- .addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReason("Mengenrabatt"))
+ .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
+ .addCharge(new Charge().setPercent(new BigDecimal(50)).setBasisAmount(price).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK").setReason("Verschiedenes"))
+ .addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReasonCode("95").setReason("Mengenrabatt"))
);
String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8);
assertTrue(theXML.contains("
-
+
-
+
FX-SCH-A-000118
@@ -2040,9 +2040,9 @@
-
+
-
+
FX-SCH-A-000119
diff --git a/validator/src/main/resources/xslt/ZF_240/FACTUR-X_BASIC.xslt b/validator/src/main/resources/xslt/ZF_240/FACTUR-X_BASIC.xslt
index 6d688013..66f6faa1 100644
--- a/validator/src/main/resources/xslt/ZF_240/FACTUR-X_BASIC.xslt
+++ b/validator/src/main/resources/xslt/ZF_240/FACTUR-X_BASIC.xslt
@@ -2633,9 +2633,9 @@
-
+
-
+
FX-SCH-A-000226
@@ -2708,9 +2708,9 @@
-
+
-
+
FX-SCH-A-000118
@@ -2723,9 +2723,9 @@
-
+
-
+
FX-SCH-A-000119
diff --git a/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EN16931.xslt b/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EN16931.xslt
index 0a0e0c64..d216c8a9 100644
--- a/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EN16931.xslt
+++ b/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EN16931.xslt
@@ -2703,9 +2703,9 @@
-
+
-
+
FX-SCH-A-000226
@@ -2778,9 +2778,9 @@
-
+
-
+
FX-SCH-A-000118
@@ -2793,9 +2793,9 @@
-
+
-
+
FX-SCH-A-000119
diff --git a/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EXTENDED.xslt b/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EXTENDED.xslt
index 2e5b60fa..32882558 100644
--- a/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EXTENDED.xslt
+++ b/validator/src/main/resources/xslt/ZF_240/FACTUR-X_EXTENDED.xslt
@@ -2903,9 +2903,9 @@
-
+
-
+
FX-SCH-A-000365
@@ -3008,9 +3008,9 @@
-
+
-
+
FX-SCH-A-000366
diff --git a/validator/src/main/resources/xslt/en16931schematron/EN16931-CII-validation.xslt b/validator/src/main/resources/xslt/en16931schematron/EN16931-CII-validation.xslt
index 7ab90522..3e184293 100644
--- a/validator/src/main/resources/xslt/en16931schematron/EN16931-CII-validation.xslt
+++ b/validator/src/main/resources/xslt/en16931schematron/EN16931-CII-validation.xslt
@@ -4,7 +4,7 @@
Licensed under European Union Public Licence (EUPL) version 1.2.
-->
-
+
@@ -175,6 +175,9 @@
+
+
+
EN16931-CII-Model
EN16931-CII-Model
@@ -184,6 +187,9 @@
+
+
+
EN16931-CII-Syntax
EN16931-CII-Syntax
@@ -193,6 +199,9 @@
+
+
+
EN16931-Codes
EN16931-Codes
@@ -208,28 +217,7 @@
-
-
-
-
-
-
-
-
- BR-66
- fatal
-
-
-
- [BR-66]-Each Specified Trade Allowance Charge (BG-20)(BG-21) shall contain a Charge Indicator.
-
-
-
-
-
-
-
-
+
@@ -250,7 +238,7 @@
-
+
@@ -271,7 +259,7 @@
-
+
@@ -292,8 +280,8 @@
-
-
+
+
@@ -328,7 +316,7 @@
-
+
@@ -349,7 +337,7 @@
-
+
@@ -460,7 +448,7 @@
-
+
@@ -571,7 +559,7 @@
-
+
@@ -681,7 +669,7 @@
-
+
BR-CO-12
@@ -877,7 +865,7 @@
-
+
@@ -1288,7 +1276,7 @@
-
+
@@ -1458,9 +1446,9 @@
-
+
-
+
BR-DEC-23
fatal
@@ -1474,7 +1462,7 @@
-
+
@@ -1570,7 +1558,7 @@
-
+
@@ -1666,7 +1654,7 @@
-
+
@@ -1702,7 +1690,7 @@
-
+
@@ -1738,7 +1726,7 @@
-
+
@@ -1759,7 +1747,7 @@
-
+
@@ -1780,7 +1768,7 @@
-
+
@@ -1797,12 +1785,18 @@
+
+
+
+
+
+
-
+
-
+
BR-CO-27
fatal
@@ -1929,7 +1923,7 @@
-
+
BR-CO-14
@@ -1971,9 +1965,9 @@
-
+
-
+
BR-AE-08
fatal
@@ -2355,9 +2349,9 @@
-
+
-
+
BR-AG-05
fatal
@@ -2391,9 +2385,9 @@
-
+
-
+
BR-AG-06
fatal
@@ -2427,9 +2421,9 @@
-
+
-
+
BR-AG-07
fatal
@@ -2448,9 +2442,9 @@
-
+
-
+
BR-E-08
fatal
@@ -2607,9 +2601,9 @@
-
+
-
+
BR-G-08
fatal
@@ -2766,9 +2760,9 @@
-
+
-
+
BR-IC-08
fatal
@@ -3066,9 +3060,9 @@
-
+
-
+
BR-O-03
fatal
@@ -3102,9 +3096,9 @@
-
+
-
+
BR-O-04
fatal
@@ -3138,9 +3132,9 @@
-
+
-
+
BR-O-02
fatal
@@ -3620,7 +3614,28 @@
-
+
+
+
+
+
+
+
+
+ CII-SR-464
+ warning
+
+
+
+ [CII-SR-464] - Only one BT-86 element is allowed on an invoice.
+
+
+
+
+
+
+
+
@@ -3776,7 +3791,7 @@
-
+
@@ -4067,7 +4082,7 @@
-
+
@@ -4088,7 +4103,7 @@
-
+
@@ -4169,7 +4184,7 @@
-
+
@@ -4265,7 +4280,7 @@
-
+
@@ -5111,7 +5126,7 @@
-
+
@@ -5147,7 +5162,7 @@
-
+
@@ -5587,21 +5602,6 @@
-
-
-
- CII-SR-440
- fatal
-
-
-
- [CII-SR-440] - ActualAmount should exist maximum once
-
-
-
-
-
-
@@ -5932,6 +5932,48 @@
+
+
+
+
+
+
+
+
+
+ CII-SR-463
+ fatal
+
+
+
+ [CII-SR-463]-Each Specified Trade Allowance Charge (BG-20)(BG-21) shall contain a Charge Indicator.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CII-SR-440
+ fatal
+
+
+
+ [CII-SR-440] - ActualAmount should exist maximum once
+
+
+
+
+
+
@@ -6995,8 +7037,8 @@
-
-
+
+
@@ -7900,9 +7942,9 @@
-
+
-
+
CII-SR-282
warning
@@ -8384,7 +8426,7 @@
CII-SR-459
- warning
+ fatal
@@ -8399,7 +8441,7 @@
CII-SR-460
- warning
+ fatal
@@ -8407,6 +8449,36 @@
+
+
+
+
+
+
+ CII-SR-465
+ warning
+
+
+
+ [CII-SR-465] - Only one BT-41 element is allowed on an invoice.
+
+
+
+
+
+
+
+
+
+ CII-SR-466
+ warning
+
+
+
+ [CII-SR-466] - Only one BT-56 element is allowed on an invoice.
+
+
+
@@ -10237,9 +10309,9 @@
-
+
-
+
CII-SR-462
fatal
@@ -10496,59 +10568,8 @@
-
-
-
-
-
-
-
-
- CII-DT-005
- fatal
-
-
-
- [CII-DT-005] - schemeID should not be present
-
-
-
-
-
-
-
-
-
- CII-DT-006
- fatal
-
-
-
- [CII-DT-006] - schemeAgencyID should not be present
-
-
-
-
-
-
-
-
-
- CII-DT-007
- fatal
-
-
-
- [CII-DT-007] - schemeVersionID should not be present
-
-
-
-
-
-
-
-
-
+
+
@@ -10609,6 +10630,117 @@
+
+
+
+
+
+
+ CII-DT-005
+ fatal
+
+
+
+ [CII-DT-005] - schemeID should not be present
+
+
+
+
+
+
+
+
+
+ CII-DT-006
+ fatal
+
+
+
+ [CII-DT-006] - schemeAgencyID should not be present
+
+
+
+
+
+
+
+
+
+ CII-DT-007
+ fatal
+
+
+
+ [CII-DT-007] - schemeVersionID should not be present
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CII-DT-101
+ fatal
+
+
+
+ [CII-DT-101] - schemeName should not be present
+
+
+
+
+
+
+
+
+
+ CII-DT-102
+ fatal
+
+
+
+ [CII-DT-102] - schemeAgencyName should not be present
+
+
+
+
+
+
+
+
+
+ CII-DT-103
+ fatal
+
+
+
+ [CII-DT-103] - schemeDataURI should not be present
+
+
+
+
+
+
+
+
+
+ CII-DT-104
+ fatal
+
+
+
+ [CII-DT-104] - schemeURI should not be present
+
+
+
@@ -10771,7 +10903,7 @@
-
+
CII-DT-015
@@ -12005,9 +12137,9 @@
-
+
-
+
BR-CL-01
fatal
@@ -12026,9 +12158,9 @@
-
+
-
+
BR-CL-03
fatal
@@ -12047,9 +12179,9 @@
-
+
-
+
BR-CL-04
fatal
@@ -12068,9 +12200,9 @@
-
+
-
+
BR-CL-05
fatal
@@ -12110,9 +12242,9 @@
-
+
-
+
BR-CL-07
fatal
@@ -12152,9 +12284,9 @@
-
+
-
+
BR-CL-10
fatal
@@ -12173,9 +12305,9 @@
-
+
-
+
BR-CL-11
fatal
@@ -12194,9 +12326,9 @@
-
+
-
+
BR-CL-13
fatal
@@ -12362,9 +12494,9 @@
-
+
-
+
BR-CL-21
fatal
@@ -12384,9 +12516,9 @@
-
+
-
+
BR-CL-22
fatal
@@ -12447,9 +12579,9 @@
-
+
-
+
BR-CL-25
fatal
@@ -12468,9 +12600,9 @@
-
+
-
+
BR-CL-26
fatal
diff --git a/validator/src/main/resources/xslt/en16931schematron/EN16931-UBL-validation.xslt b/validator/src/main/resources/xslt/en16931schematron/EN16931-UBL-validation.xslt
index bc209719..07c2f7ba 100644
--- a/validator/src/main/resources/xslt/en16931schematron/EN16931-UBL-validation.xslt
+++ b/validator/src/main/resources/xslt/en16931schematron/EN16931-UBL-validation.xslt
@@ -4,7 +4,7 @@
Licensed under European Union Public Licence (EUPL) version 1.2.
-->
-
+
@@ -177,6 +177,9 @@
+
+
+
UBL-model
UBL-model
@@ -186,6 +189,9 @@
+
+
+
UBL-syntax
UBL-syntax
@@ -195,6 +201,9 @@
+
+
+
Codesmodel
Codesmodel
@@ -231,8 +240,8 @@
-
-
+
+
@@ -341,7 +350,7 @@
-
+
BR-31
@@ -989,36 +998,6 @@
-
-
-
- BR-66
- fatal
-
-
-
- [BR-66]-An Invoice shall contain maximum one Payment Card account (BG-18).
-
-
-
-
-
-
-
-
-
- BR-67
- fatal
-
-
-
- [BR-67]-An Invoice shall contain maximum one Payment Mandate (BG-19).
-
-
-
-
-
-
@@ -1367,12 +1346,12 @@
- BR-IG-01
+ BR-AF-01
fatal
- [BR-IG-01]-An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "IGIC" shall contain in the VAT breakdown (BG-23) at least one VAT category code (BT-118) equal with "IGIC".
+ [BR-AF-01]-An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "IGIC" shall contain in the VAT breakdown (BG-23) at least one VAT category code (BT-118) equal with "IGIC".
@@ -1382,12 +1361,12 @@
- BR-IG-02
+ BR-AF-02
fatal
- [BR-IG-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
+ [BR-AF-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
@@ -1397,12 +1376,12 @@
- BR-IG-03
+ BR-AF-03
fatal
- [BR-IG-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
+ [BR-AF-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
@@ -1412,12 +1391,12 @@
- BR-IG-04
+ BR-AF-04
fatal
- [BR-IG-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
+ [BR-AF-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IGIC" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
@@ -1427,12 +1406,12 @@
- BR-IP-01
+ BR-AG-01
fatal
- [BR-IP-01]-An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "IPSI" shall contain in the VAT breakdown (BG-23) at least one VAT category code (BT-118) equal with "IPSI".
+ [BR-AG-01]-An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "IPSI" shall contain in the VAT breakdown (BG-23) at least one VAT category code (BT-118) equal with "IPSI".
@@ -1442,12 +1421,12 @@
- BR-IP-02
+ BR-AG-02
fatal
- [BR-IP-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
+ [BR-AG-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
@@ -1457,12 +1436,12 @@
- BR-IP-03
+ BR-AG-03
fatal
- [BR-IP-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
+ [BR-AG-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
@@ -1472,12 +1451,12 @@
- BR-IP-04
+ BR-AG-04
fatal
- [BR-IP-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
+ [BR-AG-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63).
@@ -2196,8 +2175,8 @@
-
-
+
+
@@ -3110,12 +3089,12 @@
- BR-IG-08
+ BR-AF-08
fatal
- [BR-IG-08]-For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "IGIC", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "IGIC" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).
+ [BR-AF-08]-For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "IGIC", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "IGIC" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).
@@ -3125,12 +3104,12 @@
- BR-IG-09
+ BR-AF-09
fatal
- [BR-IG-09]-The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "IGIC" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).
+ [BR-AF-09]-The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "IGIC" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).
@@ -3140,12 +3119,12 @@
- BR-IG-10
+ BR-AF-10
fatal
- [BR-IG-10]-A VAT breakdown (BG-23) with VAT Category code (BT-118) "IGIC" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).
+ [BR-AF-10]-A VAT breakdown (BG-23) with VAT Category code (BT-118) "IGIC" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).
@@ -3161,12 +3140,12 @@
- BR-IG-06
+ BR-AF-06
fatal
- [BR-IG-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IGIC" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero.
+ [BR-AF-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IGIC" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero.
@@ -3182,12 +3161,12 @@
- BR-IG-07
+ BR-AF-07
fatal
- [BR-IG-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IGIC" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero.
+ [BR-AF-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IGIC" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero.
@@ -3203,12 +3182,12 @@
- BR-IG-05
+ BR-AF-05
fatal
- [BR-IG-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IGIC" the invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero.
+ [BR-AF-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IGIC" the invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero.
@@ -3224,12 +3203,12 @@
- BR-IP-08
+ BR-AG-08
fatal
- [BR-IP-08]-For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "IPSI", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "IPSI" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).
+ [BR-AG-08]-For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is "IPSI", the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is "IPSI" and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).
@@ -3239,12 +3218,12 @@
- BR-IP-09
+ BR-AG-09
fatal
- [BR-IP-09]-The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "IPSI" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).
+ [BR-AG-09]-The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is "IPSI" shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).
@@ -3254,12 +3233,12 @@
- BR-IP-10
+ BR-AG-10
fatal
- [BR-IP-10]-A VAT breakdown (BG-23) with VAT Category code (BT-118) "IPSI" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).
+ [BR-AG-10]-A VAT breakdown (BG-23) with VAT Category code (BT-118) "IPSI" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120).
@@ -3275,12 +3254,12 @@
- BR-IP-06
+ BR-AG-06
fatal
- [BR-IP-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero.
+ [BR-AG-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero.
@@ -3296,12 +3275,12 @@
- BR-IP-07
+ BR-AG-07
fatal
- [BR-IP-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero.
+ [BR-AG-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero.
@@ -3317,12 +3296,12 @@
- BR-IP-05
+ BR-AG-05
fatal
- [BR-IP-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" the Invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero.
+ [BR-AG-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" the Invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero.
@@ -3679,8 +3658,8 @@
-
-
+
+
@@ -3700,7 +3679,7 @@
-
+
@@ -3721,7 +3700,7 @@
-
+
@@ -3757,7 +3736,7 @@
-
+
@@ -3778,7 +3757,7 @@
-
+
@@ -3814,7 +3793,7 @@
-
+
@@ -3835,7 +3814,7 @@
-
+
@@ -3856,7 +3835,7 @@
-
+
@@ -3876,6 +3855,27 @@
+
+
+
+
+
+
+
+
+
+ UBL-SR-53
+ fatal
+
+
+
+ [UBL-SR-53]- CompanyID (VAT Identifier) must be stated when providing the PartyTaxScheme/TaxScheme/ID.
+
+
+
+
+
+
@@ -12410,7 +12410,7 @@
- [UBL-CR-572]-A UBL invoice should not include the InvoiceLine Item BuyersItemIdentification BarecodeSymbologyID
+ [UBL-CR-572]-A UBL invoice should not include the InvoiceLine Item BuyersItemIdentification BarcodeSymbologyID
@@ -12485,7 +12485,7 @@
- [UBL-CR-577]-A UBL invoice should not include the InvoiceLine Item SellersItemIdentification BarecodeSymbologyID
+ [UBL-CR-577]-A UBL invoice should not include the InvoiceLine Item SellersItemIdentification BarcodeSymbologyID
@@ -12575,7 +12575,7 @@
- [UBL-CR-583]-A UBL invoice should not include the InvoiceLine Item StandardItemIdentification BarecodeSymbologyID
+ [UBL-CR-583]-A UBL invoice should not include the InvoiceLine Item StandardItemIdentification BarcodeSymbologyID
@@ -13287,21 +13287,6 @@
-
-
-
- UBL-CR-631
- warning
-
-
-
- [UBL-CR-631]-A UBL invoice should not include the InvoiceLine Item Price OrderableUnitFactorRate
-
-
-
-
-
-
@@ -14754,6 +14739,36 @@
+
+
+
+
+
+
+ UBL-SR-54
+ fatal
+
+
+
+ [UBL-SR-54]-An Invoice shall contain maximum one Payment Card account (BG-18).
+
+
+
+
+
+
+
+
+
+ UBL-SR-55
+ fatal
+
+
+
+ [UBL-SR-55]-An Invoice shall contain maximum one Payment Mandate (BG-19).
+
+
+
@@ -15012,9 +15027,9 @@
-
+
-
+
UBL-SR-22
fatal
@@ -15076,9 +15091,9 @@
-
+
-
+
BR-CL-01
fatal
@@ -15097,9 +15112,9 @@
-
+
-
+
BR-CL-03
fatal
@@ -15118,9 +15133,9 @@
-
+
-
+
BR-CL-04
fatal
@@ -15139,9 +15154,9 @@
-
+
-
+
BR-CL-05
fatal
@@ -15181,9 +15196,9 @@
-
+
-
+
BR-CL-07
fatal
@@ -15202,9 +15217,9 @@
-
+
-
+
BR-CL-10
fatal
@@ -15223,9 +15238,9 @@
-
+
-
+
BR-CL-11
fatal
@@ -15244,9 +15259,9 @@
-
+
-
+
BR-CL-13
fatal
@@ -15413,9 +15428,9 @@
-
+
-
+
BR-CL-21
fatal
@@ -15434,9 +15449,9 @@
-
+
-
+
BR-CL-22
fatal
@@ -15498,9 +15513,9 @@
-
+
-
+
BR-CL-25
fatal
@@ -15519,9 +15534,9 @@
-
+
-
+
BR-CL-26
fatal
diff --git a/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java b/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java
index 66fce4e3..0993b66a 100644
--- a/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java
+++ b/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java
@@ -405,6 +405,38 @@ public class XMLValidatorTest extends ResourceCase {
}
+ public void testBRDEC23Regression() {
+ // Regression test: BR-DEC-23 must fire for XRechnung CII invoices whose
+ // LineTotalAmount (BT-131) has more than 2 decimal places.
+ // The bug existed in CEN Schematron <=1.3.12 due to a wrong XPath context
+ // (SpecifiedTradeSettlement instead of SpecifiedLineTradeSettlement).
+ final ValidationContext ctx = new ValidationContext(null);
+ final XMLValidator xv = new XMLValidator(ctx);
+ final XPathEngine xpath = new JAXPXPathEngine();
+
+ File tempFile = getResourceAsFile("invalidXRV30_BR-DEC-23.xml");
+ boolean noExceptions = true;
+ try {
+ xv.setFilename(tempFile.getAbsolutePath());
+ xv.validate();
+
+ String s = "" + xv.getXMLResult() + "";
+ Source source = Input.fromString(s).build();
+
+ // must be invalid overall
+ String status = xpath.evaluate("/validation/summary/@status", source);
+ assertEquals("invalid", status);
+
+ // must contain the BR-DEC-23 rule ID in at least one error
+ assertThat(s).valueByXPath("count(//error[contains(text(),'BR-DEC-23')])")
+ .asInt()
+ .isGreaterThanOrEqualTo(1);
+ } catch (IrrecoverableValidationError e) {
+ noExceptions = false;
+ }
+ assertTrue(noExceptions);
+ }
+
public void testSubInvoiceLineHierarchy() {
final ValidationContext ctx = new ValidationContext(null);
final XMLValidator xv = new XMLValidator(ctx);
diff --git a/validator/src/test/resources/invalidXRV30_BR-DEC-23.xml b/validator/src/test/resources/invalidXRV30_BR-DEC-23.xml
new file mode 100644
index 00000000..28b7c839
--- /dev/null
+++ b/validator/src/test/resources/invalidXRV30_BR-DEC-23.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+ urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
+
+
+ urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0
+
+
+
+ BR-DEC-23-REGRESSION
+ 380
+
+ 20240101
+
+
+
+
+
+ 1
+
+
+ Test product
+
+
+
+ 288.79
+
+
+
+ 1
+
+
+
+ VAT
+ S
+ 19
+
+
+
+ 288.7934
+
+
+
+
+ 04011000-12345-03
+
+ Test Seller GmbH
+
+ 12345
+ Seller Street 1
+ Berlin
+ DE
+
+
+ seller@test.de
+
+
+ DE123456789
+
+
+
+ Test Buyer AG
+
+ 10115
+ Buyer Street 2
+ Berlin
+ DE
+
+
+ buyer@test.de
+
+
+
+
+
+ EUR
+
+ 58
+
+ DE75512108001245126199
+
+
+
+ 54.87
+ VAT
+ 288.79
+ S
+ 19
+
+
+ Zahlbar sofort ohne Abzug.
+
+
+ 288.79
+ 288.79
+ 54.87
+ 343.66
+ 343.66
+
+
+
+