Merge branch 'master' into master

This commit is contained in:
Jochen Staerk
2019-08-12 13:18:11 +02:00
committed by GitHub
48 changed files with 7172 additions and 1405 deletions

View File

@@ -1,3 +1,52 @@
1.7.4
=====
- #102 XML entities for ZF2 export
1.7.3
=====
2019-08-01
- #105 does not build in windows
- #99 BOMs confuse parser
- updated javadoc
- fixed #104 nullpointerex when specifying no parameter
- PR #112 complete profile options for v1
- access to TotalPrepaidAmount in ZF v1 #118
- have unit tests for nDigitFormat #23
1.7.2
=====
2019-07-08
Support BuyerReference (r+w), as well as SpecifiedLegalOrganization (w) and DefinedTradeContact (w)
use dom4j to format output xml document
corrected some exception logging glitches
upgrade PDFBox to 2.0.15+
extraction to use proper filename instead of alias #98
NullPointerException in ZUGFeRDImporter.extractLowLevel #96
Removed Bankleitzahl from ZF2
1.7.1
=====
2019-05-26
Corrected EN16931 ZF2 profile name
1.7.0
=====
2019-05-05
Export ZF2 final now seems halfway valid (new filename, new namespace prefixa)
Migrates profile names in ZF1 to ZF2 migration
Nullpointerex solved with certain invalid profiles
Be able to access additional files ("additional data")
Known bugs: src/test/resources/migration/reference/ZUGFeRD2_EXTENDED_Warenrechnung.xml is invalid
1.6.0
=====
2019-02-03

View File

@@ -38,7 +38,7 @@ As dependency use this
<dependency>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>mustang</artifactId>
<version>1.5.4</version>
<version>1.7.1</version>
</dependency>
<dependency>

View File

View File

@@ -5,12 +5,15 @@ import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTransaction;
import org.mustangproject.ZUGFeRD.ZUGFeRD2PullProvider;
import org.mustangproject.ZUGFeRD.ZUGFeRDExporter;
import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA1Factory;
@@ -32,8 +35,7 @@ public class MustangWriter implements IZUGFeRDExportableTransaction {
ze.export("./MustangGnuaccountingBeispielRE-20171118_506new.pdf");
System.out.println("Done.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Logger.getLogger(MustangWriter.class.getName()).log(Level.SEVERE, null, e1);
}
}

View File

