Merge remote-tracking branch 'mustang-master/master' into forked-master

# Conflicts:
#	library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java
This commit is contained in:
Sebastian Sieber
2024-12-20 09:01:31 +01:00
22 changed files with 1468 additions and 1292 deletions

View File

@@ -1,8 +1,14 @@
2.15.2
=======
2024-12-19
- correcly write charge reason codes also for non-Xrechnung #617 - correcly write charge reason codes also for non-Xrechnung #617
- correctly import additional referenced documents into invoice/corrected setting of attachments from jackson - correctly import additional referenced documents into invoice/corrected setting of attachments from jackson
- corrected parseException structure - corrected parseException structure
- allow 1p0 as potential xmp version number - allow 1p0 as potential xmp version number
- #618 import BT-20 - #618 import BT-20
- #599 add tax category code for free export
- #600 Fixes a problem where a stream was not safely closed
2.15.1 2.15.1
======= =======

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.15.2-SNAPSHOT</version> <version>2.15.3-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.2-SNAPSHOT</version> <version>2.15.3-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.2-SNAPSHOT</version> <version>2.15.3-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
--> -->

View File

@@ -3,13 +3,13 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.15.2-SNAPSHOT</version> <version>2.15.3-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.2-SNAPSHOT</version> <version>2.15.3-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
@@ -200,21 +200,51 @@
</manifest> </manifest>
<manifestSections> <manifestSections>
<manifestSection> <manifestSection>
<name>FreeSans.ttf</name> <name>SourceSansPro-Regular.ttf</name>
<manifestEntries> <manifestEntries>
<Content-Type>font/ttf</Content-Type> <Content-Type>font/ttf</Content-Type>
</manifestEntries> </manifestEntries>
</manifestSection> </manifestSection>
<manifestSection> <manifestSection>
<name>FreeSerif.ttf</name> <name>SourceSansPro-It.ttf</name>
<manifestEntries> <manifestEntries>
<Content-Type>application/x-font</Content-Type> <Content-Type>font/ttf</Content-Type>
</manifestEntries> </manifestEntries>
</manifestSection> </manifestSection>
<manifestSection> <manifestSection>
<name>Times-Bold.ttf</name> <name>SourceSansPro-Bold.ttf</name>
<manifestEntries> <manifestEntries>
<Content-Type>application/x-font</Content-Type> <Content-Type>font/ttf</Content-Type>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>SourceSansPro-BoldIt.ttf</name>
<manifestEntries>
<Content-Type>font/ttf</Content-Type>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>SourceSerifPro-Regular.ttf</name>
<manifestEntries>
<Content-Type>font/ttf</Content-Type>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>SourceSerifPro-It.ttf</name>
<manifestEntries>
<Content-Type>font/ttf</Content-Type>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>SourceSerifPro-Bold.ttf</name>
<manifestEntries>
<Content-Type>font/ttf</Content-Type>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>SourceSerifPro-BoldIt.ttf</name>
<manifestEntries>
<Content-Type>font/ttf</Content-Type>
</manifestEntries> </manifestEntries>
</manifestSection> </manifestSection>
</manifestSections> </manifestSections>

View File

@@ -83,9 +83,10 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
} }
protected byte[] filenameToByteArray(String pdfFilename) throws IOException { protected byte[] filenameToByteArray(String pdfFilename) throws IOException {
FileInputStream fileInputStream = new FileInputStream(pdfFilename); try (FileInputStream fileInputStream = new FileInputStream(pdfFilename)) {
return inputstreamToByteArray(fileInputStream); return inputstreamToByteArray(fileInputStream);
} }
}
protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException { protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException {
byte[] bytes = new byte[fileInputStream.available()]; byte[] bytes = new byte[fileInputStream.available()];

View File

@@ -659,6 +659,7 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
* *
* @return a List of LineItem instances * @return a List of LineItem instances
*/ */
@Deprecated
public List<Item> getLineItemList() { public List<Item> getLineItemList() {
final List<Node> nodeList = getLineItemNodes(); final List<Node> nodeList = getLineItemNodes();
final List<Item> lineItemList = new ArrayList<>(); final List<Item> lineItemList = new ArrayList<>();

View File

@@ -1036,6 +1036,7 @@ public class ZUGFeRDInvoiceImporter {
* for PDF embedded files in FX use getFileAttachmentsPDF() * for PDF embedded files in FX use getFileAttachmentsPDF()
* @deprecated use invoice.getAdditionalReferencedDocuments * @deprecated use invoice.getAdditionalReferencedDocuments
*/ */
@Deprecated
public List<FileAttachment> getFileAttachmentsXML() { public List<FileAttachment> getFileAttachmentsXML() {
return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments())); return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments()));
} }

View File

@@ -29,6 +29,7 @@ public class TaxCategoryCodeTypeConstants {
public static final String ZEROTAXPRODUCTS = "Z"; public static final String ZEROTAXPRODUCTS = "Z";
public static final String UNTAXEDSERVICE = "O"; public static final String UNTAXEDSERVICE = "O";
public static final String INTRACOMMUNITY = "K"; public static final String INTRACOMMUNITY = "K";
public static final String FREEEXPORT = "G";
public static Set<String> CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT).collect(Collectors.toSet()); public static Set<String> CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT).collect(Collectors.toSet());
} }

