Merge branch 'master' into bugfix/issue841b

This commit is contained in:
Frank Langelage
2025-07-30 11:46:53 +02:00
committed by GitHub
40 changed files with 6751 additions and 1300 deletions

View File

@@ -1,17 +1,29 @@
2.18.1
=======
- #893 Tradeparty globalID is not read from JSON
2.18.0
=======
2025-07-14
- support parsing of BT-90 CreditorReferenceID - support parsing of BT-90 CreditorReferenceID
- #870 - #871 schema validation does not ignore external entities
- #871 - #868 Fix wrong version in History.md
- #868 - #729 Updates about SpecifiedTradeSettlementHeaderMonetarySummation and SpecifiedTradeSettlementPaymentMeans
- #729 - #863 LineCalculator throws NPE if product is null (since 2.17.0)
- #863 - #731 Got a broken translation key when visualizing XML into PDF (xr:Business_process_type)
- #731 - #865 Add sevdesk signature to PDF creators
- #865 - #849 Ignore calculation errors when extracting xml from pdf
- #849 - #856 Read contact´s fax number.
- #856 - #850/#843 Correction for "Re-Initialize the HTML-template on language change
- #850/#843 - #855 Suppress empty nodes in output XML
- #855 - #874 Skip PDNameTreeNodes if the names are null or empty
- #874 - #830 Invalid XML generated: Item vat-category-code summed up with other 0 percent category codes
- #876/830 - #878 report arithmetic issues in validation report
- corrected typo ArithmetricException to ArithmeticException
- #726 Financial account information (IBAN) is lost when converting a cii invoice to ubl
- #885 JSON duplicates on item allowances/charges
- #887 incorrect percentual item allowances
2.17.0 2.17.0
======= =======

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.17.1-SNAPSHOT</version> <version>2.18.1-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.17.1-SNAPSHOT</version> <version>2.18.1-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.17.1-SNAPSHOT</version> <version>2.18.1-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
--> -->
@@ -106,8 +106,10 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version>
<configuration> <configuration>
<runOrder>alphabetical</runOrder> <runOrder>alphabetical</runOrder>
<argLine>-Duser.timezone=UTC</argLine>
</configuration> </configuration>
</plugin> </plugin>
<!-- allow getImplementationVersion for the pom.xml --> <!-- allow getImplementationVersion for the pom.xml -->

View File

