Merge pull request #542 from weclapp-dev/master

Visualize SpecifiedLogisticsServiceCharge
This commit is contained in:
Jochen Staerk
2024-11-17 19:50:00 +01:00
committed by GitHub
13 changed files with 5453 additions and 7031 deletions

View File

@@ -154,6 +154,8 @@
select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator='false']"/> select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator='false']"/>
<xsl:apply-templates mode="BG-21" <xsl:apply-templates mode="BG-21"
select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator='true']"/> select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator='true']"/>
<xsl:apply-templates mode="BG-X-42"
select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge"/>
<xsl:apply-templates mode="BG-22" <xsl:apply-templates mode="BG-22"
select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation"/> select="./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation"/>
<xsl:apply-templates mode="BG-23" <xsl:apply-templates mode="BG-23"
@@ -1633,6 +1635,57 @@
<!-- End: Jan Thiele --> <!-- End: Jan Thiele -->
</xr:Document_level_charge_reason_code> </xr:Document_level_charge_reason_code>
</xsl:template> </xsl:template>
<xsl:template mode="BG-X-42"
match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge">
<xsl:variable name="bg-contents"
as="item()*"><!--Der Pfad /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge der Instanz in konkreter Syntax wird auf 4 Objekte abgebildet. -->
<xsl:apply-templates mode="BT-X-271" select="./ram:Description"/>
<xsl:apply-templates mode="BT-X-272" select="./ram:AppliedAmount"/>
<xsl:apply-templates mode="BT-X-273" select="./ram:AppliedTradeTax/ram:CategoryCode"/>
<xsl:apply-templates mode="BT-X-274" select="./ram:AppliedTradeTax/ram:RateApplicablePercent"/>
</xsl:variable>
<xsl:if test="$bg-contents">
<xr:LOGISTICS_SERVICE_CHARGES>
<xsl:attribute name="xr:id" select="'BG-X-42'"/>
<xsl:attribute name="xr:src" select="xr:src-path(.)"/>
<xsl:sequence select="$bg-contents"/>
</xr:LOGISTICS_SERVICE_CHARGES>
</xsl:if>
</xsl:template>
<xsl:template mode="BT-X-271"
match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge/ram:Description">
<xr:Logistics_service_charge_description>
<xsl:attribute name="xr:id" select="'BT-X-271'"/>
<xsl:attribute name="xr:src" select="xr:src-path(.)"/>
<xsl:call-template name="amount"/>
</xr:Logistics_service_charge_description>
</xsl:template>
<xsl:template mode="BT-X-272"
match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge/ram:AppliedAmount">
<xr:Logistics_service_charge_amount>
<xsl:attribute name="xr:id" select="'BT-X-272'"/>
<xsl:attribute name="xr:src" select="xr:src-path(.)"/>
<xsl:call-template name="amount"/>
</xr:Logistics_service_charge_amount>
</xsl:template>
<xsl:template mode="BT-X-273"
match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge/ram:AppliedTradeTax/ram:CategoryCode">
<xr:Logistics_service_charge_VAT_category_code>
<xsl:attribute name="xr:id" select="'BT-X-273'"/>
<xsl:attribute name="xr:src" select="xr:src-path(.)"/>
<xsl:call-template name="code.UNTDID.5305">
<xsl:with-param name="myparam" select="."/>
</xsl:call-template>
</xr:Logistics_service_charge_VAT_category_code>
</xsl:template>
<xsl:template mode="BT-X-274"
match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge/ram:AppliedTradeTax/ram:RateApplicablePercent">
<xr:Logistics_service_charge_VAT_rate>
<xsl:attribute name="xr:id" select="'BT-X-274'"/>
<xsl:attribute name="xr:src" select="xr:src-path(.)"/>
<xsl:call-template name="percentage"/>
</xr:Logistics_service_charge_VAT_rate>
</xsl:template>
<xsl:template mode="BG-22" <xsl:template mode="BG-22"
match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation"> match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation">
<xsl:variable name="bg-contents" <xsl:variable name="bg-contents"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +1,34 @@
/**
/** ********************************************************************** * *********************************************************************
* * <p>
* Copyright 2019 Jochen Staerk * Copyright 2019 Jochen Staerk
* * <p>
* Use is subject to license terms. * Use is subject to license terms.
* * <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy * use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0. * of the License at http://www.apache.org/licenses/LICENSE-2.0.
* * <p>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * <p>
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* * <p>
*********************************************************************** */ * **********************************************************************
*/
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.commons.io.IOUtils;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters; import org.junit.runners.MethodSorters;
import org.mustangproject.util.ByteArraySearcher; import org.mustangproject.util.ByteArraySearcher;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*; import javax.xml.transform.TransformerException;
import java.io.*; import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -51,31 +52,83 @@ public class VisualizationTest extends ResourceCase {
/* remove file endings so that tests can also pass after checking /* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes) out from git with arbitrary options (which may include CSRF changes)
*/ */
result = zvi.visualize(CIIinputFile.getAbsolutePath(),ZUGFeRDVisualizer.Language.FR).replace("\r","").replace("\n",""); result = zvi.visualize(CIIinputFile.getAbsolutePath(), ZUGFeRDVisualizer.Language.FR)
.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", "");
File expectedResult=getResourceAsFile("factur-x-vis.fr.html"); File expectedResult = getResourceAsFile("factur-x-vis.fr.html");
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n",""); expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8)
.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", "");
// remove linebreaks as well... // remove linebreaks as well...
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: "+e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: "+e.getMessage()); fail("IllegalArgumentException should not happen: " + e.getMessage());
} catch (TransformerException e) { } catch (TransformerException e) {
fail("TransformerException should not happen: "+e.getMessage()); fail("TransformerException should not happen: " + e.getMessage());
} catch (IOException e) { } catch (IOException e) {
fail("IOException should not happen: "+e.getMessage()); fail("IOException should not happen: " + e.getMessage());
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
fail("ParserConfigurationException should not happen: "+e.getMessage()); fail("ParserConfigurationException should not happen: " + e.getMessage());
} catch (SAXException e) { } catch (SAXException e) {
fail("SAXException should not happen: "+e.getMessage()); fail("SAXException should not happen: " + e.getMessage());
} }
assertNotNull(result); assertNotNull(result);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(expected, result); assertEquals(expected, result);
} }
public void testCIIVisualizationExtended() {
// the writing part
String sourceFilename = "factur-x-extended.xml";
File CIIinputFile = getResourceAsFile(sourceFilename);
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
/* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes)
*/
result = zvi.visualize(CIIinputFile.getAbsolutePath(), ZUGFeRDVisualizer.Language.DE).replace("\r", "").replace("\n", "")
.replace("\t", "")
.replace(" ", "");
File expectedResult = getResourceAsFile("factur-x-vis-extended.de.html");
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", "")
.replace("\t", "")
.replace(" ", "");
// remove linebreaks as well...
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
} catch (TransformerException e) {
fail("TransformerException should not happen: " + e.getMessage());
} catch (IOException e) {
fail("IOException should not happen: " + e.getMessage());
} catch (ParserConfigurationException e) {
fail("ParserConfigurationException should not happen: " + e.getMessage());
} catch (SAXException e) {
fail("SAXException should not happen: " + e.getMessage());
}
assertNotNull(result);
// Reading ZUGFeRD
assertEquals(expected, result);
}
public void testUBLCreditNoteVisualizationBasic() { public void testUBLCreditNoteVisualizationBasic() {
// the writing part // the writing part
@@ -88,31 +141,33 @@ public class VisualizationTest extends ResourceCase {
/* remove file endings so that tests can also pass after checking /* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes) out from git with arbitrary options (which may include CSRF changes)
*/ */
result = zvi.visualize(UBLinputFile.getAbsolutePath(),ZUGFeRDVisualizer.Language.EN).replace("\r","").replace("\n","").replace(" ","").replace("\t",""); result = zvi.visualize(UBLinputFile.getAbsolutePath(), ZUGFeRDVisualizer.Language.EN).replace("\r", "").replace("\n", "").replace("\t", "").replace(" ", "");
File expectedResult=getResourceAsFile("factur-x-vis-ubl-creditnote.en.html"); File expectedResult = getResourceAsFile("factur-x-vis-ubl-creditnote.en.html");
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n","").replace(" ","").replace("\t",""); expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", "").replace("\t", "").replace(" ", "");
// remove linebreaks as well... // remove linebreaks as well...
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: "+e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: "+e.getMessage()); fail("IllegalArgumentException should not happen: " + e.getMessage());
} catch (TransformerException e) { } catch (TransformerException e) {
fail("TransformerException should not happen: "+e.getMessage()); fail("TransformerException should not happen: " + e.getMessage());
} catch (IOException e) { } catch (IOException e) {
fail("IOException should not happen: "+e.getMessage()); fail("IOException should not happen: " + e.getMessage());
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
fail("ParserConfigurationException should not happen: "+e.getMessage()); fail("ParserConfigurationException should not happen: " + e.getMessage());
} catch (SAXException e) { } catch (SAXException e) {
fail("SAXException should not happen: "+e.getMessage()); fail("SAXException should not happen: " + e.getMessage());
} }
assertNotNull(result); assertNotNull(result);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(expected, result); assertEquals(expected, result);
} }
public void testUBLVisualizationBasic() { public void testUBLVisualizationBasic() {
// the writing part // the writing part
@@ -125,28 +180,32 @@ public class VisualizationTest extends ResourceCase {
/* remove file endings so that tests can also pass after checking /* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes) out from git with arbitrary options (which may include CSRF changes)
*/ */
result = zvi.visualize(UBLinputFile.getAbsolutePath(),ZUGFeRDVisualizer.Language.EN).replace("\r","").replace("\n",""); result = zvi.visualize(UBLinputFile.getAbsolutePath(), ZUGFeRDVisualizer.Language.EN).replace("\r", "").replace("\n", "")
.replace("\t", "")
.replace(" ", "");
File expectedResult=getResourceAsFile("factur-x-vis-ubl.en.html"); File expectedResult = getResourceAsFile("factur-x-vis-ubl.en.html");
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n",""); expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", "")
.replace("\t", "")
.replace(" ", "");
// remove linebreaks as well... // remove linebreaks as well...
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: "+e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: "+e.getMessage()); fail("IllegalArgumentException should not happen: " + e.getMessage());
} catch (TransformerException e) { } catch (TransformerException e) {
fail("TransformerException should not happen: "+e.getMessage()); fail("TransformerException should not happen: " + e.getMessage());
} catch (IOException e) { } catch (IOException e) {
fail("IOException should not happen: "+e.getMessage()); fail("IOException should not happen: " + e.getMessage());
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
fail("ParserConfigurationException should not happen: "+e.getMessage()); fail("ParserConfigurationException should not happen: " + e.getMessage());
} catch (SAXException e) { } catch (SAXException e) {
fail("SAXException should not happen: "+e.getMessage()); fail("SAXException should not happen: " + e.getMessage());
} }
assertNotNull(result); assertNotNull(result);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(expected, result); assertEquals(expected, result);
} }
@@ -163,9 +222,9 @@ public class VisualizationTest extends ResourceCase {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII); zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: "+e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: "+e.getMessage()); fail("IllegalArgumentException should not happen: " + e.getMessage());
} }
try { try {
@@ -188,9 +247,9 @@ public class VisualizationTest extends ResourceCase {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL); zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: "+e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: "+e.getMessage()); fail("IllegalArgumentException should not happen: " + e.getMessage());
} }
@@ -214,9 +273,9 @@ public class VisualizationTest extends ResourceCase {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL); zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: "+e.getMessage()); fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: "+e.getMessage()); fail("IllegalArgumentException should not happen: " + e.getMessage());
} }