@@ -0,0 +1,97 @@
## New build
Target platform is java 1.7
## Build
Toecount is now part of the package which can be build with
```
mvn clean package
```
## Test
`package -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001 -Xnoagent -Djava.compiler=NONE"`
can be used as debug configuration goal in Eclipse. In that case you can set breakpoints in tests.
## Validate
[ZUV](https://github.com/ZUGFeRD/ZUV/) can be used to validate generated files.
## Deployment
A section in Maven's settings.xml is needed, in Linux (and MacOS) that's at ~/.m2/settings.xml
As „servers“, enter the following
```xml
   <servers>
    <server>
      <id>github</id>
      <password>GITHUB-TOKEN</password>
    </server>
   </servers>
```
The whole settings.xml then looks e.g. like this
```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers>
<server>
      <id>github</id>
      <password>TOKEN</password>
    </server>
</servers>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>
```
The password is generated on github.
See the following screenshot:
Sign in in GitHub and click on the profile picture -> Settings. Now just generate a new token and set the checkboxes from the screenshot.
![screenshot](development_documentation_screenshot_github_settings.png "Screenshot Github Settings")
The Token-ID is the password.
## Release
You will need a git client on the console, if that's available can e.g. be checked with "git --version" .
Change to the root of the repo.
Change to the project directory and run
* "/usr/local/Cellar/maven/3.5.2/bin/mvn clean install" . If that works you can
* clean the release with „/usr/local/Cellar/maven/3.5.2/bin/mvn release:clean“ and prepare the release with
* "/usr/local/Cellar/maven/3.5.2/bin/mvn release:prepare -DignoreSnapshots=true" and enter the version numbers.
* After that is through you can create a new release via "/usr/local/Cellar/maven/3.5.2/bin/mvn release:perform -Darguments="-Dmaven.javadoc.skip=true".This will also update the maven repo.
![screenshot](development_documentation_screenshot_release.png "Screenshot Release")
Afterwards you can access the release page and update the documentation, e.g. upload the jar, the jar javadoc and ZugferdDev. You can also enter a changelog and a better title.
## Release process
* Update documentation
* write/translate announcement
* release via/for mvn
* Publish a github release
* update mustangproject.org RE
* version number and release date
* sample file?
* Deployment jar
* put announcement on usegroup
* email the mailing list
* freshcode.club

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 98 KiB

646
pom.xml
View File

@@ -1,327 +1,341 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>mustang</artifactId>
<version>1.6.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Mustang</name>
<description>The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>mustang</artifactId>
<version>1.7.4-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Mustang</name>
<description>The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs
</description>
<url>http://www.mustangproject.org/</url>
<scm>
<connection>scm:git:https://github.com/ZUGFeRD/mustangproject.git</connection>
<developerConnection>scm:git:https://github.com/ZUGFeRD/mustangproject.git</developerConnection>
<url>https://github.com/ZUGFeRD/mustangproject</url>
<tag>mustang-1.5.2</tag>
</scm>
<repositories>
<repository><!-- for jargs -->
<id>sonatype-oss-public</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>internal.repo</id>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/mvn-repo</url>
</repository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<github.global.server>github</github.global.server>
<additionalparam>-Xdoclint:none</additionalparam>
<!-- Skip error check for javadoc -->
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.8.0-11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<version>5.0.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-core</artifactId>
<version>2.6.2</version>
<scope>test</scope>
</dependency>
<!-- For Toecount -->
<dependency>
<groupId>com.sanityinc</groupId>
<artifactId>jargs</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<url>http://www.mustangproject.org/</url>
<scm>
<connection>scm:git:https://github.com/ZUGFeRD/mustangproject.git</connection>
<developerConnection>scm:git:https://github.com/ZUGFeRD/mustangproject.git</developerConnection>
<url>https://github.com/ZUGFeRD/mustangproject</url>
<tag>mustang-1.7.3</tag>
</scm>
<repositories>
<repository><!-- for jargs -->
<id>sonatype-oss-public</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>internal.repo</id>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/mvn-repo</url>
</repository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<github.global.server>github</github.global.server>
<additionalparam>-Xdoclint:none</additionalparam>
<!-- Skip error check for javadoc -->
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.8.0-11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin><!-- mvn help:effective-pom will otherwise tell it just defaults
to 2.3.2 - which does not release in the maven repo, and neither shows any
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId>
<version>[2.0.15,)</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>[2.0.15,)</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<version>5.0.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-core</artifactId>
<version>2.6.2</version>
<scope>test</scope>
</dependency>
<!-- For Toecount -->
<dependency>
<groupId>com.sanityinc</groupId>
<artifactId>jargs</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin><!-- mvn help:effective-pom will otherwise tell it just defaults
to 2.3.2 - which does not release in the maven repo, and neither shows any
error message :-( -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- toecount -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.mustangproject.toecount.Toecount</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
mvn clean compile assembly:single -->
<!-- or whatever version you use -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- toecount -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.mustangproject.toecount.Toecount</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
mvn clean compile assembly:single -->
<!-- or whatever version you use -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- /toecount -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<!-- /toecount -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<excludePackageNames>org.mustangproject.ZUGFeRD.model.*</excludePackageNames>
<excludePackageNames>org.mustangproject.ZUGFeRD.model.*</excludePackageNames>
</configuration>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo
</altDeploymentRepository>
</configuration>
</plugin>
<plugin>
<groupId>com.github.github</groupId>
<artifactId>site-maven-plugin</artifactId>
<version>0.12</version>
<configuration>
<message>Maven artifacts for ${project.version}</message>
<!-- git commit message -->
<noJekyll>true</noJekyll>
<!-- disable webpage processing -->
<outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
<!-- matches distribution management repository url above -->
<branch>refs/heads/mvn-repo</branch>
<!-- remote branch name -->
<includes>
<include>**/*</include>
</includes>
<merge>true</merge>
<repositoryName>mustangproject</repositoryName>
<!-- github repo name -->
<repositoryOwner>ZUGFeRD</repositoryOwner>
<!-- github username -->
</configuration>
<executions>
<!-- run site-maven-plugin's 'site' target as part of the build's normal
'deploy' phase -->
<execution>
<goals>
<goal>site</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.mustangproject.toecount.Toecount</mainClass>
</transformer>
</transformers>
<minimizeJar>true</minimizeJar>
<filters>
</configuration>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo
</altDeploymentRepository>
</configuration>
</plugin>
<plugin>
<groupId>com.github.github</groupId>
<artifactId>site-maven-plugin</artifactId>
<version>0.12</version>
<configuration>
<message>Maven artifacts for ${project.version}</message>
<!-- git commit message -->
<noJekyll>true</noJekyll>
<!-- disable webpage processing -->
<outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
<!-- matches distribution management repository url above -->
<branch>refs/heads/mvn-repo</branch>
<!-- remote branch name -->
<includes>
<include>**/*</include>
</includes>
<merge>true</merge>
<repositoryName>mustangproject</repositoryName>
<!-- github repo name -->
<repositoryOwner>ZUGFeRD</repositoryOwner>
<!-- github username -->
</configuration>
<executions>
<!-- run site-maven-plugin's 'site' target as part of the build's normal
'deploy' phase -->
<execution>
<goals>
<goal>site</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.mustangproject.toecount.Toecount</mainClass>
</transformer>
</transformers>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
<filter>
<artifact>log4j:log4j</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>com.sun.xml.bind:jaxb-impl</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>com.sun.xml.bind:jaxb-core</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<!--exclude>classworlds:classworlds</exclude> <exclude>junit:junit</exclude>
<exclude>jmock:*</exclude> <exclude>*:xml-apis</exclude> <exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude -->
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filtering-java-templates</id>
<goals>
<goal>filter-sources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<target>2.1</target>
<packageName>org.mustangproject.ZUGFeRD.model</packageName>
<sources>
<source>src/main/resources/schema/ZUGFeRD1p0.xsd</source>
</sources>
</configuration>
</plugin>
</plugins>
</build>
<mailingLists>
<mailingList>
<name>User List</name>
<archive>https://groups.google.com/forum/?hl=de#!forum/mustangproject</archive>
</mailingList>
</mailingLists>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<developers>
<developer>
<name>Jochen Stärk</name>
<email>jstaerk@usegroup.de</email>
<roles>
<role>architect</role>
<role>developer</role>
</roles>
</developer>
<developer>
<name>Alexander Schmidt</name>
<email>schmidt.alexander@mail.de</email>
<roles>
<role>developer</role>
</roles>
</developer>
</developers>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
<filter>
<artifact>log4j:log4j</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>com.sun.xml.bind:jaxb-impl</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>com.sun.xml.bind:jaxb-core</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<!--exclude>classworlds:classworlds</exclude> <exclude>junit:junit</exclude>
<exclude>jmock:*</exclude> <exclude>*:xml-apis</exclude> <exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude -->
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filtering-java-templates</id>
<goals>
<goal>filter-sources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<target>2.1</target>
<packageName>org.mustangproject.ZUGFeRD.model</packageName>
<sources>
<source>src/main/resources/schema/ZUGFeRD1p0.xsd</source>
</sources>
</configuration>
</plugin>
</plugins>
</build>
<mailingLists>
<mailingList>
<name>User List</name>
<archive>https://groups.google.com/forum/?hl=de#!forum/mustangproject</archive>
</mailingList>
</mailingLists>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<developers>
<developer>
<name>Jochen Stärk</name>
<email>jstaerk@usegroup.de</email>
<roles>
<role>architect</role>
<role>developer</role>
</roles>
</developer>
<developer>
<name>Alexander Schmidt</name>
<email>schmidt.alexander@mail.de</email>
<roles>
<role>developer</role>
</roles>
</developer>
</developers>
</project>

View File

@@ -18,7 +18,7 @@
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
public class CustomXMLProvider implements IXMLProvider {
public class CustomXMLProvider implements IXMLProvider, IProfileProvider {
protected byte[] zugferdData;
@@ -48,4 +48,14 @@ public class CustomXMLProvider implements IXMLProvider {
}
@Override
public String getProfile() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setProfile(ZUGFeRDConformanceLevel level) {
// TODO Auto-generated method stub
}
}

View File

@@ -22,6 +22,13 @@ import java.io.IOException;
import java.io.InputStream;
public interface IExporterFactory {
/**
* factory: loads a PDF file and returns an appropriate exporter
*
* @param pdfFilename binary of a PDF/A1 compliant document
* @return the generated exporter
* @throws IOException if anything is wrong with filename
*/
public ZUGFeRDExporter load(String pdfFilename) throws IOException;
/**
@@ -29,6 +36,8 @@ public interface IExporterFactory {
* metadata level, this will not e.g. convert graphics to JPG-2000)
*
* @param pdfBinary binary of a PDF/A1 compliant document
* @return the generated exporter
* @throws IOException (should not happen at all)
*/
public ZUGFeRDExporter load(byte[] pdfBinary) throws IOException;
@@ -37,7 +46,8 @@ public interface IExporterFactory {
* metadata level, this will not e.g. convert graphics to JPG-2000)
*
* @param pdfSource source to read a PDF/A1 compliant document from
* @throws IOException
* @throws IOException if anything is wrong with inputstream
* @return the generated ZUGFeRDExporter
*/
public ZUGFeRDExporter load(InputStream pdfSource) throws IOException;

View File

@@ -0,0 +1,27 @@
/** **********************************************************************
*
* Copyright 2018 Jochen Staerk
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
public interface IProfileProvider {
public String getProfile();
public void setProfile(ZUGFeRDConformanceLevel level);
}

View File

@@ -19,11 +19,11 @@
package org.mustangproject.ZUGFeRD;
/**
* Mustangproject's ZUGFeRD implementation Neccessary interface for ZUGFeRD exporter Licensed under the APLv2
* Mustangproject's ZUGFeRD implementation neccessary interface for ZUGFeRD exporter Licensed under the APLv2
*
* @author jstaerk
* @version 1.2.0
* @date 2014-05-10
* dated 2014-05-10
*/
@@ -38,6 +38,24 @@ public interface IZUGFeRDExportableContact {
return null;
}
/**
* customer global identification assigned by the seller
*
* @return customer identification
*/
default String getGlobalID() {
return null;
}
/**
* customer global identification scheme
*
* @return customer identification
*/
default String getGlobalIDScheme() {
return null;
}
/**
* First and last name of the recipient
@@ -48,6 +66,14 @@ public interface IZUGFeRDExportableContact {
return null;
}
default String getPhone() {
return null;
}
default String getEMail() {
return null;
}
/**
* Postal code of the recipient

View File

@@ -27,7 +27,7 @@ import java.math.BigDecimal;
*
* @author jstaerk
* @version 1.2.0
* @date 2014-05-10
* dated 2014-05-10
*/
public interface IZUGFeRDExportableProduct {

View File

@@ -27,12 +27,21 @@ package org.mustangproject.ZUGFeRD;
* */
import java.util.Date;
import java.math.BigDecimal;
import java.util.Date;
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
public interface IZUGFeRDExportableTransaction {
/**
* appears in /rsm:CrossIndustryDocument/rsm:HeaderExchangedDocument/ram:Name
* @return Name of document
*/
default String getDocumentName() {
return "RECHNUNG";
}
/**
*
*
@@ -65,7 +74,7 @@ public interface IZUGFeRDExportableTransaction {
/**
* this should be the full sender institution name, details, manager and tax registration. It is one of the few functions which may return null. e.g.
* <p/>
* <p>
* Lieferant GmbH Lieferantenstraße 20 80333 München Deutschland Geschäftsführer: Hans Muster Handelsregisternummer: H A 123
*
* @return null or full sender institution name, details, manager and tax registration
@@ -84,6 +93,15 @@ public interface IZUGFeRDExportableTransaction {
return null;
}
/**
* who processed the order
*
* @return the contact person at the supplier side
*/
default IZUGFeRDExportableContact getOwnContact() {
return null;
}
IZUGFeRDAllowanceCharge[] getZFAllowances();
@@ -106,53 +124,11 @@ public interface IZUGFeRDExportableTransaction {
/**
* BIC of the sender
*
* @return the BIC code of the recipient sender's bank
* the creditors payment informations
*
* @return an array of IZUGFeRDTradeSettlementPayment
*/
default String getOwnBIC() {
return null;
}
/**
* BLZ of the sender
*
* @return the BLZ code of the recipient sender's bank
*/
default String getOwnBLZ() {
return null;
}
/**
* Bank name of the sender
*
* @return the name of the sender's bank
*/
default String getOwnBankName() {
return null;
}
/**
* IBAN of the sender
*
* @return the IBAN of the invoice sender's bank account
*/
default String getOwnIBAN() {
return null;
}
/**
* IBAN of the sender
*
* @return the Account Number of the invoice sender's bank account
*/
default String getOwnKto() {
return null;
}
IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment();
/**
@@ -253,16 +229,6 @@ public interface IZUGFeRDExportableTransaction {
}
/**
* get payment information text. e.g. Bank transfer
*
* @return payment information text
*/
default String getOwnPaymentInfoText() {
return null;
}
/**
* get payment term descriptional text e.g. Bis zum 22.10.2015 ohne Abzug
*
@@ -282,7 +248,6 @@ public interface IZUGFeRDExportableTransaction {
return null;
}
/**
* get reference number of the purchase order this invoice is based on
*
@@ -352,4 +317,23 @@ public interface IZUGFeRDExportableTransaction {
return null;
}
/**
* get the ID of the BuyerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement
* @return the ID of the document
*/
default String getBuyerOrderReferencedDocumentID() { return null; }
/**
* get the issue timestamp of the BuyerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement
* @return the IssueDateTime in format CCYY-MM-DDTHH:MM:SS
*/
default String getBuyerOrderReferencedDocumentIssueDateTime() { return null; }
/**
* get the TotalPrepaidAmount located in SpecifiedTradeSettlementMonetarySummation (v1) or
* SpecifiedTradeSettlementHeaderMonetarySummation (v2)
* @return the total sum (incl. VAT) of prepayments, i.e. the difference between GrandTotalAmount
* and DuePayableAmount
*/
default BigDecimal getTotalPrepaidAmount() { return BigDecimal.ZERO; }
}

View File

@@ -0,0 +1,81 @@
/** **********************************************************************
*
* Copyright 2019 by ak on 12.04.19.
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
public interface IZUGFeRDTradeSettlementPayment {
/**
* get payment information text. e.g. Bank transfer
*
* @return payment information text
*/
default String getOwnPaymentInfoText() {
return null;
}
/**
* BIC of the sender
*
* @return the BIC code of the recipient sender's bank
*/
default String getOwnBIC() {
return null;
}
/**
* BLZ of the sender
*
* @return the BLZ code of the recipient sender's bank
*/
default String getOwnBLZ() {
return null;
}
/**
* Bank name of the sender
*
* @return the name of the sender's bank
*/
default String getOwnBankName() {
return null;
}
/**
* IBAN of the sender
*
* @return the IBAN of the invoice sender's bank account
*/
default String getOwnIBAN() {
return null;
}
/**
* IBAN of the sender
*
* @return the Account Number of the invoice sender's bank account
*/
default String getOwnKto() {
return null;
}
}

View File

@@ -27,20 +27,20 @@ import java.math.BigDecimal;
*
* @author jstaerk
* @version 1.2.0
* @date 2015-10-29
* dated 2015-10-29
*/
public class VATAmount {
public VATAmount(BigDecimal basis, BigDecimal calculated, String documentCode) {
public VATAmount(BigDecimal basis, BigDecimal calculated, String categoryCode) {
super();
this.basis = basis;
this.calculated = calculated;
this.documentCode = documentCode;
this.categoryCode = categoryCode;
}
BigDecimal basis, calculated;
String documentCode;
String categoryCode;
public BigDecimal getBasis() {
return basis;
@@ -58,20 +58,39 @@ public class VATAmount {
this.calculated = calculated;
}
/**
*
* @deprecated Use {@link #getCategoryCode() instead}
* @return String with category code
*/
@Deprecated
public String getDocumentCode() {
return documentCode;
return categoryCode;
}
/**
* @param documentCode as String
* @deprecated Use {@link #setCategoryCode(String)} instead
*/
@Deprecated
public void setDocumentCode(String documentCode) {
this.documentCode = documentCode;
this.categoryCode = documentCode;
}
public String getCategoryCode() {
return categoryCode;
}
public void setCategoryCode(String categoryCode) {
this.categoryCode = categoryCode;
}
public VATAmount add(VATAmount v) {
return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.documentCode);
return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.categoryCode);
}
public VATAmount subtract(VATAmount v) {
return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated()), this.documentCode);
return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated()), this.categoryCode);
}
}

View File

@@ -52,11 +52,13 @@ public class XMPSchemaPDFAExtensions extends PDFAExtensionSchema {
public final String prefix_pdfaProperty = "pdfaProperty";
public String namespace = null;
public String prefix = null;
protected ZUGFeRDExporter exporter;
protected void setZUGFeRDVersion(int ver) {
namespace = ZUGFeRDExporter.getNamespaceForVersion(ver);
prefix = ZUGFeRDExporter.getPrefixForVersion(ver);
namespace = exporter.getNamespaceForVersion(ver);
prefix = exporter.getPrefixForVersion(ver);
}
@@ -87,14 +89,16 @@ public class XMPSchemaPDFAExtensions extends PDFAExtensionSchema {
return li;
}
public XMPSchemaPDFAExtensions(XMPMetadata metadata, int ZFVersion) {
public XMPSchemaPDFAExtensions(ZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion) {
super(metadata);
exporter=ze;
setZUGFeRDVersion(ZFVersion);
attachExtensions(metadata, true);
}
public XMPSchemaPDFAExtensions(XMPMetadata metadata, int ZFVersion, boolean withZF) {
public XMPSchemaPDFAExtensions(ZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion, boolean withZF) {
super(metadata);
exporter=ze;
setZUGFeRDVersion(ZFVersion);
attachExtensions(metadata, withZF);
}

View File

@@ -31,8 +31,13 @@ import org.apache.xmpbox.schema.XMPSchema;
public class XMPSchemaZugferd extends XMPSchema {
/**
/***
* This is what needs to be added to the RDF metadata - basically the name of the embedded Zugferd file
* @param metadata the xmp to be added to
* @param conformanceLevel e.g. conformanceLevel.EN16931
* @param URN the xml URI for the XMP
* @param prefix the xml namespace prefix for the XMP, zf for ZUGFeRD, fx for Factur-X
* @param filename the filename of the invoice
*/
public XMPSchemaZugferd(XMPMetadata metadata, ZUGFeRDConformanceLevel conformanceLevel, String URN, String prefix, String filename) {
super(metadata, URN, prefix, "ZUGFeRD Schema");

View File

@@ -19,6 +19,7 @@
package org.mustangproject.ZUGFeRD;
import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType;
import org.mustangproject.ZUGFeRD.model.DocumentContextParameterTypeConstants;
import org.mustangproject.ZUGFeRD.model.ZFNamespacePrefixMapper;
import javax.xml.bind.JAXBContext;
@@ -27,13 +28,27 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.ByteArrayOutputStream;
public class ZUGFeRD1PullProvider implements IXMLProvider {
public class ZUGFeRD1PullProvider implements IXMLProvider, IProfileProvider {
protected byte[] zugferdData;
private Marshaller marshaller;
private boolean isTest;
private ZUGFeRDConformanceLevel level;
public void setProfile(ZUGFeRDConformanceLevel level) {
this.level = level;
}
public String getProfile() {
switch (level) {
case BASIC: return DocumentContextParameterTypeConstants.BASIC;
case COMFORT: return DocumentContextParameterTypeConstants.COMFORT;
default: return DocumentContextParameterTypeConstants.EXTENDED;
}
}
/**
@@ -59,7 +74,7 @@ public class ZUGFeRD1PullProvider implements IXMLProvider {
private String createZugferdXMLForTransaction(IZUGFeRDExportableTransaction trans) {
JAXBElement<CrossIndustryDocumentType> jaxElement =
new ZUGFeRDTransactionModelConverter(trans).withTest(isTest).convertToModel();
new ZUGFeRDTransactionModelConverter(trans).withTest(isTest).withProfile(getProfile()).convertToModel();
try {
return marshalJaxToXMLString(jaxElement);

View File

@@ -18,28 +18,42 @@
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ZUGFeRD2PullProvider implements IXMLProvider {
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.toecount.Toecount;
public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
private class LineCalc {
private IZUGFeRDExportableItem currentItem = null;
private BigDecimal totalGross;
private BigDecimal itemTotalNetAmount;
private BigDecimal itemTotalVATAmount;
public LineCalc(IZUGFeRDExportableItem currentItem) {
this.currentItem = currentItem;
BigDecimal multiplicator = currentItem.getProduct().getVATPercent().divide(new BigDecimal(100)).add(new BigDecimal(1));
// priceGross=currentItem.getPrice().multiply(multiplicator);
BigDecimal multiplicator = currentItem.getProduct().getVATPercent().divide(new BigDecimal(100))
.add(new BigDecimal(1));
// priceGross=currentItem.getPrice().multiply(multiplicator);
totalGross = currentItem.getPrice().multiply(multiplicator).multiply(currentItem.getQuantity());
itemTotalNetAmount = currentItem.getQuantity().multiply(currentItem.getPrice()).setScale(2, BigDecimal.ROUND_HALF_UP);
itemTotalNetAmount = currentItem.getQuantity().multiply(currentItem.getPrice()).setScale(2,
BigDecimal.ROUND_HALF_UP);
itemTotalVATAmount = totalGross.subtract(itemTotalNetAmount);
}
@@ -53,77 +67,90 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
//// MAIN CLASS
protected byte[] zugferdData;
private IZUGFeRDExportableTransaction trans;
private boolean isTest;
private ZUGFeRDConformanceLevel level;
public void setProfile(ZUGFeRDConformanceLevel level) {
this.level = level;
}
/**
* enables the flag to indicate a test invoice in the XML structure
*/
public void setTest() {
isTest = true;
}
private String nDigitFormat(BigDecimal value, int scale) {
public static String nDigitFormat(BigDecimal value, int scale) {
/*
* I needed 123,45, locale independent.I tried
* NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is
* locale specific.I also tried DecimalFormat df = new DecimalFormat(
* "0,00" ); df.setDecimalSeparatorAlwaysShown(true);
* df.setGroupingUsed(false); DecimalFormatSymbols symbols = new
* DecimalFormatSymbols(); symbols.setDecimalSeparator(',');
* symbols.setGroupingSeparator(' ');
* NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is locale
* specific.I also tried DecimalFormat df = new DecimalFormat( "0,00" );
* df.setDecimalSeparatorAlwaysShown(true); df.setGroupingUsed(false);
* DecimalFormatSymbols symbols = new DecimalFormatSymbols();
* symbols.setDecimalSeparator(','); symbols.setGroupingSeparator(' ');
* df.setDecimalFormatSymbols(symbols);
*
* but that would not switch off grouping. Although I liked very much
* the (incomplete) "BNF diagram" in
* http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
* in the end I decided to calculate myself and take eur+sparator+cents
* but that would not switch off grouping. Although I liked very much the
* (incomplete) "BNF diagram" in
* http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html in the
* end I decided to calculate myself and take eur+sparator+cents
*
* This function will cut off, i.e. floor() subcent values Tests:
* System.err.println(utils.currencyFormat(new BigDecimal(0),
* ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.1"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.01"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ","));
*
* results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00
*/
value = value.setScale(scale, BigDecimal.ROUND_HALF_UP); // first, round so that e.g. 1.189999999999999946709294817992486059665679931640625 becomes 1.19
char[] repeat = new char[scale];
Arrays.fill(repeat, '0');
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator('.');
DecimalFormat dec = new DecimalFormat("0." + new String(repeat), otherSymbols);
return dec.format(value);
return value.setScale(scale, RoundingMode.HALF_UP).toPlainString();
}
private String vatFormat(BigDecimal value) {
return nDigitFormat(value, 2);
return ZUGFeRD2PullProvider.nDigitFormat(value, 2);
}
private String currencyFormat(BigDecimal value) {
return nDigitFormat(value, 2);
return ZUGFeRD2PullProvider.nDigitFormat(value, 2);
}
private String priceFormat(BigDecimal value) {
return nDigitFormat(value, 4);
return ZUGFeRD2PullProvider.nDigitFormat(value, 4);
}
private String quantityFormat(BigDecimal value) {
return nDigitFormat(value, 4);
return ZUGFeRD2PullProvider.nDigitFormat(value, 4);
}
@Override
public byte[] getXML() {
return zugferdData;
byte[] res = zugferdData;
StringWriter sw = new StringWriter();
Document document=null;
try {
document = DocumentHelper.parseText(new String(zugferdData));
} catch (DocumentException e1) {
Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e1);
}
try {
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(sw, format);
writer.write(document);
res = sw.toString().getBytes("UTF-8");
} catch (IOException e) {
Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e);
}
return res;
}
private BigDecimal getTotalPrepaid() {
if (trans.getTotalPrepaidAmount()==null) {
return new BigDecimal(0);
} else {
return trans.getTotalPrepaidAmount();
}
}
private BigDecimal getTotalGross() {
@@ -147,20 +174,20 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
/**
* which taxes have been used with which amounts in this transaction,
* empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable
* to 19% VAT (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT)
* 190 Eur
* which taxes have been used with which amounts in this transaction, empty for
* no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable to 19% VAT
* (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) 190 Eur
*
* @return which taxes have been used with which amounts in this invoice
*/
private HashMap<BigDecimal, VATAmount> getVATPercentAmountMap() {
HashMap<BigDecimal, VATAmount> hm = new HashMap<BigDecimal, VATAmount>();
HashMap<BigDecimal, VATAmount> hm = new HashMap<>();
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalc lc = new LineCalc(currentItem);
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), trans.getDocumentCode());
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
trans.getDocumentCode());
VATAmount current = hm.get(percent);
if (current == null) {
hm.put(percent, itemVATAmount);
@@ -171,61 +198,101 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
return hm;
}
public String getProfile() {
return "urn:cen.eu:en16931:2017";
}
public static String encodeXML(CharSequence s) {
StringBuilder sb = new StringBuilder();
int len = s.length();
for (int i=0;i<len;i++) {
int c = s.charAt(i);
if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
c = ((c-0xd7c0)<<10) | (s.charAt(++i)&0x3ff); // UTF16 decode
}
if (c < 0x80) { // ASCII range: test most common case first
if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) {
// Illegal XML character, even encoded. Skip or substitute
sb.append("&#xfffd;"); // Unicode replacement character
} else {
switch(c) {
case '&': sb.append("&amp;"); break;
case '>': sb.append("&gt;"); break;
case '<': sb.append("&lt;"); break;
// Uncomment next two if encoding for an XML attribute
// case '\'' sb.append("&apos;"); break;
// case '\"' sb.append("&quot;"); break;
// Uncomment next three if you prefer, but not required
// case '\n' sb.append("&#10;"); break;
// case '\r' sb.append("&#13;"); break;
// case '\t' sb.append("&#9;"); break;
default: sb.append((char)c);
}
}
} else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) {
// Illegal XML character, even encoded. Skip or substitute
sb.append("&#xfffd;"); // Unicode replacement character
} else {
sb.append("&#x");
sb.append(Integer.toHexString(c));
sb.append(';');
}
}
return sb.toString();
}
@Override
public void generateXML(IZUGFeRDExportableTransaction trans) {
this.trans = trans;
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); //$NON-NLS-1$
SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); //$NON-NLS-1$
String testBooleanStr = "false";
if (isTest) {
testBooleanStr = "true";
}
String senderReg = "";
if (trans.getOwnOrganisationFullPlaintextInfo() != null) {
senderReg = ""
+ "<ram:IncludedCINote>\n"
+ " <ram:Content>\n"
+ trans.getOwnOrganisationFullPlaintextInfo()
+ " </ram:Content>\n"
+ "<ram:SubjectCode>REG</ram:SubjectCode>\n"
+ "</ram:IncludedCINote>\n";
senderReg = "" + "<ram:IncludedNote>\n" + " <ram:Content>\n"
+ encodeXML(trans.getOwnOrganisationFullPlaintextInfo()) + " </ram:Content>\n"
+ "<ram:SubjectCode>REG</ram:SubjectCode>\n" + "</ram:IncludedNote>\n";
}
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" //$NON-NLS-1$
+ "<rsm:CrossIndustryInvoice xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:rsm=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100\""
// + " xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 ../Schema/ZUGFeRD1p0.xsd\""
// + "
// xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100
// ../Schema/ZUGFeRD1p0.xsd\""
+ " xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100\""
+ " xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100\">\n" //$NON-NLS-1$
+ " <rsm:ExchangedDocumentContext>\n" //$NON-NLS-1$
// + " <ram:TestIndicator><udt:Indicator>"+testBooleanStr+"</udt:Indicator></ram:TestIndicator>\n" //$NON-NLS-1$
// + "
// <ram:TestIndicator><udt:Indicator>"+testBooleanStr+"</udt:Indicator></ram:TestIndicator>\n"
// //$NON-NLS-1$
+ " <ram:GuidelineSpecifiedDocumentContextParameter>\n" //$NON-NLS-1$
+ " <ram:ID>urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931</ram:ID>\n" //$NON-NLS-1$
+ " <ram:ID>" + getProfile() + "</ram:ID>\n" //$NON-NLS-1$
+ " </ram:GuidelineSpecifiedDocumentContextParameter>\n" //$NON-NLS-1$
+ " </rsm:ExchangedDocumentContext>\n" //$NON-NLS-1$
+ " <rsm:ExchangedDocument>\n" //$NON-NLS-1$
+ " <ram:ID>" + trans.getNumber() + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <ram:Name>RECHNUNG</ram:Name>\n" //$NON-NLS-1$
+ " <ram:ID>" + encodeXML(trans.getNumber()) + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <ram:Name>RECHNUNG</ram:Name>\n" //$NON-NLS-1$
+ " <ram:TypeCode>380</ram:TypeCode>\n" //$NON-NLS-1$
+ " <ram:IssueDateTime><udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(trans.getIssueDate()) + "</udt:DateTimeString></ram:IssueDateTime>\n" //date format was 20130605 //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:IssueDateTime><udt:DateTimeString format=\"102\">" //$NON-NLS-1$
+ zugferdDateFormat.format(trans.getIssueDate()) + "</udt:DateTimeString></ram:IssueDateTime>\n" // date //$NON-NLS-1$
// format
// was
// 20130605
+ senderReg
// + " <IncludedNote>\n"
// + " <Content>\n"
// + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n"
// + "\n"
// + " </Content>\n"
// + " </IncludedNote>\n"
// + " <IncludedNote>\n"
// + " <Content>\n"
// + "Es bestehen Rabatt- und Bonusvereinbarungen.\n"
// + " </Content>\n"
// + " <SubjectCode>AAK</SubjectCode>\n"
// + " </IncludedNote>\n"
// + " <IncludedNote>\n"
// + " <Content>\n"
// + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n"
// + "\n"
// + " </Content>\n"
// + " </IncludedNote>\n"
// + " <IncludedNote>\n"
// + " <Content>\n"
// + "Es bestehen Rabatt- und Bonusvereinbarungen.\n"
// + " </Content>\n"
// + " <SubjectCode>AAK</SubjectCode>\n"
// + " </IncludedNote>\n"
+ " </rsm:ExchangedDocument>\n" //$NON-NLS-1$
+ " <rsm:SupplyChainTradeTransaction>\n"; //$NON-NLS-1$
int lineID = 0;
@@ -238,188 +305,243 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:AssociatedDocumentLineDocument>\n" //$NON-NLS-1$
+ " <ram:SpecifiedTradeProduct>\n" //$NON-NLS-1$
// + " <GlobalID schemeID=\"0160\">4012345001235</GlobalID>\n"
// + " <SellerAssignedID>KR3M</SellerAssignedID>\n"
// + " <BuyerAssignedID>55T01</BuyerAssignedID>\n"
+ " <ram:Name>" + currentItem.getProduct().getName() + "</ram:Name>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:Description>" + currentItem.getProduct().getDescription() + "</ram:Description>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <GlobalID schemeID=\"0160\">4012345001235</GlobalID>\n"
// + " <SellerAssignedID>KR3M</SellerAssignedID>\n"
// + " <BuyerAssignedID>55T01</BuyerAssignedID>\n"
+ " <ram:Name>" + encodeXML(currentItem.getProduct().getName()) + "</ram:Name>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:Description>" + encodeXML(currentItem.getProduct().getDescription()) //$NON-NLS-1$
+ "</ram:Description>\n" //$NON-NLS-1$
+ " </ram:SpecifiedTradeProduct>\n" //$NON-NLS-1$
+ " <ram:SpecifiedLineTradeAgreement>\n" //$NON-NLS-1$
+ " <ram:GrossPriceProductTradePrice>\n" //$NON-NLS-1$
+ " <ram:ChargeAmount>" + priceFormat(currentItem.getPrice()) + "</ram:ChargeAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ //currencyID=\"EUR\"
+ " <ram:BasisQuantity unitCode=\"" + currentItem.getProduct().getUnit() + "\">1.0000</ram:BasisQuantity>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <AppliedTradeAllowanceCharge>\n"
// + " <ChargeIndicator>false</ChargeIndicator>\n"
// + " <ActualAmount currencyID=\"EUR\">0.6667</ActualAmount>\n"
// + " <Reason>Rabatt</Reason>\n"
// + " </AppliedTradeAllowanceCharge>\n"
+ " <ram:ChargeAmount>" + priceFormat(currentItem.getPrice()) //$NON-NLS-1$
+ "</ram:ChargeAmount>\n" //$NON-NLS-1$ //currencyID=\"EUR\"
+ " <ram:BasisQuantity unitCode=\"" + encodeXML(currentItem.getProduct().getUnit()) //$NON-NLS-1$
+ "\">1.0000</ram:BasisQuantity>\n" //$NON-NLS-1$
// + " <AppliedTradeAllowanceCharge>\n"
// + " <ChargeIndicator>false</ChargeIndicator>\n"
// + " <ActualAmount currencyID=\"EUR\">0.6667</ActualAmount>\n"
// + " <Reason>Rabatt</Reason>\n"
// + " </AppliedTradeAllowanceCharge>\n"
+ " </ram:GrossPriceProductTradePrice>\n" //$NON-NLS-1$
+ " <ram:NetPriceProductTradePrice>\n" //$NON-NLS-1$
+ " <ram:ChargeAmount>" + priceFormat(currentItem.getPrice()) + "</ram:ChargeAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ // currencyID=\"EUR\"
+ " <ram:BasisQuantity unitCode=\"" + currentItem.getProduct().getUnit() + "\">1.0000</ram:BasisQuantity>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:ChargeAmount>" + priceFormat(currentItem.getPrice()) //$NON-NLS-1$
+ "</ram:ChargeAmount>\n" //$NON-NLS-1$ // currencyID=\"EUR\"
+ " <ram:BasisQuantity unitCode=\"" + encodeXML(currentItem.getProduct().getUnit()) //$NON-NLS-1$
+ "\">1.0000</ram:BasisQuantity>\n" //$NON-NLS-1$
+ " </ram:NetPriceProductTradePrice>\n" //$NON-NLS-1$
+ " </ram:SpecifiedLineTradeAgreement>\n" //$NON-NLS-1$
+ " <ram:SpecifiedLineTradeDelivery>\n" //$NON-NLS-1$
+ " <ram:BilledQuantity unitCode=\"" + currentItem.getProduct().getUnit() + "\">" + quantityFormat(currentItem.getQuantity()) + "</ram:BilledQuantity>\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ " <ram:BilledQuantity unitCode=\"" + encodeXML(currentItem.getProduct().getUnit()) + "\">" //$NON-NLS-1$ //$NON-NLS-2$
+ quantityFormat(currentItem.getQuantity()) + "</ram:BilledQuantity>\n" //$NON-NLS-1$
+ " </ram:SpecifiedLineTradeDelivery>\n" //$NON-NLS-1$
+ " <ram:SpecifiedLineTradeSettlement>\n" //$NON-NLS-1$
+ " <ram:ApplicableTradeTax>\n" //$NON-NLS-1$
+ " <ram:TypeCode>VAT</ram:TypeCode>\n" //$NON-NLS-1$
+ " <ram:CategoryCode>S</ram:CategoryCode>\n" //$NON-NLS-1$
+ " <ram:RateApplicablePercent>" + vatFormat(currentItem.getProduct().getVATPercent()) + "</ram:RateApplicablePercent>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:RateApplicablePercent>" //$NON-NLS-1$
+ vatFormat(currentItem.getProduct().getVATPercent()) + "</ram:RateApplicablePercent>\n" //$NON-NLS-1$
+ " </ram:ApplicableTradeTax>\n" //$NON-NLS-1$
+ " <ram:SpecifiedTradeSettlementLineMonetarySummation>\n" //$NON-NLS-1$
+ " <ram:LineTotalAmount>" + currencyFormat(lc.getItemTotalNetAmount()) + "</ram:LineTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ // currencyID=\"EUR\"
+ " <ram:LineTotalAmount>" + currencyFormat(lc.getItemTotalNetAmount()) //$NON-NLS-1$
+ "</ram:LineTotalAmount>\n" //$NON-NLS-1$ // currencyID=\"EUR\"
+ " </ram:SpecifiedTradeSettlementLineMonetarySummation>\n" //$NON-NLS-1$
+ " </ram:SpecifiedLineTradeSettlement>\n" //$NON-NLS-1$
+ " </ram:IncludedSupplyChainTradeLineItem>\n"; //$NON-NLS-1$
}
xml = xml + " <ram:ApplicableHeaderTradeAgreement>\n"; //$NON-NLS-1$
if (trans.getReferenceNumber() != null) {
xml = xml + " <ram:BuyerReference>" + encodeXML(trans.getReferenceNumber()) + "</ram:BuyerReference>\n";
}
xml = xml + " <ram:SellerTradeParty>\n" //$NON-NLS-1$
// + " <GlobalID schemeID=\"0088\">4000001123452</GlobalID>\n"
+ " <ram:Name>" + encodeXML(trans.getOwnOrganisationName()) + "</ram:Name>\n"; //$NON-NLS-1$ //$NON-NLS-2$
if ((trans.getOwnVATID()!=null)&&(trans.getOwnOrganisationName()!=null)) {
xml = xml + " <ram:SpecifiedLegalOrganization>\n" + " <ram:ID schemeID='9930'>"
+ encodeXML(trans.getOwnVATID()) + "</ram:ID>\n" + " <ram:TradingBusinessName>"
+ encodeXML(trans.getOwnOrganisationName()) + "</ram:TradingBusinessName>\n"
+ " </ram:SpecifiedLegalOrganization>";
}
if (trans.getOwnContact() != null) {
xml = xml + "<ram:DefinedTradeContact>\n" + " <ram:PersonName>" + encodeXML(trans.getOwnContact().getName())
+ "</ram:PersonName>\n";
if (trans.getOwnContact().getPhone() != null) {
xml = xml + " <ram:TelephoneUniversalCommunication>\n" + " <ram:CompleteNumber>"
+ encodeXML(trans.getOwnContact().getPhone()) + "</ram:CompleteNumber>\n"
+ " </ram:TelephoneUniversalCommunication>\n";
}
if (trans.getOwnContact().getEMail() != null) {
xml = xml + " <ram:EmailURIUniversalCommunication>\n" + " <ram:URIID>"
+ encodeXML(trans.getOwnContact().getEMail()) + "</ram:URIID>\n"
+ " </ram:EmailURIUniversalCommunication>\n";
}
xml = xml + " </ram:DefinedTradeContact>";
}
xml = xml + " <ram:ApplicableHeaderTradeAgreement>\n" //$NON-NLS-1$
// + " <BuyerReference>AB-312</BuyerReference>\n"
+ " <ram:SellerTradeParty>\n" //$NON-NLS-1$
// + " <GlobalID schemeID=\"0088\">4000001123452</GlobalID>\n"
+ " <ram:Name>" + trans.getOwnOrganisationName() + "</ram:Name>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:PostalTradeAddress>\n"
+ " <ram:PostcodeCode>" + trans.getOwnZIP() + "</ram:PostcodeCode>\n"
+ " <ram:LineOne>" + trans.getOwnStreet() + "</ram:LineOne>\n"
+ " <ram:CityName>" + trans.getOwnLocation() + "</ram:CityName>\n"
+ " <ram:CountryID>" + trans.getOwnCountry() + "</ram:CountryID>\n"
+ " </ram:PostalTradeAddress>\n"
xml = xml + " <ram:PostalTradeAddress>\n" + " <ram:PostcodeCode>"
+ encodeXML(trans.getOwnZIP()) + "</ram:PostcodeCode>\n" + " <ram:LineOne>"
+ encodeXML(trans.getOwnStreet()) + "</ram:LineOne>\n" + " <ram:CityName>" + encodeXML(trans.getOwnLocation())
+ "</ram:CityName>\n" + " <ram:CountryID>" + encodeXML(trans.getOwnCountry())
+ "</ram:CountryID>\n" + " </ram:PostalTradeAddress>\n"
+ " <ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " <ram:ID schemeID=\"FC\">" + trans.getOwnTaxID() + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:ID schemeID=\"FC\">" + encodeXML(trans.getOwnTaxID()) + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " <ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " <ram:ID schemeID=\"VA\">" + trans.getOwnVATID() + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:ID schemeID=\"VA\">" + encodeXML(trans.getOwnVATID()) + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " </ram:SellerTradeParty>\n" //$NON-NLS-1$
+ " <ram:BuyerTradeParty>\n" //$NON-NLS-1$
// + " <ID>GE2020211</ID>\n"
// + " <GlobalID schemeID=\"0088\">4000001987658</GlobalID>\n"
+ " <ram:Name>" + trans.getRecipient().getName() + "</ram:Name>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <DefinedTradeContact>\n"
// + " <PersonName>xxx</PersonName>\n"
// + " </DefinedTradeContact>\n"
// + " <ID>GE2020211</ID>\n"
// + " <GlobalID schemeID=\"0088\">4000001987658</GlobalID>\n"
+ " <ram:Name>" + encodeXML(trans.getRecipient().getName()) + "</ram:Name>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <DefinedTradeContact>\n"
// + " <PersonName>xxx</PersonName>\n"
// + " </DefinedTradeContact>\n"
+ " <ram:PostalTradeAddress>\n" //$NON-NLS-1$
+ " <ram:PostcodeCode>" + trans.getRecipient().getZIP() + "</ram:PostcodeCode>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:LineOne>" + trans.getRecipient().getStreet() + "</ram:LineOne>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:CityName>" + trans.getRecipient().getLocation() + "</ram:CityName>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:CountryID>" + trans.getRecipient().getCountry() + "</ram:CountryID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:PostalTradeAddress>\n" //$NON-NLS-1$
+ " <ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " <ram:ID schemeID=\"VA\">" + trans.getRecipient().getVATID() + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " </ram:BuyerTradeParty>\n" //$NON-NLS-1$
// + " <BuyerOrderReferencedDocument>\n"
// + " <IssueDateTime format=\"102\">20130301</IssueDateTime>\n"
// + " <ID>2013-471331</ID>\n"
// + " </BuyerOrderReferencedDocument>\n"
+ " <ram:PostcodeCode>" + encodeXML(trans.getRecipient().getZIP()) + "</ram:PostcodeCode>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:LineOne>" + encodeXML(trans.getRecipient().getStreet()) + "</ram:LineOne>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:CityName>" + encodeXML(trans.getRecipient().getLocation()) + "</ram:CityName>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:CountryID>" + encodeXML(trans.getRecipient().getCountry()) + "</ram:CountryID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:PostalTradeAddress>\n"; //$NON-NLS-1$
if (trans.getRecipient().getVATID() != null) {
xml += " <ram:SpecifiedTaxRegistration>\n" //$NON-NLS-1$
+ " <ram:ID schemeID=\"VA\">" + encodeXML(trans.getRecipient().getVATID()) + "</ram:ID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:SpecifiedTaxRegistration>\n"; //$NON-NLS-1$
}
xml += " </ram:BuyerTradeParty>\n" //$NON-NLS-1$
// + " <BuyerOrderReferencedDocument>\n"
// + " <IssueDateTime format=\"102\">20130301</IssueDateTime>\n"
// + " <ID>2013-471331</ID>\n"
// + " </BuyerOrderReferencedDocument>\n"
+ " </ram:ApplicableHeaderTradeAgreement>\n" //$NON-NLS-1$
+ " <ram:ApplicableHeaderTradeDelivery>\n"
+ " <ram:ActualDeliverySupplyChainEvent>\n"
+ " <ram:OccurrenceDateTime><udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(trans.getDeliveryDate()) + "</udt:DateTimeString></ram:OccurrenceDateTime>\n"
+ " <ram:ApplicableHeaderTradeDelivery>\n" + " <ram:ActualDeliverySupplyChainEvent>\n"
+ " <ram:OccurrenceDateTime><udt:DateTimeString format=\"102\">"
+ zugferdDateFormat.format(trans.getDeliveryDate()) + "</udt:DateTimeString></ram:OccurrenceDateTime>\n"
+ " </ram:ActualDeliverySupplyChainEvent>\n"
/*
+ " <DeliveryNoteReferencedDocument>\n"
+ " <IssueDateTime format=\"102\">20130603</IssueDateTime>\n"
+ " <ID>2013-51112</ID>\n"
+ " </DeliveryNoteReferencedDocument>\n" */
+ " </ram:ApplicableHeaderTradeDelivery>\n"
+ " <ram:ApplicableHeaderTradeSettlement>\n" //$NON-NLS-1$
+ " <ram:PaymentReference>" + trans.getNumber() + "</ram:PaymentReference>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>\n" //$NON-NLS-1$
+ " <ram:SpecifiedTradeSettlementPaymentMeans>\n" //$NON-NLS-1$
+ " <ram:TypeCode>42</ram:TypeCode>\n" //$NON-NLS-1$
+ " <ram:Information>Überweisung</ram:Information>\n" //$NON-NLS-1$
+ " <ram:PayeePartyCreditorFinancialAccount>\n" //$NON-NLS-1$
+ " <ram:IBANID>" + trans.getOwnIBAN() + "</ram:IBANID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:ProprietaryID>" + trans.getOwnKto() + "</ram:ProprietaryID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:PayeePartyCreditorFinancialAccount>\n" //$NON-NLS-1$
+ " <ram:PayeeSpecifiedCreditorFinancialInstitution>\n" //$NON-NLS-1$
+ " <ram:BICID>" + trans.getOwnBIC() + "</ram:BICID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:GermanBankleitzahlID>" + trans.getOwnBLZ() + "</ram:GermanBankleitzahlID>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <ram:Name>"+trans.getOwnBankName()+"</ram:Name>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:PayeeSpecifiedCreditorFinancialInstitution>\n" //$NON-NLS-1$
+ " </ram:SpecifiedTradeSettlementPaymentMeans>\n"; //$NON-NLS-1$
/*
* + " <DeliveryNoteReferencedDocument>\n" +
* " <IssueDateTime format=\"102\">20130603</IssueDateTime>\n" +
* " <ID>2013-51112</ID>\n" +
* " </DeliveryNoteReferencedDocument>\n"
*/
+ " </ram:ApplicableHeaderTradeDelivery>\n" + " <ram:ApplicableHeaderTradeSettlement>\n" //$NON-NLS-2$
+ " <ram:PaymentReference>" + encodeXML(trans.getNumber()) + "</ram:PaymentReference>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>\n"; //$NON-NLS-1$
for (IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) {
xml += " <ram:SpecifiedTradeSettlementPaymentMeans>\n" //$NON-NLS-1$
+ " <ram:TypeCode>42</ram:TypeCode>\n" //$NON-NLS-1$
+ " <ram:Information>Überweisung</ram:Information>\n" //$NON-NLS-1$
+ " <ram:PayeePartyCreditorFinancialAccount>\n" //$NON-NLS-1$
+ " <ram:IBANID>" + encodeXML(payment.getOwnIBAN()) + "</ram:IBANID>\n"; //$NON-NLS-1$ //$NON-NLS-2$
if (payment.getOwnKto()!=null) {
xml+= " <ram:ProprietaryID>" + encodeXML(payment.getOwnKto()) + "</ram:ProprietaryID>\n"; //$NON-NLS-1$ //$NON-NLS-2$
}
xml+= " </ram:PayeePartyCreditorFinancialAccount>\n" //$NON-NLS-1$
+ " <ram:PayeeSpecifiedCreditorFinancialInstitution>\n" //$NON-NLS-1$
+ " <ram:BICID>" + encodeXML(payment.getOwnBIC()) + "</ram:BICID>\n" //$NON-NLS-1$ //$NON-NLS-2$
// + " <ram:Name>"+trans.getOwnBankName()+"</ram:Name>\n" //$NON-NLS-1$
// //$NON-NLS-2$
+ " </ram:PayeeSpecifiedCreditorFinancialInstitution>\n" //$NON-NLS-1$
+ " </ram:SpecifiedTradeSettlementPaymentMeans>\n"; //$NON-NLS-1$
}
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) {
xml += " <ram:ApplicableTradeTax>\n" //$NON-NLS-1$
+ " <ram:CalculatedAmount>" + currencyFormat(amount.getCalculated()) + "</ram:CalculatedAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ //currencyID=\"EUR\"
+ " <ram:CalculatedAmount>" + currencyFormat(amount.getCalculated()) //$NON-NLS-1$
+ "</ram:CalculatedAmount>\n" //$NON-NLS-1$ //currencyID=\"EUR\"
+ " <ram:TypeCode>VAT</ram:TypeCode>\n" //$NON-NLS-1$
+ " <ram:BasisAmount>" + currencyFormat(amount.getBasis()) + "</ram:BasisAmount>\n" // currencyID=\"EUR\"
+ " <ram:CategoryCode>S</ram:CategoryCode>\n" //$NON-NLS-1$
+ " <ram:RateApplicablePercent>" + vatFormat(currentTaxPercent) + "</ram:RateApplicablePercent>\n" //$NON-NLS-1$
+ " </ram:ApplicableTradeTax>\n"; //$NON-NLS-1$
+ " <ram:RateApplicablePercent>" + vatFormat(currentTaxPercent) //$NON-NLS-1$
+ "</ram:RateApplicablePercent>\n" + " </ram:ApplicableTradeTax>\n"; //$NON-NLS-2$
}
}
/* xml+= "
+ " <SpecifiedTradeAllowanceCharge>\n"
+ " <ChargeIndicator>false</ChargeIndicator>\n"
+ " <BasisAmount currencyID=\"EUR\">10</BasisAmount>\n"
+ " <ActualAmount>1.00</ActualAmount>\n"
+ " <Reason>Sondernachlass</Reason>\n"
+ " <CategoryTradeTax>\n"
+ " <TypeCode>VAT</TypeCode>\n"
+ " <CategoryCode>S</CategoryCode>\n"
+ " <ApplicablePercent>19</ApplicablePercent>\n"
+ " </CategoryTradeTax>\n"
+ " </SpecifiedTradeAllowanceCharge>\n"
+ " <SpecifiedTradeAllowanceCharge>\n"
+ " <ChargeIndicator>false</ChargeIndicator>\n"
+ " <BasisAmount currencyID=\"EUR\">137.30</BasisAmount>\n"
+ " <ActualAmount>13.73</ActualAmount>\n"
+ " <Reason>Sondernachlass</Reason>\n"
+ " <CategoryTradeTax>\n"
+ " <TypeCode>VAT</TypeCode>\n"
+ " <CategoryCode>S</CategoryCode>\n"
+ " <ApplicablePercent>7</ApplicablePercent>\n"
+ " </CategoryTradeTax>\n"
+ " </SpecifiedTradeAllowanceCharge>\n"
+ " <SpecifiedLogisticsServiceCharge>\n"
+ " <Description>Versandkosten</Description>\n"
+ " <AppliedAmount>5.80</AppliedAmount>\n"
+ " <AppliedTradeTax>\n"
+ " <TypeCode>VAT</TypeCode>\n"
+ " <CategoryCode>S</CategoryCode>\n"
+ " <ApplicablePercent>7</ApplicablePercent>\n"
+ " </AppliedTradeTax>\n"
+ " </SpecifiedLogisticsServiceCharge>\n"*/
/*
* xml+= " + " <SpecifiedTradeAllowanceCharge>\n" +
* " <ChargeIndicator>false</ChargeIndicator>\n" +
* " <BasisAmount currencyID=\"EUR\">10</BasisAmount>\n" +
* " <ActualAmount>1.00</ActualAmount>\n" +
* " <Reason>Sondernachlass</Reason>\n" +
* " <CategoryTradeTax>\n" +
* " <TypeCode>VAT</TypeCode>\n" +
* " <CategoryCode>S</CategoryCode>\n" +
* " <ApplicablePercent>19</ApplicablePercent>\n" +
* " </CategoryTradeTax>\n" +
* " </SpecifiedTradeAllowanceCharge>\n" +
* " <SpecifiedTradeAllowanceCharge>\n" +
* " <ChargeIndicator>false</ChargeIndicator>\n" +
* " <BasisAmount currencyID=\"EUR\">137.30</BasisAmount>\n" +
* " <ActualAmount>13.73</ActualAmount>\n" +
* " <Reason>Sondernachlass</Reason>\n" +
* " <CategoryTradeTax>\n" +
* " <TypeCode>VAT</TypeCode>\n" +
* " <CategoryCode>S</CategoryCode>\n" +
* " <ApplicablePercent>7</ApplicablePercent>\n" +
* " </CategoryTradeTax>\n" +
* " </SpecifiedTradeAllowanceCharge>\n" +
* " <SpecifiedLogisticsServiceCharge>\n" +
* " <Description>Versandkosten</Description>\n" +
* " <AppliedAmount>5.80</AppliedAmount>\n" +
* " <AppliedTradeTax>\n" +
* " <TypeCode>VAT</TypeCode>\n" +
* " <CategoryCode>S</CategoryCode>\n" +
* " <ApplicablePercent>7</ApplicablePercent>\n" +
* " </AppliedTradeTax>\n" +
* " </SpecifiedLogisticsServiceCharge>\n"
*/
xml = xml + " <ram:SpecifiedTradePaymentTerms>\n" //$NON-NLS-1$
+ " <ram:Description>Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()) + "</ram:Description>\n"
+ " <ram:DueDateDateTime><udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(trans.getDueDate()) + "</udt:DateTimeString></ram:DueDateDateTime>\n"//20130704 //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:Description>Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate())
+ "</ram:Description>\n" + " <ram:DueDateDateTime><udt:DateTimeString format=\"102\">" //$NON-NLS-2$
+ zugferdDateFormat.format(trans.getDueDate()) + "</udt:DateTimeString></ram:DueDateDateTime>\n"// 20130704 //$NON-NLS-1$
+ " </ram:SpecifiedTradePaymentTerms>\n" //$NON-NLS-1$
+ " <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n" //$NON-NLS-1$
+ " <ram:LineTotalAmount>" + currencyFormat(getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ currencyID=\"EUR\"
+ " <ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>\n" //$NON-NLS-1$ currencyID=\"EUR\"
+ " <ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>\n" //$NON-NLS-1$ // currencyID=\"EUR\"
// + " <ChargeTotalAmount currencyID=\"EUR\">5.80</ChargeTotalAmount>\n"
// + " <AllowanceTotalAmount currencyID=\"EUR\">14.73</AllowanceTotalAmount>\n"
+ " <ram:TaxBasisTotalAmount>" + currencyFormat(getTotal()) + "</ram:TaxBasisTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ // currencyID=\"EUR\"
+ " <ram:TaxTotalAmount currencyID=\"EUR\">" + currencyFormat(getTotalGross().subtract(getTotal())) + "</ram:TaxTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:GrandTotalAmount>" + currencyFormat(getTotalGross()) + "</ram:GrandTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ // currencyID=\"EUR\"
// + " <TotalPrepaidAmount currencyID=\"EUR\">0.00</TotalPrepaidAmount>\n"
+ " <ram:DuePayableAmount>" + currencyFormat(getTotalGross()) + "</ram:DuePayableAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$ // currencyID=\"EUR\"
+ " <ram:LineTotalAmount>" + currencyFormat(getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$
// currencyID=\"EUR\"
+ " <ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>\n" //$NON-NLS-1$ currencyID=\"EUR\"
+ " <ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>\n" //$NON-NLS-1$ //
// currencyID=\"EUR\"
// + " <ChargeTotalAmount currencyID=\"EUR\">5.80</ChargeTotalAmount>\n"
// + " <AllowanceTotalAmount currencyID=\"EUR\">14.73</AllowanceTotalAmount>\n"
+ " <ram:TaxBasisTotalAmount>" + currencyFormat(getTotal()) + "</ram:TaxBasisTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " <ram:TaxTotalAmount currencyID=\"EUR\">" //$NON-NLS-1$
+ currencyFormat(getTotalGross().subtract(getTotal())) + "</ram:TaxTotalAmount>\n" //$NON-NLS-1$
+ " <ram:GrandTotalAmount>" + currencyFormat(getTotalGross()) + "</ram:GrandTotalAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " <ram:TotalPrepaidAmount currencyID=\"EUR\">" + currencyFormat(getTotalPrepaid()) + "</ram:TotalPrepaidAmount>\n"
+ " <ram:DuePayableAmount>" + currencyFormat(getTotalGross().subtract(getTotalPrepaid())) + "</ram:DuePayableAmount>\n" //$NON-NLS-1$ //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " </ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n" //$NON-NLS-1$
+ " </ram:ApplicableHeaderTradeSettlement>\n"; //$NON-NLS-1$
// + " <IncludedSupplyChainTradeLineItem>\n"
// + " <AssociatedDocumentLineDocument>\n"
// + " <IncludedNote>\n"
// + " <Content>Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. 2013-51112 in Rechnung zu stellen:</Content>\n"
// + " </IncludedNote>\n"
// + " </AssociatedDocumentLineDocument>\n"
// + " </IncludedSupplyChainTradeLineItem>\n";
// + " <IncludedSupplyChainTradeLineItem>\n"
// + " <AssociatedDocumentLineDocument>\n"
// + " <IncludedNote>\n"
// + " <Content>Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr.
// 2013-51112 in Rechnung zu stellen:</Content>\n"
// + " </IncludedNote>\n"
// + " </AssociatedDocumentLineDocument>\n"
// + " </IncludedSupplyChainTradeLineItem>\n";
xml = xml + " </rsm:SupplyChainTradeTransaction>\n" //$NON-NLS-1$
+ "</rsm:CrossIndustryInvoice>"; //$NON-NLS-1$
@@ -436,9 +558,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
zugferdData = zugferdRaw;
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //$NON-NLS-1$
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
} // $NON-NLS-1$
}
}