@@ -371,17 +371,17 @@ public class Main {
boolean optionsRecognized = false; boolean optionsRecognized = false;
String action = ""; String action = "";
Boolean disableFileLogging = false; boolean disableFileLogging = false;
try { try {
cmd = parser.parse(options, args); cmd = parser.parse(options, args);
// Retrieve all options // Retrieve all options
action = cmd.getOptionValue("action"); action = cmd.getOptionValue("action");
String directoryName = cmd.getOptionValue("directory"); String directoryName = cmd.getOptionValue("directory");
Boolean filesFromStdIn = cmd.hasOption("listfromstdin");//((Number)cmdLine.getParsedOptionValue("integer-option")).intValue(); boolean filesFromStdIn = cmd.hasOption("listfromstdin");//((Number)cmdLine.getParsedOptionValue("integer-option")).intValue();
Boolean ignoreFileExt = cmd.hasOption("ignorefileextension"); boolean ignoreFileExt = cmd.hasOption("ignorefileextension");
Boolean noAttachments = cmd.hasOption("no-additional-attachments"); boolean noAttachments = cmd.hasOption("no-additional-attachments");
Boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help"))); boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help")));
disableFileLogging = cmd.hasOption("disable-file-logging"); disableFileLogging = cmd.hasOption("disable-file-logging");
String sourceName = cmd.getOptionValue("source"); String sourceName = cmd.getOptionValue("source");
@@ -389,8 +389,8 @@ public class Main {
String outName = cmd.getOptionValue("out"); String outName = cmd.getOptionValue("out");
String format = cmd.getOptionValue("format"); String format = cmd.getOptionValue("format");
String lang = cmd.getOptionValue("language"); String lang = cmd.getOptionValue("language");
Boolean noNotices = cmd.hasOption("no-notices"); boolean noNotices = cmd.hasOption("no-notices");
Boolean LogAsPDF = cmd.hasOption("log-as-pdf"); boolean LogAsPDF = cmd.hasOption("log-as-pdf");
String zugferdVersion = cmd.getOptionValue("version"); String zugferdVersion = cmd.getOptionValue("version");
String zugferdProfile = cmd.getOptionValue("profile"); String zugferdProfile = cmd.getOptionValue("profile");

View File

@@ -68,7 +68,7 @@ public class ValidatorFileWalker
thisResultString = "invalid"; thisResultString = "invalid";
allValid = false; allValid = false;
} }
LOGGER.info(String.format("\n@%s Testing file %d: %s (%s) ", dateFormat.format(date), fileCount++, thisResultString, file)); LOGGER.info("\n@{} Testing file {}: {} ({}) ", dateFormat.format(date), fileCount++, thisResultString, file);
} }
} }
} }
@@ -79,7 +79,7 @@ public class ValidatorFileWalker
@Override @Override
public FileVisitResult postVisitDirectory(Path dir, public FileVisitResult postVisitDirectory(Path dir,
IOException exc) { IOException exc) {
LOGGER.info(String.format("\nDirectory: %s \n", dir)); LOGGER.info("\nDirectory: {} \n", dir);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.17--> <!--Created by yEd 3.21.1-->
<key attr.name="Beschreibung" attr.type="string" for="graph" id="d0"/> <key attr.name="Beschreibung" attr.type="string" for="graph" id="d0"/>
<key for="port" id="d1" yfiles.type="portgraphics"/> <key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/> <key for="port" id="d2" yfiles.type="portgeometry"/>
@@ -13,43 +13,37 @@
<key attr.name="description" attr.type="string" for="edge" id="d9"/> <key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/> <key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G"> <graph edgedefault="directed" id="G">
<data key="d0"/> <data key="d0" xml:space="preserve"/>
<node id="n0"> <node id="n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="137.0" x="120.375" y="0.0"/> <y:Geometry height="54.0" width="137.0" x="411.5" y="0.0"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.83984375" x="38.580078125" y="17.93359375">PDF+XML<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.681640625" x="38.6591796875" xml:space="preserve" y="17.6494140625">PDF+XML<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n1" yfiles.foldertype="group"> <node id="n1" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="264.666015625" width="366.0" x="1950.0" y="190.666015625"/> <y:Geometry height="281.37646484375" width="364.0" x="1912.5" y="192.37646484375"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="366.0" x="0.0" y="0.0">ZUGFeRD</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="364.0" x="0.0" xml:space="preserve" y="0.0">ZUGFeRD</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 2</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 2</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -62,73 +56,55 @@
<node id="n1::n0"> <node id="n1::n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="152.0" x="1966.0" y="227.33203125"/> <y:Geometry height="54.0" width="152.0" x="1927.5" y="229.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="100.73828125" x="25.630859375" y="17.93359375">Schematron files<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="93.373046875" x="29.3134765625" xml:space="preserve" y="17.6494140625">Schematron files<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n1::n1"> <node id="n1::n1">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="152.0" x="2148.0" y="386.33203125"/> <y:Geometry height="54.0" width="152.0" x="2109.5" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="76.521484375" x="37.7392578125" y="17.93359375">Schema files<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="72.6953125" x="39.65234375" xml:space="preserve" y="17.6494140625">Schema files<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n1::n2"> <node id="n1::n2">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="152.0" x="1966.0" y="386.33203125"/> <y:Geometry height="54.0" width="152.0" x="1927.5" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="85.615234375" x="33.1923828125" y="17.93359375">Codelist XMLs<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="81.361328125" x="35.3193359375" xml:space="preserve" y="17.6494140625">Codelist XMLs<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
</graph> </graph>
</node> </node>
<node id="n2" yfiles.foldertype="group"> <node id="n2" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="95.666015625" width="408.0" x="1512.0" y="195.666015625"/> <y:Geometry height="96.37646484375" width="406.0" x="1476.5" y="197.37646484375"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="408.0" x="0.0" y="0.0">EN16931</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="406.0" x="0.0" xml:space="preserve" y="0.0">EN16931</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 3</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 3</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -141,57 +117,45 @@
<node id="n2::n0"> <node id="n2::n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="1731.0" y="232.33203125"/> <y:Geometry height="44.0" width="173.0" x="1694.5" y="234.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="110.453125" x="31.2734375" y="12.93359375">CEF Codelist Excel<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="107.365234375" x="32.8173828125" xml:space="preserve" y="12.6494140625">CEF Codelist Excel<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n2::n1"> <node id="n2::n1">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="1528.0" y="232.33203125"/> <y:Geometry height="44.0" width="173.0" x="1491.5" y="234.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="100.2578125" x="36.37109375" y="12.93359375">CEN Schematron<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="97.369140625" x="37.8154296875" xml:space="preserve" y="12.6494140625">CEN Schematron<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
</graph> </graph>
</node> </node>
<node id="n3" yfiles.foldertype="group"> <node id="n3" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="95.666015625" width="205.0" x="2346.0" y="195.666015625"/> <y:Geometry height="96.37646484375" width="203.0" x="2306.5" y="197.37646484375"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="205.0" x="0.0" y="0.0">UN/CEFACT</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="203.0" x="0.0" xml:space="preserve" y="0.0">UN/CEFACT</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 4</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 4</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -204,16 +168,10 @@
<node id="n3::n0"> <node id="n3::n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="2362.0" y="232.33203125"/> <y:Geometry height="44.0" width="173.0" x="2321.5" y="234.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="76.521484375" x="48.2392578125" y="12.93359375">Schema files<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="72.6953125" x="50.15234375" xml:space="preserve" y="12.6494140625">Schema files<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
@@ -222,39 +180,33 @@
<node id="n4"> <node id="n4">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="BevelNode"> <y:GenericNode configuration="BevelNode">
<y:Geometry height="54.0" width="163.75" x="474.625" y="641.33203125"/> <y:Geometry height="54.0" width="163.75" x="350.3595238095238" y="675.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="70.638671875" x="46.5556640625" y="17.93359375">XML Report<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="68.025390625" x="47.8623046875" xml:space="preserve" y="17.6494140625">XML Report<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5" yfiles.foldertype="group"> <node id="n5" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="493.33203125" width="1268.0" x="0.0" y="85.0"/> <y:Geometry height="511.7529296875" width="1234.5" x="0.0" y="85.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="1268.0" x="0.0" y="0.0">ZUV</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="1234.5" x="0.0" xml:space="preserve" y="0.0">ZUV</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 5</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 5</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -267,167 +219,113 @@
<node id="n5::n0"> <node id="n5::n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="673.0" y="519.33203125"/> <y:Geometry height="44.0" width="173.0" x="640.5" y="537.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="95.18359375" x="38.908203125" y="12.93359375">PH-Schematron<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.365234375" x="41.8173828125" xml:space="preserve" y="12.6494140625">PH-Schematron<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n1"> <node id="n5::n1">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="84.0" x="801.25" y="386.33203125"/> <y:Geometry height="54.0" width="84.0" x="801.5" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="28.24609375" x="27.876953125" y="17.93359375">XML<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="28.673828125" x="27.6630859375" xml:space="preserve" y="17.6494140625">XML<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n2"> <node id="n5::n2">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="84.0" x="108.5" y="386.33203125"/> <y:Geometry height="54.0" width="84.0" x="75.0" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="57.431640625" x="13.2841796875" y="17.93359375">Metadata<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="54.033203125" x="14.9833984375" xml:space="preserve" y="17.6494140625">Metadata<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n3"> <node id="n5::n3">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="64.0" y="519.33203125"/> <y:Geometry height="44.0" width="173.0" x="30.5" y="537.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="94.66796875" x="39.166015625" y="12.93359375">Metadata check<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="88.71484375" x="42.142578125" xml:space="preserve" y="12.6494140625">Metadata check<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n4"> <node id="n5::n4">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="152.0" x="619.25" y="386.33203125"/> <y:Geometry height="54.0" width="152.0" x="619.5" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.91015625" x="46.044921875" y="17.93359375">XSLT files<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="58.685546875" x="46.6572265625" xml:space="preserve" y="17.6494140625">XSLT files<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n5"> <node id="n5::n5">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="152.0" x="1100.0" y="386.33203125"/> <y:Geometry height="54.0" width="152.0" x="1067.5" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.91015625" x="46.044921875" y="17.93359375">XSLT files<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="58.685546875" x="46.6572265625" xml:space="preserve" y="17.6494140625">XSLT files<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n6"> <node id="n5::n6">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="84.0" x="311.5" y="386.33203125"/> <y:Geometry height="54.0" width="84.0" x="278.0" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="92.81640625" x="-4.408203125" y="17.93359375">Additional data<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="83.39453125" x="0.302734375" xml:space="preserve" y="17.6494140625">Additional data<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n7"> <node id="n5::n7">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="267.0" y="519.33203125"/> <y:Geometry height="44.0" width="173.0" x="233.5" y="537.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="130.052734375" x="21.4736328125" y="12.93359375">Additional data check<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="118.076171875" x="27.4619140625" xml:space="preserve" y="12.6494140625">Additional data check<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n8"> <node id="n5::n8">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="876.0" y="519.33203125"/> <y:Geometry height="44.0" width="173.0" x="843.5" y="537.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="95.18359375" x="38.908203125" y="12.93359375">PH-Schematron<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.365234375" x="41.8173828125" xml:space="preserve" y="12.6494140625">PH-Schematron<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n9" yfiles.foldertype="group"> <node id="n5::n9" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="169.666015625" width="205.0" x="251.0" y="121.666015625"/> <y:Geometry height="171.37646484375" width="203.0" x="218.5" y="122.37646484375"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="205.0" x="0.0" y="0.0">Mustangproject</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="203.0" x="0.0" xml:space="preserve" y="0.0">Mustangproject</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 1</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 1</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -440,57 +338,45 @@
<node id="n5::n9::n0"> <node id="n5::n9::n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="267.0" y="232.33203125"/> <y:Geometry height="44.0" width="173.0" x="233.5" y="234.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="47.6875" x="62.65625" y="12.93359375">PDFBox<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="48.677734375" x="62.1611328125" xml:space="preserve" y="12.6494140625">PDFBox<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n9::n1"> <node id="n5::n9::n1">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="267.0" y="158.33203125"/> <y:Geometry height="44.0" width="173.0" x="233.5" y="159.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="53.9453125" x="59.52734375" y="12.93359375">Mustang<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="50.025390625" x="61.4873046875" xml:space="preserve" y="12.6494140625">Mustang<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
</graph> </graph>
</node> </node>
<node id="n5::n10" yfiles.foldertype="group"> <node id="n5::n10" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="95.666015625" width="205.0" x="16.0" y="121.666015625"/> <y:Geometry height="96.37646484375" width="203.0" x="451.5" y="122.37646484375"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="205.0" x="0.0" y="0.0">VeraPDF</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="203.0" x="0.0" xml:space="preserve" y="0.0">VeraPDF</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 6</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 6</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -503,16 +389,10 @@
<node id="n5::n10::n0"> <node id="n5::n10::n0">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="32.0" y="158.33203125"/> <y:Geometry height="44.0" width="173.0" x="466.5" y="159.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="52.123046875" x="60.4384765625" y="12.93359375">VeraPDF<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="53.34765625" x="59.826171875" xml:space="preserve" y="12.6494140625">VeraPDF<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
@@ -521,74 +401,66 @@
<node id="n5::n11"> <node id="n5::n11">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="1079.0" y="519.33203125"/> <y:Geometry height="44.0" width="173.0" x="1046.5" y="537.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="85.80859375" x="43.595703125" y="12.93359375">Schema check<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="82.703125" x="45.1484375" xml:space="preserve" y="12.6494140625">Schema check<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n12"> <node id="n5::n12">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNode3"> <y:GenericNode configuration="ShinyPlateNode3">
<y:Geometry height="54.0" width="152.0" x="437.25" y="386.33203125"/> <y:Geometry height="54.0" width="152.0" x="437.5" y="404.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.91015625" x="46.044921875" y="17.93359375">XSLT files<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="58.685546875" x="46.6572265625" xml:space="preserve" y="17.6494140625">XSLT files<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
<node id="n5::n13"> <node id="n5::n13">
<data key="d6"> <data key="d6">
<y:GenericNode configuration="ShinyPlateNodeWithShadow"> <y:GenericNode configuration="ShinyPlateNodeWithShadow">
<y:Geometry height="44.0" width="173.0" x="470.0" y="519.33203125"/> <y:Geometry height="44.0" width="173.0" x="437.5" y="537.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="95.18359375" x="38.908203125" y="12.93359375">PH-Schematron<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.365234375" x="41.8173828125" xml:space="preserve" y="12.6494140625">PH-Schematron<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/> </y:GenericNode>
</y:LabelModel> </data>
<y:ModelParameter> </node>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> <node id="n5::n14">
</y:ModelParameter> <data key="d5"/>
</y:NodeLabel> <data key="d6">
<y:GenericNode configuration="BevelNode3">
<y:Geometry height="44.0" width="152.0" x="15.0" y="234.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="110.72265625" x="20.638671875" xml:space="preserve" y="12.6494140625">Intra-line calculation<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
</graph> </graph>
</node> </node>
<node id="n6" yfiles.foldertype="group"> <node id="n6" yfiles.foldertype="group">
<data key="d4"/> <data key="d4" xml:space="preserve"/>
<data key="d5"/>
<data key="d6"> <data key="d6">
<y:ProxyAutoBoundsNode> <y:ProxyAutoBoundsNode>
<y:Realizers active="0"> <y:Realizers active="0">
<y:GroupNode> <y:GroupNode>
<y:Geometry height="105.666015625" width="184.0" x="1298.0" y="190.666015625"/> <y:Geometry height="106.37646484375" width="182.0" x="1264.5" y="192.37646484375"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="184.0" x="0.0" y="0.0">XRechnung</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="182.0" x="0.0" xml:space="preserve" y="0.0">XRechnung</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="1" leftF="1.0" right="1" rightF="1.0" top="0" topF="0.0"/> <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode> </y:GroupNode>
<y:GroupNode> <y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/> <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/> <y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/> <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 7</y:NodeLabel> <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="22.37646484375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.02685546875" x="-4.513427734375" xml:space="preserve" y="0.0">Folder 7</y:NodeLabel>
<y:Shape type="roundrectangle"/> <y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/> <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/> <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
@@ -599,19 +471,12 @@
</data> </data>
<graph edgedefault="directed" id="n6:"> <graph edgedefault="directed" id="n6:">
<node id="n6::n0"> <node id="n6::n0">
<data key="d5"/>
<data key="d6"> <data key="d6">
<y:GenericNode configuration="BevelNode2"> <y:GenericNode configuration="BevelNode2">
<y:Geometry height="54.0" width="152.0" x="1314.0" y="227.33203125"/> <y:Geometry height="54.0" width="152.0" x="1279.5" y="229.7529296875"/>
<y:Fill color="#FF9900" transparent="false"/> <y:Fill color="#FF9900" transparent="false"/>
<y:BorderStyle hasColor="false" type="line" width="1.0"/> <y:BorderStyle hasColor="false" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="72.7890625" x="39.60546875" y="17.93359375">Schematron<y:LabelModel> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="68.69921875" x="41.650390625" xml:space="preserve" y="17.6494140625">Schematron<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode> </y:GenericNode>
</data> </data>
</node> </node>
@@ -621,8 +486,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0">
<y:Point x="1817.5" y="370.83203125"/> <y:Point x="1781.0" y="389.2529296875"/>
<y:Point x="2042.0" y="370.83203125"/> <y:Point x="2003.5" y="389.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -634,8 +499,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0">
<y:Point x="2448.5" y="306.83203125"/> <y:Point x="2408.0" y="309.2529296875"/>
<y:Point x="2224.0" y="306.83203125"/> <y:Point x="2185.5" y="309.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -647,8 +512,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="10.5" sy="27.0" tx="-57.66666666666667" ty="-22.0"> <y:Path sx="10.5" sy="27.0" tx="-57.66666666666667" ty="-22.0">
<y:Point x="853.75" y="487.83203125"/> <y:Point x="854.0" y="506.2529296875"/>
<y:Point x="904.8333333333334" y="487.83203125"/> <y:Point x="872.3333333333334" y="506.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -660,8 +525,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="-10.5" sy="27.0" tx="43.25" ty="-22.0"> <y:Path sx="-10.5" sy="27.0" tx="43.25" ty="-22.0">
<y:Point x="832.75" y="487.83203125"/> <y:Point x="833.0" y="506.2529296875"/>
<y:Point x="802.75" y="487.83203125"/> <y:Point x="770.25" y="506.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -683,8 +548,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="-43.25" ty="-22.0"> <y:Path sx="0.0" sy="27.0" tx="-43.25" ty="-22.0">
<y:Point x="695.25" y="455.83203125"/> <y:Point x="695.5" y="474.2529296875"/>
<y:Point x="716.25" y="455.83203125"/> <y:Point x="683.75" y="474.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -696,8 +561,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="0.0" ty="-22.0"> <y:Path sx="0.0" sy="27.0" tx="0.0" ty="-22.0">
<y:Point x="1176.0" y="455.83203125"/> <y:Point x="1143.5" y="474.2529296875"/>
<y:Point x="962.5" y="455.83203125"/> <y:Point x="930.0" y="474.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -729,8 +594,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="-57.666666666666686" sy="22.0" tx="0.0" ty="-27.0"> <y:Path sx="-57.666666666666686" sy="22.0" tx="0.0" ty="-27.0">
<y:Point x="295.8333333333333" y="306.83203125"/> <y:Point x="262.3333333333333" y="309.2529296875"/>
<y:Point x="150.5" y="306.83203125"/> <y:Point x="117.0" y="309.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -742,8 +607,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="57.66666666666667" sy="22.0" tx="0.0" ty="-27.0"> <y:Path sx="57.66666666666667" sy="22.0" tx="0.0" ty="-27.0">
<y:Point x="411.1666666666667" y="306.83203125"/> <y:Point x="377.6666666666667" y="325.2529296875"/>
<y:Point x="843.25" y="306.83203125"/> <y:Point x="843.5" y="325.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -754,7 +619,10 @@
<edge id="n5::n9::e0" source="n5::n9::n1" target="n5::n9::n0"> <edge id="n5::n9::e0" source="n5::n9::n1" target="n5::n9::n0">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="0.0" ty="-22.0"/> <y:Path sx="43.25" sy="22.0" tx="0.0" ty="-22.0">
<y:Point x="363.25" y="219.2529296875"/>
<y:Point x="320.0" y="219.2529296875"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/> <y:BendStyle smoothed="false"/>
@@ -764,9 +632,9 @@
<edge id="e2" source="n0" target="n5::n10::n0"> <edge id="e2" source="n0" target="n5::n10::n0">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="-34.25" sy="27.0" tx="0.0" ty="-22.0"> <y:Path sx="34.25" sy="27.0" tx="0.0" ty="-22.0">
<y:Point x="154.625" y="69.5"/> <y:Point x="514.25" y="69.5"/>
<y:Point x="118.5" y="69.5"/> <y:Point x="553.0" y="69.5"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -777,11 +645,9 @@
<edge id="e3" source="n5::n10::n0" target="n4"> <edge id="e3" source="n5::n10::n0" target="n4">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="-70.17857142857144" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="-10.234375" ty="-27.0">
<y:Point x="118.5" y="232.83203125"/> <y:Point x="553.0" y="309.2529296875"/>
<y:Point x="48.5" y="232.83203125"/> <y:Point x="422.0" y="309.2529296875"/>
<y:Point x="48.5" y="625.83203125"/>
<y:Point x="486.32142857142856" y="625.83203125"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/> <y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -792,9 +658,9 @@
<edge id="e4" source="n0" target="n5::n9"> <edge id="e4" source="n0" target="n5::n9">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="34.25" sy="27.0" tx="-94.25" ty="-84.8330078125"> <y:Path sx="-34.25" sy="27.0" tx="87.0" ty="-85.688232421875">
<y:Point x="223.125" y="69.5"/> <y:Point x="445.75" y="69.5"/>
<y:Point x="259.25" y="69.5"/> <y:Point x="407.0" y="69.5"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -805,9 +671,9 @@
<edge id="e5" source="n5::n0" target="n4"> <edge id="e5" source="n5::n0" target="n4">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="23.39285714285714" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="30.703125" ty="-27.0">
<y:Point x="759.5" y="593.83203125"/> <y:Point x="727.0" y="628.2529296875"/>
<y:Point x="579.8928571428571" y="593.83203125"/> <y:Point x="462.9376488095238" y="628.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/> <y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -818,9 +684,9 @@
<edge id="e6" source="n5::n7" target="n4"> <edge id="e6" source="n5::n7" target="n4">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="-23.39285714285714" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="-30.703125" ty="-27.0">
<y:Point x="353.5" y="593.83203125"/> <y:Point x="320.0" y="612.2529296875"/>
<y:Point x="533.1071428571429" y="593.83203125"/> <y:Point x="401.5313988095238" y="612.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/> <y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -831,9 +697,9 @@
<edge id="e7" source="n5::n3" target="n4"> <edge id="e7" source="n5::n3" target="n4">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="-46.785714285714285" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="-51.171875" ty="-27.0">
<y:Point x="150.5" y="609.83203125"/> <y:Point x="117.0" y="628.2529296875"/>
<y:Point x="509.7142857142857" y="609.83203125"/> <y:Point x="381.0626488095238" y="628.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/> <y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -844,9 +710,9 @@
<edge id="e8" source="n5::n8" target="n4"> <edge id="e8" source="n5::n8" target="n4">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="46.78571428571428" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="51.171875" ty="-27.0">
<y:Point x="962.5" y="609.83203125"/> <y:Point x="930.0" y="644.2529296875"/>
<y:Point x="603.2857142857142" y="609.83203125"/> <y:Point x="483.4063988095238" y="644.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/> <y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -858,8 +724,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0">
<y:Point x="1614.5" y="338.83203125"/> <y:Point x="1578.0" y="357.2529296875"/>
<y:Point x="1176.0" y="338.83203125"/> <y:Point x="1143.5" y="357.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -871,8 +737,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="0.0" ty="-27.0"> <y:Path sx="0.0" sy="27.0" tx="0.0" ty="-27.0">
<y:Point x="2042.0" y="354.83203125"/> <y:Point x="2003.5" y="373.2529296875"/>
<y:Point x="695.25" y="354.83203125"/> <y:Point x="695.5" y="373.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -884,8 +750,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="31.5" sy="27.0" tx="-43.25" ty="-22.0"> <y:Path sx="31.5" sy="27.0" tx="-43.25" ty="-22.0">
<y:Point x="874.75" y="471.83203125"/> <y:Point x="875.0" y="490.2529296875"/>
<y:Point x="1122.25" y="471.83203125"/> <y:Point x="1089.75" y="490.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -896,9 +762,9 @@
<edge id="e11" source="n5::n11" target="n4"> <edge id="e11" source="n5::n11" target="n4">
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="70.17857142857142" ty="-27.0"> <y:Path sx="0.0" sy="22.0" tx="71.640625" ty="-27.0">
<y:Point x="1165.5" y="625.83203125"/> <y:Point x="1133.0" y="660.2529296875"/>
<y:Point x="626.6785714285714" y="625.83203125"/> <y:Point x="503.8751488095238" y="660.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -910,8 +776,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="43.25" ty="-22.0"> <y:Path sx="0.0" sy="27.0" tx="43.25" ty="-22.0">
<y:Point x="2224.0" y="503.83203125"/> <y:Point x="2185.5" y="522.2529296875"/>
<y:Point x="1208.75" y="503.83203125"/> <y:Point x="1176.25" y="522.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -923,8 +789,8 @@
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="57.666666666666686" ty="-22.0"> <y:Path sx="0.0" sy="27.0" tx="57.666666666666686" ty="-22.0">
<y:Point x="2042.0" y="487.83203125"/> <y:Point x="2003.5" y="506.2529296875"/>
<y:Point x="1020.1666666666667" y="487.83203125"/> <y:Point x="987.6666666666667" y="506.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -933,13 +799,12 @@
</data> </data>
</edge> </edge>
<edge id="e14" source="n6::n0" target="n5::n12"> <edge id="e14" source="n6::n0" target="n5::n12">
<data key="d8"/> <data key="d8" xml:space="preserve"/>
<data key="d9"/>
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="0.0" ty="-27.0"> <y:Path sx="0.0" sy="27.0" tx="0.0" ty="-27.0">
<y:Point x="1390.0" y="322.83203125"/> <y:Point x="1355.5" y="341.2529296875"/>
<y:Point x="513.25" y="322.83203125"/> <y:Point x="513.5" y="341.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -948,11 +813,13 @@
</data> </data>
</edge> </edge>
<edge id="n5::e10" source="n5::n12" target="n5::n13"> <edge id="n5::e10" source="n5::n12" target="n5::n13">
<data key="d8"/> <data key="d8" xml:space="preserve"/>
<data key="d9"/>
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="27.0" tx="-43.25" ty="-22.0"/> <y:Path sx="0.0" sy="27.0" tx="-43.25" ty="-22.0">
<y:Point x="513.5" y="474.2529296875"/>
<y:Point x="480.75" y="474.2529296875"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/> <y:BendStyle smoothed="false"/>
@@ -960,13 +827,12 @@
</data> </data>
</edge> </edge>
<edge id="n5::e11" source="n5::n1" target="n5::n13"> <edge id="n5::e11" source="n5::n1" target="n5::n13">
<data key="d8"/> <data key="d8" xml:space="preserve"/>
<data key="d9"/>
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="-31.5" sy="27.0" tx="43.25" ty="-22.0"> <y:Path sx="-31.5" sy="27.0" tx="43.25" ty="-22.0">
<y:Point x="811.75" y="471.83203125"/> <y:Point x="812.0" y="490.2529296875"/>
<y:Point x="599.75" y="471.83203125"/> <y:Point x="567.25" y="490.2529296875"/>
</y:Path> </y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
@@ -975,11 +841,43 @@
</data> </data>
</edge> </edge>
<edge id="e15" source="n5::n13" target="n4"> <edge id="e15" source="n5::n13" target="n4">
<data key="d8"/> <data key="d8" xml:space="preserve"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="10.234375" ty="-27.0">
<y:Point x="524.0" y="612.2529296875"/>
<y:Point x="442.4688988095238" y="612.2529296875"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n5::e12" source="n5::n9::n1" target="n5::n14">
<data key="d9"/> <data key="d9"/>
<data key="d10"> <data key="d10">
<y:PolyLineEdge> <y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="0.0" ty="-27.0"/> <y:Path sx="-43.25" sy="22.0" tx="0.0" ty="-22.0">
<y:Point x="276.75" y="219.2529296875"/>
<y:Point x="91.0" y="219.2529296875"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e16" source="n5::n14" target="n4">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="22.0" tx="-71.640625" ty="-27.0">
<y:Point x="91.0" y="294.2529296875"/>
<y:Point x="15.0" y="294.2529296875"/>
<y:Point x="15.0" y="644.2529296875"/>
<y:Point x="360.5938988095238" y="644.2529296875"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/> <y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/> <y:BendStyle smoothed="false"/>

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 608 KiB

View File

@@ -57,12 +57,26 @@ to validate the XML part of the invoices.
![Architecture of the validator](ZUV-Architektur.svg "Graph of the architecture of the validator component") ![Architecture of the validator](ZUV-Architektur.svg "Graph of the architecture of the validator component")
## New build ## Aspects
Apart from the fact that apart from
* the code
* we need tests and apart from implementing it in
Target platform is java 1.17 * the interface
* usually we need functionality in or via the invoice class.
Reading should work for both
* CII and
* UBL
And when writing,
* it should be readable as well, usually in the invoiceimporter,
* and it should be readable and writeable via Jackson (i.e. JSON)
## Build ## Build
Target platform is java 1.17
The package can be build with The package can be build with
``` ```
mvnw clean package mvnw clean package
@@ -184,7 +198,6 @@ maybe not yet even existing new release version:
``` ```
cd validator/target cd validator/target
mvn install:install-file -Dfile=validator-2.17.0-SNAPSHOT-shaded.jar -Dclassifier=shaded -DgroupId="org.mustangproject" -DartifactId=validator -Dversion="2.17.0" -Dpackaging=jar -DgeneratePom=true
``` ```
In gradle you can use something like In gradle you can use something like
``` ```

View File

@@ -3,13 +3,13 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.17.1-SNAPSHOT</version> <version>2.18.1-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.17.1-SNAPSHOT</version> <version>2.18.1-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
@@ -137,6 +137,12 @@
</dependency> </dependency>
<!-- test dependencies --> <!-- test dependencies -->
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>2.0-rc1</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
@@ -173,8 +179,10 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version>
<configuration> <configuration>
<runOrder>alphabetical</runOrder> <runOrder>alphabetical</runOrder>
<argLine>-Duser.timezone=UTC</argLine>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>

View File

@@ -38,7 +38,7 @@ public class Allowance extends Charge {
if(totalAmount != null) { if(totalAmount != null) {
return totalAmount; return totalAmount;
} else if (percent!=null) { } else if (percent!=null) {
BigDecimal singlePrice=currentItem.getValue().divide(BigDecimal.ONE.add(getPercent().divide(new BigDecimal(100))), 18, RoundingMode.HALF_UP); BigDecimal singlePrice=currentItem.getValue().multiply(BigDecimal.ONE.subtract(getPercent().divide(new BigDecimal(100))));
// BigDecimal singlePrice=currentItem.getValue().multiply(BigDecimal.ONE.subtract(getPercent().divide(new BigDecimal(100)))); // BigDecimal singlePrice=currentItem.getValue().multiply(BigDecimal.ONE.subtract(getPercent().divide(new BigDecimal(100))));
BigDecimal singlePriceDiff=currentItem.getValue().subtract(singlePrice); BigDecimal singlePriceDiff=currentItem.getValue().subtract(singlePrice);
return singlePriceDiff; return singlePriceDiff;

View File

@@ -145,10 +145,9 @@ public class Charge implements IZUGFeRDAllowanceCharge {
if(totalAmount != null) { if(totalAmount != null) {
return totalAmount; return totalAmount;
} else if (percent!=null) { } else if (percent!=null) {
BigDecimal singlePrice=currentItem.getValue().divide(BigDecimal.ONE.add(getPercent().divide(new BigDecimal(100))), 18, RoundingMode.HALF_UP); BigDecimal factor=getPercent().divide(new BigDecimal(100), 18, RoundingMode.HALF_UP);
// BigDecimal singlePrice=currentItem.getValue().multiply(BigDecimal.ONE.subtract(getPercent().divide(new BigDecimal(100)))); BigDecimal singlePrice=currentItem.getValue().multiply(factor);
BigDecimal singlePriceDiff=currentItem.getValue().add(singlePrice); return singlePrice;
return singlePriceDiff;
} else { } else {
throw new RuntimeException("percent must be set"); throw new RuntimeException("percent must be set");
} }

View File

@@ -0,0 +1,17 @@
package org.mustangproject.Exceptions;
import java.text.ParseException;
/***
* will be thrown if an invoice cant be reproduced numerically
* ArithmetricException for backwards compatibility, was a spelling error
*/
public class ArithmeticException extends ArithmetricException {
public ArithmeticException() {
super();
}
public ArithmeticException(String details) {
super(details);
}
}

View File

@@ -4,6 +4,7 @@ import java.text.ParseException;
/*** /***
* will be thrown if an invoice cant be reproduced numerically * will be thrown if an invoice cant be reproduced numerically
* (deprecated, because of typo)
*/ */
public class ArithmetricException extends ParseException { public class ArithmetricException extends ParseException {
public ArithmetricException() { public ArithmetricException() {

View File

@@ -591,11 +591,7 @@ public class Invoice implements IExportableTransaction {
* @return fluent setter * @return fluent setter
*/ */
public Invoice setZFAllowances(Allowance[] iza) { public Invoice setZFAllowances(Allowance[] iza) {
Allowances=new ArrayList<>(); Allowances=new ArrayList<>(Arrays.asList(iza));
for (IZUGFeRDAllowanceCharge cz:iza) {
Allowances.add(cz);
}
return this; return this;
} }
@@ -616,9 +612,7 @@ public class Invoice implements IExportableTransaction {
*/ */
public Invoice setZFCharges(Charge[] iza) { public Invoice setZFCharges(Charge[] iza) {
Charges=new ArrayList<>(); Charges=new ArrayList<>();
for (IZUGFeRDAllowanceCharge cz:iza) { Charges.addAll(Arrays.asList(iza));
Charges.add(cz);
}
return this; return this;
} }

View File

@@ -1,5 +1,6 @@
package org.mustangproject; package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IReferencedDocument; import org.mustangproject.ZUGFeRD.IReferencedDocument;
@@ -77,20 +78,21 @@ public class Item implements IZUGFeRDExportableItem {
icnm.getAsString("Name").ifPresent(product::setName); icnm.getAsString("Name").ifPresent(product::setName);
icnm.getAsString("Description").ifPresent(product::setDescription); icnm.getAsString("Description").ifPresent(product::setDescription);
icnm.getAsNodeMap("SellersItemIdentification").ifPresent(SellersItemIdentification -> { icnm.getAsNodeMap("SellersItemIdentification")
SellersItemIdentification.getAsString("ID").ifPresent(product::setSellerAssignedID); .flatMap(SellersItemIdentification -> SellersItemIdentification.getAsString("ID"))
}); .ifPresent(product::setSellerAssignedID);
icnm.getAsNodeMap("BuyersItemIdentification").ifPresent(BuyersItemIdentification -> { icnm.getAsNodeMap("BuyersItemIdentification")
BuyersItemIdentification.getAsString("ID").ifPresent(product::setBuyerAssignedID); .flatMap(BuyersItemIdentification -> BuyersItemIdentification.getAsString("ID"))
}); .ifPresent(product::setBuyerAssignedID);
icnm.getAsNodeMap("ClassifiedTaxCategory").flatMap(m -> m.getAsBigDecimal("Percent")) icnm.getAsNodeMap("ClassifiedTaxCategory")
.flatMap(m -> m.getAsBigDecimal("Percent"))
.ifPresent(product::setVATPercent); .ifPresent(product::setVATPercent);
}); });
itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(icnm -> { itemMap.getAsNodeMap("AssociatedDocumentLineDocument")
icnm.getAsString("LineID").ifPresent(this::setId); .flatMap(icnm -> icnm.getAsString("LineID"))
}); .ifPresent(this::setId);
itemMap.getAsNodeMap("Price").ifPresent(icnm -> { itemMap.getAsNodeMap("Price").ifPresent(icnm -> {
// ubl // ubl
@@ -118,10 +120,16 @@ public class Item implements IZUGFeRDExportableItem {
itemMap.getAsString("ID") itemMap.getAsString("ID")
.ifPresent(this::setId); .ifPresent(this::setId);
itemMap.getAsString("Note") itemMap.getAsString("Note")
.ifPresent(this::addNote); .ifPresent(this::addNote);
if (product==null) { // CII
if (itemMap.getNode("SpecifiedTradeProduct").isPresent()) {
product = new Product(itemMap.getNode("SpecifiedTradeProduct").get());
} else {
product = new Product();
}
}
itemMap.getAsNodeMap("SpecifiedLineTradeAgreement", "SpecifiedSupplyChainTradeAgreement").ifPresent(icnm -> { itemMap.getAsNodeMap("SpecifiedLineTradeAgreement", "SpecifiedSupplyChainTradeAgreement").ifPresent(icnm -> {
icnm.getAsNodeMap("BuyerOrderReferencedDocument") icnm.getAsNodeMap("BuyerOrderReferencedDocument")
@@ -136,14 +144,29 @@ public class Item implements IZUGFeRDExportableItem {
npptpNodes.getAsBigDecimal("ChargeAmount").ifPresent(this::setPrice); npptpNodes.getAsBigDecimal("ChargeAmount").ifPresent(this::setPrice);
npptpNodes.getAsBigDecimal("BasisQuantity").ifPresent(this::setBasisQuantity); npptpNodes.getAsBigDecimal("BasisQuantity").ifPresent(this::setBasisQuantity);
}); });
icnm.getAsNodeMap("GrossPriceProductTradePrice").ifPresent(gpptpNodes -> {
gpptpNodes.getAsNodeMap("AppliedTradeAllowanceCharge").ifPresent(gpptpAtacNodes -> {
/** mustang attributes differences between net and gross price to the product */
String chargeIndicator = gpptpAtacNodes.getAsStringOrNull("ChargeIndicator");
if ((chargeIndicator != null)&&(gpptpAtacNodes.getAsBigDecimal("ActualAmount").isPresent())) {
BigDecimal actual = gpptpAtacNodes.getAsBigDecimal("ActualAmount").get();
if (chargeIndicator.equals("true")) {
product.addCharge(new Charge(actual));
setPrice(getPrice().subtract(actual)); // the gross price affects the net price, which is read,
// so if we do not ignore charges|allowances we have to re-compensate the net price
} else {
product.addAllowance(new Allowance(actual));
setPrice(getPrice().add(actual));
}
}
});
});
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode). icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).
forEach(this::addReferencedDocument); forEach(this::addReferencedDocument);
}); });
itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);//CII
itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);//UBL
// RequestedQuantity is for Order-X, BilledQuantity for FX and ZF // RequestedQuantity is for Order-X, BilledQuantity for FX and ZF
itemMap.getAsNodeMap("SpecifiedLineTradeDelivery", "SpecifiedSupplyChainTradeDelivery") itemMap.getAsNodeMap("SpecifiedLineTradeDelivery", "SpecifiedSupplyChainTradeDelivery")
.flatMap(icnm -> icnm.getNode("BilledQuantity", "RequestedQuantity", "DespatchedQuantity")) .flatMap(icnm -> icnm.getNode("BilledQuantity", "RequestedQuantity", "DespatchedQuantity"))
@@ -180,7 +203,7 @@ public class Item implements IZUGFeRDExportableItem {
} }
if (amountString != null) { if (amountString != null) {
izac.setTotalAmount(new BigDecimal(amountString)); izac.setTotalAmount(new BigDecimal(amountString));
if (percentString!=null&&(percentString!="0")) { if (percentString != null && (!percentString.equals("0"))) {
izac.setTotalAmount(new BigDecimal(amountString).divide(getQuantity())); izac.setTotalAmount(new BigDecimal(amountString).divide(getQuantity()));
} }
} }
@@ -210,16 +233,16 @@ public class Item implements IZUGFeRDExportableItem {
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference); icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference);
icnm.getAsString("ReceivableSpecifiedTradeAccountingAccount").ifPresent(s -> this.accountingReference = s == null ? null : s.trim()); icnm.getAsString("ReceivableSpecifiedTradeAccountingAccount").ifPresent(s -> this.accountingReference = s.trim());
icnm.getAsNodeMap("BillingSpecifiedPeriod").ifPresent(periodNode -> { icnm.getAsNodeMap("BillingSpecifiedPeriod").ifPresent(periodNode -> {
Date start = periodNode.getAsNodeMap("StartDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(dts -> XMLTools.tryDate(dts)).orElse(null); Date start = periodNode.getAsNodeMap("StartDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(XMLTools::tryDate).orElse(null);
Date end = periodNode.getAsNodeMap("EndDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(dts -> XMLTools.tryDate(dts)).orElse(null); Date end = periodNode.getAsNodeMap("EndDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(XMLTools::tryDate).orElse(null);
setDetailedDeliveryPeriod(start, end); setDetailedDeliveryPeriod(start, end);
}); });
}); });
itemMap.getAllNodes("AllowanceCharge").map(NodeMap::new).forEach(stac -> { //UBL itemMap.getAllNodes("AllowanceCharge").map(NodeMap::new).forEach(stac -> { //CII
String isChargeString = stac.getAsString("ChargeIndicator").get(); String isChargeString = stac.getAsString("ChargeIndicator").get();
String percentString = stac.getAsStringOrNull("MultiplierFactorNumeric"); String percentString = stac.getAsStringOrNull("MultiplierFactorNumeric");
@@ -301,12 +324,16 @@ public class Item implements IZUGFeRDExportableItem {
return this; return this;
} }
@Override public IZUGFeRDAllowanceCharge[] getAllowances() { @JsonIgnore
@Override
public IZUGFeRDAllowanceCharge[] getAllowances() { // in JSON is already returned as itemAllowances (and only read from there)
IZUGFeRDAllowanceCharge[] izac = new IZUGFeRDAllowanceCharge[Allowances.size()]; IZUGFeRDAllowanceCharge[] izac = new IZUGFeRDAllowanceCharge[Allowances.size()];
return Allowances.toArray(izac); return Allowances.toArray(izac);
} }
@Override public IZUGFeRDAllowanceCharge[] getCharges() { @JsonIgnore
@Override
public IZUGFeRDAllowanceCharge[] getCharges() { // in JSON is already returned as itemAllowances (and only read from there)
IZUGFeRDAllowanceCharge[] izac = new IZUGFeRDAllowanceCharge[Charges.size()]; IZUGFeRDAllowanceCharge[] izac = new IZUGFeRDAllowanceCharge[Charges.size()];
return Charges.toArray(izac); return Charges.toArray(izac);
} }
@@ -425,9 +452,7 @@ public class Item implements IZUGFeRDExportableItem {
public void setItemAllowances(ArrayList<Allowance> theAllowances) { public void setItemAllowances(ArrayList<Allowance> theAllowances) {
if (theAllowances != null) { if (theAllowances != null) {
Allowances.clear(); Allowances.clear();
for (Allowance theAllowance : theAllowances) { Allowances.addAll(theAllowances);
Allowances.add(theAllowance);
}
} }
} }
@@ -437,9 +462,7 @@ public class Item implements IZUGFeRDExportableItem {
public void setItemCharges(ArrayList<Charge> theCharges) { public void setItemCharges(ArrayList<Charge> theCharges) {
if (theCharges != null) { if (theCharges != null) {
Charges.clear(); Charges.clear();
for (Charge theCharge : theCharges) { Charges.addAll(theCharges);
Charges.add(theCharge);
}
} }
} }

View File

@@ -1,13 +1,10 @@
package org.mustangproject; package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonSetter;
import org.mustangproject.ZUGFeRD.IDesignatedProductClassification; import org.mustangproject.ZUGFeRD.IDesignatedProductClassification;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct;
import org.mustangproject.util.NodeMap; import org.mustangproject.util.NodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
@@ -107,7 +104,10 @@ public class Product implements IZUGFeRDExportableProduct {
classifications.add(new DesignatedProductClassification(classCode, className))); classifications.add(new DesignatedProductClassification(classCode, className)));
}); });
nodeMap.getAsString("OriginTradeCounty").ifPresent(this::setCountryOfOrigin); nodeMap.getAsNodeMap("OriginTradeCountry")
.flatMap(nodes -> nodes.getNode("ID"))
.map(Node::getTextContent)
.ifPresent(this::setCountryOfOrigin);
} }
/*** /***
@@ -406,6 +406,16 @@ public class Product implements IZUGFeRDExportableProduct {
return this; return this;
} }
/***
* Jackson courtesy function, please use addCharge if you have the choice
* @return array of or null, if none
*/
public Product setCharges(ArrayList<Charge> charges) {
this.charges=charges;
return this;
}
/*** /***
* returns the AppliedTradeAllowanceCharges of this product which are actually Charges * returns the AppliedTradeAllowanceCharges of this product which are actually Charges
* @return array of or null, if none * @return array of or null, if none
@@ -432,5 +442,13 @@ public class Product implements IZUGFeRDExportableProduct {
return allowances.toArray(allowanceArr); return allowances.toArray(allowanceArr);
} }
/***
* Jackson courtesy function, please use addAllowance if you have the choice
* @return array of or null, if none
*/
public Product setAllowances(ArrayList<Allowance> allowances) {
this.allowances=allowances;
return this;
}
} }