View File

@@ -1,4 +1,3 @@
/** /**
* ********************************************************************* * *********************************************************************
* <p> * <p>
@@ -27,7 +26,9 @@ import org.junit.jupiter.api.Test;
import org.mustangproject.*; import org.mustangproject.*;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import java.io.*; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
@@ -293,9 +294,9 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
assertFalse(hasExceptions); assertFalse(hasExceptions);
TransactionCalculator tc = new TransactionCalculator(invoice); TransactionCalculator tc = new TransactionCalculator(invoice);
assertEquals(new BigDecimal("1.00"), tc.getGrandTotal()); assertEquals(new BigDecimal("1.00"), tc.getGrandTotal());
assertTrue(invoice.getTradeSettlement().length==1); assertTrue(invoice.getTradeSettlement().length == 1);
assertTrue(invoice.getTradeSettlement()[0] instanceof IZUGFeRDTradeSettlementPayment); assertTrue(invoice.getTradeSettlement()[0] instanceof IZUGFeRDTradeSettlementPayment);
IZUGFeRDTradeSettlementPayment paym=(IZUGFeRDTradeSettlementPayment)invoice.getTradeSettlement()[0]; IZUGFeRDTradeSettlementPayment paym = (IZUGFeRDTradeSettlementPayment) invoice.getTradeSettlement()[0];
assertEquals("DE12500105170648489890", paym.getOwnIBAN()); assertEquals("DE12500105170648489890", paym.getOwnIBAN());
assertEquals("COBADEFXXX", paym.getOwnBIC()); assertEquals("COBADEFXXX", paym.getOwnBIC());
@@ -306,19 +307,19 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
/** /**
* testing if other files embedded in pdf additionally to the invoice can be read correctly * testing if other files embedded in pdf additionally to the invoice can be read correctly
* */ */
public void testDetach() { public void testDetach() {
boolean hasExceptions = false; boolean hasExceptions = false;
byte[] fileA=null; byte[] fileA = null;
byte[] fileB=null; byte[] fileB = null;
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushAttachments.pdf"); ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushAttachments.pdf");
for (FileAttachment fa:zii.getFileAttachmentsPDF()) { for (FileAttachment fa : zii.getFileAttachmentsPDF()) {
if (fa.getFilename().equals("one.pdf")) { if (fa.getFilename().equals("one.pdf")) {
fileA=fa.getData(); fileA = fa.getData();
} else if (fa.getFilename().equals("two.pdf")) { } else if (fa.getFilename().equals("two.pdf")) {
fileB=fa.getData(); fileB = fa.getData();
} }
} }
byte[] b = {12, 13}; // the sample data that was used to write the files byte[] b = {12, 13}; // the sample data that was used to write the files
@@ -330,19 +331,18 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
} }
public void testImportDebit() { public void testImportDebit() {
File CIIinputFile = getResourceAsFile("cii/minimalDebit.xml"); File CIIinputFile = getResourceAsFile("cii/minimalDebit.xml");
try { try {
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile));
Invoice i=zii.extractInvoice(); Invoice i = zii.extractInvoice();
assertEquals("DE21860000000086001055", i.getSender().getBankDetails().get(0).getIBAN()); assertEquals("DE21860000000086001055", i.getSender().getBankDetails().get(0).getIBAN());
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
String jsonArray = mapper.writeValueAsString(i); String jsonArray = mapper.writeValueAsString(i);
// assertEquals("",jsonArray); // assertEquals("",jsonArray);
} catch (IOException e) { } catch (IOException e) {
fail("IOException not expected"); fail("IOException not expected");
@@ -354,14 +354,14 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
} }
public void testImportMinimum() { public void testImportMinimum() {
File CIIinputFile = getResourceAsFile("cii/facturFrMinimum.xml"); File CIIinputFile = getResourceAsFile("cii/facturFrMinimum.xml");
try { try {
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile));
CalculatedInvoice i=new CalculatedInvoice(); CalculatedInvoice i = new CalculatedInvoice();
zii.extractInto(i); zii.extractInto(i);
assertEquals("671.15", i.getGrandTotal().toString()); assertEquals("671.15", i.getGrandTotal().toString());

View File

@@ -0,0 +1,427 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- English disclaimer below.-->
<!--Nutzungsrechte
ZUGFeRD Datenformat Version 2.3.0, 18.09.2024
Beispiel Version 18.09.2024
Zweck des Forums elektronisch Rechnung Deutschland, welches am 31. März 2010 unter der Arbeitsgemeinschaft für
wirtschaftliche Verwaltung e. V. gegründet wurde, ist u. a. die Schaffung und Spezifizierung eines offenen Datenformats
für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht diskriminierender, standardisierter
Technologien („ZUGFeRD Datenformat“).
Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung
frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine
Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht
diskriminierenden Bedingungen an.
Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung
abrufbar unter www.ferd-net.de.
Im Einzelnen schließt die Nutzungsgewährung ein:
=====================================
FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils
geltenden und akzeptierten Fassung (www.ferd-net.de) ein.
Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung,
Weiterbearbeitung und Verbindung mit anderen Produkten.
Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder
anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige
Anwendungen und Dienste.
Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente
und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um
notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch
die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden.
Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares,
unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit
anderen Produkten einzuräumen.
Die Lizenz wird kostenfrei zur Verfügung gestellt.
Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen
Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten,
Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete,
beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der
Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.-->
<!--Right of use
ZUGFeRD Data format version 2.3.0, September 18th, 2024
The purpose of the Forum elektronische Rechnung Deutschland (FeRD), which was founded on March 31, 2010 under the
umbrella of Arbeitsgemeinschaft für wirtschaftliche Verwaltung e. V., is, among other things, to create and specify an
open data format for structured electronic data exchange on the basis of open and non discriminatory, standardised
technologies ("ZUGFeRD data format").
The ZUGFeRD data format is used by both companies and public administration according to the FeRD
made freely accessible. For this purpose FeRD offers all companies and organisations of the public administration a
License to use the copyrighted ZUGFeRD data format in a fair, appropriate and non
discriminatory conditions.
The specification of the FeRD for the implementation of the ZUGFeRD data format is, in its currently valid version
available at www.ferd-net.de.
In detail, the grant of use includes
=====================================
FeRD grants a license for the use of the copyrighted ZUGFeRD data format in the respective
valid and accepted version (www.ferd-net.de).
The license includes an irrevocable right of use including the right of further development,
Further processing and connection with other products.
The license applies in particular to the development, design, production, sale, use or
other use of the ZUGFeRD data format for hardware and/or software products and other
applications and services.
This license does not include the essential patents of the members of FeRD. The essential patents are patents
and patent applications worldwide which contain one or more claims that are
necessary claims. Necessary claims are only those claims of the essential patents which are
the implementation of the ZUGFeRD data format would necessarily be violated.
The Licensee is entitled to provide its respective group companies with an unlimited, worldwide, non-transferable,
irrevocable right of use including the right of further development, further processing and connection with
other products.
The license is provided free of charge.
Except in the case of intentional fault or gross negligence, FeRD is not liable for loss of use, loss of
Profit, loss of data, loss of communication, loss of revenue, loss of contracts, loss of business or for costs
damages, losses or liabilities in connection with an interruption of business, nor for concrete,
incidental, indirect, punitive or consequential damages, even if the possibility of
costs, losses or damages could normally have been foreseen.-->
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<rsm:ExchangedDocumentContext>
<ram:TestIndicator>
<udt:Indicator>true</udt:Indicator>
</ram:TestIndicator>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>KR87654321012</ram:ID>
<ram:Name>KOSTENRECHNUNG</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20241115</udt:DateTimeString>
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:ContentCode>ST3</ram:ContentCode>
<ram:Content>Es bestehen Rabatt- oder Bonusvereinbarungen.</ram:Content>
<ram:SubjectCode>AAK</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:ContentCode>EEV</ram:ContentCode>
<ram:Content>Der Verkäufer bleibt Eigentümer der Waren bis zur vollständigen Erfüllung der Kaufpreisforderung.</ram:Content>
<ram:SubjectCode>AAJ</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>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
</ram:Content>
<ram:SubjectCode>REG</ram:SubjectCode>
</ram:IncludedNote>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000014</ram:GlobalID>
<ram:SellerAssignedID>WA997</ram:SellerAssignedID>
<ram:Name>Wirkarbeit HT</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:Description>Zählpunkt</ram:Description>
<ram:Value>DE0001346484600000000000000100038</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>0.0520</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>0.0520</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="KWH">1000.0000</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>52.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>2</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000021</ram:GlobalID>
<ram:SellerAssignedID>ÖST250</ram:SellerAssignedID>
<ram:Name>Ökosteuer Lieferant</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>0.0205</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>0.0205</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="KWH">1000.0000</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>20.50</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>3</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4260331811362</ram:GlobalID>
<ram:Name>Kommissionierer 1250032 D. Muster</ram:Name>
<ram:Description>Besteller: Hr. Mayer, Personalnr. 4488</ram:Description>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>15.0000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:ActualAmount>4.50</ram:ActualAmount>
<ram:Reason>Artikelrabatt 1</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>10.5000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="HUR">27.5000</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>288.75</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>4</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">2001015001325</ram:GlobalID>
<ram:SellerAssignedID>FB05</ram:SellerAssignedID>
<ram:Name>FALTENBEUTEL 16x6x28 CM</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>0.0105</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>0.0105</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="H87">3500.0000</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>36.75</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>5</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000038</ram:GlobalID>
<ram:SellerAssignedID>KOP05</ram:SellerAssignedID>
<ram:Name>Kopierpapier A4</ram:Name>
<ram:Description>Zählerstand von-bis: 543210 - 544420</ram:Description>
<ram:ApplicableProductCharacteristic>
<ram:Description>Zähler-Nr.</ram:Description>
<ram:Value>MG-X79318</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>0.0100</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>0.0100</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="H87">1210.0000</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>12.10</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:ID>549910</ram:ID>
<ram:GlobalID schemeID="0088">4333741000005</ram:GlobalID>
<ram:Name>MUSTERLIEFERANT GMBH</ram:Name>
<ram:DefinedTradeContact>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49 932 431 500</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>max.mustermann@musterlieferant.de</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>99199</ram:PostcodeCode>
<ram:LineOne>BAHNHOFSTRASSE 99</ram:LineOne>
<ram:CityName>MUSTERHAUSEN</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">201/113/40209</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>339420</ram:ID>
<ram:GlobalID schemeID="0088">4304171000002</ram:GlobalID>
<ram:Name>MUSTER-KUNDE GMBH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>40235</ram:PostcodeCode>
<ram:LineOne>KUNDENWEG 88</ram:LineOne>
<ram:CityName>DUESSELDORF</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
<ram:AdditionalReferencedDocument>
<ram:IssuerAssignedID>A777123</ram:IssuerAssignedID>
<ram:TypeCode>130</ram:TypeCode>
</ram:AdditionalReferencedDocument>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>
<ram:ShipToTradeParty>
<ram:GlobalID schemeID="0088">4304171088093</ram:GlobalID>
<ram:Name>MUSTER-MARKT</ram:Name>
<ram:DefinedTradeContact>
<ram:DepartmentName>7322</ram:DepartmentName>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>31157</ram:PostcodeCode>
<ram:LineOne>HAUPTSTRASSE 44</ram:LineOne>
<ram:CityName>SARSTEDT</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:ShipToTradeParty>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20241030</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
<ram:DeliveryNoteReferencedDocument>
<ram:IssuerAssignedID>L87654321012</ram:IssuerAssignedID>
</ram:DeliveryNoteReferencedDocument>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:InvoiceeTradeParty>
<ram:ID>339420</ram:ID>
<ram:GlobalID schemeID="0088">4304171000002</ram:GlobalID>
<ram:Name>MUSTER-KUNDE GMBH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>40235</ram:PostcodeCode>
<ram:LineOne>KUNDENWEG 88</ram:LineOne>
<ram:CityName>DUESSELDORF</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:InvoiceeTradeParty>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>76.67</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>403.55</ram:BasisAmount>
<ram:LineTotalBasisAmount>410.10</ram:LineTotalBasisAmount>
<ram:AllowanceChargeBasisAmount>-6.55</ram:AllowanceChargeBasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:BasisAmount>410.10</ram:BasisAmount>
<ram:ActualAmount>21.55</ram:ActualAmount>
<ram:Reason>Sonderrabatt</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedLogisticsServiceCharge>
<ram:Description>Transportkosten: Frachbetrag</ram:Description>
<ram:AppliedAmount>15.00</ram:AppliedAmount>
<ram:AppliedTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:AppliedTradeTax>
</ram:SpecifiedLogisticsServiceCharge>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Skontovereinbarung: 2% bei Zahlung innerhalb 10 Tagen nach Rechnungsdatum</ram:Description>
<ram:ApplicableTradePaymentDiscountTerms>
<ram:BasisPeriodMeasure unitCode="DAY">10</ram:BasisPeriodMeasure>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
</ram:ApplicableTradePaymentDiscountTerms>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>410.10</ram:LineTotalAmount>
<ram:ChargeTotalAmount>15.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount>21.55</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount>403.55</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">76.67</ram:TaxTotalAmount>
<ram:GrandTotalAmount>480.22</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount>480.22</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

File diff suppressed because it is too large Load Diff

View File

@@ -1359,6 +1359,7 @@
</div> </div>
<div class="boxabstand"></div> <div class="boxabstand"></div>
</div> </div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig first"> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig first">
<div class="boxzeile"> <div class="boxzeile">
<div id="uebersichtZahlungsinformationen" class="box subBox"> <div id="uebersichtZahlungsinformationen" class="box subBox">
@@ -2625,4 +2626,4 @@ function downloadData (element_id) {
}); });
// //
</script></html> </script></html>