View File

@@ -33,6 +33,7 @@ import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
@@ -55,7 +56,7 @@ public class ZUGFeRDExporter implements Closeable {
public static final int DefaultZUGFeRDVersion = 1;
private static boolean isFacturX = false;
private boolean isFacturX = false;
/**
* To use the ZUGFeRD exporter, implement IZUGFeRDExportableTransaction in
@@ -96,7 +97,7 @@ public class ZUGFeRDExporter implements Closeable {
*/
protected String producer = "mustangproject";
/**
* Author/Creator attribute for PDF for PDF
* Author/Creator attribute for PDF
*/
protected String creator = "mustangproject";
/**
@@ -133,7 +134,7 @@ public class ZUGFeRDExporter implements Closeable {
additionalXMLs.put(filename, xml);
}
public static String getNamespaceForVersion(int ver) {
public String getNamespaceForVersion(int ver) {
if (isFacturX) {
return "urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#";
} else if (ver == 1) {
@@ -146,7 +147,7 @@ public class ZUGFeRDExporter implements Closeable {
}
}
public static String getPrefixForVersion(int ver) {
public String getPrefixForVersion(int ver) {
if (isFacturX) {
return "fx";
} else {
@@ -154,11 +155,15 @@ public class ZUGFeRDExporter implements Closeable {
}
}
public static String getFilenameForVersion(int ver) {
public String getFilenameForVersion(int ver) {
if (isFacturX) {
return "factur-x.xml";
} else {
return "ZUGFeRD-invoice.xml";
if (ver==1) {
return "ZUGFeRD-invoice.xml";
} else {
return "zugferd-invoice.xml";
}
}
}
@@ -191,15 +196,16 @@ public class ZUGFeRDExporter implements Closeable {
/**
* All files are PDF/A-3, setConformance refers to the level conformance.
* <p/>
*
* PDF/A-3 has three conformance levels, called "A", "U" and "B".
* <p/>
* <p>
* PDF/A-3-B where B means only visually preservable, U -standard for Mustang-
* means visually and unicode preservable and A means full compliance, i.e.
* visually, unicode and structurally preservable and tagged PDF, i.e. useful
* metainformation for blind people.
* <p/>
* <p>
* Feel free to pass "A" as new level if you know what you are doing :-)
* @param newLevel "A", "U" or "B"
*
* @deprecated Use {@link ZUGFeRDExporterFromA1Factory} instead
*/
@@ -213,16 +219,17 @@ public class ZUGFeRDExporter implements Closeable {
/**
* All files are PDF/A-3, setConformance refers to the level conformance.
* <p/>
* <p>
* PDF/A-3 has three conformance levels, called "A", "U" and "B".
* <p/>
* <p>
* PDF/A-3-B where B means only visually preservable, U -standard for Mustang-
* means visually and unicode preservable and A means full compliance, i.e.
* visually, unicode and structurally preservable and tagged PDF, i.e. useful
* metainformation for blind people.
* <p/>
* <p>
* Feel free to pass "A" as new level if you know what you are doing :-)
*
* @param newLevel "A", "U" or "B"
* @deprecated Use
* {@link #setConformanceLevel(org.mustangproject.ZUGFeRD.PDFAConformanceLevel)}
* instead
@@ -247,27 +254,45 @@ public class ZUGFeRDExporter implements Closeable {
ignoreA1Errors = true;
}
/**
/***
* load from a pdf which is already A/3
* @param filename the PDF
* @throws IOException if anything is wrong with filename
* @deprecated Use the factory method {@link #createFromPDFA3(String)} instead
*/
@Deprecated
public void loadPDFA3(String filename) throws IOException {
doc = PDDocument.load(new File(filename));
}
/***
* factory create a ZUGFeRD exporter for a PDF/A-3 pdf file
* @param filename of the pdf
* @return the created ZUGFeRDExporter
* @throws IOException if something is wrong with filename
*/
public static ZUGFeRDExporter createFromPDFA3(String filename) throws IOException {
return new ZUGFeRDExporter(PDDocument.load(new File(filename)));
}
/**
* @deprecated Use the factory method {@link #createFromPDFA3(InputStream)}
* instead
* load from a pdf which is already A/3 from filestream
* @param file InputStream to load pdf from
* @deprecated Use the factory method {@link #createFromPDFA3(InputStream)} instead
* @throws IOException in case anything is wrong with file
*
*/
@Deprecated
public void loadPDFA3(InputStream file) throws IOException {
doc = PDDocument.load(file);
}
/***
* factory create a ZUGFeRD exporter for a PDF/A-3 inputstream
* @param pdfSource the InputStream of the pdf
* @return the created ZUGFeRDExporter
* @throws IOException (should not happen)
*/
public static ZUGFeRDExporter createFromPDFA3(InputStream pdfSource) throws IOException {
return new ZUGFeRDExporter(PDDocument.load(pdfSource));
}
@@ -275,7 +300,13 @@ public class ZUGFeRDExporter implements Closeable {
/**
* Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the
* metadata level, this will not e.g. convert graphics to JPG-2000)
*
* @param filename the pdf
* @param producer the name of the xmp producer (app)
* @param creator the name of the xmp creator (user)
* @param attachZugferdHeaders whether to attach XMP ZUGFeRD headers
* @return the created PDFbox PDDocumentCatalog
* @throws IOException if anything is wrong with file
* @throws TransformerException in case of xml (XMP) parsing issues
* @deprecated use the {@link ZUGFeRDExporterFromA1Factory} instead
*/
@Deprecated
@@ -287,7 +318,18 @@ public class ZUGFeRDExporter implements Closeable {
return doc.getDocumentCatalog();
}
/**
/***
*
* Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the
* metadata level, this will not e.g. convert graphics to JPG-2000)
* @param file the InputStream of the pdf
* @param producer the name of the xmp producer (app)
* @param creator the name of the xmp creator (user)
* @param attachZugferdHeaders whether to attach XMP ZUGFeRD headers
* @return the created PDFbox PDDocumentCatalog
* @throws IOException if anything is wrong with file
* @throws TransformerException in case of xml (XMP) parsing issues
* @deprecated use the {@link ZUGFeRDExporterFromA1Factory} instead
*/
@Deprecated
@@ -299,6 +341,7 @@ public class ZUGFeRDExporter implements Closeable {
return doc.getDocumentCatalog();
}
private IExporterFactory createPDFA1Factory() {
ZUGFeRDExporterFromA1Factory factory = new ZUGFeRDExporterFromA1Factory();
if (ignoreA1Errors) {
@@ -321,10 +364,11 @@ public class ZUGFeRDExporter implements Closeable {
* populate the XML. This parameter may be null, if so the XML data
* should hav ebeen set via
* <code>setZUGFeRDXMLData(byte[] zugferdData)</code>
* @throws IOException if anything is wrong with already loaded PDF
*/
public void PDFattachZugferdFile(IZUGFeRDExportableTransaction trans) throws IOException {
prepareDocument();
((IProfileProvider) xmlProvider).setProfile(profile);
xmlProvider.generateXML(trans);
String filename = getFilenameForVersion(ZFVersion);
PDFAttachGenericFile(doc, filename, "Alternative",
@@ -335,6 +379,11 @@ public class ZUGFeRDExporter implements Closeable {
}
}
/***
* Perform the final export to a now ZUGFeRD-enriched PDF file
* @param ZUGFeRDfilename the pdf file name
* @throws IOException if anything is wrong in the target location
*/
public void export(String ZUGFeRDfilename) throws IOException {
if (!documentPrepared) {
prepareDocument();
@@ -349,8 +398,17 @@ public class ZUGFeRDExporter implements Closeable {
}
}
/***
* Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream
* @param output the OutputStream
* @throws IOException if anything is wrong in the OutputStream
*/
public void export(OutputStream output) throws IOException {
if (!fileAttached) {
if (!documentPrepared) {
prepareDocument();
}
if ((!fileAttached) && (attachZUGFeRDHeaders)) {
throw new IOException(
"File must be attached (usually with PDFattachZugferdFile) before perfoming this operation");
}
@@ -369,7 +427,7 @@ public class ZUGFeRDExporter implements Closeable {
* @param description Human-readable description of the file content
* @param subType type of the data e.g. could be "text/xml" - mime like
* @param data the binary data of the file/attachment
* @throws java.io.IOException
* @throws java.io.IOException if anything is wrong with filename
*/
public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description,
String subType, byte[] data) throws IOException {
@@ -421,17 +479,27 @@ public class ZUGFeRDExporter implements Closeable {
doc.getDocumentCatalog().setNames(names);
// AF entry (Array) in catalog with the FileSpec
COSArray cosArray = (COSArray) doc.getDocumentCatalog().getCOSObject().getItem("AF");
if (cosArray == null) {
cosArray = new COSArray();
}
cosArray.add(fs);
COSDictionary dict2 = doc.getDocumentCatalog().getCOSObject();
COSArray array = new COSArray();
array.add(fs.getCOSObject()); // see below
dict2.setItem("AF", array);
doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray);
}
COSBase AFEntry = (COSBase)doc.getDocumentCatalog().getCOSObject().getItem("AF");
if ((AFEntry == null))
{
COSArray cosArray = new COSArray();
cosArray.add(fs);
doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray);
} else if (AFEntry instanceof COSArray)
{
COSArray cosArray = (COSArray)AFEntry;
cosArray.add(fs);
doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray);
} else if ((AFEntry instanceof COSObject) &&
((COSObject)AFEntry).getObject() instanceof COSArray)
{
COSArray cosArray = (COSArray)((COSObject)AFEntry).getObject();
cosArray.add(fs);
} else
{
throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)");
}
}
/**
* Sets the ZUGFeRD XML data to be attached as a single byte array. This is
@@ -439,6 +507,7 @@ public class ZUGFeRDExporter implements Closeable {
* API or component.
*
* @param zugferdData XML data to be set as a byte array (XML file in raw form).
* @throws IOException (should not happen)
*/
public void setZUGFeRDXMLData(byte[] zugferdData) throws IOException {
CustomXMLProvider cus = new CustomXMLProvider();
@@ -488,19 +557,19 @@ public class ZUGFeRDExporter implements Closeable {
* neccessary PDF/A schema extension description to be able to add this
* information to RDF
*
* @param metadata
* @param metadata the PDFbox XMPMetadata object
*/
protected void addXMP(XMPMetadata metadata) {
if (attachZUGFeRDHeaders) {
XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, profile,
ZUGFeRDExporter.getNamespaceForVersion(ZFVersion), ZUGFeRDExporter.getPrefixForVersion(ZFVersion),
ZUGFeRDExporter.getFilenameForVersion(ZFVersion));
getNamespaceForVersion(ZFVersion), getPrefixForVersion(ZFVersion),
getFilenameForVersion(ZFVersion));
metadata.addSchema(zf);
}
XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(metadata, ZFVersion, attachZUGFeRDHeaders);
XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, ZFVersion, attachZUGFeRDHeaders);
pdfaex.setZUGFeRDVersion(ZFVersion);
metadata.addSchema(pdfaex);
@@ -517,12 +586,12 @@ public class ZUGFeRDExporter implements Closeable {
buffer.write(prefix.getBytes("UTF-8")); // see https://github.com/ZUGFeRD/mustangproject/issues/44
serializer.serialize(xmpMetadata, buffer, false);
buffer.write(suffix.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e)
{
throw new TransformerException(e);
} catch (IOException e)
{
throw new TransformerException(e);
}
return buffer.toByteArray();
}
@@ -600,7 +669,7 @@ public class ZUGFeRDExporter implements Closeable {
/**
* the human author (use factory method instead)
*
* @param creator
* @param creator the (human) name who created the PDF
*/
@Deprecated
public void setCreator(String creator) {
@@ -610,7 +679,7 @@ public class ZUGFeRDExporter implements Closeable {
/**
* the CreatorTool attribute for the PDF
*
* @param creator
* @param creatorTool the application which created the PDF
*/
protected void setCreatorTool(String creatorTool) {
this.creatorTool = creatorTool;
@@ -619,7 +688,7 @@ public class ZUGFeRDExporter implements Closeable {
/**
* the authoring software (use factory method instead)
*
* @param producer
* @param producer the authoring software
*/
@Deprecated
public void setProducer(String producer) {
@@ -640,4 +709,17 @@ public class ZUGFeRDExporter implements Closeable {
this.attachZUGFeRDHeaders = attachZUGFeRDHeaders;
}
/**
* encapsulate the deprecated setters
* @param zfVersion 1 or 2
* @param zugferdConformanceLevel BASIC, COMFORT, EN16931, etc.
* @param creator PDF creator
* @param producer PDF producer
*/
public void configure(int zfVersion, ZUGFeRDConformanceLevel zugferdConformanceLevel, String creator, String producer) {
setZUGFeRDVersion(zfVersion);
setZUGFeRDConformanceLevel(zugferdConformanceLevel);
setCreator(creator);
setProducer(producer);
}
}

View File

@@ -63,20 +63,9 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
public ZUGFeRDExporter load(String pdfFilename) throws IOException {
ensurePDFIsValidPDFA(new FileDataSource(pdfFilename));
ZUGFeRDExporter zugFeRDExporter;
PDDocument doc = PDDocument.load(new File(pdfFilename));
zugFeRDExporter = new ZUGFeRDExporter(doc);
zugFeRDExporter.setZUGFeRDVersion(ZFVersion);
zugFeRDExporter.setZUGFeRDConformanceLevel(zugferdConformanceLevel);
zugFeRDExporter.setCreator(creator);
// Use creator as default for compatibility
zugFeRDExporter.setCreatorTool(creatorTool != null ? creatorTool : creator);
zugFeRDExporter.setProducer(producer);
zugFeRDExporter.setAttachZUGFeRDHeaders(attachZUGFeRDHeaders);
zugFeRDExporter.setPDFA3(ensurePDFisUpgraded);
return zugFeRDExporter;
try (FileInputStream pdf = new FileInputStream(pdfFilename)) {
return load(readAllBytes(pdf));
}
}
@@ -88,13 +77,9 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
*/
public ZUGFeRDExporter load(byte[] pdfBinary) throws IOException {
ensurePDFIsValidPDFA(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
ZUGFeRDExporter zugFeRDExporter;
PDDocument doc = PDDocument.load(pdfBinary);
zugFeRDExporter = new ZUGFeRDExporter(doc);
zugFeRDExporter.setZUGFeRDVersion(ZFVersion);
zugFeRDExporter.setZUGFeRDConformanceLevel(zugferdConformanceLevel);
zugFeRDExporter.setCreator(creator);
zugFeRDExporter.setProducer(producer);
ZUGFeRDExporter zugFeRDExporter = new ZUGFeRDExporter(doc);
zugFeRDExporter.configure(ZFVersion, zugferdConformanceLevel, creator, producer);
zugFeRDExporter.setAttachZUGFeRDHeaders(attachZUGFeRDHeaders);
zugFeRDExporter.setPDFA3(ensurePDFisUpgraded);
@@ -173,14 +158,14 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
/**
* All files are PDF/A-3, setConformance refers to the level conformance.
* <p/>
* <p>
* PDF/A-3 has three coformance levels, called "A", "U" and "B".
* <p/>
* <p>
* PDF/A-3-B where B means only visually preservable, U -standard for Mustang-
* means visually and unicode preservable and A means full compliance, i.e.
* visually, unicode and structurally preservable and tagged PDF, i.e. useful
* metainformation for blind people.
* <p/>
* <p>
* Feel free to pass "A" as new level if you know what you are doing :-)
*/
public IExporterFactory setConformanceLevel(PDFAConformanceLevel newLevel) {

View File

@@ -32,6 +32,7 @@ import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.mustangproject.toecount.Toecount;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
@@ -45,31 +46,41 @@ import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ZUGFeRDImporter {
/**
* @var if metadata has been found
* if metadata has been found
*/
private boolean containsMeta = false;
/**
* @var the reference (i.e. invoice number) of the sender
* map filenames of additional XML files to their contents
*/
private HashMap<String, byte[]> additionalXMLs = new HashMap<>();
/**
* Raw XML form of the extracted data - may be directly obtained.
*/
private byte[] rawXML = null;
/**
* XMP metadata
*/
private String xmpString = null; // XMP metadata
/**
* parsed Document
*/
private Document document;
public ZUGFeRDImporter(String pdfFilename) {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFilename));
try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) {
extractLowLevel(bis);
bis.close();
} catch (IOException e) {
e.printStackTrace();
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e);
}
}
@@ -78,7 +89,7 @@ public class ZUGFeRDImporter {
try {
extractLowLevel(pdfStream);
} catch (IOException e) {
e.printStackTrace();
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e);
}
}
@@ -122,15 +133,16 @@ public class ZUGFeRDImporter {
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
for (String filename : names.keySet()) {
for (String alias : names.keySet()) {
PDComplexFileSpecification fileSpec = names.get(alias);
String filename=fileSpec.getFilename();
/**
* currently (in the release candidate of version 1) only one attached file with
* the name ZUGFeRD-invoice.xml is allowed
* filenames for invoice data (ZUGFeRD v1 and v2, Factur-X)
*/
if ((filename.equals("ZUGFeRD-invoice.xml") || filename.equals("factur-x.xml"))) { //$NON-NLS-1$
if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml"))) { //$NON-NLS-1$
containsMeta = true;
PDComplexFileSpecification fileSpec = names.get(filename);
PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
// String embeddedFilename = filePath + filename;
// File file = new File(filePath + filename);
@@ -139,18 +151,14 @@ public class ZUGFeRDImporter {
// ByteArrayOutputStream();
// FileOutputStream fos = new FileOutputStream(file);
rawXML = embeddedFile.toByteArray();
setMeta(new String(rawXML));
setRawXML(embeddedFile.toByteArray());
// fos.write(embeddedFile.getByteArray());
// fos.close();
}
if (filename.startsWith("additional_data")) {
PDComplexFileSpecification fileSpec = names.get(filename);
PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
additionalXMLs.put(filename, embeddedFile.toByteArray());
}
}
}
@@ -161,7 +169,7 @@ public class ZUGFeRDImporter {
try {
transformer = tf.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
}
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
@@ -170,13 +178,52 @@ public class ZUGFeRDImporter {
System.err.println(output);
}
private Document getDocument() throws ParserConfigurationException, IOException, SAXException, TransformerException {
private Document getDocument() { return document; }
private void setDocument() throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
xmlFact.setNamespaceAware(false);
DocumentBuilder builder = xmlFact.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(rawXML));
//prettyPrint(doc);
return doc;
ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
is.skip(guessBOMSize(is));
document = builder.parse(is);
}
public void setRawXML(byte[] rawXML) throws IOException {
this.rawXML = rawXML;
try {
setDocument();
} catch (ParserConfigurationException | SAXException e) {
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e);
}
}
/**
* Skips over a BOM at the beginning of the given ByteArrayInputStream, if one exists.
* @param is the ByteArrayInputStream used
* @throws IOException
* @see <a href="https://www.w3.org/TR/xml/#sec-guessing">Autodetection of Character Encodings</a>
*/
private int guessBOMSize(ByteArrayInputStream is) throws IOException {
byte[] pad = new byte[4];
is.read(pad);
is.reset();
int test2 = ((pad[0] & 0xFF) << 8) | (pad[1] & 0xFF);
int test3 = ((test2 & 0xFFFF) << 8) | (pad[2] & 0xFF);
int test4 = ((test3 & 0xFFFFFF) << 8) | (pad[3] & 0xFF);
//
if (test4 == 0x0000FEFF || test4 == 0xFFFE0000 || test4 == 0x0000FFFE || test4 == 0xFEFF0000) {
// UCS-4: BOM takes 4 bytes
return 4;
} else if (test3 == 0xEFBBFF) {
// UTF-8: BOM takes 3 bytes
return 3;
} else if (test2 == 0xFEFF || test2 == 0xFFFE) {
// UTF-16: BOM takes 2 bytes
return 2;
}
return 0;
}
private String extractString(String xpathStr) {
@@ -189,11 +236,8 @@ public class ZUGFeRDImporter {
XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
result = xpath.evaluate(xpathStr, document);
} catch (ParserConfigurationException e) {
e.printStackTrace();
throw new ZUGFeRDExportException(e);
} catch (IOException | SAXException | TransformerException | XPathExpressionException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
throw new ZUGFeRDExportException(e);
}
return result;
@@ -217,12 +261,30 @@ public class ZUGFeRDImporter {
}
/**
* @return the sender's bank's BLZ code
* @return the referred document
*/
public String getReference() {
return extractString("//ApplicableHeaderTradeAgreement/BuyerReference");
}
/**
* @return the sender's bank's BLZ code
* @deprecated use BIC and IBAN instead of BLZ and KTO
*/
@Deprecated
public String getBLZ() {
return extractString("//PayeeSpecifiedCreditorFinancialInstitution/GermanBankleitzahlID");
}
/**
* @return the sender's account number
* @deprecated use BIC and IBAN instead of BLZ and KTO
*/
@Deprecated
public String getKTO() {
return extractString("//PayeePartyCreditorFinancialAccount/ProprietaryID");
}
/**
* @return the sender's bank's BIC code
*/
@@ -230,21 +292,21 @@ public class ZUGFeRDImporter {
return extractString("//PayeeSpecifiedCreditorFinancialInstitution/BICID");
}
/**
* @return the sender's bankname
* @return the sender's bank name
*/
public String getBankName() {
return extractString("/CrossIndustryInvoice/SupplyChainTradeTransaction/ApplicableHeaderTradeSettlement/SpecifiedTradeSettlementPaymentMeans/PayeeSpecifiedCreditorFinancialInstitution/Name");
return extractString("//PayeeSpecifiedCreditorFinancialInstitution/Name");
}
/**
* @return the sender's account IBAN code
*/
public String getIBAN() {
return extractString("//PayeePartyCreditorFinancialAccount/IBANID");
}
public String getKTO() {
return extractString("//PayeePartyCreditorFinancialAccount/ProprietaryID");
}
public String getHolder() {
return extractString("//SellerTradeParty/Name");
}
@@ -290,8 +352,8 @@ public class ZUGFeRDImporter {
/**
* @param meta raw XML to be set
*/
public void setMeta(String meta) {
this.rawXML = meta.getBytes();
public void setMeta(String meta) throws IOException {
setRawXML(meta.getBytes());
}
/**
@@ -336,6 +398,7 @@ public class ZUGFeRDImporter {
/**
* Returns the raw XML data as extracted from the ZUGFeRD PDF file.
* @return the raw ZUGFeRD XML data
*/
public byte[] getRawXML() {
return rawXML;
@@ -359,7 +422,7 @@ public class ZUGFeRDImporter {
static String convertStreamToString(java.io.InputStream is) {
// source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to
// https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks
Scanner s = new Scanner(is).useDelimiter("\\A");
Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}

View File

@@ -63,8 +63,22 @@ public class ZUGFeRDMigrator {
*/
ByteArrayOutputStream baos = new ByteArrayOutputStream();
applySchematronXsl(new FileInputStream(xmlFilename), baos);
String res = null;
res = baos.toString("UTF-8");
//migrate the profiles
res=res.replace("urn:ferd:CrossIndustryDocument:invoice:1p0:basic", "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic");
res=res.replace("urn:ferd:CrossIndustryDocument:invoice:1p0:comfort", "urn:cen.eu:en16931:2017");
res=res.replace("urn:ferd:CrossIndustryDocument:invoice:1p0:extended", "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended");
//somehow the XML parser seems to insert erreneous XML namespaces, depending on which one it is, saxon seems to be cleaner.
//nevertheless, remove them manually
res=res.replace("<rsm:ExchangedDocument xmlns:qdt=\"urn:un:unece:uncefact:data:standard:QualifiedDataType:100\">", "<rsm:ExchangedDocument>");
res=res.replace("<rsm:SupplyChainTradeTransaction xmlns:qdt=\"urn:un:unece:uncefact:data:standard:QualifiedDataType:100\">", "<rsm:SupplyChainTradeTransaction>");
return res;
}

View File

@@ -19,6 +19,7 @@
package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
@@ -29,53 +30,7 @@ import java.util.HashMap;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.mustangproject.ZUGFeRD.model.AmountType;
import org.mustangproject.ZUGFeRD.model.CodeType;
import org.mustangproject.ZUGFeRD.model.CountryIDType;
import org.mustangproject.ZUGFeRD.model.CreditorFinancialAccountType;
import org.mustangproject.ZUGFeRD.model.CreditorFinancialInstitutionType;
import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType;
import org.mustangproject.ZUGFeRD.model.DateTimeType;
import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants;
import org.mustangproject.ZUGFeRD.model.DocumentCodeType;
import org.mustangproject.ZUGFeRD.model.DocumentContextParameterType;
import org.mustangproject.ZUGFeRD.model.DocumentContextParameterTypeConstants;
import org.mustangproject.ZUGFeRD.model.DocumentLineDocumentType;
import org.mustangproject.ZUGFeRD.model.ExchangedDocumentContextType;
import org.mustangproject.ZUGFeRD.model.ExchangedDocumentType;
import org.mustangproject.ZUGFeRD.model.IDType;
import org.mustangproject.ZUGFeRD.model.IndicatorType;
import org.mustangproject.ZUGFeRD.model.LogisticsServiceChargeType;
import org.mustangproject.ZUGFeRD.model.NoteType;
import org.mustangproject.ZUGFeRD.model.NoteTypeConstants;
import org.mustangproject.ZUGFeRD.model.ObjectFactory;
import org.mustangproject.ZUGFeRD.model.PaymentMeansCodeType;
import org.mustangproject.ZUGFeRD.model.PaymentMeansCodeTypeConstants;
import org.mustangproject.ZUGFeRD.model.PercentType;
import org.mustangproject.ZUGFeRD.model.QuantityType;
import org.mustangproject.ZUGFeRD.model.ReferencedDocumentType;
import org.mustangproject.ZUGFeRD.model.SupplyChainEventType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeAgreementType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeDeliveryType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeLineItemType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeSettlementType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeTransactionType;
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeType;
import org.mustangproject.ZUGFeRD.model.TaxRegistrationType;
import org.mustangproject.ZUGFeRD.model.TaxRegistrationTypeConstants;
import org.mustangproject.ZUGFeRD.model.TaxTypeCodeType;
import org.mustangproject.ZUGFeRD.model.TaxTypeCodeTypeConstants;
import org.mustangproject.ZUGFeRD.model.TextType;
import org.mustangproject.ZUGFeRD.model.TradeAddressType;
import org.mustangproject.ZUGFeRD.model.TradeAllowanceChargeType;
import org.mustangproject.ZUGFeRD.model.TradePartyType;
import org.mustangproject.ZUGFeRD.model.TradePaymentTermsType;
import org.mustangproject.ZUGFeRD.model.TradePriceType;
import org.mustangproject.ZUGFeRD.model.TradeProductType;
import org.mustangproject.ZUGFeRD.model.TradeSettlementMonetarySummationType;
import org.mustangproject.ZUGFeRD.model.TradeSettlementPaymentMeansType;
import org.mustangproject.ZUGFeRD.model.TradeTaxType;
import org.mustangproject.ZUGFeRD.model.*;
class ZUGFeRDTransactionModelConverter {
private static final SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd");
@@ -85,6 +40,7 @@ class ZUGFeRDTransactionModelConverter {
private final Totals totals;
private boolean isTest;
private String currency = "EUR";
private String profile;
ZUGFeRDTransactionModelConverter(IZUGFeRDExportableTransaction trans) {
@@ -114,7 +70,7 @@ class ZUGFeRDTransactionModelConverter {
DocumentContextParameterType contextParameter = xmlFactory
.createDocumentContextParameterType();
IDType idType = xmlFactory.createIDType();
idType.setValue(DocumentContextParameterTypeConstants.EXTENDED);
idType.setValue(profile);
contextParameter.setID(idType);
context.getGuidelineSpecifiedDocumentContextParameter().add(
contextParameter);
@@ -150,7 +106,7 @@ class ZUGFeRDTransactionModelConverter {
document.setTypeCode(documentCodeType);
TextType name = xmlFactory.createTextType();
name.setValue("RECHNUNG");
name.setValue(trans.getDocumentName());
document.getName().add(name);
if (trans.getOwnOrganisationFullPlaintextInfo() != null) {
@@ -168,7 +124,7 @@ class ZUGFeRDTransactionModelConverter {
if (trans.getReferenceNumber() != null && !"".equals(trans.getReferenceNumber())) {
NoteType referenceInfo = xmlFactory.createNoteType();
TextType referenceInfoContent = xmlFactory.createTextType();
referenceInfoContent.setValue("Ursprungsbeleg: " + trans.getReferenceNumber());
referenceInfoContent.setValue(trans.getReferenceNumber());
referenceInfo.getContent().add(referenceInfoContent);
document.getIncludedNote().add(referenceInfo);
}
@@ -200,8 +156,13 @@ class ZUGFeRDTransactionModelConverter {
tradeAgreement.setBuyerTradeParty(getBuyer());
tradeAgreement.setSellerTradeParty(getSeller());
if (getBuyerOrderReferencedDocument() != null) {
tradeAgreement.getBuyerOrderReferencedDocument().add(getBuyerOrderReferencedDocument());
if (trans.getBuyerOrderReferencedDocumentID() != null) {
ReferencedDocumentType refdoc = xmlFactory.createReferencedDocumentType();
IDType id = xmlFactory.createIDType();
id.setValue(trans.getBuyerOrderReferencedDocumentID());
refdoc.getID().add(id);
refdoc.setIssueDateTime(trans.getBuyerOrderReferencedDocumentIssueDateTime());
tradeAgreement.getBuyerOrderReferencedDocument().add(refdoc);
}
return tradeAgreement;
@@ -232,6 +193,12 @@ class ZUGFeRDTransactionModelConverter {
buyerID.setValue(trans.getRecipient().getID());
buyerTradeParty.getID().add(buyerID);
}
if (trans.getRecipient().getGlobalID() != null) {
IDType globalID = xmlFactory.createIDType();
globalID.setValue(trans.getRecipient().getGlobalID());
globalID.setSchemeID(trans.getRecipient().getGlobalIDScheme());
buyerTradeParty.getGlobalID().add(globalID);
}
TextType buyerName = xmlFactory.createTextType();
buyerName.setValue(trans.getRecipient().getName());
@@ -410,7 +377,7 @@ class ZUGFeRDTransactionModelConverter {
currencyCode.setValue(currency);
tradeSettlement.setInvoiceCurrencyCode(currencyCode);
tradeSettlement.getSpecifiedTradeSettlementPaymentMeans().add(
tradeSettlement.getSpecifiedTradeSettlementPaymentMeans().addAll(
getPaymentData());
tradeSettlement.getApplicableTradeTax().addAll(getTradeTax());
tradeSettlement.getSpecifiedTradePaymentTerms().addAll(
@@ -434,46 +401,50 @@ class ZUGFeRDTransactionModelConverter {
}
private TradeSettlementPaymentMeansType getPaymentData() {
TradeSettlementPaymentMeansType paymentData = xmlFactory
.createTradeSettlementPaymentMeansType();
PaymentMeansCodeType paymentDataType = xmlFactory
.createPaymentMeansCodeType();
paymentDataType.setValue(PaymentMeansCodeTypeConstants.BANKACCOUNT);
paymentData.setTypeCode(paymentDataType);
private List<TradeSettlementPaymentMeansType> getPaymentData() {
List<TradeSettlementPaymentMeansType> result = new ArrayList<>();
for (IZUGFeRDTradeSettlementPayment settlementPayment : trans.getTradeSettlementPayment()) {
TradeSettlementPaymentMeansType paymentData = xmlFactory
.createTradeSettlementPaymentMeansType();
PaymentMeansCodeType paymentDataType = xmlFactory
.createPaymentMeansCodeType();
paymentDataType.setValue(PaymentMeansCodeTypeConstants.BANKACCOUNT);
paymentData.setTypeCode(paymentDataType);
TextType paymentInfo = xmlFactory.createTextType();
String paymentInfoText = trans.getOwnPaymentInfoText();
if (paymentInfoText == null) {
paymentInfoText = "";
TextType paymentInfo = xmlFactory.createTextType();
String paymentInfoText = settlementPayment.getOwnPaymentInfoText();
if (paymentInfoText == null) {
paymentInfoText = "";
}
paymentInfo.setValue(paymentInfoText);
paymentData.getInformation().add(paymentInfo);
CreditorFinancialAccountType bankAccount = xmlFactory
.createCreditorFinancialAccountType();
IDType iban = xmlFactory.createIDType();
iban.setValue(settlementPayment.getOwnIBAN());
bankAccount.setIBANID(iban);
IDType kto = xmlFactory.createIDType();
kto.setValue(settlementPayment.getOwnKto());
bankAccount.setProprietaryID(kto);
paymentData.setPayeePartyCreditorFinancialAccount(bankAccount);
CreditorFinancialInstitutionType bankData = xmlFactory
.createCreditorFinancialInstitutionType();
IDType bicId = xmlFactory.createIDType();
bicId.setValue(settlementPayment.getOwnBIC());
bankData.setBICID(bicId);
TextType bankName = xmlFactory.createTextType();
bankName.setValue(settlementPayment.getOwnBankName());
bankData.setName(bankName);
IDType blz = xmlFactory.createIDType();
blz.setValue(settlementPayment.getOwnBLZ());
bankData.setGermanBankleitzahlID(blz);
paymentData.setPayeeSpecifiedCreditorFinancialInstitution(bankData);
result.add(paymentData);
}
paymentInfo.setValue(paymentInfoText);
paymentData.getInformation().add(paymentInfo);
CreditorFinancialAccountType bankAccount = xmlFactory
.createCreditorFinancialAccountType();
IDType iban = xmlFactory.createIDType();
iban.setValue(trans.getOwnIBAN());
bankAccount.setIBANID(iban);
IDType kto = xmlFactory.createIDType();
kto.setValue(trans.getOwnKto());
bankAccount.setProprietaryID(kto);
paymentData.setPayeePartyCreditorFinancialAccount(bankAccount);
CreditorFinancialInstitutionType bankData = xmlFactory
.createCreditorFinancialInstitutionType();
IDType bicId = xmlFactory.createIDType();
bicId.setValue(trans.getOwnBIC());
bankData.setBICID(bicId);
TextType bankName = xmlFactory.createTextType();
bankName.setValue(trans.getOwnBankName());
bankData.setName(bankName);
IDType blz = xmlFactory.createIDType();
blz.setValue(trans.getOwnBLZ());
bankData.setGermanBankleitzahlID(blz);
paymentData.setPayeeSpecifiedCreditorFinancialInstitution(bankData);
return paymentData;
return result;
}
@@ -490,7 +461,7 @@ class ZUGFeRDTransactionModelConverter {
TaxCategoryCodeType taxCategoryCode = xmlFactory.createTaxCategoryCodeType();
VATAmount vatAmount = VATPercentAmountMap.get(currentTaxPercent);
taxCategoryCode.setValue(vatAmount.getDocumentCode());
taxCategoryCode.setValue(vatAmount.getCategoryCode());
tradeTax.setCategoryCode(taxCategoryCode);
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
@@ -754,9 +725,14 @@ class ZUGFeRDTransactionModelConverter {
grandTotalAmount.setValue(currencyFormat(totals.getTotalGross()));
monetarySummation.getGrandTotalAmount().add(grandTotalAmount);
AmountType totalPrepaidAmount = xmlFactory.createAmountType();
totalPrepaidAmount.setCurrencyID(currency);
totalPrepaidAmount.setValue(currencyFormat(trans.getTotalPrepaidAmount()));
monetarySummation.getTotalPrepaidAmount().add(totalPrepaidAmount);
AmountType duePayableAmount = xmlFactory.createAmountType();
duePayableAmount.setCurrencyID(currency);
duePayableAmount.setValue(currencyFormat(totals.getTotalGross()));
duePayableAmount.setValue(currencyFormat(totals.getTotalGross().subtract(trans.getTotalPrepaidAmount())));
monetarySummation.getDuePayableAmount().add(duePayableAmount);
return monetarySummation;
@@ -911,70 +887,26 @@ class ZUGFeRDTransactionModelConverter {
private BigDecimal vatFormat(BigDecimal value) {
return nDigitFormat(value, 2);
}
return value.setScale(2, RoundingMode.HALF_UP);
}
private BigDecimal currencyFormat(BigDecimal value) {
return nDigitFormat(value, 2);
}
return value.setScale(2, RoundingMode.HALF_UP);
}
private BigDecimal priceFormat(BigDecimal value) {
return nDigitFormat(value, 4);
}
return value.setScale(4, RoundingMode.HALF_UP);
}
private BigDecimal quantityFormat(BigDecimal value) {
return nDigitFormat(value, 4);
}
private BigDecimal nDigitFormat(BigDecimal value, int scale) {
/*
* I needed 123,45, locale independent.I tried
* NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is
* locale specific.I also tried DecimalFormat df = new DecimalFormat(
* "0,00" ); df.setDecimalSeparatorAlwaysShown(true);
* df.setGroupingUsed(false); DecimalFormatSymbols symbols = new
* DecimalFormatSymbols(); symbols.setDecimalSeparator(',');
* symbols.setGroupingSeparator(' ');
* df.setDecimalFormatSymbols(symbols);
*
* but that would not switch off grouping. Although I liked very much
* the (incomplete) "BNF diagram" in
* http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
* in the end I decided to calculate myself and take eur+sparator+cents
*
* This function will cut off, i.e. floor() subcent values Tests:
* System.err.println(utils.currencyFormat(new BigDecimal(0),
* ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.1"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.01"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"),
* ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ","));
*
* results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00
*/
value = value.setScale(scale, BigDecimal.ROUND_HALF_UP); // first, round
// so that
// e.g.
// 1.189999999999999946709294817992486059665679931640625
// becomes
// 1.19
char[] repeat = new char[scale];
Arrays.fill(repeat, '0');
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator('.');
DecimalFormat dec = new DecimalFormat("0." + new String(repeat),
otherSymbols);
return new BigDecimal(dec.format(value));
}
return value.setScale(4, RoundingMode.HALF_UP);
}
/**
* which taxes have been used with which amounts in this transaction, empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable to 19% VAT
* (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) 190 Eur
@@ -992,7 +924,7 @@ class ZUGFeRDTransactionModelConverter {
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalc lc = new LineCalc(currentItem);
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), trans.getDocumentCode());
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), lc.getCategoryCode());
VATAmount current = hm.get(percent);
if (current == null) {
hm.put(percent, itemVATAmount);
@@ -1027,8 +959,7 @@ class ZUGFeRDTransactionModelConverter {
VATAmount itemVATAmount = new VATAmount(
logisticsServiceCharge.getTotalAmount(),
logisticsServiceCharge.getTotalAmount()
.multiply(percent).divide(new BigDecimal(100)),
trans.getDocumentCode());
.multiply(percent).divide(new BigDecimal(100)), logisticsServiceCharge.getCategoryCode());
VATAmount current = hm.get(percent);
if (current == null) {
hm.put(percent, itemVATAmount);
@@ -1043,8 +974,7 @@ class ZUGFeRDTransactionModelConverter {
BigDecimal percent = charge.getTaxPercent();
VATAmount itemVATAmount = new VATAmount(
charge.getTotalAmount(), charge.getTotalAmount()
.multiply(percent).divide(new BigDecimal(100)),
trans.getDocumentCode());
.multiply(percent).divide(new BigDecimal(100)), charge.getCategoryCode());
VATAmount current = hm.get(percent);
if (current == null) {
hm.put(percent, itemVATAmount);
@@ -1063,12 +993,18 @@ class ZUGFeRDTransactionModelConverter {
return this;
}
public ZUGFeRDTransactionModelConverter withProfile(String profile) {
this.profile = profile;
return this;
}
private class LineCalc {
private BigDecimal totalGross;
private BigDecimal itemTotalNetAmount;
private BigDecimal itemTotalVATAmount;
private BigDecimal itemNetAmount;
private String categoryCode;
public LineCalc(IZUGFeRDExportableItem currentItem) {
@@ -1111,6 +1047,7 @@ class ZUGFeRDTransactionModelConverter {
.add(totalCharge)
.divide(currentItem.getQuantity(), 4,
BigDecimal.ROUND_HALF_UP);
categoryCode = currentItem.getCategoryCode();
}
@@ -1128,6 +1065,8 @@ class ZUGFeRDTransactionModelConverter {
return itemNetAmount;
}
public String getCategoryCode() { return categoryCode; }
}
private class Totals {

View File

@@ -0,0 +1,165 @@
/** **********************************************************************
*
* Copyright 2018 Jochen Staerk
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ZUGFeRDVisualizer {
static final ClassLoader CLASS_LOADER = ZUGFeRDVisualizer.class.getClassLoader();
private static final String RESOURCE_PATH = ""; //$NON-NLS-1$
private static final Logger LOG = Logger.getLogger(ZUGFeRDVisualizer.class.getName());
// private static File createTempFileResult(final Transformer transformer, final
// StreamSource toTransform,
// final String suffix) throws TransformerException, IOException {
// File result = File.createTempFile("ZUV_", suffix); //$NON-NLS-1$
// result.deleteOnExit();
//
// try (FileOutputStream fos = new FileOutputStream(result)) {
// transformer.transform(toTransform, new StreamResult(fos));
// }
// return result;
// }
private TransformerFactory mFactory = null;
private Templates mXsltXRTemplate = null;
private Templates mXsltHTMLTemplate = null;
private Templates mXsltZF1HTMLTemplate = null;
public ZUGFeRDVisualizer() {
mFactory = new net.sf.saxon.TransformerFactoryImpl();
// fact = TransformerFactory.newInstance();
mFactory.setURIResolver(new ClasspathResourceURIResolver());
try {
mXsltXRTemplate = mFactory.newTemplates(
new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/cii-xr.xsl")));
mXsltHTMLTemplate = mFactory.newTemplates(new StreamSource(
CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/xrechnung-html.xsl")));
mXsltZF1HTMLTemplate = mFactory.newTemplates(new StreamSource(
CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt")));
} catch (TransformerConfigurationException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
public String visualize(String xmlFilename)
throws FileNotFoundException, TransformerException, UnsupportedEncodingException {
/**
* *
* http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf
* http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf
* http://countwordsfree.com/xmlviewer
*/
FileInputStream fis=new FileInputStream(xmlFilename);
String fileContent="";
try {
fileContent = new String(Files.readAllBytes(Paths.get(xmlFilename)));
} catch (IOException e2) {
LOG.log(Level.SEVERE, null, e2);
}
ByteArrayOutputStream iaos = new ByteArrayOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String zf1Signature = "rsm:CrossIndustryDocument";
if (fileContent.contains(zf1Signature)) {
applyZF1SchematronXsl(fis, baos);
} else {
//zf2 or fx
applySchematronXsl(fis, iaos);
// take the copy of the stream and re-write it to an InputStream
PipedInputStream in = new PipedInputStream();
PipedOutputStream out;
try {
out = new PipedOutputStream(in);
new Thread(new Runnable() {
public void run() {
try {
// write the original OutputStream to the PipedOutputStream
// note that in order for the below method to work, you need
// to ensure that the data has finished writing to the
// ByteArrayOutputStream
iaos.writeTo(out);
} catch (IOException e) {
LOG.log(Level.SEVERE, null, e);
} finally {
// close the PipedOutputStream here because we're done writing data
// once this thread has completed its run
if (out != null) {
// close the PipedOutputStream cleanly
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
LOG.log(Level.SEVERE, null, e);
}
}
}
}
}).start();
applySchematronXsl2(in, baos);
} catch (IOException e1) {
LOG.log(Level.SEVERE, null, e1);
}
}
return baos.toString("UTF-8");
}
public void applySchematronXsl(final InputStream xmlFile, final OutputStream HTMLOutstream)
throws TransformerException {
Transformer transformer = mXsltXRTemplate.newTransformer();
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
}
public void applyZF1SchematronXsl(final InputStream xmlFile, final OutputStream HTMLOutstream)
throws TransformerException {
Transformer transformer = mXsltZF1HTMLTemplate.newTransformer();
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
}
public void applySchematronXsl2(final InputStream xmlFile, final OutputStream HTMLOutstream)
throws TransformerException {
Transformer transformer = mXsltHTMLTemplate.newTransformer();
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
}
private static class ClasspathResourceURIResolver implements URIResolver {
ClasspathResourceURIResolver() {
// Do nothing, just prevents synthetic access warning.
}
@Override
public Source resolve(String href, String base) throws TransformerException {
return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + href));
}
}
}

View File

@@ -19,7 +19,7 @@
package org.mustangproject.ZUGFeRD.model;
public class DocumentContextParameterTypeConstants {
public static final String BASIC = "urn:ferd:CrossIndustryDocument:invoice:1p0:basic";
public static final String COMFORT = "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort";
public static final String EXTENDED = "urn:ferd:CrossIndustryDocument:invoice:1p0:extended";
// this does not look complete :-/
}

View File

@@ -30,8 +30,14 @@ import org.mustangproject.ZUGFeRD.*;
import javax.xml.transform.TransformerException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -69,8 +75,9 @@ public class Toecount {
+ " [--source <filename>]: set input PDF file\n"
+ " [--source-xml <filename>]: set input XML file\n"
+ " [--out <filename>]: set output PDF file\n"
+ " [--zugferd-version <1|2>]: set ZUGFeRD version\n"
+ " [--zugferd-profile <...>]: set ZUGFeRD profile\n"
+ " [--format <fx|zf>]: set ZUGFeRD or FacturX\n"
+ " [--version <1|2>]: set ZUGFeRD version\n"
+ " [--profile <...>]: set ZUGFeRD profile\n"
+ " For ZUGFeRD v1: <B>ASIC, <C>OMFORT or <E>XTENDED\n"
+ " For ZUGFeRD v2: <M>INIMUM, BASIC <W>L, <B>ASIC, <C>IUS, <E>N16931, E<X>TENDED ";
}
@@ -102,8 +109,8 @@ public class Toecount {
+ "\t\t[--source <filename>]: set input PDF file\r\n"
+ "\t\t[--source-xml <filename>]: set input XML file\r\n"
+ "\t\t[--out <filename>]: set output PDF file\r\n"
+ "\t\t[--zugferd-version <1|2>]: set ZUGFeRD version\r\n"
+ "\t\t[--zugferd-profile <...>]: set ZUGFeRD profile\r\n"
+ "\t\t[--format <fx|zf>]: enable factur-x or ZUGFeRD\r\n"
+ "\t\t[--version <1|2>]: set ZUGFeRD version\r\n" + "\t\t[--profile <...>]: set ZUGFeRD profile\r\n"
+ "\t\t\tFor ZUGFeRD v1: <B>ASIC, <C>OMFORT or <E>XTENDED\r\n"
+ "\t\t\tFor ZUGFeRD v2: <M>INIMUM, BASIC <W>L, <B>ASIC, <C>IUS, <E>N16931, E<X>TENDED\r\n");
}
@@ -112,11 +119,15 @@ public class Toecount {
* Asks the user (repeatedly, if neccessary) on the command line for a String
* (offering a defaultValue) conforming to a Regex pattern
*
* @param prompt the question to be asked to the user
* @param defaultValue the default return value if user hits enter
* @param pattern a regex of acceptable values
* @param prompt
* the question to be asked to the user
* @param defaultValue
* the default return value if user hits enter
* @param pattern
* a regex of acceptable values
* @return the user answer conforming to pattern
* @throws Exception if pattern not compielable or IOexception on input
* @throws Exception
* if pattern not compielable or IOexception on input
*/
protected static String getStringFromUser(String prompt, String defaultValue, String pattern) throws Exception {
String input = "";
@@ -137,8 +148,8 @@ public class Toecount {
try {
input = buffer.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
if (input.isEmpty()) {
@@ -155,15 +166,15 @@ public class Toecount {
/**
* Prompts the user for a input or output filename
*
* @param the text the user is asked
* @param a default Filename
* @param expectedExtension will warn if filename does not match expected file extension
* @param ensureFileExists will warn if file does NOT exist (for input files)
* @param prompt the text the user is asked
* @param defaultFilename a default Filename
* @param expectedExtension will warn if filename does not match expected file extension
* @param ensureFileExists will warn if file does NOT exist (for input files)
* @param ensureFileNotExists will warn if file DOES exist (for output files)
* @return String
*/
protected static String getFilenameFromUser(String prompt, String defaultFilename, String expectedExtension,
boolean ensureFileExists, boolean ensureFileNotExists) {
boolean ensureFileExists, boolean ensureFileNotExists) {
boolean fileExistenceOK = false;
String selectedName = "";
do {
@@ -174,8 +185,8 @@ public class Toecount {
try {
selectedName = buffer.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
if (selectedName.isEmpty()) {
@@ -191,8 +202,7 @@ public class Toecount {
try {
selectedAnswer = buffer.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
if (!selectedAnswer.equals("Y") && !selectedAnswer.equals("y")) {
System.err.println("Aborted by user");
@@ -234,6 +244,8 @@ public class Toecount {
// Option: Help
Option<Boolean> helpOption = parser.addBooleanOption('h', "help");
// Option: Action
Option<String> actionOption = parser.addStringOption('a', "action");
// Generic options available for multiple command
// --source: input file
@@ -264,12 +276,13 @@ public class Toecount {
// (--source: input PDF file)
// (--source-xml: input XML file)
// (--out: output PDF file)
// (--zugferd-version: ZUGFeRD version)
// (--zugferd-profile: ZUGFeRD profile)
// (--version: ZUGFeRD version)
// (--profile: ZUGFeRD profile)
Option<Boolean> combineOption = parser.addBooleanOption('c', "combine");
Option<String> sourceXmlOption = parser.addStringOption("source-xml");
Option<String> zugferdVersionOption = parser.addStringOption("zugferd-version");
Option<String> zugferdProfileOption = parser.addStringOption("zugferd-profile");
Option<String> formatOption = parser.addStringOption('f', "format");
Option<String> zugferdVersionOption = parser.addStringOption("version");
Option<String> zugferdProfileOption = parser.addStringOption("profile");
// Command: Show metrics in dir
// --directory
@@ -290,17 +303,19 @@ public class Toecount {
}
// Retrieve all options
String action = parser.getOptionValue(actionOption);
String directoryName = parser.getOptionValue(dirnameOption);
Boolean filesFromStdIn = parser.getOptionValue(filesFromStdInOption, Boolean.FALSE);
Boolean combineRequested = parser.getOptionValue(combineOption, Boolean.FALSE);
Boolean extractRequested = parser.getOptionValue(extractOption, Boolean.FALSE);
Boolean helpRequested = parser.getOptionValue(helpOption, Boolean.FALSE);
Boolean upgradeRequested = parser.getOptionValue(upgradeOption, Boolean.FALSE);
Boolean combineRequested = parser.getOptionValue(combineOption, Boolean.FALSE) || ((action!=null)&&(action.equals("combine")));
Boolean extractRequested = parser.getOptionValue(extractOption, Boolean.FALSE) || ((action!=null)&&(action.equals("extract")));
Boolean helpRequested = parser.getOptionValue(helpOption, Boolean.FALSE) || ((action!=null)&&(action.equals("help")));
Boolean upgradeRequested = parser.getOptionValue(upgradeOption, Boolean.FALSE) || ((action!=null)&&(action.equals("upgrade")));
Boolean ignoreFileExt = parser.getOptionValue(ignoreFileExtOption, Boolean.FALSE);
Boolean a3only = parser.getOptionValue(a3onlyOption, Boolean.FALSE);
Boolean a3only = parser.getOptionValue(a3onlyOption, Boolean.FALSE) || ((action!=null)&&(action.equals("a3")));
String sourceName = parser.getOptionValue(sourceOption);
String sourceXMLName = parser.getOptionValue(sourceXmlOption);
String outName = parser.getOptionValue(outOption);
String format = parser.getOptionValue(formatOption);
String zugferdVersion = parser.getOptionValue(zugferdVersionOption);
String zugferdProfile = parser.getOptionValue(zugferdProfileOption);
@@ -309,7 +324,7 @@ public class Toecount {
} else if (((directoryName != null) && (directoryName.length() > 0)) || filesFromStdIn.booleanValue()) {
performMetrics(directoryName, filesFromStdIn, ignoreFileExt);
} else if (combineRequested) {
performCombine(sourceName, sourceXMLName, outName, zugferdVersion, zugferdProfile);
performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile);
} else if (extractRequested) {
performExtract(sourceName, outName);
} else if (a3only) {
@@ -322,7 +337,7 @@ public class Toecount {
System.exit(2);
}
} catch (Exception e) {
e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
System.exit(-1);
}
@@ -338,7 +353,7 @@ public class Toecount {
System.out.println("ZUGFeRD 1.0 XML source set to " + xmlName);
}
if (outName == null) {
outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.xml", "xml", false, true);
outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "zugferd-invoice.xml", "xml", false, true);
} else {
System.out.println("ZUGFeRD 1.0 XML source set to " + outName);
}
@@ -417,15 +432,15 @@ public class Toecount {
}
}
private static void performCombine(String pdfName, String xmlName, String outName, String zfVersion,
String zfProfile) throws Exception {
private static void performCombine(String pdfName, String xmlName, String outName, String format, String zfVersion,
String zfProfile) throws Exception {
/*
* ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory()
* .setProducer("toecount") .setCreator(System.getProperty("user.name"))
* .loadFromPDFA1("invoice.pdf");
*/
try {
int zfIntVersion = 1;
int zfIntVersion = ZUGFeRDExporter.DefaultZUGFeRDVersion;
ZUGFeRDConformanceLevel zfConformanceLevelProfile = ZUGFeRDConformanceLevel.EXTENDED;
if (pdfName == null) {
@@ -446,35 +461,42 @@ public class Toecount {
System.out.println("Ouput PDF set to " + outName);
}
if (zfVersion == null) {
if (format == null) {
try {
zfVersion = getStringFromUser("ZUGFeRD version (1 or 2)", "1", "1|2");
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD,)", "zf", "fx|zf");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
} else {
System.out.println("ZUGFeRD version set to " + zfVersion);
System.out.println("Format set to " + format);
}
if (zfVersion == null) {
try {
zfVersion = getStringFromUser("Version (1 or 2)", "1", "1|2");
} catch (Exception e) {
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
} else {
System.out.println("Version set to " + zfVersion);
}
zfIntVersion = Integer.valueOf(zfVersion);
if (zfProfile == null) {
try {
if (zfIntVersion == 1) {
zfProfile = getStringFromUser("ZUGFeRD profile b)asic, c)omfort or e)xtended", "e",
"B|b|C|c|E|e");
if (format.equals("zf") && (zfIntVersion == 1)) {
zfProfile = getStringFromUser("Profile b)asic, c)omfort or e)xtended", "e", "B|b|C|c|E|e");
} else {
zfProfile = getStringFromUser(
"ZUGFeRD profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, E[X]TENDED",
"E", "M|m|W|w|B|b|C|c|E|e|X|x|");
"Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, E[X]TENDED", "E",
"M|m|W|w|B|b|C|c|E|e|X|x|");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
} else {
System.out.println("ZUGFeRD profile set to " + zfProfile);
System.out.println("Profile set to " + zfProfile);
}
zfProfile = zfProfile.toLowerCase();
@@ -483,7 +505,11 @@ public class Toecount {
ensureFileExists(xmlName);
ensureFileNotExists(outName);
if (zfIntVersion == 1) {
if ((format.equals("fx")) && (zfIntVersion > 1)) {
throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)");
}
if ((format.equals("zf")) && (zfIntVersion == 1)) {
if (zfProfile.equals("b")) {
zfConformanceLevelProfile = ZUGFeRDConformanceLevel.BASIC;
} else if (zfProfile.equals("c")) {
@@ -493,7 +519,7 @@ public class Toecount {
} else {
throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile));
}
} else if (zfIntVersion == 2) {
} else if (((format.equals("zf")) && (zfIntVersion == 2)) || (format.equals("fx"))) {
if (zfProfile.equals("m")) {
zfConformanceLevelProfile = ZUGFeRDConformanceLevel.MINIMUM;
} else if (zfProfile.equals("w")) {
@@ -510,15 +536,18 @@ public class Toecount {
throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile));
}
} else {
throw new Exception(String.format("Unknown ZUGFeRD version '%i'", zfIntVersion));
throw new Exception(String.format("Unknown version '%i'", zfIntVersion));
}
// All params are good! continue...
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setProducer("Toecount")
.setZUGFeRDVersion(zfIntVersion)
.setCreator(System.getProperty("user.name")).setZUGFeRDConformanceLevel(zfConformanceLevelProfile)
.load(pdfName);
ze.setZUGFeRDVersion(zfIntVersion);
if (format.equals("fx")) {
ze.setFacturX();
}
ze.setZUGFeRDXMLData(Files.readAllBytes(Paths.get(xmlName)));
@@ -527,9 +556,8 @@ public class Toecount {
System.out.println("Written to " + outName);
} catch (IOException e) {
e.printStackTrace();
// } catch (JAXBException e) {
// e.printStackTrace();
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
}
}

View File

@@ -63,7 +63,12 @@ Migrated by Mustangproject XSLT
<!-- xsl:template match="//*[local-name() = 'HeaderExchangedDocument']">
<xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> -->
<!-- attribute rename -->
<!-- element remode -->
<xsl:template match="//*[local-name() = 'TestIndicator']">
<!-- Testindicator element has been removed -->
</xsl:template>
<!-- element rename -->
<xsl:template match="//*[local-name() = 'SpecifiedExchangedDocumentContext']">
<xsl:element name="rsm:ExchangedDocumentContext">
<xsl:apply-templates select="@*|node()" />

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/** **********************************************************************
*
* Copyright 2019 Jochen Staerk
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import junit.framework.Test;
import junit.framework.TestSuite;
import junit.framework.TestCase;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class BaseTest extends TestCase {
/**
* Create the test case
*
* @param testName name of the test case
*/
public BaseTest(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(BaseTest.class);
}
public void testCorrectDigits() {
assertEquals("0.00", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal(0),2));
assertEquals("-1.10", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("-1.10"),2));
assertEquals("-1.10", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("-1.1"),2));
assertEquals("-1.01", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("-1.01"),2));
assertEquals("20000123.35", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("20000123.3489"),2));
assertEquals("20000123.34", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("20000123.3419"),2));
assertEquals("12.00", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("12"),2));
assertEquals("12", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("12"),0));
assertEquals("20000123.342", ZUGFeRD2PullProvider.nDigitFormat(new BigDecimal("20000123.3419"),3));
}
}

View File

@@ -21,6 +21,7 @@ package org.mustangproject.ZUGFeRD;
import java.util.Date;
public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTransaction {
private String number;
private Date issueDate;
private String ownOrganisationFullPlaintextInfo;
@@ -30,11 +31,7 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
private IZUGFeRDAllowanceCharge[] zFLogisticsServiceCharges;
private IZUGFeRDExportableItem[] zFItems;
private IZUGFeRDExportableContact recipient;
private String ownKto;
private String ownBLZ;
private String ownBIC;
private String ownBankName;
private String ownIBAN;
private IZUGFeRDTradeSettlementPayment[] settlementPayments;
private String ownTaxID;
private String ownVATID;
private String ownOrganisationName;
@@ -44,7 +41,6 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
private String ownCountry;
private Date deliveryDate;
private String currency;
private String ownPaymentInfoText;
private String paymentTermDescription;
private String referenceNumber;
@@ -94,28 +90,8 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
}
@Override
public String getOwnKto() {
return ownKto;
}
@Override
public String getOwnBLZ() {
return ownBLZ;
}
@Override
public String getOwnBIC() {
return ownBIC;
}
@Override
public String getOwnBankName() {
return ownBankName;
}
@Override
public String getOwnIBAN() {
return ownIBAN;
public IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() {
return settlementPayments;
}
@Override
@@ -163,11 +139,6 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
return currency;
}
@Override
public String getOwnPaymentInfoText() {
return ownPaymentInfoText;
}
@Override
public String getPaymentTermDescription() {
return paymentTermDescription;
@@ -223,31 +194,6 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnBLZ(String ownBLZ) {
this.ownBLZ = ownBLZ;
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnBIC(String ownBIC) {
this.ownBIC = ownBIC;
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnBankName(String ownBankName) {
this.ownBankName = ownBankName;
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnKto(String ownKto) {
this.ownKto = ownKto;
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnIBAN(String ownIBAN) {
this.ownIBAN = ownIBAN;
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnTaxID(String ownTaxID) {
this.ownTaxID = ownTaxID;
return this;
@@ -293,11 +239,6 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
return this;
}
public IZUGFeRDExportableTransactionImpl setOwnPaymentInfoText(String ownPaymentInfoText) {
this.ownPaymentInfoText = ownPaymentInfoText;
return this;
}
public IZUGFeRDExportableTransactionImpl setPaymentTermDescription(String paymentTermDescription) {
this.paymentTermDescription = paymentTermDescription;
return this;
@@ -307,4 +248,9 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
this.referenceNumber = referenceNumber;
return this;
}
public IZUGFeRDExportableTransactionImpl setTradeSettlementPayment(IZUGFeRDTradeSettlementPayment... settlementPayments) {
this.settlementPayments = settlementPayments;
return this;
}
}

View File

@@ -0,0 +1,90 @@
/** **********************************************************************
*
* Copyright 2019 by ak on 12.04.19.
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
public class IZUGFeRDTradeSettlementPaymentImpl implements IZUGFeRDTradeSettlementPayment {
private String ownKto;
private String ownBLZ;
private String ownBIC;
private String ownBankName;
private String ownIBAN;
private String ownPaymentInfoText;
@Override
public String getOwnKto() {
return ownKto;
}
@Override
public String getOwnBLZ() {
return ownBLZ;
}
@Override
public String getOwnBIC() {
return ownBIC;
}
@Override
public String getOwnBankName() {
return ownBankName;
}
@Override
public String getOwnIBAN() {
return ownIBAN;
}
@Override
public String getOwnPaymentInfoText() {
return ownPaymentInfoText;
}
public IZUGFeRDTradeSettlementPaymentImpl setOwnBLZ(String ownBLZ) {
this.ownBLZ = ownBLZ;
return this;
}
public IZUGFeRDTradeSettlementPaymentImpl setOwnBIC(String ownBIC) {
this.ownBIC = ownBIC;
return this;
}
public IZUGFeRDTradeSettlementPaymentImpl setOwnBankName(String ownBankName) {
this.ownBankName = ownBankName;
return this;
}
public IZUGFeRDTradeSettlementPaymentImpl setOwnKto(String ownKto) {
this.ownKto = ownKto;
return this;
}
public IZUGFeRDTradeSettlementPaymentImpl setOwnIBAN(String ownIBAN) {
this.ownIBAN = ownIBAN;
return this;
}
public IZUGFeRDTradeSettlementPaymentImpl setOwnPaymentInfoText(String ownPaymentInfoText) {
this.ownPaymentInfoText = ownPaymentInfoText;
return this;
}
}

View File

@@ -0,0 +1,226 @@
/** **********************************************************************
*
* Copyright 2019 by ak on 12.04.19.
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import junit.framework.TestCase;
import java.math.BigDecimal;
public abstract class MustangReaderTestCase extends TestCase implements IZUGFeRDExportableTransaction {
public MustangReaderTestCase(String testName) {
super(testName);
}
@Override
public IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() {
Payment[] payments = new Payment[1];
payments[0] = new Payment();
return payments;
}
protected class Payment implements IZUGFeRDTradeSettlementPayment {
@Override
public String getOwnKto() {
return "44421800";
}
@Override
public String getOwnBLZ() {
return "41441604";
}
@Override
public String getOwnBIC() {
return "COBADEFFXXX";
}
@Override
public String getOwnBankName() {
return "Commerzbank";
}
@Override
public String getOwnPaymentInfoText() {
return "Überweisung";
}
@Override
public String getOwnIBAN() {
return "DE88 2008 0000 0970 3757 00";
}
}
protected class RecipientContact implements IZUGFeRDExportableContact {
@Override
public String getCountry() {
return "DE";
}
@Override
public String getLocation() {
return "Spielkreis";
}
@Override
public String getName() {
return "Theodor Est";
}
@Override
public String getStreet() {
return "Bahnstr. 42";
}
@Override
public String getVATID() {
return "DE999999999";
}
@Override
public String getZIP() {
return "88802";
}
}
protected class SenderContact implements IZUGFeRDExportableContact {
@Override
public String getName() {
return "Ingmar N. Fo";
}
@Override
public String getPhone() {
return "++49(0)237823";
}
@Override
public String getEMail() {
return "info@localhost.local";
}
}
protected class Item implements IZUGFeRDExportableItem {
public Item(BigDecimal price, BigDecimal quantity, Product product) {
super();
this.price = price;
this.quantity = quantity;
this.product = product;
}
private BigDecimal price, quantity;
private Product product;
@Override
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public BigDecimal getQuantity() {
return quantity;
}
public void setQuantity(BigDecimal quantity) {
this.quantity = quantity;
}
@Override
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemAllowances() {
return null;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemCharges() {
return null;
}
}
protected class Product implements IZUGFeRDExportableProduct {
private String description, name, unit;
private BigDecimal VATPercent;
public Product(String description, String name, String unit, BigDecimal VATPercent) {
super();
this.description = description;
this.name = name;
this.unit = unit;
this.VATPercent = VATPercent;
}
@Override
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Override
public BigDecimal getVATPercent() {
return VATPercent;
}
public void setVATPercent(BigDecimal VATPercent) {
this.VATPercent = VATPercent;
}
}
}

View File

@@ -27,6 +27,7 @@ import org.junit.runners.MethodSorters;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MustangReaderWriterCustomXMLTest extends TestCase {
@@ -49,7 +50,7 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
// //////// TESTS
// //////////////////////////////////////////////////////////////////////////////////////////
public void testCustomZF2Export() throws Exception {
public void testCustomZF2Export() {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506custom.pdf";
// the writing part
@@ -61,8 +62,10 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
.load(SOURCE_PDF);
final byte[] UTF8ByteOrderMark = new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf};
/* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */
String ownZUGFeRDXML = new String(UTF8ByteOrderMark) + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
/* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less.
* test the export with bom (which is valid) because this will also test the import (which also needs to work and needs to be tested)
* */
String ownZUGFeRDXML = new String(UTF8ByteOrderMark, StandardCharsets.UTF_8) + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<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\">\n" +
" <rsm:ExchangedDocumentContext>\n" +
" <ram:TestIndicator><udt:Indicator>false</udt:Indicator></ram:TestIndicator>\n" +
@@ -286,10 +289,10 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
* ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds
* metadata, writes to @{code ./target/testout-*} and then imports to check the
* values. It would not make sense to have it run before the less complex
* importer test (which is probably redundant) --> as only Name Ascending is
* importer test (which is probably redundant). As only Name Ascending is
* supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export
*/
public void testCustomZF1Export() throws Exception {
public void testCustomZF1Export() {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505custom.pdf";
// the writing part
@@ -297,7 +300,10 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
try {
InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.BASIC)
ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory()
.setProducer("My Application")
.setCreator("Test")
.setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.BASIC)
.load(SOURCE_PDF);
/* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */
String ownZUGFeRDXML = "<rsm:CrossIndustryDocument xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12\" xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15\" xmlns:rsm=\"urn:ferd:CrossIndustryDocument:invoice:1p0\">\n"

View File

@@ -19,7 +19,6 @@
package org.mustangproject.ZUGFeRD;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
@@ -33,7 +32,7 @@ import java.util.Date;
import java.util.GregorianCalendar;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExportableTransaction {
public class MustangReaderWriterEdgeTest extends MustangReaderTestCase {
@Override
public Date getDeliveryDate() {
@@ -55,36 +54,11 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
return "RE-20170509/505";
}
@Override
public String getOwnKto() {
return "44421800";
}
@Override
public String getOwnBLZ() {
return "41441604";
}
@Override
public String getOwnBIC() {
return "COBADEFFXXX";
}
@Override
public String getOwnBankName() {
return "Commerzbank";
}
@Override
public String getOwnCountry() {
return "DE";
}
@Override
public String getOwnIBAN() {
return "DE88 2008 0000 0970 3757 00";
}
@Override
public String getOwnLocation() {
return "Stadthausen";
@@ -100,6 +74,13 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
return "Ecke 12";
}
@Override
public IZUGFeRDExportableContact getOwnContact() {
return new SenderContact();
}
@Override
public String getOwnTaxID() {
return "22/815/0815/4";
@@ -117,10 +98,9 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
@Override
public IZUGFeRDExportableContact getRecipient() {
return new Contact();
return new RecipientContact();
}
@Override
public String getOwnOrganisationFullPlaintextInfo() {
return null;
@@ -144,11 +124,6 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
return allItems;
}
@Override
public String getOwnPaymentInfoText() {
return "Überweisung";
}
@Override
public String getPaymentTermDescription() {
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
@@ -172,141 +147,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
@Override
public String getReferenceNumber() {
return null;
}
class Contact implements IZUGFeRDExportableContact {
@Override
public String getCountry() {
return "DE";
}
@Override
public String getLocation() {
return "Spielkreis";
}
@Override
public String getName() {
return "Theodor Est";
}
@Override
public String getStreet() {
return "Bahnstr. 42";
}
@Override
public String getVATID() {
return "DE999999999";
}
@Override
public String getZIP() {
return "88802";
}
}
class Item implements IZUGFeRDExportableItem {
public Item(BigDecimal price, BigDecimal quantity, Product product) {
super();
this.price = price;
this.quantity = quantity;
this.product = product;
}
private BigDecimal price, quantity;
private Product product;
@Override
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public BigDecimal getQuantity() {
return quantity;
}
public void setQuantity(BigDecimal quantity) {
this.quantity = quantity;
}
@Override
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemAllowances() {
return null;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemCharges() {
return null;
}
}
class Product implements IZUGFeRDExportableProduct {
private String description, name, unit;
private BigDecimal VATPercent;
public Product(String description, String name, String unit, BigDecimal VATPercent) {
super();
this.description = description;
this.name = name;
this.unit = unit;
this.VATPercent = VATPercent;
}
@Override
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Override
public BigDecimal getVATPercent() {
return VATPercent;
}
public void setVATPercent(BigDecimal vATPercent) {
VATPercent = vATPercent;
}
return "AB321";
}
/**
@@ -329,22 +170,20 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
/**
* The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20170509_505.pdf to check the values.
* --> as only Name Ascending is supported for Test Unit sequence, I renamed the this test-A-Export to run before
* As only Name Ascending is supported for Test Unit sequence, I renamed the this test-A-Import to run before
* testZExport
*
* @throws IOException
*/
public void testAImport() throws IOException {
public void testAImport() {
InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf");
ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
// Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
assertEquals(zi.getBIC(), getOwnBIC());
assertEquals(zi.getBLZ(), getOwnBLZ());
assertEquals(zi.getIBAN(), getOwnIBAN());
assertEquals(zi.getKTO(), getOwnKto());
assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC());
assertEquals(zi.getBLZ(), getTradeSettlementPayment()[0].getOwnBLZ());
assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN());
assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getDueDate(), "20170530");
assertEquals(zi.getForeignReference(), getNumber());
@@ -354,12 +193,11 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
/**
* The exporter test bases on @{code ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds metadata,
* writes
* to @{code ./target/testout-*} and then imports to check the values.
* It would not make sense to have it run before the less complex importer test (which is probably redundant)
* --> as only Name Ascending is supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export
* writes to @{code ./target/testout-*} and then imports to check the values.
* It would not make sense to have it run before the less complex importer test (which is probably redundant).
* As only Name Ascending is supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export
*/
public void testEdgeExport() throws Exception {
public void testEdgeExport() {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf";
// the writing part
@@ -370,13 +208,15 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA3Factory()
.setProducer("My Application")
.setCreator(System.getProperty("user.name"))
.setZUGFeRDVersion(1)
.ignorePDFAErrors()
.load(SOURCE_PDF)) {
ze.setZUGFeRDVersion(1);
ze.PDFattachZugferdFile(this);
String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryDocument"));
ze.export(TARGET_PDF);
} catch (IOException e) {
fail("IOException should not happen in testEdgeExport");
}
// now check the contents (like MustangReaderTest)
@@ -384,10 +224,10 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
// Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
assertEquals(zi.getBIC(), getOwnBIC());
assertEquals(zi.getBLZ(), getOwnBLZ());
assertEquals(zi.getIBAN(), getOwnIBAN());
assertEquals(zi.getKTO(), getOwnKto());
assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC());
assertEquals(zi.getBLZ(), getTradeSettlementPayment()[0].getOwnBLZ());
assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN());
assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getForeignReference(), getNumber());
}

View File

@@ -19,62 +19,49 @@
package org.mustangproject.ZUGFeRD;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
import org.apache.xmpbox.xml.DomXmpParser;
import org.apache.xmpbox.xml.XmpParsingException;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.ZUGFeRD.model.DocumentContextParameterTypeConstants;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.*;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExportableTransaction {
public class MustangReaderWriterTest extends MustangReaderTestCase {
@Override
public Date getDeliveryDate() {
return new GregorianCalendar(2017, Calendar.NOVEMBER, 17).getTime();
return new GregorianCalendar(2019, Calendar.JUNE, 10).getTime();
}
@Override
public Date getDueDate() {
return new GregorianCalendar(2017, Calendar.DECEMBER, 9).getTime();
return new GregorianCalendar(2019, Calendar.JULY, 1).getTime();
}
@Override
public Date getIssueDate() {
return new GregorianCalendar(2017, Calendar.NOVEMBER, 18).getTime();
return new GregorianCalendar(2019, Calendar.JUNE, 10).getTime();
}
@Override
public String getNumber() {
return "RE-20171118/506";
}
@Override
public String getOwnKto() {
return "44421800";
}
@Override
public String getOwnBLZ() {
return "41441604";
}
@Override
public String getOwnBIC() {
return "COBADEFFXXX";
}
@Override
public String getOwnBankName() {
return "Commerzbank";
return "RE-20190610/507";
}
@Override
@@ -82,11 +69,6 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
return "DE";
}
@Override
public String getOwnIBAN() {
return "DE88 2008 0000 0970 3757 00";
}
@Override
public String getOwnLocation() {
return "Stadthausen";
@@ -119,7 +101,12 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
@Override
public IZUGFeRDExportableContact getRecipient() {
return new Contact();
return new RecipientContact();
}
@Override
public IZUGFeRDExportableContact getOwnContact() {
return new SenderContact();
}
@Override
@@ -135,26 +122,21 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
@Override
public IZUGFeRDExportableItem[] getZFItems() {
Item[] allItems = new Item[3];
Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR",
Product designProduct = new Product("", "Design (hours): Of a sample invoice", "HUR",
new BigDecimal("7.000000"));
Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000"));
Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000"));
Product balloonProduct = new Product("", "Ballons: various colors, ~2000ml", "C62", new BigDecimal("19.000000"));
Product airProduct = new Product("", "Hot air „heiße Luft“ (litres)", "LTR", new BigDecimal("19.000000"));
allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct);
allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct);
allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct);
allItems[2] = new Item(new BigDecimal("0.025"), new BigDecimal("800"), airProduct);
return allItems;
}
@Override
public String getOwnPaymentInfoText() {
return "Überweisung";
}
@Override
public String getPaymentTermDescription() {
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate());
SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd");
return "Remit until " + isoDateFormat.format(getDueDate());
}
@Override
@@ -180,141 +162,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
@Override
public String getReferenceNumber() {
return null;
}
class Contact implements IZUGFeRDExportableContact {
@Override
public String getCountry() {
return "DE";
}
@Override
public String getLocation() {
return "Spielkreis";
}
@Override
public String getName() {
return "Theodor Est";
}
@Override
public String getStreet() {
return "Bahnstr. 42";
}
@Override
public String getVATID() {
return "DE999999999";
}
@Override
public String getZIP() {
return "88802";
}
}
class Item implements IZUGFeRDExportableItem {
public Item(BigDecimal price, BigDecimal quantity, Product product) {
super();
this.price = price;
this.quantity = quantity;
this.product = product;
}
private BigDecimal price, quantity;
private Product product;
@Override
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public BigDecimal getQuantity() {
return quantity;
}
public void setQuantity(BigDecimal quantity) {
this.quantity = quantity;
}
@Override
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemAllowances() {
return null;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemCharges() {
return null;
}
}
class Product implements IZUGFeRDExportableProduct {
private String description, name, unit;
private BigDecimal VATPercent;
public Product(String description, String name, String unit, BigDecimal VATPercent) {
super();
this.description = description;
this.name = name;
this.unit = unit;
this.VATPercent = VATPercent;
}
@Override
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Override
public BigDecimal getVATPercent() {
return VATPercent;
}
public void setVATPercent(BigDecimal VATPercent) {
this.VATPercent = VATPercent;
}
return "AB321";
}
/**
@@ -337,29 +185,27 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
// //////////////////////////////////////////////////////////////////////////////////////////
/**
* The importer test imports from
* ./src/test/MustangGnuaccountingBeispielRE-20170509_505.pdf to check the
* values. --> as only Name Ascending is supported for Test Unit sequence, I
* renamed the this test-A-Export to run before testZExport
*
* @throws IOException
* The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20170509_505.pdf to check the
* values. As only Name Ascending is supported for Test Unit sequence, I renamed the this testAImport
* to run before testZExport
*/
public void testAImport() throws IOException {
public void testAImport() {
InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf");
ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
// Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
assertEquals(zi.getBLZ(), getOwnBLZ());
assertEquals(zi.getBIC(), getOwnBIC());
assertEquals(zi.getIBAN(), getOwnIBAN());
assertEquals(zi.getKTO(), getOwnKto());
assertEquals(zi.getBLZ(), getTradeSettlementPayment()[0].getOwnBLZ());
assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC());
assertEquals(zi.getIBAN(),getTradeSettlementPayment()[0].getOwnIBAN());
assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getForeignReference(), "RE-20170509/505");
assertEquals(zi.getBankName(), "Commerzbank");
}
public void testForeignImport() throws IOException {
public void testForeignImport() {
InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf");
ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
@@ -456,8 +302,39 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF);
File tempFile = File.createTempFile("ZUGFeRD-", "-test");
ze.export(tempFile.getName());
ze.export(tempFile.getAbsolutePath());
tempFile.deleteOnExit();
checkPdfA3B(tempFile);
}
public void testMigratePDFA1ToA3Stream() throws IOException {
// just make sure there is no Exception
InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf");
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF);
File tempFile = File.createTempFile("ZUGFeRD-", "-test");
tempFile.deleteOnExit();
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
ze.export(fos);
}
checkPdfA3B(tempFile);
}
private void checkPdfA3B(File tempFile) throws IOException, InvalidPasswordException {
try (PDDocument doc = PDDocument.load(tempFile)) {
PDMetadata metadata = doc.getDocumentCatalog().getMetadata();
InputStream exportXMPMetadata = metadata.exportXMPMetadata();
byte[] xmpBytes = new byte[exportXMPMetadata.available()];
exportXMPMetadata.read(xmpBytes);
final XMPMetadata xmp = new DomXmpParser().parse(xmpBytes);
PDFAIdentificationSchema pdfaid = xmp.getPDFIdentificationSchema();
assertEquals(pdfaid.getPart().intValue(), 3);
assertEquals(pdfaid.getConformance(), "U");
} catch (XmpParsingException e) {
throw new IllegalStateException("Failed to read PDF", e);
}
}
/**
@@ -465,16 +342,16 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
* ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds
* metadata, writes to @{code ./target/testout-*} and then imports to check the
* values. It would not make sense to have it run before the less complex
* importer test (which is probably redundant) --> as only Name Ascending is
* importer test (which is probably redundant). As only Name Ascending is
* supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export
*/
public void testZExport() throws Exception {
public void testZExport() {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf";
// the writing part
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf");
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf");
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(2).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).load(SOURCE_PDF)) {
@@ -488,10 +365,12 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
String pdfContent = baos.toString("UTF-8");
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
// check for pdf-a schema extension
assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
assertFalse(pdfContent.indexOf("<pdfaSchema:prefix>zf</pdfaSchema:prefix>") == -1);
assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1);
// assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
// assertFalse(pdfContent.indexOf("<pdfaSchema:prefix>zf</pdfaSchema:prefix>") == -1);
// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1);
} catch (IOException e) {
fail("IOException should not happen in testZExport");
}
// now check the contents (like MustangReaderTest)
@@ -499,14 +378,46 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
// Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
assertEquals(zi.getBIC(), getOwnBIC());
assertEquals(zi.getIBAN(), getOwnIBAN());
assertEquals(zi.getKTO(), getOwnKto());
assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC());
assertEquals(zi.getReference(), getReferenceNumber());
assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN());
assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getForeignReference(), getNumber());
}
/*
/**
* Quick and dirty copy of testZExport to check if v1 files contain
* the correct profile string when the comfort profile is selected.
*/
public void testZExportv1Profile() {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf";
// the writing part
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf");
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(1).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.COMFORT).load(SOURCE_PDF)) {
ze.PDFattachZugferdFile(this);
ze.disableAutoClose(true);
ze.export(TARGET_PDF);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.BASIC) >= 0);
assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.EXTENDED) >= 0);
assertTrue(pdfContent.indexOf(DocumentContextParameterTypeConstants.COMFORT) >= 0);
} catch (IOException e) {
fail("IOException should not happen in testZExport");
}
}
public void testFXExport() throws Exception {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506fx.pdf";
@@ -515,7 +426,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf");
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(2).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).load(SOURCE_PDF)) {
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(2).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).load(SOURCE_PDF)) {
ze.setFacturX();
ze.PDFattachZugferdFile(this);
ze.disableAutoClose(true);
@@ -529,7 +440,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
// check for pdf-a schema extension
assertFalse(pdfContent.indexOf("<fx:ConformanceLevel>EN 16931</fx:ConformanceLevel>") == -1);
assertFalse(pdfContent.indexOf("<pdfaSchema:prefix>fx</pdfaSchema:prefix>") == -1);
assertFalse(pdfContent.indexOf("urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931") == -1);
assertFalse(pdfContent.indexOf("urn:cen.eu:en16931:2017") == -1);
}
// now check the contents (like MustangReaderTest)
@@ -537,18 +448,14 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
// Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
assertEquals(zi.getBIC(), getOwnBIC());
assertEquals(zi.getIBAN(), getOwnIBAN());
assertEquals(zi.getKTO(), getOwnKto());
assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC());
assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN());
assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getForeignReference(), getNumber());
}
*/
/**
* @throws Exception
* @Test(expected = IndexOutOfBoundsException.class)
*/
public void testExceptionOnPDF14() throws Exception {
public void testExceptionOnPDF14() {
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505new.pdf";

View File

@@ -34,6 +34,10 @@ public class ResourceUtilities {
/**
* Loading a File into a String using a certain encoding and file path
* @param encoding the charset used in the file
* @param path the path to the file
* @return the file contents as a String
* @throws IOException if the file cannot be read
*/
public static String readFile(Charset encoding, String path) throws IOException {
byte[] content = Files.readAllBytes(Paths.get(path));
@@ -42,6 +46,10 @@ public class ResourceUtilities {
/**
* Saving a String as a file to a certain file path
* @param encoding the charset used in the file
* @param path the path to the file
* @param content the contents of the file
* @throws FileNotFoundException if the file cannot be found
*/
public static void saveFile(Charset encoding, String path, String content) throws FileNotFoundException {
@@ -147,7 +155,7 @@ public class ResourceUtilities {
/**
* To fix the 3 slashes bug for File URI: For example:
* file:/C:/work/test.txt -> file:///C:/work/test.txt
* file:/C:/work/test.txt gives file:///C:/work/test.txt
*
* @param u - the File URI
* @return the String of the URI

View File

@@ -41,7 +41,7 @@ import static org.junit.Assert.assertFalse;
* will be migrated to <code>src/test/resources/migration/output</code>.
* If there is a similar named file as test reference <code>src/test/resources/migration/reference</code> a test
* will be triggered for every single file.
* <p/>
*
* Note: Any 'ZUGFeRD1' will be exchanged to 'ZUGFeRD2' during migration and adequate reference will be searched for.
*/
@RunWith(Parameterized.class)

View File

@@ -0,0 +1,209 @@
/** **********************************************************************
*
* Copyright 2019 Jochen Staerk
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ZF2EdgeTest extends MustangReaderTestCase {
final String TARGET_PDF = "./target/testout-ZF2newEdge.pdf";
@Override
public Date getDeliveryDate() {
return new GregorianCalendar(2017, Calendar.MAY, 7).getTime();
}
@Override
public Date getDueDate() {
return new GregorianCalendar(2017, Calendar.MAY, 30).getTime();
}
@Override
public Date getIssueDate() {
return new GregorianCalendar(2017, Calendar.MAY, 9).getTime();
}
@Override
public String getNumber() {
return "RE-20170509/505";
}
@Override
public String getOwnCountry() {
return "DE";
}
@Override
public String getOwnLocation() {
return "Stadthausen";
}
@Override
public String getOwnOrganisationName() {
return "Bei Spiel GmbH";
}
@Override
public String getOwnStreet() {
return "Ecke 12";
}
@Override
public IZUGFeRDExportableContact getOwnContact() {
return new SenderContact();
}
@Override
public String getOwnTaxID() {
return "22/815/0815/4";
}
@Override
public String getOwnVATID() {
return "DE136695976";
}
@Override
public String getOwnZIP() {
return "12345";
}
@Override
public IZUGFeRDExportableContact getRecipient() {
return new RecipientContact();
}
@Override
public String getOwnOrganisationFullPlaintextInfo() {
return null;
}
@Override
public String getCurrency() {
return "EUR";
}
@Override
public IZUGFeRDExportableItem[] getZFItems() {
Item[] allItems = new Item[3];
Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", new BigDecimal("7.000000"));
Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62", new BigDecimal("19.000000"));// test for issue 103
Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000"));
allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct);
allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct);
allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct);
return allItems;
}
@Override
public String getPaymentTermDescription() {
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate());
}
@Override
public IZUGFeRDAllowanceCharge[] getZFAllowances() {
return null;
}
@Override
public IZUGFeRDAllowanceCharge[] getZFCharges() {
return null;
}
@Override
public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() {
return null;
}
@Override
public String getReferenceNumber() {
return "AB321";
}
/**
* Create the test case
*
* @param testName name of the test case
*/
public ZF2EdgeTest(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(ZF2EdgeTest.class);
}
// //////// TESTS //////////////////////////////////////////////////////////////////////////////////////////
/**
* The exporter test bases on @{code ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds metadata,
* writes to @{code ./target/testout-*} and then imports to check the values.
*/
public void testEdgeExport() {
// the writing part
try (InputStream SOURCE_PDF =
this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf");
ZUGFeRDExporter ze = new ZUGFeRDExporterFromA3Factory()
.setProducer("My Application")
.setCreator(System.getProperty("user.name"))
.setZUGFeRDVersion(2)
.ignorePDFAErrors()
.load(SOURCE_PDF)) {
ze.PDFattachZugferdFile(this);
String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
ze.export(TARGET_PDF);
} catch (IOException e) {
fail("IOException should not be raised in testEdgeExport");
}
// now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
// Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC());
assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getForeignReference(), getNumber());
}
}

View File

@@ -45,7 +45,7 @@ public class ZUGFeRDTransactionModelConverterTest {
.setOwnStreet("own street")
.setOwnCountry("own country")
.setOwnLocation("own city")
.setOwnBankName("own bank")
.setTradeSettlementPayment(new IZUGFeRDTradeSettlementPaymentImpl().setOwnBankName("own bank"))
.setZFItems(
new IZUGFeRDExportableItemImpl()
.setProduct(new IZUGFeRDExportableProductImpl()

View File

@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Nutzungsrechte
ZUGFeRD Datenformat Version 1.0, 25.6.2014
Beispiel Version 29.09.2014
Zweck des Forums für elektronische Rechnungen bei der AWV e.V („FeRD“) ist u.a. die Schaffung und Spezifizierung
eines offenen Datenformats für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht
diskriminierender, standardisierter Technologien („ZUGFeRD Datenformat“)
Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung
frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine
Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht
diskriminierenden Bedingungen an.
Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung
abrufbar unter www.ferd-net.de.
Im Einzelnen schließt die Nutzungsgewährung ein:
=====================================
FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils
geltenden und akzeptierten Fassung (www.ferd-net.de) ein.
Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung,
Weiterbearbeitung und Verbindung mit anderen Produkten.
Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder
anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige
Anwendungen und Dienste.
Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente
und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um
notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch
die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden.
Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares,
unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit
anderen Produkten einzuräumen.
Die Lizenz wird kostenfrei zur Verfügung gestellt.
Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen
Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten,
Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete,
beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der
Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.
-->
<rsm:CrossIndustryDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rsm="urn:ferd:CrossIndustryDocument:invoice:1p0" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15">
<rsm:SpecifiedExchangedDocumentContext>
<ram:TestIndicator><udt:Indicator>true</udt:Indicator></ram:TestIndicator><!-- Im Echtbetrieb muss der TestIndicator entweder vollständig entfallen oder auf false stehen. -->
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:comfort</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:SpecifiedExchangedDocumentContext>
<rsm:HeaderExchangedDocument>
<ram:ID>471102</ram:ID>
<ram:Name>RECHNUNG</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime><udt:DateTimeString format="102">20130305</udt:DateTimeString></ram:IssueDateTime>
<ram:IncludedNote>
<ram:Content>Rechnung gemäß Bestellung vom 01.03.2013.</ram:Content>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>Lieferant GmbH
Lieferantenstraße 20
80333 München
Deutschland
Geschäftsführer: Hans Muster
Handelsregisternummer: H A 123
</ram:Content>
<ram:SubjectCode>REG</ram:SubjectCode>
</ram:IncludedNote>
</rsm:HeaderExchangedDocument>
<rsm:SpecifiedSupplyChainTradeTransaction>
<ram:ApplicableSupplyChainTradeAgreement>
<ram:SellerTradeParty>
<ram:GlobalID schemeID="0088">4000001123452</ram:GlobalID>
<ram:Name>Lieferant GmbH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>80333</ram:PostcodeCode>
<ram:LineOne>Lieferantenstraße 20</ram:LineOne>
<ram:CityName>München</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">201/113/40209</ram:ID>
</ram:SpecifiedTaxRegistration>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>GE2020211</ram:ID>
<ram:GlobalID schemeID="0088">4000001987658</ram:GlobalID>
<ram:Name>Kunden AG Mitte</ram:Name>
<ram:DefinedTradeContact>
<ram:PersonName>Hans Muster</ram:PersonName>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>69876</ram:PostcodeCode>
<ram:LineOne>Kundenstraße 15</ram:LineOne>
<ram:CityName>Frankfurt</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
</ram:ApplicableSupplyChainTradeAgreement>
<ram:ApplicableSupplyChainTradeDelivery>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime><udt:DateTimeString format="102">20130305</udt:DateTimeString> </ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableSupplyChainTradeDelivery>
<ram:ApplicableSupplyChainTradeSettlement>
<ram:PaymentReference>2013-471102</ram:PaymentReference>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>31</ram:TypeCode>
<ram:Information>Überweisung</ram:Information>
<ram:PayeePartyCreditorFinancialAccount>
<ram:IBANID>DE08700901001234567890</ram:IBANID>
</ram:PayeePartyCreditorFinancialAccount>
<ram:PayeeSpecifiedCreditorFinancialInstitution>
<ram:BICID>GENODEF1M04</ram:BICID>
</ram:PayeeSpecifiedCreditorFinancialInstitution>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">19.25</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">275.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">37.62</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">198.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Zahlbar innerhalb 30 Tagen netto bis 04.04.2013, 3% Skonto innerhalb 10 Tagen bis 15.03.2013</ram:Description>
<ram:DueDateDateTime><udt:DateTimeString format="102">20130404</udt:DateTimeString></ram:DueDateDateTime>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">473.00</ram:LineTotalAmount>
<ram:ChargeTotalAmount currencyID="EUR">0.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount currencyID="EUR">0.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount currencyID="EUR">473.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">56.87</ram:TaxTotalAmount>
<ram:GrandTotalAmount currencyID="EUR">529.87</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount currencyID="EUR">0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount currencyID="EUR">529.87</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:ApplicableSupplyChainTradeSettlement>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">9.9000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">9.9000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">20.0000</ram:BilledQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">198.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0160">4012345001235</ram:GlobalID>
<ram:SellerAssignedID>TB100A4</ram:SellerAssignedID>
<ram:Name>Trennblätter A4</ram:Name>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>2</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">5.5000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">5.5000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">50.0000</ram:BilledQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">275.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0160">4000050986428</ram:GlobalID>
<ram:SellerAssignedID>ARNR2</ram:SellerAssignedID>
<ram:Name>Joghurt Banane</ram:Name>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
</rsm:SpecifiedSupplyChainTradeTransaction>
</rsm:CrossIndustryDocument>

View File

@@ -0,0 +1,520 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Nutzungsrechte
ZUGFeRD Datenformat Version 1.0, 25.6.2014
Beispiel Version 29.09.2014
Zweck des Forums für elektronische Rechnungen bei der AWV e.V („FeRD“) ist u.a. die Schaffung und Spezifizierung
eines offenen Datenformats für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht
diskriminierender, standardisierter Technologien („ZUGFeRD Datenformat“)
Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung
frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine
Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht
diskriminierenden Bedingungen an.
Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung
abrufbar unter www.ferd-net.de.
Im Einzelnen schließt die Nutzungsgewährung ein:
=====================================
FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils
geltenden und akzeptierten Fassung (www.ferd-net.de) ein.
Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung,
Weiterbearbeitung und Verbindung mit anderen Produkten.
Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder
anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige
Anwendungen und Dienste.
Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente
und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um
notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch
die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden.
Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares,
unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit
anderen Produkten einzuräumen.
Die Lizenz wird kostenfrei zur Verfügung gestellt.
Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen
Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten,
Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete,
beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der
Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.
-->
<rsm:CrossIndustryDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rsm="urn:ferd:CrossIndustryDocument:invoice:1p0" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15">
<rsm:SpecifiedExchangedDocumentContext>
<ram:TestIndicator><udt:Indicator>true</udt:Indicator></ram:TestIndicator><!-- Im Echtbetrieb muss der TestIndicator entweder vollständig entfallen oder auf false stehen. -->
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:extended</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:SpecifiedExchangedDocumentContext>
<rsm:HeaderExchangedDocument>
<ram:ID>R87654321012345</ram:ID>
<ram:Name>WARENRECHNUNG</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20130806</udt:DateTimeString>
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:ContentCode>ST3</ram:ContentCode>
<ram:Content>Es bestehen Rabatt- oder Bonusvereinbarungen.</ram:Content>
<ram:SubjectCode>AAK</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:ContentCode>EEV</ram:ContentCode>
<ram:Content>Der Verkäufer bleibt Eigentümer der Waren bis zu vollständigen Erfüllung der Kaufpreisforderung.</ram:Content>
<ram:SubjectCode>AAJ</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>MUSTERLIEFERANT GMBH
BAHNHOFSTRASSE 99
99199 MUSTERHAUSEN
Geschäftsführung:
Max Mustermann
USt-IdNr: DE123456789
Telefon: +49 932 431 0
www.musterlieferant.de
HRB Nr. 372876
Amtsgericht Musterstadt
GLN 4304171000002
WEEE-Reg-Nr.: DE87654321</ram:Content>
<ram:SubjectCode>REG</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>Leergutwert: 46,50</ram:Content>
</ram:IncludedNote>
</rsm:HeaderExchangedDocument>
<rsm:SpecifiedSupplyChainTradeTransaction>
<ram:ApplicableSupplyChainTradeAgreement>
<ram:SellerTradeParty>
<ram:ID>549910</ram:ID>
<ram:GlobalID schemeID="0088">4333741000005</ram:GlobalID>
<ram:Name>MUSTERLIEFERANT GMBH</ram:Name>
<ram:DefinedTradeContact>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49 932 431 500</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>max.mustermann@musterlieferant.de</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>99199</ram:PostcodeCode>
<ram:LineOne>BAHNHOFSTRASSE 99</ram:LineOne>
<ram:CityName>MUSTERHAUSEN</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>009420</ram:ID>
<ram:GlobalID schemeID="0088">4304171000002</ram:GlobalID>
<ram:Name>MUSTER-KUNDE GMBH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>40235</ram:PostcodeCode>
<ram:LineOne>KUNDENWEG 88</ram:LineOne>
<ram:CityName>DUESSELDORF</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
<ram:BuyerOrderReferencedDocument>
<ram:IssueDateTime>2013-08-01T00:00:00</ram:IssueDateTime>
<ram:ID>B123456789</ram:ID>
</ram:BuyerOrderReferencedDocument>
<ram:AdditionalReferencedDocument>
<ram:IssueDateTime>2013-08-02T00:00:00</ram:IssueDateTime>
<ram:TypeCode>VN</ram:TypeCode>
<ram:ID>A456123</ram:ID>
</ram:AdditionalReferencedDocument>
</ram:ApplicableSupplyChainTradeAgreement>
<ram:ApplicableSupplyChainTradeDelivery>
<ram:ShipToTradeParty>
<ram:GlobalID schemeID="0088">4304171088093</ram:GlobalID>
<ram:Name>MUSTER-MARKT</ram:Name>
<ram:DefinedTradeContact>
<ram:DepartmentName>8211</ram:DepartmentName>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>31157</ram:PostcodeCode>
<ram:LineOne>HAUPTSTRASSE 44</ram:LineOne>
<ram:CityName>SARSTEDT</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:ShipToTradeParty>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20130805</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
<ram:DeliveryNoteReferencedDocument>
<ram:IssueDateTime>2013-08-05T00:00:00</ram:IssueDateTime>
<ram:ID>L87654321012345</ram:ID>
</ram:DeliveryNoteReferencedDocument>
</ram:ApplicableSupplyChainTradeDelivery>
<ram:ApplicableSupplyChainTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:InvoiceeTradeParty>
<ram:ID>009420</ram:ID>
<ram:GlobalID schemeID="0088">4304171000002</ram:GlobalID>
<ram:Name>MUSTER-KUNDE GMBH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>40235</ram:PostcodeCode>
<ram:LineOne>KUNDENWEG 88</ram:LineOne>
<ram:CityName>DUESSELDORF</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:InvoiceeTradeParty>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">61.07</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">321.40</ram:BasisAmount>
<ram:LineTotalBasisAmount currencyID="EUR">326.50</ram:LineTotalBasisAmount>
<ram:AllowanceChargeBasisAmount currencyID="EUR">-5.10</ram:AllowanceChargeBasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">8.93</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">127.59</ram:BasisAmount>
<ram:LineTotalBasisAmount currencyID="EUR">130.70</ram:LineTotalBasisAmount>
<ram:AllowanceChargeBasisAmount currencyID="EUR">-3.11</ram:AllowanceChargeBasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">280.00</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">5.60</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 1</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">130.70</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">2.61</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 1</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:BasisAmount currencyID="EUR">280.00</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">2.50</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 2</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:BasisAmount currencyID="EUR">130.70</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">0.50</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 2</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedLogisticsServiceCharge>
<ram:Description>Transportkosten</ram:Description>
<ram:AppliedAmount currencyID="EUR">3.00</ram:AppliedAmount>
<ram:AppliedTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:AppliedTradeTax>
</ram:SpecifiedLogisticsServiceCharge>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Bei Zahlung innerhalb 14 Tagen gewähren wir 2,0% Skonto.</ram:Description>
<ram:ApplicableTradePaymentDiscountTerms>
<ram:BasisPeriodMeasure unitCode="DAY">14</ram:BasisPeriodMeasure>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
</ram:ApplicableTradePaymentDiscountTerms>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">457.20</ram:LineTotalAmount>
<ram:ChargeTotalAmount currencyID="EUR">3.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount currencyID="EUR">11.21</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount currencyID="EUR">448.99</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">70.00</ram:TaxTotalAmount>
<ram:GrandTotalAmount currencyID="EUR">518.99</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount currencyID="EUR">0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount currencyID="EUR">518.99</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:ApplicableSupplyChainTradeSettlement>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:IncludedNote>
<ram:Content>Wichtige Information: Bei Bestellungen bis zum 19.12. ist die Auslieferung bis spätestens 23.12. garantiert.</ram:Content>
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedSupplyChainTradeSettlement />
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument />
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.0000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.0000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">100.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">4.0000</ram:PackageQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">100.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000014</ram:GlobalID>
<ram:SellerAssignedID>ZS997</ram:SellerAssignedID>
<ram:Name>Zitronensäure 100ml</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_TYPE</ram:TypeCode>
<ram:Description>Verpackungsart</ram:Description>
<ram:Value>BO</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument />
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.5000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">1.5000</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">0.0300</ram:ActualAmount>
<ram:Reason>Artikelrabatt 1</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:BasisQuantity unitCode="C62">1</ram:BasisQuantity>
<ram:ActualAmount currencyID="EUR">0.0200</ram:ActualAmount>
<ram:Reason>Artikelrabatt 2</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.4500</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">50.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">72.50</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000021</ram:GlobalID>
<ram:SellerAssignedID>GZ250</ram:SellerAssignedID>
<ram:Name>Gelierzucker Extra 250g</ram:Name>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument />
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">0.0000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">0.0000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">10.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">0.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000021</ram:GlobalID>
<ram:SellerAssignedID>GZ250</ram:SellerAssignedID>
<ram:Name>Gelierzucker Extra 250g</ram:Name>
<ram:Description>Artikel wie vereinbart ohne Berechnung</ram:Description>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:IncludedNote>
<ram:Content>Öko-Kontroll-Nr.: DE-BW-006-987654321054</ram:Content>
<ram:SubjectCode>AAY</ram:SubjectCode>
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">12.0000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">12.0000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">15.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BO">20.0000</ram:PackageQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">180.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4100130013294</ram:GlobalID>
<ram:SellerAssignedID>2031</ram:SellerAssignedID>
<ram:BuyerAssignedID>K4321</ram:BuyerAssignedID>
<ram:Name>Bierbrau Pils 20/0500</ram:Name>
<ram:Description>EAN-VKE: 4100130913297</ram:Description>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_MATERIAL</ram:TypeCode>
<ram:Description>Verpackung</ram:Description>
<ram:Value>Kiste</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument />
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">3.1000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">3.1000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">15.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BC">1.0000</ram:PackageQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">46.50</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">2001015001325</ram:GlobalID>
<ram:SellerAssignedID>1805</ram:SellerAssignedID>
<ram:BuyerAssignedID>K4322</ram:BuyerAssignedID>
<ram:Name>Leergutpfand 20 x 0,5l</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_MATERIAL</ram:TypeCode>
<ram:Description>Verpackung</ram:Description>
<ram:Value>unverpackt</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument />
<ram:SpecifiedSupplyChainTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">30.0000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:CalculationPercent>3.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">30.0000</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">0.9000</ram:ActualAmount>
<ram:Reason>Artikelrabatt 1</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">29.1000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedSupplyChainTradeAgreement>
<ram:SpecifiedSupplyChainTradeDelivery>
<ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="PX">1.0000</ram:PackageQuantity>
</ram:SpecifiedSupplyChainTradeDelivery>
<ram:SpecifiedSupplyChainTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:ApplicablePercent>7.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">58.20</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:SpecifiedSupplyChainTradeSettlement>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000038</ram:GlobalID>
<ram:SellerAssignedID>MP107</ram:SellerAssignedID>
<ram:Name>Mischpalette Joghurt Karton 3 x 20</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_MATERIAL</ram:TypeCode>
<ram:Description>Verpackung</ram:Description>
<ram:Value>Karton</ram:Value>
</ram:ApplicableProductCharacteristic>
<ram:IncludedReferencedProduct>
<ram:GlobalID schemeID="0088">4123456001035</ram:GlobalID>
<ram:SellerAssignedID>JOG103</ram:SellerAssignedID>
<ram:Name>Erdbeer 20 x 150g Becher</ram:Name>
<ram:UnitQuantity unitCode="C62">20.0000</ram:UnitQuantity>
</ram:IncludedReferencedProduct>
<ram:IncludedReferencedProduct>
<ram:GlobalID schemeID="0088">4123456002032</ram:GlobalID>
<ram:SellerAssignedID>JOG203</ram:SellerAssignedID>
<ram:Name>Banane 20 x 150g Becher</ram:Name>
<ram:UnitQuantity unitCode="C62">20.0000</ram:UnitQuantity>
</ram:IncludedReferencedProduct>
<ram:IncludedReferencedProduct>
<ram:GlobalID schemeID="0088">4123456003039</ram:GlobalID>
<ram:SellerAssignedID>JOG303</ram:SellerAssignedID>
<ram:Name>Schoko 20 x 150g Becher</ram:Name>
<ram:UnitQuantity unitCode="C62">20.0000</ram:UnitQuantity>
</ram:IncludedReferencedProduct>
</ram:SpecifiedTradeProduct>
</ram:IncludedSupplyChainTradeLineItem>
</rsm:SpecifiedSupplyChainTradeTransaction>
</rsm:CrossIndustryDocument>

View File

@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2018 Jochen Staerk
Use is subject to license terms.
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"><!--
Migrated by Mustangproject XSLT
--><rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
<ram:ID>RE-20170509/506</ram:ID>
<ram:Name>RECHNUNG2</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20170510</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Künstlerische Gestaltung (Stunde): Einer weiteren Beispielrechnung</ram:Name>
<ram:Description/>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">160.0000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">160.0000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="HUR">1.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 currencyID="EUR">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:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">0.7900</ram:ChargeAmount>
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">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 currencyID="EUR">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:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">0.1000</ram:ChargeAmount>
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">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 currencyID="EUR">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">20170507</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<ram:PaymentReference>RE-20170509/505</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:ProprietaryID>44421800</ram:ProprietaryID>
</ram:PayeePartyCreditorFinancialAccount>
<ram:PayeeSpecifiedCreditorFinancialInstitution>
<ram:BICID>COBADEFFXXX</ram:BICID>
<ram:GermanBankleitzahlID>41441604</ram:GermanBankleitzahlID>
<ram:Name>Commerzbank</ram:Name>
</ram:PayeeSpecifiedCreditorFinancialInstitution>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">11.20</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">160.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">63.84</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">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 zum 30.05.2017</ram:Description>
<ram:DueDateDateTime>
<udt:DateTimeString format="102">20170530</udt:DateTimeString>
</ram:DueDateDateTime>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">496.00</ram:LineTotalAmount>
<ram:ChargeTotalAmount currencyID="EUR">0.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount currencyID="EUR">0.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount currencyID="EUR">496.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">75.04</ram:TaxTotalAmount>
<ram:GrandTotalAmount currencyID="EUR">571.04</ram:GrandTotalAmount>
<ram:DuePayableAmount currencyID="EUR">571.04</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

View File

@@ -21,14 +21,11 @@
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<!--Migrated by Mustangproject XSLT-->
<rsm:ExchangedDocumentContext>
<ram:TestIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:TestIndicator>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:extended</ram:ID>
<ram:ID>urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
<rsm:ExchangedDocument>
<ram:ID>RE-20170509/505</ram:ID>
<ram:Name>RECHNUNG</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
@@ -36,7 +33,7 @@
<udt:DateTimeString format="102">20170509</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>

View File

@@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Nutzungsrechte
ZUGFeRD Datenformat Version 1.0, 25.6.2014
Beispiel Version 29.09.2014
Zweck des Forums für elektronische Rechnungen bei der AWV e.V („FeRD“) ist u.a. die Schaffung und Spezifizierung
eines offenen Datenformats für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht
diskriminierender, standardisierter Technologien („ZUGFeRD Datenformat“)
Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung
frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine
Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht
diskriminierenden Bedingungen an.
Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung
abrufbar unter www.ferd-net.de.
Im Einzelnen schließt die Nutzungsgewährung ein:
=====================================
FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils
geltenden und akzeptierten Fassung (www.ferd-net.de) ein.
Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung,
Weiterbearbeitung und Verbindung mit anderen Produkten.
Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder
anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige
Anwendungen und Dienste.
Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente
und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um
notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch
die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden.
Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares,
unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit
anderen Produkten einzuräumen.
Die Lizenz wird kostenfrei zur Verfügung gestellt.
Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen
Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten,
Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete,
beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der
Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.
-->
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"><!--
Migrated by Mustangproject XSLT
--><rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>471102</ram:ID>
<ram:Name>RECHNUNG</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20130305</udt:DateTimeString>
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:Content>Rechnung gemäß Bestellung vom 01.03.2013.</ram:Content>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>Lieferant GmbH
Lieferantenstraße 20
80333 München
Deutschland
Geschäftsführer: Hans Muster
Handelsregisternummer: H A 123
</ram:Content>
<ram:SubjectCode>REG</ram:SubjectCode>
</ram:IncludedNote>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0160">4012345001235</ram:GlobalID>
<ram:SellerAssignedID>TB100A4</ram:SellerAssignedID>
<ram:Name>Trennblätter A4</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">9.9000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">9.9000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">20.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 currencyID="EUR">198.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>2</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0160">4000050986428</ram:GlobalID>
<ram:SellerAssignedID>ARNR2</ram:SellerAssignedID>
<ram:Name>Joghurt Banane</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">5.5000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">5.5000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">50.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 currencyID="EUR">275.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:GlobalID schemeID="0088">4000001123452</ram:GlobalID>
<ram:Name>Lieferant GmbH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>80333</ram:PostcodeCode>
<ram:LineOne>Lieferantenstraße 20</ram:LineOne>
<ram:CityName>München</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">201/113/40209</ram:ID>
</ram:SpecifiedTaxRegistration>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>GE2020211</ram:ID>
<ram:GlobalID schemeID="0088">4000001987658</ram:GlobalID>
<ram:Name>Kunden AG Mitte</ram:Name>
<ram:DefinedTradeContact>
<ram:PersonName>Hans Muster</ram:PersonName>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>69876</ram:PostcodeCode>
<ram:LineOne>Kundenstraße 15</ram:LineOne>
<ram:CityName>Frankfurt</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20130305</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<ram:PaymentReference>2013-471102</ram:PaymentReference>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>31</ram:TypeCode>
<ram:Information>Überweisung</ram:Information>
<ram:PayeePartyCreditorFinancialAccount>
<ram:IBANID>DE08700901001234567890</ram:IBANID>
</ram:PayeePartyCreditorFinancialAccount>
<ram:PayeeSpecifiedCreditorFinancialInstitution>
<ram:BICID>GENODEF1M04</ram:BICID>
</ram:PayeeSpecifiedCreditorFinancialInstitution>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">19.25</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">275.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">37.62</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">198.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Zahlbar innerhalb 30 Tagen netto bis 04.04.2013, 3% Skonto innerhalb 10 Tagen bis 15.03.2013</ram:Description>
<ram:DueDateDateTime>
<udt:DateTimeString format="102">20130404</udt:DateTimeString>
</ram:DueDateDateTime>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">473.00</ram:LineTotalAmount>
<ram:ChargeTotalAmount currencyID="EUR">0.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount currencyID="EUR">0.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount currencyID="EUR">473.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">56.87</ram:TaxTotalAmount>
<ram:GrandTotalAmount currencyID="EUR">529.87</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount currencyID="EUR">0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount currencyID="EUR">529.87</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

View File

@@ -0,0 +1,543 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Nutzungsrechte
ZUGFeRD Datenformat Version 1.0, 25.6.2014
Beispiel Version 29.09.2014
Zweck des Forums für elektronische Rechnungen bei der AWV e.V („FeRD“) ist u.a. die Schaffung und Spezifizierung
eines offenen Datenformats für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht
diskriminierender, standardisierter Technologien („ZUGFeRD Datenformat“)
Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung
frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine
Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht
diskriminierenden Bedingungen an.
Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung
abrufbar unter www.ferd-net.de.
Im Einzelnen schließt die Nutzungsgewährung ein:
=====================================
FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils
geltenden und akzeptierten Fassung (www.ferd-net.de) ein.
Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung,
Weiterbearbeitung und Verbindung mit anderen Produkten.
Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder
anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige
Anwendungen und Dienste.
Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente
und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um
notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch
die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden.
Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares,
unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit
anderen Produkten einzuräumen.
Die Lizenz wird kostenfrei zur Verfügung gestellt.
Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen
Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten,
Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete,
beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der
Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.
-->
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"><!--
Migrated by Mustangproject XSLT
--><rsm:ExchangedDocumentContext>
<!-- Im Echtbetrieb muss der TestIndicator entweder vollständig entfallen oder auf false stehen. -->
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>R87654321012345</ram:ID>
<ram:Name>WARENRECHNUNG</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20130806</udt:DateTimeString>
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:ContentCode>ST3</ram:ContentCode>
<ram:Content>Es bestehen Rabatt- oder Bonusvereinbarungen.</ram:Content>
<ram:SubjectCode>AAK</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:ContentCode>EEV</ram:ContentCode>
<ram:Content>Der Verkäufer bleibt Eigentümer der Waren bis zu vollständigen Erfüllung der Kaufpreisforderung.</ram:Content>
<ram:SubjectCode>AAJ</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>MUSTERLIEFERANT GMBH
BAHNHOFSTRASSE 99
99199 MUSTERHAUSEN
Geschäftsführung:
Max Mustermann
USt-IdNr: DE123456789
Telefon: +49 932 431 0
www.musterlieferant.de
HRB Nr. 372876
Amtsgericht Musterstadt
GLN 4304171000002
WEEE-Reg-Nr.: DE87654321</ram:Content>
<ram:SubjectCode>REG</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>Leergutwert: 46,50</ram:Content>
</ram:IncludedNote>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:IncludedNote>
<ram:Content>Wichtige Information: Bei Bestellungen bis zum 19.12. ist die Auslieferung bis spätestens 23.12. garantiert.</ram:Content>
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedLineTradeSettlement/>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument/>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000014</ram:GlobalID>
<ram:SellerAssignedID>ZS997</ram:SellerAssignedID>
<ram:Name>Zitronensäure 100ml</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_TYPE</ram:TypeCode>
<ram:Description>Verpackungsart</ram:Description>
<ram:Value>BO</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.0000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.0000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">100.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">4.0000</ram:PackageQuantity>
</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 currencyID="EUR">100.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument/>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000021</ram:GlobalID>
<ram:SellerAssignedID>GZ250</ram:SellerAssignedID>
<ram:Name>Gelierzucker Extra 250g</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.5000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">1.5000</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">0.0300</ram:ActualAmount>
<ram:Reason>Artikelrabatt 1</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:BasisQuantity unitCode="C62">1</ram:BasisQuantity>
<ram:ActualAmount currencyID="EUR">0.0200</ram:ActualAmount>
<ram:Reason>Artikelrabatt 2</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">1.4500</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">50.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
</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 currencyID="EUR">72.50</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument/>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000021</ram:GlobalID>
<ram:SellerAssignedID>GZ250</ram:SellerAssignedID>
<ram:Name>Gelierzucker Extra 250g</ram:Name>
<ram:Description>Artikel wie vereinbart ohne Berechnung</ram:Description>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">0.0000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">0.0000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">10.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
</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 currencyID="EUR">0.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:IncludedNote>
<ram:Content>Öko-Kontroll-Nr.: DE-BW-006-987654321054</ram:Content>
<ram:SubjectCode>AAY</ram:SubjectCode>
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4100130013294</ram:GlobalID>
<ram:SellerAssignedID>2031</ram:SellerAssignedID>
<ram:BuyerAssignedID>K4321</ram:BuyerAssignedID>
<ram:Name>Bierbrau Pils 20/0500</ram:Name>
<ram:Description>EAN-VKE: 4100130913297</ram:Description>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_MATERIAL</ram:TypeCode>
<ram:Description>Verpackung</ram:Description>
<ram:Value>Kiste</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">12.0000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">12.0000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">15.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BO">20.0000</ram:PackageQuantity>
</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 currencyID="EUR">180.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument/>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">2001015001325</ram:GlobalID>
<ram:SellerAssignedID>1805</ram:SellerAssignedID>
<ram:BuyerAssignedID>K4322</ram:BuyerAssignedID>
<ram:Name>Leergutpfand 20 x 0,5l</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_MATERIAL</ram:TypeCode>
<ram:Description>Verpackung</ram:Description>
<ram:Value>unverpackt</ram:Value>
</ram:ApplicableProductCharacteristic>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">3.1000</ram:ChargeAmount>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">3.1000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">15.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BC">1.0000</ram:PackageQuantity>
</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 currencyID="EUR">46.50</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument/>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0088">4123456000038</ram:GlobalID>
<ram:SellerAssignedID>MP107</ram:SellerAssignedID>
<ram:Name>Mischpalette Joghurt Karton 3 x 20</ram:Name>
<ram:ApplicableProductCharacteristic>
<ram:TypeCode>PACKAGING_MATERIAL</ram:TypeCode>
<ram:Description>Verpackung</ram:Description>
<ram:Value>Karton</ram:Value>
</ram:ApplicableProductCharacteristic>
<ram:IncludedReferencedProduct>
<ram:GlobalID schemeID="0088">4123456001035</ram:GlobalID>
<ram:SellerAssignedID>JOG103</ram:SellerAssignedID>
<ram:Name>Erdbeer 20 x 150g Becher</ram:Name>
<ram:UnitQuantity unitCode="C62">20.0000</ram:UnitQuantity>
</ram:IncludedReferencedProduct>
<ram:IncludedReferencedProduct>
<ram:GlobalID schemeID="0088">4123456002032</ram:GlobalID>
<ram:SellerAssignedID>JOG203</ram:SellerAssignedID>
<ram:Name>Banane 20 x 150g Becher</ram:Name>
<ram:UnitQuantity unitCode="C62">20.0000</ram:UnitQuantity>
</ram:IncludedReferencedProduct>
<ram:IncludedReferencedProduct>
<ram:GlobalID schemeID="0088">4123456003039</ram:GlobalID>
<ram:SellerAssignedID>JOG303</ram:SellerAssignedID>
<ram:Name>Schoko 20 x 150g Becher</ram:Name>
<ram:UnitQuantity unitCode="C62">20.0000</ram:UnitQuantity>
</ram:IncludedReferencedProduct>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:GrossPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">30.0000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>3.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">30.0000</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">0.9000</ram:ActualAmount>
<ram:Reason>Artikelrabatt 1</ram:Reason>
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount currencyID="EUR">29.1000</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="PX">1.0000</ram:PackageQuantity>
</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 currencyID="EUR">58.20</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:ID>549910</ram:ID>
<ram:GlobalID schemeID="0088">4333741000005</ram:GlobalID>
<ram:Name>MUSTERLIEFERANT GMBH</ram:Name>
<ram:DefinedTradeContact>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49 932 431 500</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>max.mustermann@musterlieferant.de</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>99199</ram:PostcodeCode>
<ram:LineOne>BAHNHOFSTRASSE 99</ram:LineOne>
<ram:CityName>MUSTERHAUSEN</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>009420</ram:ID>
<ram:GlobalID schemeID="0088">4304171000002</ram:GlobalID>
<ram:Name>MUSTER-KUNDE GMBH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>40235</ram:PostcodeCode>
<ram:LineOne>KUNDENWEG 88</ram:LineOne>
<ram:CityName>DUESSELDORF</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
<ram:BuyerOrderReferencedDocument>
<ram:IssuerAssignedID>B123456789</ram:IssuerAssignedID>
<ram:FormattedIssueDateTime>
<qdt:DateTimeString>2013-08-01T00:00:00</qdt:DateTimeString>
</ram:FormattedIssueDateTime>
</ram:BuyerOrderReferencedDocument>
<ram:AdditionalReferencedDocument>
<ram:IssuerAssignedID>A456123</ram:IssuerAssignedID>
<ram:TypeCode>VN</ram:TypeCode>
<ram:FormattedIssueDateTime>
<qdt:DateTimeString>2013-08-02T00:00:00</qdt:DateTimeString>
</ram:FormattedIssueDateTime>
</ram:AdditionalReferencedDocument>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>
<ram:ShipToTradeParty>
<ram:GlobalID schemeID="0088">4304171088093</ram:GlobalID>
<ram:Name>MUSTER-MARKT</ram:Name>
<ram:DefinedTradeContact>
<ram:DepartmentName>8211</ram:DepartmentName>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>31157</ram:PostcodeCode>
<ram:LineOne>HAUPTSTRASSE 44</ram:LineOne>
<ram:CityName>SARSTEDT</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:ShipToTradeParty>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20130805</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
<ram:DeliveryNoteReferencedDocument>
<ram:IssuerAssignedID>L87654321012345</ram:IssuerAssignedID>
<ram:FormattedIssueDateTime>
<qdt:DateTimeString>2013-08-05T00:00:00</qdt:DateTimeString>
</ram:FormattedIssueDateTime>
</ram:DeliveryNoteReferencedDocument>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:InvoiceeTradeParty>
<ram:ID>009420</ram:ID>
<ram:GlobalID schemeID="0088">4304171000002</ram:GlobalID>
<ram:Name>MUSTER-KUNDE GMBH</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>40235</ram:PostcodeCode>
<ram:LineOne>KUNDENWEG 88</ram:LineOne>
<ram:CityName>DUESSELDORF</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:InvoiceeTradeParty>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">61.07</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">321.40</ram:BasisAmount>
<ram:LineTotalBasisAmount currencyID="EUR">326.50</ram:LineTotalBasisAmount>
<ram:AllowanceChargeBasisAmount currencyID="EUR">-5.10</ram:AllowanceChargeBasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">8.93</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">127.59</ram:BasisAmount>
<ram:LineTotalBasisAmount currencyID="EUR">130.70</ram:LineTotalBasisAmount>
<ram:AllowanceChargeBasisAmount currencyID="EUR">-3.11</ram:AllowanceChargeBasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">280.00</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">5.60</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 1</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
<ram:BasisAmount currencyID="EUR">130.70</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">2.61</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 1</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:BasisAmount currencyID="EUR">280.00</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">2.50</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 2</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator>
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:BasisAmount currencyID="EUR">130.70</ram:BasisAmount>
<ram:ActualAmount currencyID="EUR">0.50</ram:ActualAmount>
<ram:Reason>Rechnungsrabatt 2</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedLogisticsServiceCharge>
<ram:Description>Transportkosten</ram:Description>
<ram:AppliedAmount currencyID="EUR">3.00</ram:AppliedAmount>
<ram:AppliedTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:AppliedTradeTax>
</ram:SpecifiedLogisticsServiceCharge>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Bei Zahlung innerhalb 14 Tagen gewähren wir 2,0% Skonto.</ram:Description>
<ram:ApplicableTradePaymentDiscountTerms>
<ram:BasisPeriodMeasure unitCode="DAY">14</ram:BasisPeriodMeasure>
<ram:CalculationPercent>2.00</ram:CalculationPercent>
</ram:ApplicableTradePaymentDiscountTerms>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">457.20</ram:LineTotalAmount>
<ram:ChargeTotalAmount currencyID="EUR">3.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount currencyID="EUR">11.21</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount currencyID="EUR">448.99</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">70.00</ram:TaxTotalAmount>
<ram:GrandTotalAmount currencyID="EUR">518.99</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount currencyID="EUR">0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount currencyID="EUR">518.99</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>