View File

@@ -541,6 +541,32 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
return this; return this;
} }
/***
* for jackson, primarily, use addGlobalID(SchemedID) instead
* @param ID the id part without scheme
* @return fluent setter
*/
public TradeParty setGlobalID(String ID) {
if (globalId==null) {
globalId=new SchemedID();
}
globalId.setId(ID);
return this;
}
/***
* for jackson, primarily, use addGlobalID(SchemedID) instead
* @param scheme the scheme part without id
* @return fluent setter
*/
public TradeParty setGlobalIDScheme(String scheme) {
if (globalId==null) {
globalId=new SchemedID();
}
globalId.setScheme(scheme);
return this;
}
public TradeParty addGlobalID(SchemedID schemedID) { public TradeParty addGlobalID(SchemedID schemedID) {
globalId = schemedID; globalId = schemedID;
return this; return this;
@@ -746,7 +772,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
if (bankDetails.isEmpty() && debitDetails.isEmpty()) { if (bankDetails.isEmpty() && debitDetails.isEmpty()) {
return null; return null;
} }
List<IZUGFeRDTradeSettlement> tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()).map(IZUGFeRDTradeSettlement.class::cast).collect(Collectors.toList()); List<IZUGFeRDTradeSettlement> tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()).collect(Collectors.toList());
IZUGFeRDTradeSettlement[] result = new IZUGFeRDTradeSettlement[tradeSettlements.size()]; IZUGFeRDTradeSettlement[] result = new IZUGFeRDTradeSettlement[tradeSettlements.size()];
for (int i = 0; i < tradeSettlements.size(); i++) { for (int i = 0; i < tradeSettlements.size(); i++) {

View File

@@ -97,12 +97,12 @@ public class DAPullProvider extends ZUGFeRD2PullProvider {
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>"; + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>";
} }
String allowanceChargeStr = ""; String allowanceChargeStr = "";
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { if (currentItem.getItemAllowances() != null) {
for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
} }
} }
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { if (currentItem.getItemCharges() != null) {
for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);

View File

@@ -22,7 +22,7 @@ public class LineCalculator {
public LineCalculator(IZUGFeRDExportableItem currentItem) { public LineCalculator(IZUGFeRDExportableItem currentItem) {
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { if (currentItem.getItemAllowances() != null) {
for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
BigDecimal factor=BigDecimal.ONE; BigDecimal factor=BigDecimal.ONE;
BigDecimal singleAllowance=allowance.getTotalAmount(currentItem); BigDecimal singleAllowance=allowance.getTotalAmount(currentItem);
@@ -35,7 +35,7 @@ public class LineCalculator {
} }
} }
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { if (currentItem.getItemCharges() != null) {
for (IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { for (IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
BigDecimal factor=BigDecimal.ONE; BigDecimal factor=BigDecimal.ONE;
BigDecimal singleCharge=charge.getTotalAmount(currentItem); BigDecimal singleCharge=charge.getTotalAmount(currentItem);
@@ -47,7 +47,7 @@ public class LineCalculator {
} }
} }
if (currentItem.getItemTotalAllowances() != null && currentItem.getItemTotalAllowances().length > 0) { if (currentItem.getItemTotalAllowances() != null) {
for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) { for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) {
addAllowanceItemTotal(itemTotalAllowance.getTotalAmount(currentItem)); addAllowanceItemTotal(itemTotalAllowance.getTotalAmount(currentItem));
} }
@@ -94,7 +94,7 @@ public class LineCalculator {
? BigDecimal.ONE.setScale(4) ? BigDecimal.ONE.setScale(4)
: currentItem.getBasisQuantity(); : currentItem.getBasisQuantity();
itemTotalNetAmount = quantity.multiply(price).divide(basisQuantity, 18, RoundingMode.HALF_UP) itemTotalNetAmount = quantity.multiply(price).divide(basisQuantity, 18, RoundingMode.HALF_UP)
.add(lineCharge).subtract(lineAllowance).subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP); .add(lineCharge).subtract(lineAllowance).subtract(allowanceItemTotal.setScale(2, RoundingMode.HALF_UP)).setScale(2, RoundingMode.HALF_UP);
itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator);//.setScale(2, RoundingMode.HALF_UP); itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator);//.setScale(2, RoundingMode.HALF_UP);
} }

View File

@@ -57,7 +57,7 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription()); paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription());
} }
if ((paymentTermsDescription == null) && (trans.getDocumentCode() != CORRECTEDINVOICE)/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) { if (paymentTermsDescription == null && !CORRECTEDINVOICE.equals(trans.getDocumentCode())/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) {
paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate());
} }
@@ -125,12 +125,12 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>"; + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>";
} }
String allowanceChargeStr = ""; String allowanceChargeStr = "";
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { if (currentItem.getItemAllowances() != null) {
for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
} }
} }
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { if (currentItem.getItemCharges() != null) {
for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);
@@ -313,6 +313,7 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) {
if (payment != null) { if (payment != null) {
hasDueDate = true; hasDueDate = true;
break;
// xml += payment.getSettlementXML(); // xml += payment.getSettlementXML();
} }
} }

