diff --git a/History.md b/History.md
index 28958c2b..c603c60c 100644
--- a/History.md
+++ b/History.md
@@ -1,3 +1,5 @@
+- support parsing of BT-90 CreditorReferenceID
+
2.17.0
=======
2025-06-11
diff --git a/library/pom.xml b/library/pom.xml
index 6323b0f0..ed2754e2 100644
--- a/library/pom.xml
+++ b/library/pom.xml
@@ -133,7 +133,7 @@
com.helger
en16931-cii2ubl
- 2.2.4
+ 2.3.0
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java
index f27cce5b..daa26916 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java
@@ -568,6 +568,15 @@ public class ZUGFeRDInvoiceImporter {
}
}
+ String creditorReferenceID = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"CreditorReferenceID\"]").trim();//BT-90
+ if ((creditorReferenceID == null)||(creditorReferenceID.length()==0)) {
+ //maybe it's there in UBL?
+ creditorReferenceID = extractString("//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyIdentification\"]/*[local-name()=\"ID\"]").trim();
+ }
+ if ((creditorReferenceID != null)&&(creditorReferenceID.length()>0)) {
+ zpp.setCreditorReferenceID(creditorReferenceID);
+ }
+
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]|//*[local-name()=\"Delivery\"]");
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java
index 44d70478..bad53f35 100644
--- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java
+++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java
@@ -34,12 +34,14 @@ import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
+import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@@ -265,6 +267,24 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
assertEquals(new BigDecimal("18.92"), tc.getGrandTotal());
}
+ public void testIBANImport() {
+ File CIIinputFile = getResourceAsFile("cii/lastschrift_iban_bug.xml");
+ try {
+ ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile));
+
+
+ CalculatedInvoice invoice = new CalculatedInvoice();
+ zii.extractInto(invoice);
+ assertEquals("DE11111111111111111111", invoice.getCreditorReferenceID());
+ assertEquals("DE22222222222222222222", invoice.getSender().getBankDetails().stream().map(BankDetails::getIBAN).collect(Collectors.joining(",")));
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
public void testBasisQuantityImport() {
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2newEdge.pdf");
diff --git a/library/src/test/resources/cii/lastschrift_iban_bug.xml b/library/src/test/resources/cii/lastschrift_iban_bug.xml
new file mode 100644
index 00000000..95ec90d8
--- /dev/null
+++ b/library/src/test/resources/cii/lastschrift_iban_bug.xml
@@ -0,0 +1,152 @@
+
+
+
+
+ urn:cen.eu:en16931:2017
+
+
+
+ 123456
+ 380
+
+ 20250426
+
+
+ Jahresbeitrag
+
+
+
+
+
+ 1
+
+
+ Product: Plus
+
+
+
+ 239.00
+
+
+
+ 1.00
+
+
+
+ VAT
+ S
+ 19.00
+
+
+ 239.00
+
+
+
+
+
+ 1
+
+
+ Getting Started-Rabatt
+
+
+
+ 120.00
+
+
+
+ -1.00
+
+
+
+ VAT
+ S
+ 19.00
+
+
+ -120.00
+
+
+
+
+ 7777777
+
+ ---
+
+ ---
+ Geschäftsführer
+
+ ---
+
+
+ q@q.com
+
+
+
+ 12345
+ Str. 11
+ ---
+ DE
+
+
+ a@a.com
+
+
+ DE111111111
+
+
+
+ a & b GmbH
+
+ 123456
+ --
+ Str. 17
+ --
+ DE
+
+
+
+
+
+ DE11111111111111111111
+ EUR
+
+ 59
+
+ DE22222222222222222222
+
+
+
+ 22.61
+ VAT
+ 119.00
+ S
+ 19.00
+
+
+
+ 20250426
+
+
+ 20250525
+
+
+
+ Zahlbar sofort
+
+ 20250426
+
+
+
+ 119.00
+ 0.00
+ 0.00
+ 119.00
+ 22.61
+ 141.61
+ 0.00
+ 141.61
+
+
+
+
diff --git a/validator/src/main/java/org/mustangproject/validator/Validator.java b/validator/src/main/java/org/mustangproject/validator/Validator.java
index 545ee574..c3372126 100644
--- a/validator/src/main/java/org/mustangproject/validator/Validator.java
+++ b/validator/src/main/java/org/mustangproject/validator/Validator.java
@@ -61,6 +61,9 @@ public abstract class Validator {
Source xmlData = new StreamSource(new ByteArrayInputStream(xmlRawData));
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
+ schemaFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+ schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
Schema schema = schemaFactory.newSchema(schemaFile);
javax.xml.validation.Validator validator = schema.newValidator();
validator.validate(xmlData);