Binary file not shown.

Binary file not shown.

View File

@@ -23,15 +23,35 @@
<renderers> <renderers>
<renderer mime="application/pdf"> <renderer mime="application/pdf">
<fonts><!-- https://xmlgraphics.apache.org/fop/1.1/fonts.html auto-embed --> <fonts>
<!-- https://xmlgraphics.apache.org/fop/1.1/fonts.html auto-embed -->
<auto-detect/> <auto-detect/>
<font kerning="no" embed-url="classpath:FreeSans.ttf" embedding-mode="subset"> <font kerning="yes" embed-url="classpath:fonts/SourceSansPro-Regular.ttf" embedding-mode="subset">
<font-triplet name="SourceSerifPro" style="normal" weight="normal" /> <font-triplet name="SourceSansPro" style="normal" weight="400"/>
<font-triplet name="Times-Bold" style="normal" weight="normal" /> </font>
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-It.ttf" embedding-mode="subset">
<font-triplet name="SourceSansPro" style="italic" weight="400"/>
</font>
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-Bold.ttf" embedding-mode="subset">
<font-triplet name="SourceSansPro" style="normal" weight="700"/>
</font>
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-BoldIt.ttf" embedding-mode="subset">
<font-triplet name="SourceSansPro" style="italic" weight="700"/>
</font>
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-Regular.ttf" embedding-mode="subset">
<font-triplet name="SourceSerifPro" style="normal" weight="400"/>
</font>
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-It.ttf" embedding-mode="subset">
<font-triplet name="SourceSerifPro" style="italic" weight="400"/>
</font>
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-Bold.ttf" embedding-mode="subset">
<font-triplet name="SourceSerifPro" style="normal" weight="700"/>
</font>
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-BoldIt.ttf" embedding-mode="subset">
<font-triplet name="SourceSerifPro" style="italic" weight="700"/>
</font> </font>
</fonts> </fonts>
<output-profile>classpath:AdobeCompat-v2.icc</output-profile> <output-profile>classpath:AdobeCompat-v2.icc</output-profile>
</renderer> </renderer>
</renderers> </renderers>
</fop> </fop>

View File

@@ -12,7 +12,7 @@
== Schriften == Schriften
=========================================================================== --> =========================================================================== -->
<xsl:variable name="fontSans">SourceSerifPro</xsl:variable> <xsl:variable name="fontSans">SourceSansPro</xsl:variable>
<xsl:variable name="fontSerif">SourceSerifPro</xsl:variable> <xsl:variable name="fontSerif">SourceSerifPro</xsl:variable>
<xsl:variable name="amount-picture" select="xrf:_('amount-format')"/> <xsl:variable name="amount-picture" select="xrf:_('amount-format')"/>

View File