View File

@@ -1221,6 +1221,7 @@
</div> </div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig first"> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig first">
<div class="boxzeile"> <div class="boxzeile">
<div id="uebersichtZahlungsinformationen" class="box subBox"> <div id="uebersichtZahlungsinformationen" class="box subBox">
@@ -1946,4 +1947,4 @@ function downloadData (element_id) {
}); });
// //
</script></html> </script></html>

View File

@@ -1252,6 +1252,7 @@
</div> </div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig"></div>
<div class="boxtabelle boxabstandtop boxtabelleZweispaltig first"> <div class="boxtabelle boxabstandtop boxtabelleZweispaltig first">
<div class="boxzeile"> <div class="boxzeile">
<div id="uebersichtZahlungsinformationen" class="box subBox"> <div id="uebersichtZahlungsinformationen" class="box subBox">
@@ -2118,4 +2119,4 @@ function downloadData (element_id) {
}); });
// //
</script></html> </script></html>

View File

@@ -2,15 +2,6 @@ package org.mustangproject.validator;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlunit.builder.Input;
import org.xmlunit.xpath.JAXPXPathEngine;
import org.xmlunit.xpath.XPathEngine;
import static org.xmlunit.assertj.XmlAssert.assertThat; import static org.xmlunit.assertj.XmlAssert.assertThat;
@@ -34,13 +25,13 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
assertThat(res).valueByXPath("/validation/pdf/summary/@status") assertThat(res).valueByXPath("/validation/pdf/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
assertThat(res).valueByXPath("/validation/xml/summary/@status") assertThat(res).valueByXPath("/validation/xml/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
tempFile = getResourceAsFile("validAvoir_FR_type380_BASICWL.pdf"); tempFile = getResourceAsFile("validAvoir_FR_type380_BASICWL.pdf");
@@ -48,20 +39,20 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
res = zfv.validate(tempFile.getAbsolutePath()); res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
tempFile = getResourceAsFile("validAvoir_FR_type380_BASICWL.pdf"); tempFile = getResourceAsFile("validAvoir_FR_type380_BASICWL.pdf");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(tempFile.getAbsolutePath()); res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
tempFile = getResourceAsFile("validXRechnung.pdf"); tempFile = getResourceAsFile("validXRechnung.pdf");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(tempFile.getAbsolutePath()); res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
/* /*
tempFile = getResourceAsFile("testout-OX.pdf"); tempFile = getResourceAsFile("testout-OX.pdf");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
@@ -79,67 +70,67 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(tempFile.getAbsolutePath()); res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate("/does/not/exist"); res = zfv.validate("/does/not/exist");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
} }
public void testPDFValidationInputStream() { public void testPDFValidationInputStream() {
byte[] fileBytes = getResourceAsByteArray("invalidPDF.pdf"); byte[] fileBytes = getResourceAsByteArray("invalidPDF.pdf");
/**used to be Rule Status /**used to be Rule Status
Specification: ISO 19005-3:2012, Clause: 6.2.11.4, Test number: 4 Specification: ISO 19005-3:2012, Clause: 6.2.11.4, Test number: 4
If the FontDescriptor dictionary of an embedded CID font contains a CIDSet stream, then it shall identify all CIDs which are present in the font program, regardless of whether a CID in the font is referenced or used by the PDF or not. Failed If the FontDescriptor dictionary of an embedded CID font contains a CIDSet stream, then it shall identify all CIDs which are present in the font program, regardless of whether a CID in the font is referenced or used by the PDF or not. Failed
2 occurrences Hide 2 occurrences Hide
PDCIDFont PDCIDFont
fontFile_size == 0 || fontName.search(/[A-Z]{6}\+/) != 0 || CIDSet_size == 0 || cidSetListsAllGlyphs == true fontFile_size == 0 || fontName.search(/[A-Z]{6}\+/) != 0 || CIDSet_size == 0 || cidSetListsAllGlyphs == true
root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[166]/font[0](WIUIIO+CIDFont+F2)/DescendantFonts[0](WIUIIO+CIDFont+F2) root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[166]/font[0](WIUIIO+CIDFont+F2)/DescendantFonts[0](WIUIIO+CIDFont+F2)
root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[192]/font[0](VEXQUA+CIDFont+F1)/DescendantFonts[0](VEXQUA+CIDFont+F1) root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[192]/font[0](VEXQUA+CIDFont+F1)/DescendantFonts[0](VEXQUA+CIDFont+F1)
but new sample since that has been downgraded to warning but new sample since that has been downgraded to warning
*/ */
ZUGFeRDValidator zfv = new ZUGFeRDValidator(); ZUGFeRDValidator zfv = new ZUGFeRDValidator();
String res = zfv.validate(new ByteArrayInputStream (fileBytes), "invalidPDF.pdf"); String res = zfv.validate(new ByteArrayInputStream(fileBytes), "invalidPDF.pdf");
assertThat(res).valueByXPath("/validation/pdf/summary/@status") assertThat(res).valueByXPath("/validation/pdf/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
assertThat(res).valueByXPath("/validation/xml/summary/@status") assertThat(res).valueByXPath("/validation/xml/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
fileBytes = getResourceAsByteArray("validAvoir_FR_type380_BASICWL.pdf"); fileBytes = getResourceAsByteArray("validAvoir_FR_type380_BASICWL.pdf");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (fileBytes), "validAvoir_FR_type380_BASICWL.pdf"); res = zfv.validate(new ByteArrayInputStream(fileBytes), "validAvoir_FR_type380_BASICWL.pdf");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
fileBytes = getResourceAsByteArray("validXRechnung.pdf"); fileBytes = getResourceAsByteArray("validXRechnung.pdf");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (fileBytes), "validXRechnung.pdf"); res = zfv.validate(new ByteArrayInputStream(fileBytes), "validXRechnung.pdf");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid"); .isEqualTo("valid");
fileBytes = getResourceAsByteArray("invalidXRechnung.pdf"); fileBytes = getResourceAsByteArray("invalidXRechnung.pdf");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (fileBytes), "invalidXRechnung.pdf"); res = zfv.validate(new ByteArrayInputStream(fileBytes), "invalidXRechnung.pdf");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
zfv = new ZUGFeRDValidator(); zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (new byte[0]), "/does/not/exist"); res = zfv.validate(new ByteArrayInputStream(new byte[0]), "/does/not/exist");
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid"); .isEqualTo("invalid");
} }
public void testPDFA3AValidation() { public void testPDFA3AValidation() {
File tempFile = getResourceAsFile("zugferd_2p1_EXTENDED_PDFA-3A.pdf"); File tempFile = getResourceAsFile("zugferd_2p1_EXTENDED_PDFA-3A.pdf");
@@ -163,15 +154,15 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
String res = zfv.validate(tempFile.getAbsolutePath()); String res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("count(//error)") assertThat(res).valueByXPath("count(//error)")
.asInt() .asInt()
.isNotEqualTo(0); .isNotEqualTo(0);
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.asString() .asString()
.isEqualTo("invalid");// expect to be valid because XR notices are, well, only notices .isEqualTo("invalid");// expect to be valid because XR notices are, well, only notices
assertThat(res).valueByXPath("/validation/xml/summary/@status") assertThat(res).valueByXPath("/validation/xml/summary/@status")
.asString() .asString()
.isEqualTo("invalid"); .isEqualTo("invalid");
} }
@@ -198,6 +189,7 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
} }
public void testXR30Validation() { public void testXR30Validation() {
File tempFile = getResourceAsFile("validXRV30.xml"); File tempFile = getResourceAsFile("validXRV30.xml");
@@ -242,10 +234,10 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
} }
/*** /***
* the XMLValidatorTests only cover the <xml></xml> part, this one includes the root element and * the XMLValidatorTests only cover the <xml></xml> part, this one includes the root element and
* the global <summary></summary> part as well * the global <summary></summary> part as well
*/ */
public void testXMLValidation() { public void testXMLValidation() {
File tempFile = getResourceAsFile("validV2.xml"); File tempFile = getResourceAsFile("validV2.xml");
ZUGFeRDValidator zfv = new ZUGFeRDValidator(); ZUGFeRDValidator zfv = new ZUGFeRDValidator();
@@ -253,18 +245,18 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
String res = zfv.validate(tempFile.getAbsolutePath()); String res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("count(//error)") assertThat(res).valueByXPath("count(//error)")
.asInt() .asInt()
.isEqualTo(0); .isEqualTo(0);
assertThat(res).valueByXPath("count(//notice)") assertThat(res).valueByXPath("count(//notice)")
.asInt() .asInt()
.isEqualTo(12); // 12 notices RE XRechnung 3.0 .isEqualTo(12); // 12 notices RE XRechnung 3.0
assertThat(res).valueByXPath("/validation/summary/@status") assertThat(res).valueByXPath("/validation/summary/@status")
.asString() .asString()
.isEqualTo("valid");// expect to be valid because XR notices are, well, only notices .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices
assertThat(res).valueByXPath("/validation/xml/summary/@status") assertThat(res).valueByXPath("/validation/xml/summary/@status")
.asString() .asString()
.isEqualTo("valid"); .isEqualTo("valid");
} }
} }