Merge branch 'ZUGFeRD:master' into master
This commit is contained in:
24
History.md
24
History.md
@@ -1,23 +1,21 @@
|
|||||||
595
|
|
||||||
591
|
|
||||||
577
|
|
||||||
575
|
|
||||||
573
|
|
||||||
601
|
|
||||||
|
|
||||||
2.15.1
|
2.15.1
|
||||||
=======
|
=======
|
||||||
|
2024-12-07
|
||||||
- #566 Failed to parse PDF - Could not reproduce the invoice
|
- #566 Failed to parse PDF - Could not reproduce the invoice
|
||||||
? be able to access ID in error message
|
|
||||||
- closes #579 prepaidamount is only read in UBL
|
- closes #579 prepaidamount is only read in UBL
|
||||||
- #581 parse lineTotalAmount
|
- #581 parse lineTotalAmount, TaxBasisAmount, duePayableAmount
|
||||||
- also parse TaxBasisAmount
|
|
||||||
- #576 read lineid, #578 set lineid
|
- #576 read lineid, #578 set lineid
|
||||||
- log error ids
|
- log error ids, be able to access them from context
|
||||||
- #503 import more ubl
|
- #503 import more ubl
|
||||||
- allow jackson to run over more classes, e.g., DirectDebit, bean contructor for direct debit
|
- allow jackson to run over more classes, e.g., DirectDebit, bean contructor for direct debit
|
||||||
- allow json includedNotes
|
- allow json in document includedNotes and
|
||||||
- support importing duePayableAmount
|
- #591 Import IncludedNotes also on item level
|
||||||
|
- #595 Treat all fatal XR schematron rules as errors, not as warnings.
|
||||||
|
- #577 dom4j: exclude all (optional) dependencies to avoid potential conflicts.
|
||||||
|
- #575 Fix compilation problems.
|
||||||
|
- #573 Feature/category code
|
||||||
|
- #601 exceptions in metrics
|
||||||
|
- #606 also parse BT-25
|
||||||
|
|
||||||
|
|
||||||
2.15.0
|
2.15.0
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
should also work for XRechnung/CII.
|
should also work for XRechnung/CII.
|
||||||
</name>
|
</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
|
<maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
<artifactId>validator</artifactId>
|
<artifactId>validator</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
<!-- prototypes of new mustangproject versions can be installed by referring to them and installed to the local repo from a jar file with
|
<!-- prototypes of new mustangproject versions can be installed by referring to them and installed to the local repo from a jar file with
|
||||||
mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true
|
mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
<artifactId>library</artifactId>
|
<artifactId>library</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII)</name>
|
<name>Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII)</name>
|
||||||
<description>FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT
|
<description>FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import org.mustangproject.ZUGFeRD.IDesignatedProductClassification;
|
|||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
public class DesignatedProductClassification implements IDesignatedProductClassification {
|
public class DesignatedProductClassification implements IDesignatedProductClassification {
|
||||||
private final ClassCode classCode;
|
private ClassCode classCode;
|
||||||
private String className;
|
private String className;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,6 +54,13 @@ public class DesignatedProductClassification implements IDesignatedProductClassi
|
|||||||
this(classCode, null);
|
this(classCode, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean constructor for schemed product descriptor
|
||||||
|
*/
|
||||||
|
public DesignatedProductClassification() {
|
||||||
|
classCode = null;// we need this constructor for jackson, i.e. to be able to JSON
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassCode getClassCode() {
|
public ClassCode getClassCode() {
|
||||||
return classCode;
|
return classCode;
|
||||||
|
|||||||
@@ -808,6 +808,7 @@ public class ZUGFeRDInvoiceImporter {
|
|||||||
} else {
|
} else {
|
||||||
zpp.setDespatchAdviceReferencedDocumentID(extractString("//*[local-name()=\"DespatchDocumentReference\"]/*[local-name()=\"ID\"]"));
|
zpp.setDespatchAdviceReferencedDocumentID(extractString("//*[local-name()=\"DespatchDocumentReference\"]/*[local-name()=\"ID\"]"));
|
||||||
}
|
}
|
||||||
|
zpp.setInvoiceReferencedDocumentID(extractString("//*[local-name()=\"InvoiceReferencedDocument\"]/*[local-name()=\"IssuerAssignedID\"]|//*[local-name()=\"BillingReference\"]/*[local-name()=\"InvoiceDocumentReference\"]/*[local-name()=\"ID\"]"));
|
||||||
|
|
||||||
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim());
|
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim());
|
||||||
|
|
||||||
@@ -929,6 +930,7 @@ public class ZUGFeRDInvoiceImporter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TransactionCalculator tc = new TransactionCalculator(zpp);
|
TransactionCalculator tc = new TransactionCalculator(zpp);
|
||||||
String expectedStringTotalGross = tc.getGrandTotal()
|
String expectedStringTotalGross = tc.getGrandTotal()
|
||||||
.subtract(Objects.requireNonNullElse(zpp.getTotalPrepaidAmount(), BigDecimal.ZERO)).toPlainString();
|
.subtract(Objects.requireNonNullElse(zpp.getTotalPrepaidAmount(), BigDecimal.ZERO)).toPlainString();
|
||||||
|
|||||||
@@ -539,6 +539,7 @@ public class ZF2PushTest extends TestCase {
|
|||||||
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
|
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
|
||||||
.addCashDiscount(new CashDiscount(new BigDecimal(2), 14))
|
.addCashDiscount(new CashDiscount(new BigDecimal(2), 14))
|
||||||
.setDeliveryDate(sdf.parse("2020-11-02")).setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE)
|
.setDeliveryDate(sdf.parse("2020-11-02")).setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE)
|
||||||
|
.setInvoiceReferencedDocumentID("abc123")
|
||||||
);
|
);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -582,6 +583,7 @@ public class ZF2PushTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
Invoice i = zii.extractInvoice();
|
Invoice i = zii.extractInvoice();
|
||||||
|
|
||||||
|
assertEquals("abc123", i.getInvoiceReferencedDocumentID());
|
||||||
assertEquals("4304171000002", i.getRecipient().getGlobalID());
|
assertEquals("4304171000002", i.getRecipient().getGlobalID());
|
||||||
assertEquals("2001015001325", i.getZFItems()[0].getProduct().getGlobalID());
|
assertEquals("2001015001325", i.getZFItems()[0].getProduct().getGlobalID());
|
||||||
assertEquals(orgID, i.getSender().getID());
|
assertEquals(orgID, i.getSender().getID());
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>Mustang</name>
|
<name>Mustang</name>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.mustangproject</groupId>
|
<groupId>org.mustangproject</groupId>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<name>Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung)</name>
|
<name>Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung)</name>
|
||||||
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<!-- for jargs -->
|
<!-- for jargs -->
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>library</artifactId>
|
<artifactId>library</artifactId>
|
||||||
<version>2.15.1-SNAPSHOT</version>
|
<version>2.15.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dom4j</groupId>
|
<groupId>org.dom4j</groupId>
|
||||||
|
|||||||
@@ -267,6 +267,7 @@ public class PDFValidator extends Validator {
|
|||||||
final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8);
|
final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8);
|
||||||
final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8);
|
final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8);
|
||||||
final byte[] cibpdfbrewerSignature = "CIB pdf brewer".getBytes(StandardCharsets.UTF_8);
|
final byte[] cibpdfbrewerSignature = "CIB pdf brewer".getBytes(StandardCharsets.UTF_8);
|
||||||
|
final byte[] lexofficeSignature = "lexoffice".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
if (ByteArraySearcher.contains(fileContents, symtraxSignature)) {
|
if (ByteArraySearcher.contains(fileContents, symtraxSignature)) {
|
||||||
Signature = "Symtrax";
|
Signature = "Symtrax";
|
||||||
@@ -284,6 +285,8 @@ public class PDFValidator extends Validator {
|
|||||||
Signature = "Ghostscript";
|
Signature = "Ghostscript";
|
||||||
} else if (ByteArraySearcher.contains(fileContents, cibpdfbrewerSignature)) {
|
} else if (ByteArraySearcher.contains(fileContents, cibpdfbrewerSignature)) {
|
||||||
Signature = "CIB pdf brewer";
|
Signature = "CIB pdf brewer";
|
||||||
|
} else if (ByteArraySearcher.contains(fileContents, lexofficeSignature)) {
|
||||||
|
Signature = "Lexware office";
|
||||||
}
|
}
|
||||||
|
|
||||||
context.setSignature(Signature);
|
context.setSignature(Signature);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package org.mustangproject.validator;
|
package org.mustangproject.validator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
@@ -69,14 +70,12 @@ public class XMLValidator extends Validator {
|
|||||||
final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9)
|
final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9)
|
||||||
.setPart(EPart.fx);
|
.setPart(EPart.fx);
|
||||||
try (final StringWriter sw = new StringWriter();
|
try (final StringWriter sw = new StringWriter();
|
||||||
final PrintWriter pw = new PrintWriter(sw))
|
final PrintWriter pw = new PrintWriter(sw)) {
|
||||||
{
|
|
||||||
e.printStackTrace(pw);
|
e.printStackTrace(pw);
|
||||||
vri.setStacktrace(sw.toString());
|
vri.setStacktrace(sw.toString());
|
||||||
context.addResultItem(vri);
|
context.addResultItem(vri);
|
||||||
}
|
} catch (IOException ex) {
|
||||||
catch (IOException ex) {
|
throw new UncheckedIOException(ex);
|
||||||
throw new UncheckedIOException (ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +190,7 @@ public class XMLValidator extends Validator {
|
|||||||
boolean isExtended = false;
|
boolean isExtended = false;
|
||||||
boolean isXRechnung = false;
|
boolean isXRechnung = false;
|
||||||
String currentZFVersionDir = "ZF_232";
|
String currentZFVersionDir = "ZF_232";
|
||||||
int mainSchematronSectionErrorTypeCode=4;
|
int mainSchematronSectionErrorTypeCode = 4;
|
||||||
String xsltFilename = null;
|
String xsltFilename = null;
|
||||||
// urn:ferd:CrossIndustryDocument:invoice:1p0:extended,
|
// urn:ferd:CrossIndustryDocument:invoice:1p0:extended,
|
||||||
// urn:ferd:CrossIndustryDocument:invoice:1p0:comfort,
|
// urn:ferd:CrossIndustryDocument:invoice:1p0:comfort,
|
||||||
@@ -269,16 +268,16 @@ public class XMLValidator extends Validator {
|
|||||||
// saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s
|
// saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s
|
||||||
// tcdl2.0.tsdtf.sch iso_svrl.xsl
|
// tcdl2.0.tsdtf.sch iso_svrl.xsl
|
||||||
|
|
||||||
} else if (root.getLocalName().equalsIgnoreCase("Invoice") || root.getLocalName().equalsIgnoreCase("CreditNote") ) {
|
} else if (root.getLocalName().equalsIgnoreCase("Invoice") || root.getLocalName().equalsIgnoreCase("CreditNote")) {
|
||||||
context.setGeneration("2");
|
context.setGeneration("2");
|
||||||
context.setFormat("UBL");
|
context.setFormat("UBL");
|
||||||
isXRechnung = context.getProfile().contains("xrechnung");
|
isXRechnung = context.getProfile().contains("xrechnung");
|
||||||
// UBL
|
// UBL
|
||||||
LOGGER.debug("UBL");
|
LOGGER.debug("UBL");
|
||||||
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-"+root.getLocalName()+"-2.1.xsd", 18, EPart.fx);
|
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-" + root.getLocalName() + "-2.1.xsd", 18, EPart.fx);
|
||||||
xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt";
|
xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt";
|
||||||
|
|
||||||
mainSchematronSectionErrorTypeCode=24;
|
mainSchematronSectionErrorTypeCode = 24;
|
||||||
|
|
||||||
if (isXRechnung) {
|
if (isXRechnung) {
|
||||||
validateSchematron(zfXML, xsltFilename, 24, ESeverity.error);
|
validateSchematron(zfXML, xsltFilename, 24, ESeverity.error);
|
||||||
@@ -287,14 +286,14 @@ public class XMLValidator extends Validator {
|
|||||||
XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass
|
XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass
|
||||||
* */
|
* */
|
||||||
//validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_211/EN16931/FACTUR-X_EN16931.xsd", 18, EPart.fx);
|
//validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_211/EN16931/FACTUR-X_EN16931.xsd", 18, EPart.fx);
|
||||||
String xrVersion=context.getProfile().substring(context.getProfile().length()-3).replace(".","");
|
String xrVersion = context.getProfile().substring(context.getProfile().length() - 3).replace(".", "");
|
||||||
if (!xrVersion.equals("12")&&!xrVersion.equals("20")&&!xrVersion.equals("21")&&!xrVersion.equals("22")&&!xrVersion.equals("23")&&!xrVersion.equals("30")) {
|
if (!xrVersion.equals("12") && !xrVersion.equals("20") && !xrVersion.equals("21") && !xrVersion.equals("22") && !xrVersion.equals("23") && !xrVersion.equals("30")) {
|
||||||
throw new Exception("Unsupported XR version");
|
throw new Exception("Unsupported XR version");
|
||||||
}
|
}
|
||||||
LOGGER.debug("is XRechnung v"+xrVersion);
|
LOGGER.debug("is XRechnung v" + xrVersion);
|
||||||
xsltFilename = "/xslt/XR_"+xrVersion+"/XRechnung-UBL-validation.xslt";
|
xsltFilename = "/xslt/XR_" + xrVersion + "/XRechnung-UBL-validation.xslt";
|
||||||
XrechnungSeverity = ESeverity.error;
|
XrechnungSeverity = ESeverity.error;
|
||||||
mainSchematronSectionErrorTypeCode=27;
|
mainSchematronSectionErrorTypeCode = 27;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,7 +352,7 @@ public class XMLValidator extends Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xsltFilename!=null) {
|
if (xsltFilename != null) {
|
||||||
// main schematron validation
|
// main schematron validation
|
||||||
validateSchematron(zfXML, xsltFilename, mainSchematronSectionErrorTypeCode, ESeverity.error);
|
validateSchematron(zfXML, xsltFilename, mainSchematronSectionErrorTypeCode, ESeverity.error);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user