@@ -166,6 +166,118 @@ public class DeSerializationTest extends ResourceCase {
} }
public void testDeserializedFiles() {
File inputUBL = getResourceAsFile("XRECHNUNG_Elektron.ubl.xml");
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
zii.doIgnoreCalculationErrors();
Invoice i = new Invoice();
String exText = null;
try {
zii.fromXML(new String(Files.readAllBytes(inputUBL.toPath()), StandardCharsets.UTF_8));
ObjectMapper mapper = new ObjectMapper();
zii.extractInto(i);
String json = mapper.writeValueAsString(i);
Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class);
assertEquals("181301674", i.getNumber());
assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber());
assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments()[0].getFilename(), i.getAdditionalReferencedDocuments()[0].getFilename());
assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments().length, 2);
} catch (IOException e) {
exText = e.getMessage();
} catch (XPathExpressionException e) {
exText = e.getMessage();
} catch (ParseException e) {
exText = e.getMessage();
}
assertNull(exText);
}
public void testFileSerialization() {
String base64 = "b25ldHdvdGhyZWU=";
String json = "{\n" +
" \"additionalReferencedDocuments\": [\n" +
" {\n" +
" \"data\": \"" + base64 + "\",\n" +
" \"description\": \"Additional file attachment\",\n" +
" \"filename\": \"text.txt\",\n" +
" \"mimetype\": \"text/plain\",\n" +
" \"relation\": \"Data\"\n" +
" }\n" +
"],\n" +
"\n" +
" \"number\": \"471102\",\n" +
" \"currency\": \"EUR\",\n" +
" \"issueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" +
" \"dueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" +
" \"deliveryDate\": \"2018-03-04T00:00:00.000+01:00\",\n" +
" \"sender\": {\n" +
" \"name\": \"Lieferant GmbH\",\n" +
" \"zip\": \"80333\",\n" +
" \"street\": \"Lieferantenstraße 20\",\n" +
" \"location\": \"München\",\n" +
" \"country\": \"DE\",\n" +
" \"taxID\": \"201/113/40209\",\n" +
" \"vatID\": \"DE123456789\",\n" +
" \"globalID\": \"4000001123452\",\n" +
" \"globalIDScheme\": \"0088\"\n" +
" },\n" +
" \"recipient\": {\n" +
" \"name\": \"Kunden AG Mitte\",\n" +
" \"zip\": \"69876\",\n" +
" \"street\": \"Kundenstraße 15\",\n" +
" \"location\": \"Frankfurt\",\n" +
" \"country\": \"DE\"\n" +
" },\n" +
" \"zfitems\": [\n" +
" {\n" +
" \"price\": 9.9,\n" +
" \"quantity\": 20,\n" +
" \"product\": {\n" +
" \"unit\": \"H87\",\n" +
" \"name\": \"Trennblätter A4\",\n" +
" \"description\": \"\",\n" +
" \"vatpercent\": 19,\n" +
" \"taxCategoryCode\": \"S\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"price\": 5.5,\n" +
" \"quantity\": 50,\n" +
" \"product\": {\n" +
" \"unit\": \"H87\",\n" +
" \"name\": \"Joghurt Banane\",\n" +
" \"description\": \"\",\n" +
" \"vatpercent\": 7,\n" +
" \"taxCategoryCode\": \"S\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}\n";
ObjectMapper mapper = new ObjectMapper();
try {
Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class);
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
zf2p.setProfile(Profiles.getByName("XRechnung"));
zf2p.generateXML(newInvoiceFromJSON);
String theXML = new String(zf2p.getXML());
assertTrue(theXML.contains("<udt:DateTimeString format=\"102\">20180304</udt:DateTimeString>"));
assertTrue(theXML.contains(base64));
} catch (Exception e) {
fail("No exception expected");
}
}
public void testFull300Roundtrip() { public void testFull300Roundtrip() {
File inputCII = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml"); File inputCII = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml");

View File

@@ -62,9 +62,11 @@ public class VisualizationTest extends ResourceCase {
try { try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
result = zvi.visualize(CIIinputFile.getAbsolutePath(), lang); result = zvi.visualize(CIIinputFile.getAbsolutePath(), lang);
Files.write(Paths.get("./target/testout-" + resultFileName), result.getBytes(StandardCharsets.UTF_8));
File expectedResult = getResourceAsFile(resultFileName); File expectedResult = getResourceAsFile(resultFileName);
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8); expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8)
;
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());

View File

@@ -261,7 +261,7 @@ public class ZF2PushTest extends TestCase {
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal("0.1")))) .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal("0.1"))))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))) .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50))))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("AK"))) .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK")))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addCharge(new Charge(new BigDecimal(1))).addAllowance(new Allowance(new BigDecimal("1")))) .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addCharge(new Charge(new BigDecimal(1))).addAllowance(new Allowance(new BigDecimal("1"))))
); );
@@ -807,12 +807,14 @@ public class ZF2PushTest extends TestCase {
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("\\Users\\jstaerk\\temp\\1424413_anonymized.xml"); // ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("\\Users\\jstaerk\\temp\\1424413_anonymized.xml");
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(this.getClass().getResourceAsStream("/factur-x.xml"));
try { try {
Invoice i = zii.extractInvoice(); Invoice i = zii.extractInvoice();
TransactionCalculator tc=new TransactionCalculator(i); TransactionCalculator tc=new TransactionCalculator(i);
assertEquals(0,tc.getGrandTotal().compareTo(new BigDecimal("442.83"))); // assertEquals(0,tc.getGrandTotal().compareTo(new BigDecimal("442.83")));
assertEquals(0,tc.getGrandTotal().compareTo(new BigDecimal("571.04")));
} catch (XPathExpressionException e) { } catch (XPathExpressionException e) {
fail("XPathExpressionException should not be raised"); fail("XPathExpressionException should not be raised");

View File

@@ -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.2-SNAPSHOT</version> <version>2.15.3-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Mustang</name> <name>Mustang</name>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.15.2-SNAPSHOT</version> <version>2.15.3-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.2-SNAPSHOT</version> <version>2.15.3-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.2-SNAPSHOT</version> <version>2.15.3-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>