View File

@@ -89,7 +89,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
private BigDecimal sumAllowanceCharge(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) { private BigDecimal sumAllowanceCharge(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) {
BigDecimal res = BigDecimal.ZERO; BigDecimal res = BigDecimal.ZERO;
if ((charges != null) && (charges.length > 0)) { if (charges != null) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) { for (IZUGFeRDAllowanceCharge currentCharge : charges) {
if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0)) { if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0)) {
res = res.add(currentCharge.getTotalAmount(this)); res = res.add(currentCharge.getTotalAmount(this));
@@ -172,6 +172,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
* @return item sum +- charges/allowances * @return item sum +- charges/allowances
*/ */
public BigDecimal getTaxBasis() { public BigDecimal getTaxBasis() {
BigDecimal debug_1=getTotal();
return getTotal().add(getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP)) return getTotal().add(getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP))
.subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP)) .subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP))
.setScale(2, RoundingMode.HALF_UP); .setScale(2, RoundingMode.HALF_UP);
@@ -211,7 +212,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
} }
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) { if (charges != null) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) { for (IZUGFeRDAllowanceCharge currentCharge : charges) {
BigDecimal taxPercent = currentCharge.getTaxPercent(); BigDecimal taxPercent = currentCharge.getTaxPercent();
if (taxPercent != null) { if (taxPercent != null) {
@@ -229,7 +230,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
} }
} }
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) { if (allowances != null) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) { for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
BigDecimal taxPercent = currentAllowance.getTaxPercent(); BigDecimal taxPercent = currentAllowance.getTaxPercent();
if (taxPercent != null) { if (taxPercent != null) {
@@ -285,8 +286,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
} }
final IZUGFeRDAllowanceCharge[] charges = this.trans.getZFCharges(); final IZUGFeRDAllowanceCharge[] charges = this.trans.getZFCharges();
if (charges != null && charges.length > 0) if (charges != null) {
{
for (final IZUGFeRDAllowanceCharge currentCharge : charges) for (final IZUGFeRDAllowanceCharge currentCharge : charges)
{ {
final BigDecimal taxPercent = currentCharge.getTaxPercent(); final BigDecimal taxPercent = currentCharge.getTaxPercent();
@@ -309,8 +309,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
} }
} }
final IZUGFeRDAllowanceCharge[] allowances = this.trans.getZFAllowances(); final IZUGFeRDAllowanceCharge[] allowances = this.trans.getZFAllowances();
if (allowances != null && allowances.length > 0) if (allowances != null) {
{
for (final IZUGFeRDAllowanceCharge currentAllowance : allowances) for (final IZUGFeRDAllowanceCharge currentAllowance : allowances)
{ {
final BigDecimal taxPercent = currentAllowance.getTaxPercent(); final BigDecimal taxPercent = currentAllowance.getTaxPercent();

View File

@@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.ParseException;
import org.mustangproject.XMLTools; import org.mustangproject.XMLTools;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -18,7 +19,7 @@ public class XRechnungImporter extends ZUGFeRDImporter {
try { try {
setRawXML(rawXml); setRawXML(rawXml);
containsMeta = true; containsMeta = true;
} catch (final IOException e) { } catch (final IOException | ParseException e) {
LOGGER.error ("Failed to set raw XML", e); LOGGER.error ("Failed to set raw XML", e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
@@ -30,7 +31,7 @@ public class XRechnungImporter extends ZUGFeRDImporter {
try { try {
setRawXML(Files.readAllBytes(Paths.get(filename))); setRawXML(Files.readAllBytes(Paths.get(filename)));
containsMeta = true; containsMeta = true;
} catch (final IOException e) { } catch (final IOException | ParseException e) {
LOGGER.error ("Failed to set raw XML", e); LOGGER.error ("Failed to set raw XML", e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
@@ -38,16 +39,13 @@ public class XRechnungImporter extends ZUGFeRDImporter {
} }
public XRechnungImporter(InputStream fileinput) { public XRechnungImporter(InputStream fileinput) {
super(); super();
try { try {
setRawXML(XMLTools.getBytesFromStream(fileinput)); setRawXML(XMLTools.getBytesFromStream(fileinput));
containsMeta = true; containsMeta = true;
} catch (final IOException e) { } catch (final IOException | ParseException e) {
LOGGER.error ("Failed to set raw XML", e); LOGGER.error ("Failed to set raw XML", e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
} }

View File

@@ -359,7 +359,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
paymentTermsDescription += discount.getAsXRechnung(); paymentTermsDescription += discount.getAsXRechnung();
} }
} else if ((paymentTermsDescription == null) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CORRECTEDINVOICE) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)) { } else if (paymentTermsDescription == null
&& !DocumentCodeTypeConstants.CORRECTEDINVOICE.equals(trans.getDocumentCode())
&& !DocumentCodeTypeConstants.CREDITNOTE.equals(trans.getDocumentCode())
) {
if (trans.getDueDate() != null) { if (trans.getDueDate() != null) {
paymentTermsDescription = "Please remit until " + germanDateFormat.format(trans.getDueDate()); paymentTermsDescription = "Please remit until " + germanDateFormat.format(trans.getDueDate());
} }
@@ -434,11 +437,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
xml += "<ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>"; xml += "<ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>";
if (currentItem.getProduct().getDescription() != null && currentItem.getProduct().getDescription().length() > 0) { if (currentItem.getProduct().getDescription() != null) {
xml += "<ram:Description>" + xml += "<ram:Description>" +
XMLTools.encodeXML(currentItem.getProduct().getDescription()) + XMLTools.encodeXML(currentItem.getProduct().getDescription()) +
"</ram:Description>"; "</ram:Description>";
} }
if (currentItem.getProduct().getAttributes() != null) { if (currentItem.getProduct().getAttributes() != null) {
for (Entry<String, String> entry : currentItem.getProduct().getAttributes().entrySet()) { for (Entry<String, String> entry : currentItem.getProduct().getAttributes().entrySet()) {
xml += "<ram:ApplicableProductCharacteristic>" + xml += "<ram:ApplicableProductCharacteristic>" +
@@ -447,7 +451,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
"</ram:ApplicableProductCharacteristic>"; "</ram:ApplicableProductCharacteristic>";
} }
} }
if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) { if (currentItem.getProduct().getClassifications() != null) {
for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) { for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) {
xml += "<ram:DesignatedProductClassification>" xml += "<ram:DesignatedProductClassification>"
+ "<ram:ClassCode listID=\"" + XMLTools.encodeXML(classification.getClassCode().getListID()) + "\""; + "<ram:ClassCode listID=\"" + XMLTools.encodeXML(classification.getClassCode().getListID()) + "\"";
@@ -702,7 +706,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
} }
} }
if ((trans.getDocumentCode() == DocumentCodeTypeConstants.CORRECTEDINVOICE) || (trans.getDocumentCode() == DocumentCodeTypeConstants.CREDITNOTE)) { if (DocumentCodeTypeConstants.CORRECTEDINVOICE.equals(trans.getDocumentCode())
|| DocumentCodeTypeConstants.CREDITNOTE.equals(trans.getDocumentCode())
) {
hasDueDate = false; hasDueDate = false;
} }
@@ -857,7 +863,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} else { } else {
xml += buildPaymentTermsXml(); xml += buildPaymentTermsXml();
} }
if ((profile == Profiles.getByName("Extended")) && (trans.getCashDiscounts() != null) && (trans.getCashDiscounts().length > 0)) { if (profile == Profiles.getByName("Extended") && trans.getCashDiscounts() != null) {
for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts() for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts()
) { ) {
xml += discount.getAsCII(); xml += discount.getAsCII();

View File

@@ -564,10 +564,9 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
// iterate over all pdf pages // iterate over all pdf pages
for (Object object : doc.getPages()) { for (PDPage page : doc.getPages()) {
if (object instanceof PDPage) { if (page != null) {
PDPage page = (PDPage) object;
PDResources res = page.getResources(); PDResources res = page.getResources();
// Check for fonts in PDXObjects: // Check for fonts in PDXObjects:

View File

@@ -14,6 +14,7 @@ package org.mustangproject.ZUGFeRD;
* @author jstaerk * @author jstaerk
*/ */
import java.io.*; import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
@@ -351,6 +352,16 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
public String getHolder() { public String getHolder() {
if (importedInvoice!=null && importedInvoice.getTradeSettlement()!=null) {
for (IZUGFeRDTradeSettlement settlement : importedInvoice.getTradeSettlement()) {
if (settlement instanceof IZUGFeRDTradeSettlementPayment) {
String s = ((IZUGFeRDTradeSettlementPayment) settlement).getAccountName();
if ( s != null ) {
return s;
}
}
}
}
return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']"); return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']");
} }
@@ -452,7 +463,11 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
* @throws IOException if raw can not be set * @throws IOException if raw can not be set
*/ */
public void setMeta(String meta) throws IOException { public void setMeta(String meta) throws IOException {
try {
setRawXML(meta.getBytes()); setRawXML(meta.getBytes());
} catch (ParseException e) {
LOGGER.error("Failed to parse", e);
}
} }

View File

@@ -10,7 +10,6 @@ import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.mustangproject.*; import org.mustangproject.*;
import org.mustangproject.Exceptions.ArithmetricException;
import org.mustangproject.Exceptions.StructureException; import org.mustangproject.Exceptions.StructureException;
import org.mustangproject.util.NodeMap; import org.mustangproject.util.NodeMap;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -127,8 +126,7 @@ public class ZUGFeRDInvoiceImporter {
if (Arrays.equals(pad, pdfSignature)) { // we have a pdf if (Arrays.equals(pad, pdfSignature)) { // we have a pdf
try { try(PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream))) {
PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream));
// PDDocumentInformation info = doc.getDocumentInformation(); // PDDocumentInformation info = doc.getDocumentInformation();
final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
//start //start
@@ -174,7 +172,12 @@ public class ZUGFeRDInvoiceImporter {
} else { } else {
// no PDF probably XML // no PDF probably XML
containsMeta = true; containsMeta = true;
try {
setRawXML(XMLTools.getBytesFromStream(pdfStream)); setRawXML(XMLTools.getBytesFromStream(pdfStream));
} catch(ParseException e) {
LOGGER.error("Failed to parse PDF", e);
}
} }
} }
@@ -209,7 +212,16 @@ public class ZUGFeRDInvoiceImporter {
*/ */
final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) { Set<String> validFilenames = Set.of(
"ZUGFeRD-invoice.xml",
"zugferd-invoice.xml",
"factur-x.xml",
"xrechnung.xml",
"order-x.xml",
"cida.xml"
);
if (validFilenames.contains(filename)) {
containsMeta = true; containsMeta = true;
// String embeddedFilename = filePath + filename; // String embeddedFilename = filePath + filename;
@@ -219,8 +231,11 @@ public class ZUGFeRDInvoiceImporter {
// ByteArrayOutputStream(); // ByteArrayOutputStream();
// FileOutputStream fos = new FileOutputStream(file); // FileOutputStream fos = new FileOutputStream(file);
try {
setRawXML(embeddedFile.toByteArray()); setRawXML(embeddedFile.toByteArray());
} catch (ParseException e) {
LOGGER.error("Failed to parse XML", e);
}
// fos.write(embeddedFile.getByteArray()); // fos.write(embeddedFile.getByteArray());
// fos.close(); // fos.close();
} }
@@ -237,7 +252,7 @@ public class ZUGFeRDInvoiceImporter {
* @param doParse automatically parse input for zugferdImporter (not ZUGFeRDInvoiceImporter) * @param doParse automatically parse input for zugferdImporter (not ZUGFeRDInvoiceImporter)
* @throws IOException if parsing xml throws it (unlikely its string based) * @throws IOException if parsing xml throws it (unlikely its string based)
*/ */
public void setRawXML(byte[] rawXML, boolean doParse) throws IOException { public void setRawXML(byte[] rawXML, boolean doParse) throws IOException, ParseException {
this.containsMeta = true; this.containsMeta = true;
this.rawXML = rawXML; this.rawXML = rawXML;
this.version = null; this.version = null;
@@ -245,7 +260,7 @@ public class ZUGFeRDInvoiceImporter {
try { try {
setDocument(); setDocument();
} catch (ParserConfigurationException | SAXException | ParseException e) { } catch (ParserConfigurationException | SAXException e) {
LOGGER.error("Failed to parse XML", e); LOGGER.error("Failed to parse XML", e);
throw new ZUGFeRDExportException(e); throw new ZUGFeRDExportException(e);
} }
@@ -257,7 +272,7 @@ public class ZUGFeRDInvoiceImporter {
* @param rawXML the cii(?) as a string * @param rawXML the cii(?) as a string
* @throws IOException if parsing xml throws it (unlikely its string based) * @throws IOException if parsing xml throws it (unlikely its string based)
*/ */
public void setRawXML(byte[] rawXML) throws IOException { public void setRawXML(byte[] rawXML) throws IOException, ParseException {
setRawXML(rawXML, true); setRawXML(rawXML, true);
} }
@@ -353,39 +368,31 @@ public class ZUGFeRDInvoiceImporter {
delivery.addGlobalID(sID); delivery.addGlobalID(sID);
} }
}); });
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { Optional<NodeMap> addressNodeMapp = deliveryLocationNodeMap.getAsNodeMap("Address");
s.getAsString("StreetName").ifPresent(t -> delivery.setStreet(t)); addressNodeMapp.flatMap(s -> s.getAsString("StreetName"))
}); .ifPresent(delivery::setStreet);
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { addressNodeMapp.flatMap(s -> s.getAsString("AdditionalStreetName"))
s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t)); .ifPresent(delivery::setAdditionalAddress);
}); addressNodeMapp.flatMap(s -> s.getAsString("CityName"))
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { .ifPresent(delivery::setLocation);
s.getAsString("CityName").ifPresent(t -> delivery.setLocation(t)); addressNodeMapp.flatMap(s -> s.getAsString("PostalZone"))
}); .ifPresent(delivery::setZIP);
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { addressNodeMapp.flatMap(s -> s.getAsNodeMap("Country")).flatMap(t -> t.getAsString("IdentificationCode"))
s.getAsString("PostalZone").ifPresent(t -> delivery.setZIP(t)); .ifPresent(delivery::setCountry);
}); addressNodeMapp.flatMap(s -> s.getAsNodeMap("AddressLine")).flatMap(t -> t.getAsString("Line"))
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { .ifPresent(delivery::setAdditionalAddressExtension);
s.getAsNodeMap("Country").ifPresent(t -> t.getAsString("IdentificationCode").ifPresent(u -> delivery.setCountry(u))); addressNodeMapp.flatMap(s -> s.getAsString("AdditionalStreetName"))
}); .ifPresent(delivery::setAdditionalAddress);
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { addressNodeMapp.flatMap(s -> s.getAsString("AdditionalStreetName"))
s.getAsNodeMap("AddressLine").ifPresent(t -> t.getAsString("Line").ifPresent(u -> delivery.setAdditionalAddressExtension(u))); .ifPresent(delivery::setAdditionalAddress);
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t));
});
}); });
new NodeMap(deliveryNode).getAsNodeMap("DeliveryParty").ifPresent(partyMap -> { new NodeMap(deliveryNode).getAsNodeMap("DeliveryParty")
partyMap.getAsNodeMap("PartyName").ifPresent(s -> { .flatMap(partyMap -> partyMap.getAsNodeMap("PartyName"))
s.getAsString("Name").ifPresent(t -> delivery.setName(t)); .flatMap(s -> s.getAsString("Name"))
}); .ifPresent(delivery::setName);
});
String street, name, additionalStreet, city, postal, countrySubentity, line, country = null;
zpp.setDeliveryAddress(delivery); zpp.setDeliveryAddress(delivery);
} }
@@ -572,11 +579,11 @@ public class ZUGFeRDInvoiceImporter {
} }
String creditorReferenceID = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"CreditorReferenceID\"]").trim();//BT-90 String creditorReferenceID = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"CreditorReferenceID\"]").trim();//BT-90
if ((creditorReferenceID == null)||(creditorReferenceID.length()==0)) { if (creditorReferenceID == null || creditorReferenceID.isEmpty()) {
//maybe it's there in UBL? //maybe it's there in UBL?
creditorReferenceID = extractString("//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyIdentification\"]/*[local-name()=\"ID\"]").trim(); creditorReferenceID = extractString("//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyIdentification\"]/*[local-name()=\"ID\"]").trim();
} }
if ((creditorReferenceID != null)&&(creditorReferenceID.length()>0)) { if (creditorReferenceID != null && !creditorReferenceID.isEmpty()) {
zpp.setCreditorReferenceID(creditorReferenceID); zpp.setCreditorReferenceID(creditorReferenceID);
} }
@@ -1088,7 +1095,7 @@ public class ZUGFeRDInvoiceImporter {
.collect(Collectors.joining(" + ")); .collect(Collectors.joining(" + "));
} catch (Exception ignored) { } catch (Exception ignored) {
} }
throw new ArithmetricException("Payable total in XML is " + payableTotalFromXml + ", but calculated total is " + calculatedPayableTotal + moreDetails); throw new ArithmeticException("Payable total in XML is " + payableTotalFromXml + ", but calculated total is " + calculatedPayableTotal + moreDetails);
} }
} }
} }
@@ -1205,7 +1212,7 @@ public class ZUGFeRDInvoiceImporter {
* sets the XML for the importer to parse * sets the XML for the importer to parse
* @param XML the UBL or CII * @param XML the UBL or CII
*/ */
public void fromXML(String XML) { public void fromXML(String XML) throws ParseException{
try { try {
containsMeta = true; containsMeta = true;
setRawXML(XML.getBytes(StandardCharsets.UTF_8)); setRawXML(XML.getBytes(StandardCharsets.UTF_8));

View File

@@ -12,12 +12,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import java.io.File; import java.io.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date;
/*** /***
* tests the linecalculator and transactioncalculator classes * tests the linecalculator and transactioncalculator classes
@@ -79,6 +78,56 @@ public class CalculationTest extends ResourceCase {
assertEquals(valueOf(287.9408).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); assertEquals(valueOf(287.9408).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros());
} }
@Test
public void testAllowanceAndChargeEx4() {
/** numbers from en16931 example 4 */
SimpleDateFormat sqlDate = new SimpleDateFormat("yyyy-MM-dd");
Invoice invoice = new Invoice();
invoice.setDocumentName("Rechnung");
invoice.setNumber("777777");
try {
invoice.setIssueDate(sqlDate.parse("2020-12-31"));
} catch (Exception e) {
LOGGER.error("Failed to set dates", e);
}
/* trade party (sender) */
TradeParty sender = new TradeParty("Maier GmbH", "Musterweg 5", "11111", "Testung", "DE");
sender.addVATID("DE2222222222");
invoice.setSender(sender);
/* trade party (recipient) */
TradeParty recipient = new TradeParty("Teston GmbH" + " " + "Zentrale" + " " + "", "Testweg 5", "11111", "Testung", "DE");
invoice.setRecipient(recipient);
/* item */
Product product;
Item item;
product = new Product("Pens", "", "H87", new BigDecimal(25));
product.addAllowance(new Allowance(new BigDecimal(1)));
item = new Item(product, new BigDecimal("9.50"), new BigDecimal(25));
item.addCharge(new Charge(new BigDecimal(10)).setReasonCode("ZZZ").setReason("Zuschlag"));
LineCalculator lc = new LineCalculator(item);
assertEquals(new BigDecimal("222.50"), lc.getItemTotalNetAmount());
invoice.addItem(item);
product = new Product("Paper", "", "H87", new BigDecimal(25));
item = new Item(product, new BigDecimal("4.50"), new BigDecimal(15));
item.addAllowance(new Allowance().setPercent(new BigDecimal(5)).setReasonCode("ZZZ").setReason("Zuschlag"));
lc = new LineCalculator(item);
assertEquals(new BigDecimal("64.12"), lc.getItemTotalNetAmount());
invoice.addItem(item);
invoice.addAllowance(new Allowance().setPercent(new BigDecimal(10)).setTaxPercent(new BigDecimal(25)).setReasonCode("ZZZ").setReason("Mengenrabatt"));
invoice.addCharge(new Charge(new BigDecimal(15)).setReasonCode("ZZZ").setReason("Frachtkosten"));
TransactionCalculator calculator = new TransactionCalculator(invoice);
assertEquals(valueOf(286.62).stripTrailingZeros(), calculator.getTotal());// interestingly, EN16931-1 has 286.63 here?
assertEquals(valueOf(272.96).stripTrailingZeros(), calculator.getTaxBasis()); // and 272.97 here
assertEquals(valueOf(337.45).stripTrailingZeros(), calculator.getDuePayable()); // and 337.46 here???
}
@Test @Test
public void testLineCalculatorForeignCurrencyExample() { public void testLineCalculatorForeignCurrencyExample() {
/*** xml of official fx sample with allowances and charges /*** xml of official fx sample with allowances and charges
@@ -152,7 +201,7 @@ public class CalculationTest extends ResourceCase {
Product product; Product product;
Item item; Item item;
product = new Product("AAA", "", "H84", sales_tax_percent1).setSellerAssignedID("1AAA"); product = new Product("AAA", "", "H87", sales_tax_percent1).setSellerAssignedID("1AAA");
item = new Item(product, new BigDecimal("4.750"), new BigDecimal(5.00)); item = new Item(product, new BigDecimal("4.750"), new BigDecimal(5.00));
// set values for additional charge and discount used for next lines // set values for additional charge and discount used for next lines
@@ -168,54 +217,23 @@ public class CalculationTest extends ResourceCase {
} }
invoice.addItem(item); invoice.addItem(item);
// reset values for additional charge and discount used for next lines
item_increase = BigDecimal.ZERO;
item_discount = BigDecimal.ZERO;
product = new Product("BBB", "", "H84", sales_tax_percent1).setSellerAssignedID("2BBB"); product = new Product("BBB", "", "H87", sales_tax_percent1).setSellerAssignedID("2BBB");
item = new Item(product, new BigDecimal("5.750"), new BigDecimal(4.00)); item = new Item(product, new BigDecimal("5.750"), new BigDecimal(4.00));
if (item_increase.compareTo(BigDecimal.ZERO) > 0) {
item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag"));
}
if (item_discount.compareTo(BigDecimal.ZERO) > 0) {
item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt"));
}
invoice.addItem(item); invoice.addItem(item);
product = new Product("CCC", "", "H84", sales_tax_percent1).setSellerAssignedID("3CCC"); product = new Product("CCC", "", "H87", sales_tax_percent1).setSellerAssignedID("3CCC");
item = new Item(product, new BigDecimal("6.750"), new BigDecimal(3.00)); item = new Item(product, new BigDecimal("6.750"), new BigDecimal(3.00));
if (item_increase.compareTo(BigDecimal.ZERO) > 0) {
item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag"));
}
if (item_discount.compareTo(BigDecimal.ZERO) > 0) {
item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt"));
}
invoice.addItem(item); invoice.addItem(item);
product = new Product("DDD", "", "H84", sales_tax_percent1).setSellerAssignedID("4DDD"); product = new Product("DDD", "", "H87", sales_tax_percent1).setSellerAssignedID("4DDD");
item = new Item(product, new BigDecimal("7.750"), new BigDecimal(2.00)); item = new Item(product, new BigDecimal("7.750"), new BigDecimal(2.00));
if (item_increase.compareTo(BigDecimal.ZERO) > 0) {
item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag"));
}
if (item_discount.compareTo(BigDecimal.ZERO) > 0) {
item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt"));
}
invoice.addItem(item); invoice.addItem(item);
product = new Product("EEE", "", "H84", sales_tax_percent1).setSellerAssignedID("5EEE"); product = new Product("EEE", "", "H87", sales_tax_percent1).setSellerAssignedID("5EEE");
item = new Item(product, new BigDecimal("8.750"), new BigDecimal(1.00)); item = new Item(product, new BigDecimal("8.750"), new BigDecimal(1.00));
if (item_increase.compareTo(BigDecimal.ZERO) > 0) {
item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag"));
}
if (item_discount.compareTo(BigDecimal.ZERO) > 0) {
item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt"));
}
invoice.addItem(item); invoice.addItem(item);
// reset values for additional charge and discount used on invoice level
item_increase = BigDecimal.valueOf(3.50);
item_discount = BigDecimal.valueOf(10.00);
if (total_increase_percent.compareTo(BigDecimal.ZERO) > 0) { if (total_increase_percent.compareTo(BigDecimal.ZERO) > 0) {
invoice.addCharge(new Charge().setPercent(total_increase_percent).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschläge")); invoice.addCharge(new Charge().setPercent(total_increase_percent).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschläge"));
@@ -224,7 +242,7 @@ public class CalculationTest extends ResourceCase {
invoice.addAllowance(new Allowance().setPercent(total_discount_percent).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatte")); invoice.addAllowance(new Allowance().setPercent(total_discount_percent).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatte"));
} }
TransactionCalculator calculator = new TransactionCalculator(invoice); TransactionCalculator calculator = new TransactionCalculator(invoice);
assertEquals(valueOf(307.18).stripTrailingZeros(), calculator.getGrandTotal().stripTrailingZeros()); assertEquals(valueOf(101.85).stripTrailingZeros(), calculator.getGrandTotal().stripTrailingZeros());
} }
public void testSimpleItemPercentAllowance() { public void testSimpleItemPercentAllowance() {
@@ -259,14 +277,64 @@ public class CalculationTest extends ResourceCase {
Product product; Product product;
Item item; Item item;
product = new Product("AAA", "", "H84", BigDecimal.ZERO); product = new Product("AAA", "", "H87", BigDecimal.ZERO);
item = new Item(product, new BigDecimal("1.10"), new BigDecimal(5.00)); item = new Item(product, new BigDecimal("1.10"), new BigDecimal(5.00));
item.addAllowance(new Allowance().setPercent(new BigDecimal(10)).setTaxPercent(BigDecimal.ZERO)); item.addAllowance(new Allowance().setPercent(new BigDecimal(10)).setTaxPercent(BigDecimal.ZERO));
invoice.addItem(item); invoice.addItem(item);
TransactionCalculator calculator = new TransactionCalculator(invoice); TransactionCalculator calculator = new TransactionCalculator(invoice);
assertEquals(new BigDecimal(5), calculator.getGrandTotal().stripTrailingZeros()); assertEquals(new BigDecimal("4.95"), calculator.getGrandTotal().stripTrailingZeros());
}
public void testSimpleDocumentPercentCharge() {
String orgname = "Test company";
String number = "123";
String priceStr = "3.00";
BigDecimal price = new BigDecimal(priceStr);
// similar, but slightly less complicated to whats later testted in testRelativeChargesAllowancesExport
Invoice i = new Invoice().setCurrency("CHF").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
.setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"));
// 9+50%=>13,50 expected net
// .addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReason("Mengenrabatt"))
TransactionCalculator tc = new TransactionCalculator(i);
assertEquals(new BigDecimal("13.50"), tc.getTaxBasis());
assertEquals(new BigDecimal("16.07"), tc.getDuePayable());
}
public void testSimpleDocumentPercentAllowance() {
String orgname = "Test company";
String number = "123";
String priceStr = "3.00";
BigDecimal price = new BigDecimal(priceStr);
// similar, but slightly less complicated to whats later testted in testRelativeChargesAllowancesExport
Invoice i = new Invoice().setCurrency("CHF").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
.setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"));
// 9-50%=>4,50 expected net
// .addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReason("Mengenrabatt"))
TransactionCalculator tc = new TransactionCalculator(i);
assertEquals(new BigDecimal("4.50"), tc.getTaxBasis());
assertEquals(new BigDecimal("5.36"), tc.getDuePayable());
} }
public void testSimpleItemTotalAllowance() { public void testSimpleItemTotalAllowance() {
@@ -301,7 +369,7 @@ public class CalculationTest extends ResourceCase {
Product product; Product product;
Item item; Item item;
product = new Product("AAA", "", "H84", BigDecimal.ZERO); product = new Product("AAA", "", "H87", BigDecimal.ZERO);
item = new Item(product, new BigDecimal("1.00"), new BigDecimal(5.00)); item = new Item(product, new BigDecimal("1.00"), new BigDecimal(5.00));
item.addAllowance(new Allowance(new BigDecimal(1)).setTaxPercent(BigDecimal.ZERO)); item.addAllowance(new Allowance(new BigDecimal(1)).setTaxPercent(BigDecimal.ZERO));
@@ -314,7 +382,7 @@ public class CalculationTest extends ResourceCase {
/** /**
* LineCalculator should not throw an exception when calculating a non-terminating decimal expansion * LineCalculator should not throw an exception when calculating a non-terminating decimal expansion
* */ */
@Test @Test
public void testNonTerminatingDecimalExpansion() { public void testNonTerminatingDecimalExpansion() {
final Product product = new Product(); final Product product = new Product();

View File

@@ -21,6 +21,13 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.*;
import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -29,28 +36,11 @@ import java.nio.file.Files;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import org.junit.FixMethodOrder; import static org.assertj.core.api.Assertions.assertThat;
import org.junit.experimental.theories.FromDataPoints;
import org.junit.runners.MethodSorters;
import org.mustangproject.Allowance;
import org.mustangproject.BankDetails;
import org.mustangproject.CalculatedInvoice;
import org.mustangproject.CashDiscount;
import org.mustangproject.Charge;
import org.mustangproject.Contact;
import org.mustangproject.Invoice;
import org.mustangproject.Item;
import org.mustangproject.Product;
import org.mustangproject.SchemedID;
import org.mustangproject.TradeParty;
import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DeSerializationTest extends ResourceCase { public class DeSerializationTest extends ResourceCase {
@@ -71,6 +61,29 @@ public class DeSerializationTest extends ResourceCase {
} }
public void testProduct() throws IOException, XPathExpressionException, ParseException {
File inputCII = getResourceAsFile("Extended_fremdwaehrung.xml");
var zii = new ZUGFeRDInvoiceImporter();
zii.doIgnoreCalculationErrors();
zii.fromXML(Files.readString(inputCII.toPath()));
var product = zii.extractInvoice()
.getZFItems()[0]
.getProduct();
assertThat(product.getCountryOfOrigin()).as("Product Country of origin")
.isEqualTo("DE");
assertThat(product.getSellerAssignedID()).as("Product Seller assigned ID")
.isEqualTo("CO-123/V2A");
assertThat(product.getBuyerAssignedID()).as("Product Buyer assigned ID")
.isEqualTo("Toolbox 0815");
assertThat(product.getName()).as("Name")
.isEqualTo("Stahlcoil");
assertThat(product.getAttributes()).as("Product attributes")
.containsKey("LeoID")
.containsValue("704310.0105636504");
}
public void testInvoiceLine() throws JsonProcessingException { public void testInvoiceLine() throws JsonProcessingException {
File inputCII = getResourceAsFile("factur-x.xml"); File inputCII = getResourceAsFile("factur-x.xml");
boolean hasExceptions = false; boolean hasExceptions = false;
@@ -79,7 +92,7 @@ public class DeSerializationTest extends ResourceCase {
try { try {
zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8)); zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8));
} catch (IOException e) { } catch (IOException | ParseException e) {
hasExceptions = true; hasExceptions = true;
} }
@@ -395,7 +408,7 @@ public class DeSerializationTest extends ResourceCase {
try { try {
Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class);
TransactionCalculator tc=new TransactionCalculator(newInvoiceFromJSON); TransactionCalculator tc=new TransactionCalculator(newInvoiceFromJSON);
assertEquals(new BigDecimal("18.92"),tc.getGrandTotal()); assertEquals(new BigDecimal("18.33"),tc.getGrandTotal());
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -414,10 +427,12 @@ public class DeSerializationTest extends ResourceCase {
String number = "123"; String number = "123";
String priceStr = "1.00"; String priceStr = "1.00";
String taxID = "9990815"; String taxID = "9990815";
BigDecimal price = new BigDecimal(priceStr); BigDecimal price = new BigDecimal(priceStr);
Invoice newInvoiceFromJSON = null; Invoice newInvoiceFromJSON = null;
boolean hasExceptions = false; boolean hasExceptions = false;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String json = "";
try { try {
SchemedID gtin = new SchemedID("0160", "2001015001325"); SchemedID gtin = new SchemedID("0160", "2001015001325");
SchemedID gln = new SchemedID("0088", "4304171000002"); SchemedID gln = new SchemedID("0088", "4304171000002");
@@ -435,7 +450,7 @@ public class DeSerializationTest extends ResourceCase {
.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);
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(i); json = mapper.writeValueAsString(i);
newInvoiceFromJSON = mapper.readValue(json, Invoice.class); newInvoiceFromJSON = mapper.readValue(json, Invoice.class);
} catch (ParseException e) { } catch (ParseException e) {
hasExceptions = true; hasExceptions = true;
@@ -444,8 +459,34 @@ public class DeSerializationTest extends ResourceCase {
} }
assertEquals(newInvoiceFromJSON.getBuyerOrderReferencedDocumentID(), "28934"); assertEquals(newInvoiceFromJSON.getBuyerOrderReferencedDocumentID(), "28934");
assertFalse(hasExceptions); assertFalse(hasExceptions);
}
public void testFromJSON() throws JsonProcessingException {
String globalID = "4000001123452";
String globalIDScheme = "0088";
String itemDeliveryFrom="2022-01-28T23:00:00.000+00:00";
String itemDeliveryTo="2022-01-30T23:00:00.000+00:00";
String json="{\"number\":\"123\",\"buyerOrderReferencedDocumentID\":\"28934\",\"currency\":\"CHF\",\"issueDate\":1752744199178,\"dueDate\":1752744199178,\"deliveryDate\":1604271600000,\"sender\":{\"name\":\"Test company\",\"zip\":\"55232\",\"street\":\"teststr\",\"location\":\"teststadt\",\"country\":\"DE\",\"taxID\":\"9990815\",\"vatID\":\"DE0815\",\"id\":\"0009845\",\"globalID\":\""+globalID+"\",\"globalIDScheme\":\""+globalIDScheme+"\",\"email\":\"sender@test.org\",\"vatid\":\"DE0815\"},\"recipient\":{\"name\":\"Franz Müller\",\"zip\":\"55232\",\"street\":\"teststr.12\",\"location\":\"Entenhausen\",\"country\":\"DE\",\"vatID\":\"DE4711\",\"additionalAddress\":\"Hinterhaus 3\",\"contact\":{\"name\":\"Franz Müller\",\"phone\":\"01779999999\",\"email\":\"franz@mueller.de\",\"zip\":\"55232\",\"street\":\"teststr. 12\",\"location\":\"Entenhausen\",\"country\":\"DE\",\"fax\":\"++49555123456\"},\"globalID\":\"4304171000002\",\"globalIDScheme\":\"0088\",\"email\":\"recipient@test.org\",\"vatid\":\"DE4711\"},\"deliveryAddress\":{\"name\":\"just the other side of the street\",\"zip\":\"55232\",\"street\":\"teststr.12a\",\"location\":\"Entenhausen\",\"country\":\"DE\",\"vatID\":\"DE47110\",\"vatid\":\"DE47110\"},\"cashDiscounts\":[{\"percent\":2,\"days\":14}],\"notes\":[\"document level 1/2\",\"document level 2/2\"],\"sellerOrderReferencedDocumentID\":\"9384\",\"contractReferencedDocument\":\"376zreurzu0983\",\"valid\":true,\"vatdueDateTypeCode\":\"72\",\"zfitems\":[{\"price\":1.00,\"quantity\":1,\"basisQuantity\":1,\"detailedDeliveryPeriodFrom\":\""+itemDeliveryFrom+"\",\"detailedDeliveryPeriodTo\":\""+itemDeliveryTo+"\",\"id\":\"a123\",\"buyerOrderReferencedDocumentLineID\":\"xxx\",\"product\":{\"unit\":\"H87\",\"name\":\"Testprodukt\",\"sellerAssignedID\":\"4711\",\"taxCategoryCode\":\"S\",\"globalID\":\"2001015001325\",\"globalIDScheme\":\"0160\",\"intraCommunitySupply\":false,\"reverseCharge\":false,\"vatpercent\":16},\"notes\":[\"item level 1/1\"],\"notesWithSubjectCode\":[{\"content\":\"item level 1/1\"}],\"itemAllowances\":[{\"totalAmount\":0.0200000000000000004163336342344337026588618755340576171875,\"taxPercent\":16,\"reason\":\"item discount\",\"categoryCode\":\"S\"}],\"value\":1.00}],\"ownVATID\":\"DE0815\",\"detailedDeliveryPeriodFrom\":1601503200000,\"detailedDeliveryPeriodTo\":1601848800000,\"ownTaxID\":\"9990815\",\"ownZIP\":\"55232\",\"ownLocation\":\"teststadt\",\"zfallowances\":[{\"totalAmount\":0.200000000000000011102230246251565404236316680908203125,\"taxPercent\":16,\"reason\":\"discount\",\"categoryCode\":\"S\"}],\"ownStreet\":\"teststr\",\"zfcharges\":[{\"totalAmount\":0.5,\"taxPercent\":16,\"reason\":\"quick delivery charge\",\"categoryCode\":\"S\"}],\"ownCountry\":\"DE\"}";
ObjectMapper mapper = new ObjectMapper();
Invoice fromJSON = mapper.readValue(json, Invoice.class);
assertEquals(globalID, fromJSON.getSender().getGlobalID());
assertEquals(globalIDScheme, fromJSON.getSender().getGlobalIDScheme());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
assertEquals("2022-01-28", sdf.format(fromJSON.getZFItems()[0].getDetailedDeliveryPeriodFrom()));
assertEquals("2022-01-30", sdf.format(fromJSON.getZFItems()[0].getDetailedDeliveryPeriodTo()));
assertEquals("sender@test.org", fromJSON.getSender().getEmail());
}
public void testGrossFromJSON() throws JsonProcessingException {
String json="{ \"documentCode\": \"380\", \"number\": \"123\", \"currency\": \"EUR\", \"paymentTermDescription\": \"Please remit until 28.07.2025\", \"issueDate\": 1753653600000, \"dueDate\": 1753653600000, \"sender\": { \"name\": \"Test company\", \"zip\": \"55232\", \"street\": \"teststr\", \"location\": \"teststadt\", \"country\": \"DE\", \"taxID\": \"4711\", \"vatID\": \"DE0815\", \"vatid\": \"DE0815\" }, \"recipient\": { \"name\": \"Franz Müller\", \"zip\": \"55232\", \"street\": \"teststr.12\", \"location\": \"Entenhausen\", \"country\": \"DE\", \"contact\": { \"name\": \"contact testname\", \"phone\": \"123456\", \"email\": \"contact.testemail@example.org\", \"fax\": \"0911623562\" } }, \"totalPrepaidAmount\": 0.00, \"lineTotalAmount\": 29.00, \"duePayable\": 34.51, \"grandTotal\": 34.51, \"taxBasis\": 29.00, \"valid\": true, \"zfitems\": [ { \"price\": 3.0000, \"quantity\": 10.0000, \"basisQuantity\": 1.0000, \"id\": \"1\", \"product\": { \"unit\": \"H87\", \"name\": \"Testprodukt\", \"taxCategoryCode\": \"S\", \"allowances\": [ { \"totalAmount\": 0.1000, \"categoryCode\": \"S\" } ], \"vatpercent\": 19.00, \"intraCommunitySupply\": false, \"reverseCharge\": false }, \"value\": 3.0000 } ], \"ownVATID\": \"DE0815\", \"ownTaxID\": \"4711\", \"ownLocation\": \"teststadt\", \"ownZIP\": \"55232\", \"ownCountry\": \"DE\", \"ownStreet\": \"teststr\"}";
ObjectMapper mapper = new ObjectMapper();
CalculatedInvoice fromJSON = mapper.readValue(json, CalculatedInvoice.class);
fromJSON.calculate();
assertEquals(new BigDecimal("34.51"),fromJSON.getDuePayable());
} }
public void testDueDateRoundtrip() throws JsonProcessingException { public void testDueDateRoundtrip() throws JsonProcessingException {

View File

@@ -189,8 +189,7 @@ public class XRTest extends TestCase {
zf2p.setProfile(Profiles.getByName("XRechnung")); zf2p.setProfile(Profiles.getByName("XRechnung"));
zf2p.generateXML(i); zf2p.generateXML(i);
final String xmlGen = new String(zf2p.getXML());
System.out.println(xmlGen);
final Document doc = DocumentBuilderFactory.newInstance() final Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder() .newDocumentBuilder()
.parse(new ByteArrayInputStream(zf2p.getXML())); .parse(new ByteArrayInputStream(zf2p.getXML()));

View File

@@ -53,6 +53,7 @@ public class ZF2PushTest extends TestCase {
final String TARGET_ALLOWANCESPDF = "./target/testout-ZF2PushAllowances.pdf"; final String TARGET_ALLOWANCESPDF = "./target/testout-ZF2PushAllowances.pdf";
final String TARGET_CREDITNOTEPDF = "./target/testout-ZF2PushCreditNote.pdf"; final String TARGET_CREDITNOTEPDF = "./target/testout-ZF2PushCreditNote.pdf";
final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf"; final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf";
final String TARGET_ITEMGROSS = "./target/testout-ZF2PushGross.pdf";
final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf"; final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf";
final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf"; final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf";
final String TARGET_RELATIVECHARGESALLOWANCESPDF = "./target/testout-ZF2PushRelativeChargesAllowances.pdf"; final String TARGET_RELATIVECHARGESALLOWANCESPDF = "./target/testout-ZF2PushRelativeChargesAllowances.pdf";
@@ -114,8 +115,8 @@ public class ZF2PushTest extends TestCase {
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
assertTrue(zi.getUTF8().contains("DE88200800000970375700")); //the iban assertTrue(zi.getUTF8().contains("DE88200800000970375700")); //the iban
assertTrue(zi.getUTF8().contains("Max Mustermann")); //account holder assertTrue(zi.getUTF8().contains("Max Mustermann")); //account holder
assertTrue(zi.getUTF8().contains("DueDateDateTime")); //account holder assertTrue(zi.getUTF8().contains("DueDateDateTime"));
assertTrue(zi.getUTF8().contains("20201212")); //account holder assertTrue(zi.getUTF8().contains("20201212"));
assertTrue(zi.getUTF8().contains("<rsm:CrossIndustryInvoice")); assertTrue(zi.getUTF8().contains("<rsm:CrossIndustryInvoice"));
@@ -124,7 +125,7 @@ public class ZF2PushTest extends TestCase {
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals("571.04", zi.getAmount()); assertEquals("571.04", zi.getAmount());
assertEquals(orgname, zi.getHolder()); assertEquals("Max Mustermann", zi.getHolder());
assertEquals(number, zi.getForeignReference()); assertEquals(number, zi.getForeignReference());
try { try {
assertEquals(zi.getVersion(), 2); assertEquals(zi.getVersion(), 2);
@@ -159,7 +160,7 @@ public class ZF2PushTest extends TestCase {
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711") .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711")
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))) .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE")))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)).setTaxExemptionReason("Kleinunternehmer gemäß §19 UStG").setTaxCategoryCode("E"), price, new BigDecimal(1.0)).addNote(theNote)) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(0)).setTaxExemptionReason("Kleinunternehmer gemäß §19 UStG").setTaxCategoryCode("E"), price, new BigDecimal(1.0)).addNote(theNote))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice")); assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
@@ -219,7 +220,7 @@ public class ZF2PushTest extends TestCase {
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711") .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711")
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))) .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE")))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
Invoice read = new Invoice(); Invoice read = new Invoice();
@@ -237,13 +238,12 @@ public class ZF2PushTest extends TestCase {
fail("ParseException should not be raised"); fail("ParseException should not be raised");
} }
} }
public void testGross() {
public void testItemChargesAllowancesExport() {
String orgname = "Test company"; String orgname = "Test company";
String number = "123"; String number = "123";
String amountStr = "3.00"; String priceStr = "3.00";
BigDecimal amount = new BigDecimal(amountStr); BigDecimal price = new BigDecimal(priceStr);
try { try {
InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -253,7 +253,71 @@ public class ZF2PushTest extends TestCase {
ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended"); ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended");
// ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number) // ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
// .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", "", "H84", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
BigDecimal qty=new BigDecimal(10.0);
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")
.setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")))
.setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).addAllowance(new Allowance(new BigDecimal("0.1"))), price, qty));
ze.setTransaction(i);
String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
ze.export(TARGET_ITEMGROSS);
} catch (IOException e) {
fail("IOException should not be raised");
}
try {
// now check the contents (like MustangReaderTest)
ZUGFeRDInvoiceImporter zi = new ZUGFeRDInvoiceImporter(TARGET_ITEMGROSS);
CalculatedInvoice ci=new CalculatedInvoice();
zi.extractInto(ci);
assertThat(zi.getUTF8()).valueByXPath("//*[local-name()=\"GrossPriceProductTradePrice\"]/*[local-name()=\"ChargeAmount\"]")
.asString()
.isEqualTo("3.0000");
assertThat(zi.getUTF8()).valueByXPath("//*[local-name()=\"NetPriceProductTradePrice\"]/*[local-name()=\"ChargeAmount\"]")
.asString()
.isEqualTo("2.9000");
assertEquals("EUR", ci.getCurrency());
assertTrue(zi.getUTF8().contains("0911623562")); // fax number
ObjectMapper mapper = new ObjectMapper();
String jsonArray = mapper.writeValueAsString(ci);
// Reading ZUGFeRD
assertEquals(new BigDecimal("34.51"), ci.getDuePayable());
} catch (Exception e) {
fail("Exception should not be raised");
}
}
public void testItemChargesAllowancesExport() {
String orgname = "Test company";
String number = "123";
String priceStr = "3.00";
BigDecimal price = new BigDecimal(priceStr);
try {
InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1();
ze.ignorePDFAErrors().load(SOURCE_PDF);
ze.setProfile(Profiles.getByName("Extended"));
ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended");
// ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
// .addItem(new Item(new Product("Testprodukt", "", "H84", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()) Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
@@ -261,10 +325,10 @@ public class ZF2PushTest extends TestCase {
.setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))) .setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")))
.setNumber(number) .setNumber(number)
.addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("AReason").setTaxPercent(new BigDecimal(19))) .addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("AReason").setTaxPercent(new BigDecimal(19)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal("0.1")).setReasonCode("95"))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal("0.1")).setReasonCode("95")))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)).setReason("In love with salesperson"))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)).setReason("In love with salesperson")))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("AnotherReason"))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("AnotherReason")))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("Yet another reason")).addAllowance(new Allowance(new BigDecimal("1")).setReason("Something completely strange"))); .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("Yet another reason")).addAllowance(new Allowance(new BigDecimal("1")).setReason("Something completely strange")));
ze.setTransaction(i); ze.setTransaction(i);
@@ -283,7 +347,7 @@ public class ZF2PushTest extends TestCase {
assertTrue(zi.getUTF8().contains("ABK")); assertTrue(zi.getUTF8().contains("ABK"));
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals("18.92", zi.getAmount()); assertEquals("18.33", zi.getAmount());
assertEquals(orgname, zi.getHolder()); assertEquals(orgname, zi.getHolder());
assertEquals(number, zi.getForeignReference()); assertEquals(number, zi.getForeignReference());
assertEquals(zi.getVersion(), 2); assertEquals(zi.getVersion(), 2);
@@ -300,8 +364,8 @@ public class ZF2PushTest extends TestCase {
String orgname = "Test company"; String orgname = "Test company";
String number = "123"; String number = "123";
String amountStr = "3.00"; String priceStr = "3.00";
BigDecimal amount = new BigDecimal(amountStr); BigDecimal price = new BigDecimal(priceStr);
try { try {
InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -309,7 +373,7 @@ public class ZF2PushTest extends TestCase {
ze.ignorePDFAErrors().load(SOURCE_PDF); ze.ignorePDFAErrors().load(SOURCE_PDF);
ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended"); ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended");
// ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number) // ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
// .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", "", "H84", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID("4711")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID("4711"))
@@ -317,10 +381,10 @@ public class ZF2PushTest extends TestCase {
.setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))) .setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")))
.setDeliveryAddress(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816")) .setDeliveryAddress(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816"))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setIntraCommunitySupply(), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setIntraCommunitySupply(), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setIntraCommunitySupply(), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setIntraCommunitySupply(), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setIntraCommunitySupply(), amount, new BigDecimal(2.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setIntraCommunitySupply(), price, new BigDecimal(2.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setIntraCommunitySupply(), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setIntraCommunitySupply(), price, new BigDecimal(1.0)))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
@@ -373,7 +437,7 @@ public class ZF2PushTest extends TestCase {
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))) .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE")))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)).setTaxExemptionReason("Kein Ausweis der Umsatzsteuer bei innergemeinschaftlichen Lieferungen").setTaxCategoryCode("K"), price, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(0)).setTaxExemptionReason("Kein Ausweis der Umsatzsteuer bei innergemeinschaftlichen Lieferungen").setTaxCategoryCode("K"), price, new BigDecimal(1.0)))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice")); assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
@@ -413,8 +477,8 @@ public class ZF2PushTest extends TestCase {
String orgname = "Test company"; String orgname = "Test company";
String number = "123"; String number = "123";
String amountStr = "3.00"; String priceStr = "3.00";
BigDecimal amount = new BigDecimal(amountStr); BigDecimal price = new BigDecimal(priceStr);
try { try {
InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -423,17 +487,17 @@ public class ZF2PushTest extends TestCase {
ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended"); ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended");
// ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number) // ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
// .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", "", "H84", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID("4711")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID("4711"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816") .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816")
.setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))) .setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setReverseCharge(), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setReverseCharge(), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(2.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setReverseCharge(), price, new BigDecimal(2.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).setReverseCharge(), price, new BigDecimal(1.0)))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
@@ -464,8 +528,8 @@ public class ZF2PushTest extends TestCase {
String orgname = "Test company"; String orgname = "Test company";
String number = "123"; String number = "123";
String amountStr = "3.00"; String priceStr = "3.00";
BigDecimal amount = new BigDecimal(amountStr); BigDecimal price = new BigDecimal(priceStr);
try { try {
InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -477,9 +541,9 @@ public class ZF2PushTest extends TestCase {
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addCharge(new Charge(new BigDecimal(0.5)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK")) .addCharge(new Charge(new BigDecimal(0.5)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"))
.addAllowance(new Allowance(new BigDecimal(0.2)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK")) .addAllowance(new Allowance(new BigDecimal(0.2)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"))
); );
@@ -540,7 +604,7 @@ public class ZF2PushTest extends TestCase {
.setContractReferencedDocument(contractID) .setContractReferencedDocument(contractID)
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711") .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711")
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3")) .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3"))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addBuyerOrderReferencedDocumentID("orderId").addBuyerOrderReferencedDocumentLineID("xxx").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15"))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addBuyerOrderReferencedDocumentID("orderId").addBuyerOrderReferencedDocumentLineID("xxx").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15")))
.addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16))) .addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16)))
.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))
@@ -631,7 +695,7 @@ public class ZF2PushTest extends TestCase {
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).addAllowance(new Allowance(BigDecimal.ONE)), new BigDecimal(500.0), qty).addAllowance(new Allowance(new BigDecimal(300)).setTaxPercent(new BigDecimal(19)))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)).addAllowance(new Allowance(BigDecimal.ONE)), new BigDecimal(500.0), qty).addAllowance(new Allowance(new BigDecimal(300)).setTaxPercent(new BigDecimal(19))))
.addAllowance(new Allowance(new BigDecimal(600)).setTaxPercent(new BigDecimal(19))) .addAllowance(new Allowance(new BigDecimal(600)).setTaxPercent(new BigDecimal(19)))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
@@ -675,9 +739,9 @@ public class ZF2PushTest extends TestCase {
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)).addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"))) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, new BigDecimal(1.0))).addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReasonCode("ABK"))
.addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReason("Mengenrabatt")) .addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)).setReason("Mengenrabatt"))
); );
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
@@ -691,7 +755,7 @@ public class ZF2PushTest extends TestCase {
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_RELATIVECHARGESALLOWANCESPDF); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_RELATIVECHARGESALLOWANCESPDF);
assertEquals("CHF", zi.getInvoiceCurrencyCode()); assertEquals("CHF", zi.getInvoiceCurrencyCode());
assertEquals("11.10", zi.getAmount()); assertEquals("10.71", zi.getAmount());
assertEquals(orgname, zi.getHolder()); assertEquals(orgname, zi.getHolder());
assertEquals(number, zi.getForeignReference()); assertEquals(number, zi.getForeignReference());
try { try {
@@ -726,9 +790,9 @@ public class ZF2PushTest extends TestCase {
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815")) .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815"))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)).setCorrection("0815"); .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty)).setCorrection("0815");
ze.setTransaction(i); ze.setTransaction(i);
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice")); assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
@@ -777,9 +841,9 @@ public class ZF2PushTest extends TestCase {
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX"))) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX")))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815")) .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815"))
.setNumber(number).setDespatchAdviceReferencedDocumentID(despatchAdviceReferencedDocumentID) .setNumber(number).setDespatchAdviceReferencedDocumentID(despatchAdviceReferencedDocumentID)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)) .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)).setCreditNote(); .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty)).setCreditNote();
ze.setTransaction(i); ze.setTransaction(i);
String theXML = new String(ze.getProvider().getXML()); String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice")); assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
@@ -831,7 +895,7 @@ public class ZF2PushTest extends TestCase {
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX"))) .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX")))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815")) .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0815"))
.setNumber(number) .setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)); .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), price, qty));
// empty strings for document id's // empty strings for document id's
i.setSellerOrderReferencedDocumentID("") i.setSellerOrderReferencedDocumentID("")

View File

@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mustangproject.*; import org.mustangproject.*;
import org.skyscreamer.jsonassert.JSONAssert;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import java.io.File; import java.io.File;
@@ -38,6 +39,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -264,7 +266,7 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
} }
assertFalse(hasExceptions); assertFalse(hasExceptions);
TransactionCalculator tc = new TransactionCalculator(invoice); TransactionCalculator tc = new TransactionCalculator(invoice);
assertEquals(new BigDecimal("18.92"), tc.getGrandTotal()); assertEquals(new BigDecimal("18.33"), tc.getGrandTotal());
} }
public void testIBANImport() { public void testIBANImport() {
@@ -405,8 +407,7 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
String jsonArray = mapper.writeValueAsString(i); String jsonArray = mapper.writeValueAsString(i);
JSONAssert.assertEquals("{\"documentCode\":\"380\",\"number\":\"471102\",\"currency\":\"EUR\",\"paymentTermDescription\":\"Der Betrag in Höhe von EUR 529,87 wird am 20.03.2018 von Ihrem Konto per SEPA-Lastschrift eingezogen.\\n \",\"issueDate\":1520121600000,\"deliveryDate\":1520121600000,\"sender\":{\"name\":\"Lieferant GmbH\",\"zip\":\"80333\",\"street\":\"Lieferantenstraße 20\",\"location\":\"München\",\"country\":\"DE\",\"taxID\":\"201/113/40209\",\"vatID\":\"DE123456789\",\"debitDetails\":[{\"mandate\":\"REF A-123\",\"paymentMeansCode\":\"59\",\"paymentMeansInformation\":\"SEPA direct debit\",\"iban\":\"DE21860000000086001055\"}],\"vatid\":\"DE123456789\"},\"recipient\":{\"name\":\"Kunden AG Mitte\",\"zip\":\"69876\",\"street\":\"Kundenstraße 15\",\"location\":\"Frankfurt\",\"country\":\"DE\",\"bankDetails\":[{\"paymentMeansCode\":\"58\",\"paymentMeansInformation\":\"SEPA credit transfer\",\"iban\":\"DE21860000000086001055\"}]},\"totalPrepaidAmount\":0.00,\"creditorReferenceID\":\"DE98ZZZ09999999999\",\"valid\":false,\"zfitems\":[{\"price\":9.9000,\"quantity\":20.0000,\"basisQuantity\":1.0000,\"id\":\"1\",\"product\":{\"unit\":\"H87\",\"name\":\"Trennblätter A4\",\"taxCategoryCode\":\"S\",\"vatpercent\":19.00,\"reverseCharge\":false,\"intraCommunitySupply\":false},\"value\":9.9000},{\"price\":5.5000,\"quantity\":50.0000,\"basisQuantity\":1.0000,\"id\":\"2\",\"product\":{\"unit\":\"H87\",\"name\":\"Joghurt Banane\",\"taxCategoryCode\":\"S\",\"vatpercent\":7.00,\"reverseCharge\":false,\"intraCommunitySupply\":false},\"value\":5.5000}],\"tradeSettlement\":[{\"mandate\":\"REF A-123\",\"paymentMeansCode\":\"59\",\"paymentMeansInformation\":\"SEPA direct debit\",\"iban\":\"DE21860000000086001055\"}],\"ownTaxID\":\"201/113/40209\",\"ownZIP\":\"80333\",\"ownCountry\":\"DE\",\"ownVATID\":\"DE123456789\",\"ownLocation\":\"München\",\"ownStreet\":\"Lieferantenstraße 20\"}",jsonArray,false);
// assertEquals("",jsonArray);
} catch (IOException e) { } catch (IOException e) {
fail("IOException not expected"); fail("IOException not expected");
@@ -415,8 +416,37 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
} catch (ParseException e) { } catch (ParseException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}
public static Date atStartOfDay(Date date) {
ZoneId tz=ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0));
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), tz);
LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
return Date.from(startOfDay.atZone(tz).toInstant());
}
public void testImportAllowances() {
try {
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushItemChargesAllowances.pdf");
Invoice i = zii.extractInvoice();
ObjectMapper mapper = new ObjectMapper();
String jsonArray = mapper.writeValueAsString(i);
SimpleDateFormat iso=new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat german=new SimpleDateFormat("dd.MM.yyyy");
Date now=new Date();
Date morning=atStartOfDay(now);
String expectedDueDate= String.valueOf(morning.toInstant().getEpochSecond() *1000);
String expectedIssueDate= String.valueOf(morning.toInstant().getEpochSecond() *1000);
String expectedPaymentTermDesciption="Please remit until "+german.format(now);
JSONAssert.assertEquals("{ \"documentCode\": \"380\", \"number\": \"123\", \"currency\": \"EUR\", \"paymentTermDescription\": \""+expectedPaymentTermDesciption+"\", \"issueDate\": "+expectedIssueDate+", \"dueDate\": "+expectedDueDate+", \"sender\": { \"name\": \"Test company\", \"zip\": \"55232\", \"street\": \"teststr\", \"location\": \"teststadt\", \"country\": \"DE\", \"taxID\": \"4711\", \"vatID\": \"DE0815\", \"vatid\": \"DE0815\" }, \"recipient\": { \"name\": \"Franz Müller\", \"zip\": \"55232\", \"street\": \"teststr.12\", \"location\": \"Entenhausen\", \"country\": \"DE\", \"contact\": { \"name\": \"contact testname\", \"phone\": \"123456\", \"email\": \"contact.testemail@example.org\", \"fax\": \"0911623562\" } }, \"totalPrepaidAmount\": 0.00, \"valid\": true, \"zfitems\": [ { \"price\": 3.0000, \"quantity\": 1.0000, \"basisQuantity\": 1.0000, \"id\": \"1\", \"product\": { \"unit\": \"H87\", \"name\": \"Testprodukt\", \"taxCategoryCode\": \"S\", \"vatpercent\": 19.00, \"reverseCharge\": false, \"intraCommunitySupply\": false }, \"itemAllowances\": [ { \"totalAmount\": 0.10, \"taxPercent\": 0, \"categoryCode\": \"S\" } ], \"value\": 3.0000 }, { \"price\": 3.0000, \"quantity\": 1.0000, \"basisQuantity\": 1.0000, \"id\": \"2\", \"product\": { \"unit\": \"H87\", \"name\": \"Testprodukt\", \"taxCategoryCode\": \"S\", \"vatpercent\": 19.00, \"reverseCharge\": false, \"intraCommunitySupply\": false }, \"itemAllowances\": [ { \"percent\": 50.00, \"totalAmount\": 1.5, \"basisAmount\": 3.00, \"taxPercent\": 0, \"reason\": \"In love with salesperson\", \"categoryCode\": \"S\" } ], \"value\": 3.0000 }, { \"price\": 3.0000, \"quantity\": 2.0000, \"basisQuantity\": 1.0000, \"id\": \"3\", \"product\": { \"unit\": \"H87\", \"name\": \"Testprodukt\", \"taxCategoryCode\": \"S\", \"vatpercent\": 19.00, \"reverseCharge\": false, \"intraCommunitySupply\": false }, \"itemCharges\": [ { \"totalAmount\": 1.00, \"taxPercent\": 0, \"reason\": \"AnotherReason\", \"categoryCode\": \"S\" } ], \"value\": 3.0000 }, { \"price\": 3.0000, \"quantity\": 1.0000, \"basisQuantity\": 1.0000, \"id\": \"4\", \"product\": { \"unit\": \"H87\", \"name\": \"Testprodukt\", \"taxCategoryCode\": \"S\", \"vatpercent\": 19.00, \"reverseCharge\": false, \"intraCommunitySupply\": false }, \"itemCharges\": [ { \"totalAmount\": 1.00, \"taxPercent\": 0, \"reason\": \"Yet another reason\", \"categoryCode\": \"S\" } ], \"itemAllowances\": [ { \"totalAmount\": 1.00, \"taxPercent\": 0, \"reason\": \"Something completely strange\", \"categoryCode\": \"S\" } ], \"value\": 3.0000 } ], \"ownCountry\": \"DE\", \"zfcharges\": [ { \"totalAmount\": 1.00, \"taxPercent\": 19.00, \"reason\": \"AReason\", \"reasonCode\": \"ABK\", \"categoryCode\": \"S\" } ], \"ownVATID\": \"DE0815\", \"ownStreet\": \"teststr\", \"ownTaxID\": \"4711\", \"ownLocation\": \"teststadt\", \"ownZIP\": \"55232\"}",jsonArray,true);
} catch (IOException e) {
fail("IOException not expected");
} catch (XPathExpressionException e) {
throw new RuntimeException(e);
} catch (ParseException e) {
throw new RuntimeException(e);
}
} }
public void testImportMinimum() { public void testImportMinimum() {

View File

@@ -131,6 +131,10 @@ costs, losses or damages could normally have been foreseen.-->
<ram:SellerAssignedID>CO-123/V2A</ram:SellerAssignedID> <ram:SellerAssignedID>CO-123/V2A</ram:SellerAssignedID>
<ram:BuyerAssignedID>Toolbox 0815</ram:BuyerAssignedID> <ram:BuyerAssignedID>Toolbox 0815</ram:BuyerAssignedID>
<ram:Name>Stahlcoil</ram:Name> <ram:Name>Stahlcoil</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:Description>LeoID</ram:Description>
<ram:Value>704310.0105636504</ram:Value>
</ram:ApplicableProductCharacteristic>
<ram:OriginTradeCountry> <ram:OriginTradeCountry>
<ram:ID>DE</ram:ID> <ram:ID>DE</ram:ID>
</ram:OriginTradeCountry> </ram:OriginTradeCountry>

13
pom.xml
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.17.1-SNAPSHOT</version> <packaging>pom</packaging> <version>2.18.1-SNAPSHOT</version> <packaging>pom</packaging>
<name>Mustang</name> <name>Mustang</name>
<modules> <modules>
@@ -70,28 +70,27 @@
<plugin> <plugin>
<groupId>org.sonatype.plugins</groupId> <groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId> <artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.13</version> <version>1.7.0</version>
<extensions>true</extensions> <extensions>true</extensions>
<configuration> <configuration>
<serverId>ossrh</serverId> <serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl> <nexusUrl>https://ossrh-staging-api.central.sonatype.com/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose> <autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version>
<configuration> <configuration>
<runOrder>alphabetical</runOrder> <runOrder>alphabetical</runOrder>
<argLine>-Duser.timezone=UTC</argLine>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId> <artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version> <version>3.3.1</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
<executions> <executions>
<execution> <execution>
<id>attach-javadoc</id> <id>attach-javadoc</id>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.17.1-SNAPSHOT</version> <version>2.18.1-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.17.1-SNAPSHOT</version> <version>2.18.1-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.17.1-SNAPSHOT</version> <version>2.18.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
@@ -129,8 +129,10 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version>
<configuration> <configuration>
<runOrder>alphabetical</runOrder> <runOrder>alphabetical</runOrder>
<argLine>-Duser.timezone=UTC</argLine>
</configuration> </configuration>
</plugin> </plugin>
<!-- allow getImplementationVersion for the pom.xml --> <!-- allow getImplementationVersion for the pom.xml -->

View File

@@ -12,7 +12,6 @@ import java.util.Calendar;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
@@ -130,11 +129,11 @@ public class PDFValidator extends Validator {
final Document docXMP; final Document docXMP;
if (xmp == null || xmp.length() == 0) { if (xmp == null || xmp.isEmpty()) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found") context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found")
.setSection(17).setPart(EPart.pdf)); .setSection(17).setPart(EPart.pdf));
} }
else else {
/* /*
* checking for sth like <zf:ConformanceLevel>EXTENDED</zf:ConformanceLevel> * checking for sth like <zf:ConformanceLevel>EXTENDED</zf:ConformanceLevel>
* <zf:DocumentType>INVOICE</zf:DocumentType> * <zf:DocumentType>INVOICE</zf:DocumentType>
@@ -261,6 +260,7 @@ public class PDFValidator extends Validator {
} catch (final SAXException | IOException | ParserConfigurationException | XPathExpressionException e) { } catch (final SAXException | IOException | ParserConfigurationException | XPathExpressionException e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} }
}
zfXML = zi.getUTF8(); zfXML = zi.getUTF8();
// step 3 find signatures // step 3 find signatures
@@ -306,7 +306,7 @@ public class PDFValidator extends Validator {
final HashMap<String, byte[]> additionalData = zi.getAdditionalData(); final HashMap<String, byte[]> additionalData = zi.getAdditionalData();
for (final String filename : additionalData.keySet()) { for (final String filename : additionalData.keySet()) {
// validating xml in byte[] additionalData.get(filename) // validating xml in byte[] additionalData.get(filename)
LOGGER.info("validating additionalData " + filename); LOGGER.info("validating additionalData {}", filename);
validateSchema(additionalData.get(filename), "ad/basic/additional_data_base_schema.xsd", 2, EPart.pdf); validateSchema(additionalData.get(filename), "ad/basic/additional_data_base_schema.xsd", 2, EPart.pdf);
} }

View File

@@ -32,13 +32,13 @@ public class ValidationContext {
} }
if (logger != null) { if (logger != null) {
if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) { if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) {
logger.error("Fatal Error " + vr.getSection() + ": " + vr.getMessage()); logger.error("Fatal Error {}: {}", vr.getSection(), vr.getMessage());
} else if ((vr.getSeverity() == ESeverity.error)) { } else if ((vr.getSeverity() == ESeverity.error)) {
logger.error("Error " + vr.getSection() + ": " + vr.getMessage()); logger.error("Error {}: {}", vr.getSection(), vr.getMessage());
} else if (vr.getSeverity() == ESeverity.warning) { } else if (vr.getSeverity() == ESeverity.warning) {
logger.warn("Warning " + vr.getSection() + ": " + vr.getMessage()); logger.warn("Warning {}: {}", vr.getSection(), vr.getMessage());
} else if (vr.getSeverity() == ESeverity.notice) { } else if (vr.getSeverity() == ESeverity.notice) {
logger.info("Notice " + vr.getSection() + ": " + vr.getMessage()); logger.info("Notice {}: {}", vr.getSection(), vr.getMessage());
} }
} }
@@ -106,20 +106,17 @@ public class ValidationContext {
} }
public String getXMLResult() { public String getXMLResult() {
String res = getCustomXML(); StringBuilder res = new StringBuilder(getCustomXML());
if (results.size() > 0) { if (results != null && !results.isEmpty()) {
res += "<messages>"; res.append("<messages>");
}
for (final ValidationResultItem validationResultItem : results) { for (final ValidationResultItem validationResultItem : results) {
// xml and pdf are handled in their respective sections // xml and pdf are handled in their respective sections
res += validationResultItem.getXMLOnce() + "\n"; res.append(validationResultItem.getXMLOnce()).append("\n");
} }
if (results.size() > 0) { res.append("</messages>");
res += "</messages>";
} }
res += "<summary status=\"" + (isValid ? "valid" : "invalid") + "\"/>"; res.append("<summary status=\"").append(isValid ? "valid" : "invalid").append("\"/>");
return res; return res.toString();
} }
/*** /***

View File

@@ -8,6 +8,7 @@ import java.io.UncheckedIOException;
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;
import java.text.ParseException;
import java.util.Calendar; import java.util.Calendar;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
@@ -20,7 +21,9 @@ import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import org.mustangproject.CalculatedInvoice;
import org.mustangproject.XMLTools; import org.mustangproject.XMLTools;
import org.mustangproject.ZUGFeRD.ZUGFeRDInvoiceImporter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@@ -223,12 +226,6 @@ public class XMLValidator extends Validator {
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox); validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox);
xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt"; xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt";
} else if (root.getLocalName().equalsIgnoreCase("SCRDMCCBDACIOMessageStructure")) {
context.setGeneration("1");
isOrderX = true;
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox);
xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt";
} else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X
context.setGeneration("2"); context.setGeneration("2");
@@ -306,7 +303,7 @@ public class XMLValidator extends Validator {
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;
@@ -387,6 +384,7 @@ public class XMLValidator extends Validator {
} }
} }
} }
checkArithmetics(context);
} catch (final IrrecoverableValidationError er) { } catch (final IrrecoverableValidationError er) {
@@ -410,6 +408,28 @@ public class XMLValidator extends Validator {
} }
private void checkArithmetics(ValidationContext context) {
ZUGFeRDInvoiceImporter zi=new ZUGFeRDInvoiceImporter();
try {
zi.fromXML(zfXML);
CalculatedInvoice ci=new CalculatedInvoice();
zi.extractInto(ci);
} catch ( ArithmeticException e) {
try {
context.addResultItem(new ValidationResultItem(ESeverity.warning, "Arithmetical issue:"+e.getMessage()).setSection(10));
} catch (IrrecoverableValidationError ie) {
LOGGER.error(ie.getMessage(), ie);
}
} catch (XPathExpressionException e) {
LOGGER.error(e.getMessage(), e);
} catch (ParseException e) {
LOGGER.error(e.getMessage(), e);
}
}
public void validateXR(String xml, ESeverity errorImpact) throws IrrecoverableValidationError { public void validateXR(String xml, ESeverity errorImpact) throws IrrecoverableValidationError {
//Guideline ID=urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2 or //Guideline ID=urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2 or
@@ -507,7 +527,7 @@ public class XMLValidator extends Validator {
} }
} }
LOGGER.info("FailedAssert ", thisFailText); LOGGER.info("FailedAssert {}", thisFailText);
context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")") context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")")
.setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID) .setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID)

View File

@@ -17,8 +17,7 @@ public class ResourceCase extends TestCase {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is
public static File getResourceAsFile(String resourcePath) { public static File getResourceAsFile(String resourcePath) {
try { try(InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath)) {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) { if (in == null) {
return null; return null;
} }
@@ -42,8 +41,7 @@ public class ResourceCase extends TestCase {
} }
public static byte[] getResourceAsByteArray(String resourcePath) { public static byte[] getResourceAsByteArray(String resourcePath) {
try { try(InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath)) {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) { if (in == null) {
return null; return null;
} }

View File

@@ -8,6 +8,8 @@ import org.xmlunit.builder.Input;
import org.xmlunit.xpath.JAXPXPathEngine; import org.xmlunit.xpath.JAXPXPathEngine;
import org.xmlunit.xpath.XPathEngine; import org.xmlunit.xpath.XPathEngine;
import static org.xmlunit.assertj.XmlAssert.assertThat;
public class XMLValidatorTest extends ResourceCase { public class XMLValidatorTest extends ResourceCase {
public void testZF2XMLValidation() { public void testZF2XMLValidation() {
@@ -282,6 +284,30 @@ public class XMLValidatorTest extends ResourceCase {
} }
public void testArithmetics() {
final ValidationContext ctx = new ValidationContext(null);
final XMLValidator xv = new XMLValidator(ctx);
final XPathEngine xpath = new JAXPXPathEngine();
File tempFile = getResourceAsFile("invalidArithmetics.xml");
try {
xv.setFilename(tempFile.getAbsolutePath());
xv.validate();
String s="<validation>" + xv.getXMLResult() + "</validation>";
Source source = Input.fromString(s).build();
String content = xpath.evaluate("/validation/summary/@status", source);
assertEquals("valid", content);
assertThat(s).valueByXPath("count(//warning)")
.asInt()
.isEqualTo(1);
} catch (final IrrecoverableValidationError e) {
// ignore, will be in XML output anyway
}
}
public void testXRValidationUBL() { public void testXRValidationUBL() {
ValidationContext ctx = new ValidationContext(null); ValidationContext ctx = new ValidationContext(null);
XMLValidator xv = new XMLValidator(ctx); XMLValidator xv = new XMLValidator(ctx);

View File

@@ -219,7 +219,7 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
.isEqualTo(2); .isEqualTo(2);
assertThat(res).valueByXPath("count(//warning)") assertThat(res).valueByXPath("count(//warning)")
.asInt() .asInt()
.isEqualTo(2); .isEqualTo(3);
assertThat(res).valueByXPath("count(//notice)") assertThat(res).valueByXPath("count(//notice)")
.asInt() .asInt()

View File

@@ -0,0 +1,186 @@
<?xml version='1.0' encoding="UTF-8" standalone="yes"?>
<rsm:CrossIndustryInvoice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>RE-20171118/506</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime><udt:DateTimeString format="102">20171118</udt:DateTimeString></ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Künstlerische Gestaltung (Stunde): Einer Beispielrechnung</ram:Name>
<ram:Description></ram:Description>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>160.0000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>160.0000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="HUR">2.0000</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>160.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>2</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Luftballon: Bunt, ca. 500ml</ram:Name>
<ram:Description></ram:Description>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>0.7900</ram:ChargeAmount>
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>0.7900</ram:ChargeAmount>
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">400.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>316.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>3</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Heiße Luft pro Liter</ram:Name>
<ram:Description></ram:Description>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount>0.1000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>0.1000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="LTR">200.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.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:Name>Bei Spiel GmbH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>12345</ram:PostcodeCode>
<ram:LineOne>Ecke 12</ram:LineOne>
<ram:CityName>Stadthausen</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">22/815/0815/4</ram:ID>
</ram:SpecifiedTaxRegistration>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE136695976</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:Name>Theodor Est</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>88802</ram:PostcodeCode>
<ram:LineOne>Bahnstr. 42</ram:LineOne>
<ram:CityName>Spielkreis</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE999999999</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:BuyerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime><udt:DateTimeString format="102">20171117</udt:DateTimeString></ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<ram:PaymentReference>RE-20171118/506</ram:PaymentReference>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>42</ram:TypeCode>
<ram:Information>Überweisung</ram:Information>
<ram:PayeePartyCreditorFinancialAccount>
<ram:IBANID>DE88 2008 0000 0970 3757 00</ram:IBANID>
</ram:PayeePartyCreditorFinancialAccount>
<ram:PayeeSpecifiedCreditorFinancialInstitution>
<ram:BICID>COBADEFFXXX</ram:BICID>
</ram:PayeeSpecifiedCreditorFinancialInstitution>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>11.20</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>160.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>63.84</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>336.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Zahlbar ohne Abzug bis 09.12.2017</ram:Description>
<ram:DueDateDateTime><udt:DateTimeString format="102">20171209</udt:DateTimeString></ram:DueDateDateTime>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>496.00</ram:LineTotalAmount>
<ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount>496.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">75.04</ram:TaxTotalAmount>
<ram:GrandTotalAmount>571.04</ram:GrandTotalAmount>
<ram:DuePayableAmount>571.04</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>