Merge branch 'master' into issues/503-ubl
# Conflicts: # library/src/main/java/org/mustangproject/TradeParty.java # library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java
This commit is contained in:
42
History.md
42
History.md
@@ -1,7 +1,41 @@
|
|||||||
- 481
|
2.15.0
|
||||||
- 494
|
=======
|
||||||
- 391
|
2024-
|
||||||
- 491
|
- 435 use invoiceimporter as common technical basis also for zugferdimporter
|
||||||
|
- also import delivery address
|
||||||
|
- 527 metrics may raise error on some pdf files
|
||||||
|
- 517 read product GlobalID
|
||||||
|
- 380 Added test for input stream validation
|
||||||
|
- 518 corrently validate more XRechnung versions
|
||||||
|
- make document charges and allowances serializable
|
||||||
|
- 523 Verapdf claims PDF-A/3s created witth visualize are invalid
|
||||||
|
- 530 duedate can not be set directly
|
||||||
|
- 532 support validation warnings!
|
||||||
|
- 534 new signature
|
||||||
|
- 538 Mustang validator always claims PDF is invalid if flavour is PDF/A-3A
|
||||||
|
- 555 be able to validate ubl credit notes
|
||||||
|
- when parsing now distinguishing between the parseExceptions StructureException and ArithmetricException
|
||||||
|
|
||||||
|
|
||||||
|
2.14.2
|
||||||
|
=======
|
||||||
|
2024-10-14
|
||||||
|
|
||||||
|
- also parse BICs in InvoiceImporter not only IBANs
|
||||||
|
- #509 CLI currently does not write a logfile
|
||||||
|
- #505 crash after invoking ZUGFeRD2PullProvider
|
||||||
|
- #506 Fix POM missing dependencies
|
||||||
|
|
||||||
|
2.14.1
|
||||||
|
=======
|
||||||
|
2024-10-06
|
||||||
|
|
||||||
|
- #481 also be able to convert XRechnung/UBL to PDF not only CII
|
||||||
|
- #494 Quantity/Price Decimal Places
|
||||||
|
- #391 Runden bei Negativwerten
|
||||||
|
- #491/501 non terminating decimal expansion
|
||||||
|
- upgraded en16931 cen schematron to 1.3.12
|
||||||
|
- #499/500 PDF layout corrections
|
||||||
|
|
||||||
2.14.0
|
2.14.0
|
||||||
=======
|
=======
|
||||||
|
|||||||
@@ -35,11 +35,30 @@
|
|||||||
<version>1.8.0</version>
|
<version>1.8.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- logging -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.2.13</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>1.2.13</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<!-- This library is needed so that logback stderr output is sent to, well, stderr, otherwise it lands in stdout -->
|
||||||
|
<groupId>org.codehaus.janino</groupId>
|
||||||
|
<artifactId>janino</artifactId>
|
||||||
|
<version>3.1.7</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
<version>2.0.12</version>
|
<version>2.0.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- end of logging -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.mustangproject.commandline;
|
package org.mustangproject.commandline;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -10,18 +8,43 @@ import java.nio.file.Paths;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class CliIT {
|
public class CliIT {
|
||||||
|
|
||||||
|
public static File getResourceAsFile(String resourcePath) {
|
||||||
|
try {
|
||||||
|
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
|
||||||
|
if (in == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
|
||||||
|
tempFile.deleteOnExit();
|
||||||
|
|
||||||
|
try (FileOutputStream out = new FileOutputStream(tempFile)) {
|
||||||
|
// copy stream
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = in.read(buffer)) != -1) {
|
||||||
|
out.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tempFile;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCii2Ubl() throws Exception {
|
public void testCii2Ubl() throws Exception {
|
||||||
Path output = Paths.get("target/ubl.xml");
|
Path output = Paths.get("target/ubl.xml");
|
||||||
Files.deleteIfExists(output);
|
Files.deleteIfExists(output);
|
||||||
Path jar = Files.newDirectoryStream(Paths.get("target"), "Mustang-CLI-*.jar").iterator().next();
|
Path jar = Files.newDirectoryStream(Paths.get("target"), "Mustang-CLI-*.jar").iterator().next();
|
||||||
ProcessBuilder pb = new ProcessBuilder("java", "-jar", jar.toString(),
|
ProcessBuilder pb = new ProcessBuilder("java", "-jar", jar.toString(),
|
||||||
"--action", "ubl", "--source", "src/test/resources/cii.xml", "--out",
|
"--action", "ubl", "--source", "src/test/resources/cii.xml", "--out",
|
||||||
output.toString());
|
output.toString());
|
||||||
pb.redirectErrorStream(true);
|
pb.redirectErrorStream(true);
|
||||||
Process process = pb.start();
|
Process process = pb.start();
|
||||||
String result = getOutput(process);
|
String result = getOutput(process);
|
||||||
@@ -43,4 +66,17 @@ public class CliIT {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMetric() {
|
||||||
|
StatRun sr = new StatRun();
|
||||||
|
File tempFile = getResourceAsFile("corrupt-factur-x-waytoosmall.pdf");
|
||||||
|
|
||||||
|
FileChecker fc = new FileChecker(tempFile.getAbsolutePath(), sr);
|
||||||
|
|
||||||
|
fc.checkForZUGFeRD();
|
||||||
|
System.out.print(fc.getOutputLine());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
%PDF-1.4
|
||||||
|
%ェォャュ
|
||||||
@@ -64,7 +64,8 @@
|
|||||||
<groupId>net.sf.saxon</groupId>
|
<groupId>net.sf.saxon</groupId>
|
||||||
<artifactId>Saxon-HE</artifactId>
|
<artifactId>Saxon-HE</artifactId>
|
||||||
<version>12.4</version>
|
<version>12.4</version>
|
||||||
</dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
@@ -74,7 +75,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.xmlgraphics</groupId>
|
<groupId>org.apache.xmlgraphics</groupId>
|
||||||
<artifactId>fop</artifactId>
|
<artifactId>fop</artifactId>
|
||||||
<version>2.9</version>
|
<version>2.10</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>xml-apis</groupId>
|
<groupId>xml-apis</groupId>
|
||||||
@@ -82,18 +83,24 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- JAXB -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.xml.bind</groupId>
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
<version>4.0.2</version>
|
<version>4.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jaxb</groupId>
|
||||||
|
<artifactId>jaxb-runtime</artifactId>
|
||||||
|
<version>4.0.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
<groupId>org.eclipse.angus</groupId>
|
<groupId>org.eclipse.angus</groupId>
|
||||||
<artifactId>angus-activation</artifactId>
|
<artifactId>angus-activation</artifactId>
|
||||||
<version>2.0.2</version>
|
<version>2.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Apache PDFBox -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>preflight</artifactId>
|
<artifactId>preflight</artifactId>
|
||||||
@@ -104,11 +111,20 @@
|
|||||||
<artifactId>pdfbox</artifactId>
|
<artifactId>pdfbox</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- DOM4j -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dom4j</groupId>
|
<groupId>org.dom4j</groupId>
|
||||||
<artifactId>dom4j</artifactId>
|
<artifactId>dom4j</artifactId>
|
||||||
<version>2.1.4</version>
|
<version>2.1.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- CII to UBL conversion -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.helger</groupId>
|
||||||
|
<artifactId>en16931-cii2ubl</artifactId>
|
||||||
|
<version>2.2.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
@@ -121,27 +137,12 @@
|
|||||||
<version>5.10.2</version>
|
<version>5.10.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- CII to UBL conversion -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.helger</groupId>
|
|
||||||
<artifactId>en16931-cii2ubl</artifactId>
|
|
||||||
<version>2.2.4</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish.jaxb</groupId>
|
|
||||||
<artifactId>jaxb-runtime</artifactId>
|
|
||||||
<version>4.0.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xmlunit</groupId>
|
<groupId>org.xmlunit</groupId>
|
||||||
<artifactId>xmlunit-core</artifactId>
|
<artifactId>xmlunit-core</artifactId>
|
||||||
<version>2.10.0</version>
|
<version>2.10.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xmlunit</groupId>
|
<groupId>org.xmlunit</groupId>
|
||||||
<artifactId>xmlunit-assertj</artifactId>
|
<artifactId>xmlunit-assertj</artifactId>
|
||||||
@@ -232,11 +233,9 @@
|
|||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.5.3</version>
|
<version>3.5.3</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
<minimizeJar>false
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
</minimizeJar><!-- no longer java 11 compatible if set to true because it removes e.g. javax/xml/bind/annotation/XmlSchema-->
|
|
||||||
<filters>
|
<filters>
|
||||||
|
|
||||||
<filter>
|
<filter>
|
||||||
<artifact>*:*</artifact>
|
<artifact>*:*</artifact>
|
||||||
<excludes>
|
<excludes>
|
||||||
@@ -245,18 +244,6 @@
|
|||||||
<exclude>META-INF/*.RSA</exclude>
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
|
||||||
<artifact>log4j:log4j</artifact>
|
|
||||||
<includes>
|
|
||||||
<include>**</include>
|
|
||||||
</includes>
|
|
||||||
</filter>
|
|
||||||
<filter>
|
|
||||||
<artifact>commons-logging:commons-logging</artifact>
|
|
||||||
<includes>
|
|
||||||
<include>**</include>
|
|
||||||
</includes>
|
|
||||||
</filter>
|
|
||||||
</filters>
|
</filters>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
@@ -265,15 +252,6 @@
|
|||||||
<goals>
|
<goals>
|
||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</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>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.mustangproject;
|
package org.mustangproject;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -28,6 +30,7 @@ public class Allowance extends Charge {
|
|||||||
* @return false since its not supposed to be calculated negatively
|
* @return false since its not supposed to be calculated negatively
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
public boolean isCharge() {
|
public boolean isCharge() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2023 Jochen Stärk, see LICENSE file
|
||||||
|
package org.mustangproject;
|
||||||
|
|
||||||
|
|
||||||
|
import org.mustangproject.ZUGFeRD.TransactionCalculator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public class CalculatedInvoice extends Invoice implements Serializable {
|
||||||
|
|
||||||
|
protected BigDecimal grandTotal=null;
|
||||||
|
|
||||||
|
public void calculate() {
|
||||||
|
TransactionCalculator tc=new TransactionCalculator(this);
|
||||||
|
grandTotal=tc.getGrandTotal();
|
||||||
|
}
|
||||||
|
public BigDecimal getGrandTotal() {
|
||||||
|
if (grandTotal==null) {
|
||||||
|
calculate();
|
||||||
|
}
|
||||||
|
return grandTotal;
|
||||||
|
}
|
||||||
|
public CalculatedInvoice setGrandTotal(BigDecimal grand) {
|
||||||
|
grandTotal=grand;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.mustangproject;
|
package org.mustangproject;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import org.mustangproject.ZUGFeRD.IAbsoluteValueProvider;
|
import org.mustangproject.ZUGFeRD.IAbsoluteValueProvider;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
|
||||||
|
|
||||||
@@ -151,6 +152,7 @@ public class Charge implements IZUGFeRDAllowanceCharge {
|
|||||||
* @return true since it is supposed to be calculated negatively
|
* @return true since it is supposed to be calculated negatively
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
public boolean isCharge() {
|
public boolean isCharge() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.mustangproject.Exceptions;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* will be thrown if a invoice cant be reproduced numerically
|
||||||
|
*/
|
||||||
|
public class ArithmetricException extends ParseException {
|
||||||
|
public ArithmetricException() {
|
||||||
|
super(
|
||||||
|
"Could not reproduce the invoice, this could mean that it could not be read properly", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.mustangproject.Exceptions;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* will be thrown if a invoice cant be read
|
||||||
|
*/
|
||||||
|
public class StructureException extends ParseException {
|
||||||
|
public StructureException(String message, int line) {
|
||||||
|
super(message, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import java.util.Collection;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import org.mustangproject.ZUGFeRD.*;
|
import org.mustangproject.ZUGFeRD.*;
|
||||||
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
|||||||
* @see IExportableTransaction if you want to implement an interface instead
|
* @see IExportableTransaction if you want to implement an interface instead
|
||||||
*/
|
*/
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
public class Invoice implements IExportableTransaction {
|
public class Invoice implements IExportableTransaction {
|
||||||
|
|
||||||
protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, invoiceReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null;
|
protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, invoiceReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null;
|
||||||
@@ -520,6 +522,20 @@ public class Invoice implements IExportableTransaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* this is wrong and only used from jackson
|
||||||
|
* @param iza
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Invoice setZFAllowances(Allowance[] iza) {
|
||||||
|
Allowances=new ArrayList<>();
|
||||||
|
|
||||||
|
for (IZUGFeRDAllowanceCharge cz:iza) {
|
||||||
|
Allowances.add(cz);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IZUGFeRDAllowanceCharge[] getZFCharges() {
|
public IZUGFeRDAllowanceCharge[] getZFCharges() {
|
||||||
@@ -530,6 +546,18 @@ public class Invoice implements IExportableTransaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* this is wrong and only used from jackson
|
||||||
|
* @param iza
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Invoice setZFCharges(Charge[] iza) {
|
||||||
|
Charges=new ArrayList<>();
|
||||||
|
for (IZUGFeRDAllowanceCharge cz:iza) {
|
||||||
|
Charges.add(cz);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() {
|
public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.mustangproject;
|
package org.mustangproject;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import org.mustangproject.ZUGFeRD.IReferencedDocument;
|
import org.mustangproject.ZUGFeRD.IReferencedDocument;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
|
||||||
@@ -18,6 +19,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
public class Item implements IZUGFeRDExportableItem {
|
public class Item implements IZUGFeRDExportableItem {
|
||||||
protected BigDecimal price = BigDecimal.ZERO;
|
protected BigDecimal price = BigDecimal.ZERO;
|
||||||
protected BigDecimal quantity;
|
protected BigDecimal quantity;
|
||||||
@@ -314,7 +316,7 @@ public class Item implements IZUGFeRDExportableItem {
|
|||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* adds item level references along with their typecodes and issuerassignedIDs (contract ID, cost centre, ...)
|
* adds item level references along with their typecodes and issuerassignedIDs (contract ID, cost centre, ...)
|
||||||
* @param doc the ReferencedDocument to add
|
* @param doc the ReferencedDocument to add
|
||||||
* @return fluent setter
|
* @return fluent setter
|
||||||
*/
|
*/
|
||||||
@@ -333,8 +335,8 @@ public class Item implements IZUGFeRDExportableItem {
|
|||||||
}
|
}
|
||||||
return additionalReference.toArray(new IReferencedDocument[0]);
|
return additionalReference.toArray(new IReferencedDocument[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* specify a item level delivery period
|
* specify a item level delivery period
|
||||||
* (apart from the document level delivery period, and the document level
|
* (apart from the document level delivery period, and the document level
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.mustangproject;
|
package org.mustangproject;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import org.mustangproject.ZUGFeRD.IDesignatedProductClassification;
|
import org.mustangproject.ZUGFeRD.IDesignatedProductClassification;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct;
|
||||||
import org.mustangproject.util.NodeMap;
|
import org.mustangproject.util.NodeMap;
|
||||||
@@ -17,6 +18,8 @@ import java.util.Map;
|
|||||||
* describes a product, good or service used in an invoice item line
|
* describes a product, good or service used in an invoice item line
|
||||||
*/
|
*/
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
|
|
||||||
public class Product implements IZUGFeRDExportableProduct {
|
public class Product implements IZUGFeRDExportableProduct {
|
||||||
protected String unit, name, sellerAssignedID, buyerAssignedID;
|
protected String unit, name, sellerAssignedID, buyerAssignedID;
|
||||||
protected String description="";
|
protected String description="";
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty;
|
||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDLegalOrganisation;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDLegalOrganisation;
|
||||||
@@ -19,9 +20,10 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|||||||
* A organisation, i.e. usually a company
|
* A organisation, i.e. usually a company
|
||||||
*/
|
*/
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
public class TradeParty implements IZUGFeRDExportableTradeParty {
|
public class TradeParty implements IZUGFeRDExportableTradeParty {
|
||||||
|
|
||||||
protected String name, zip, street, location, country;
|
protected String name, zip, street, location, country, taxScheme;
|
||||||
protected String taxID = null, vatID = null;
|
protected String taxID = null, vatID = null;
|
||||||
protected String ID = null;
|
protected String ID = null;
|
||||||
protected String description = null;
|
protected String description = null;
|
||||||
@@ -89,21 +91,46 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTopElementName.equals("PartyIdentification")) {
|
if (currentTopElementName.equals("PartyTaxScheme")) {
|
||||||
|
NodeList partyTaxScheme = party.item(partyIndex).getChildNodes();
|
||||||
|
for (int partyTaxSchemeIndex = 0; partyTaxSchemeIndex < partyTaxScheme.getLength(); partyTaxSchemeIndex++) {
|
||||||
|
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName() != null) {
|
||||||
|
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("CompanyID")) {
|
||||||
|
setTaxID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
|
||||||
|
|
||||||
NodeList partyName = party.item(partyIndex).getChildNodes();
|
|
||||||
for (int partyNameIndex = 0; partyNameIndex < partyName.getLength(); partyNameIndex++) {
|
|
||||||
if (partyName.item(partyNameIndex).getLocalName() != null) {
|
|
||||||
if (partyName.item(partyNameIndex).getLocalName().equals("ID")) {
|
|
||||||
setID(partyName.item(partyNameIndex).getTextContent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UBL only: formally it can have a name as well but BT27 party name *should* be stored in
|
|
||||||
// so overwrite if one exists
|
// if (currentTopElementName.equals("PartyTaxScheme")) {
|
||||||
|
// NodeList partyTaxScheme = party.item(partyIndex).getChildNodes();
|
||||||
|
// for (int partyTaxSchemeIndex = 0; partyTaxSchemeIndex < partyTaxScheme.getLength(); partyTaxSchemeIndex++) {
|
||||||
|
// if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName() != null) {
|
||||||
|
// if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("TaxScheme")) {
|
||||||
|
// NodeList taxScheme = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes();
|
||||||
|
// for (int taxSchemeIndex = 0 ; taxSchemeIndex < taxScheme.getLength(); taxSchemeIndex++) {
|
||||||
|
// if (taxScheme.item(taxSchemeIndex).getLocalName() != null) {
|
||||||
|
// if(taxScheme.item(taxSchemeIndex).getLocalName().equals("ID")){
|
||||||
|
// if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("CompanyID")) {
|
||||||
|
// setTaxID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
|
||||||
|
// } else {
|
||||||
|
// setVATID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
/*
|
||||||
|
UBL only: formally it can have a name as well but BT27 party name *should* be stored in
|
||||||
|
so overwrite if one exists
|
||||||
|
*/
|
||||||
|
|
||||||
if (currentTopElementName.equals("PartyLegalEntity")) {
|
if (currentTopElementName.equals("PartyLegalEntity")) {
|
||||||
NodeList legal = party.item(partyIndex).getChildNodes();
|
NodeList legal = party.item(partyIndex).getChildNodes();
|
||||||
for (int legalChildIndex = 0; legalChildIndex < legal.getLength(); legalChildIndex++) {
|
for (int legalChildIndex = 0; legalChildIndex < legal.getLength(); legalChildIndex++) {
|
||||||
@@ -111,6 +138,9 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
if (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) {
|
if (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) {
|
||||||
setName(legal.item(legalChildIndex).getTextContent());
|
setName(legal.item(legalChildIndex).getTextContent());
|
||||||
}
|
}
|
||||||
|
if (legal.item(legalChildIndex).getLocalName().equals("CompanyLegalForm")) {
|
||||||
|
setDescription(legal.item(legalChildIndex).getTextContent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,26 +253,27 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentUBLChild.equals("SpecifiedTaxRegistration")) {
|
if (currentUBLChild.equals("PartyTaxScheme")) {
|
||||||
NodeList taxChilds = nodes.item(nodeIndex).getChildNodes();
|
NodeList taxChilds = nodes.item(nodeIndex).getChildNodes();
|
||||||
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
|
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
|
||||||
if (taxChilds.item(taxChildIndex).getLocalName() != null) {
|
if (taxChilds.item(taxChildIndex).getLocalName() != null) {
|
||||||
if ((taxChilds.item(taxChildIndex).getLocalName().equals("ID"))) {
|
if ((taxChilds.item(taxChildIndex).getLocalName().equals("TaxScheme"))) {
|
||||||
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) {
|
if (taxChilds.item(taxChildIndex).getLocalName().equals("CompanyID")) {
|
||||||
Node firstChild = taxChilds.item(taxChildIndex).getFirstChild();
|
if (taxChilds.item(taxChildIndex).getLocalName().equals("ID")) {
|
||||||
if (firstChild != null) {
|
if (taxChilds.item(taxChildIndex).getLocalName().equals("CompanyID")) {
|
||||||
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("VA")) {
|
setVATID(taxChilds.item(taxChildIndex).getTextContent());
|
||||||
setVATID(firstChild.getNodeValue());
|
|
||||||
}
|
}
|
||||||
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("FC")) {
|
// setTaxID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
|
||||||
setTaxID(firstChild.getNodeValue());
|
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("ID").getNodeValue().equals("FC")) {
|
||||||
|
if (taxChilds.item(taxChildIndex).getLocalName().equals("CompanyID")) {
|
||||||
|
setTaxID(taxChilds.item(taxChildIndex).getTextContent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,7 +355,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
NodeList itemChilds = currentItemNode.getChildNodes();
|
NodeList itemChilds = currentItemNode.getChildNodes();
|
||||||
for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) {
|
for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) {
|
||||||
if (itemChilds.item(itemChildIndex).getLocalName() != null) {
|
if (itemChilds.item(itemChildIndex).getLocalName() != null) {
|
||||||
if (itemChilds.item(itemChildIndex).getLocalName().equals("GlobalID")) {
|
if (itemChilds.item(itemChildIndex).getLocalName().equals("ID")) {
|
||||||
setID(itemChilds.item(itemChildIndex).getTextContent());
|
setID(itemChilds.item(itemChildIndex).getTextContent());
|
||||||
}
|
}
|
||||||
if (itemChilds.item(itemChildIndex).getLocalName().equals("Name")) {
|
if (itemChilds.item(itemChildIndex).getLocalName().equals("Name")) {
|
||||||
@@ -513,6 +544,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (optional)
|
* (optional)
|
||||||
*
|
*
|
||||||
@@ -524,6 +556,14 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* primarily for invoiceimporter and JSON
|
||||||
|
* @return the list of sepa mandates
|
||||||
|
*/
|
||||||
|
public List<DirectDebit> getDebitDetails() {
|
||||||
|
return debitDetails;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IZUGFeRDLegalOrganisation getLegalOrganisation() {
|
public IZUGFeRDLegalOrganisation getLegalOrganisation() {
|
||||||
return legalOrg;
|
return legalOrg;
|
||||||
@@ -660,7 +700,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCountry() {
|
public String getCountry() {
|
||||||
return country;
|
return taxScheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -669,7 +709,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
* @return fluent setter
|
* @return fluent setter
|
||||||
*/
|
*/
|
||||||
public TradeParty setCountry(String country) {
|
public TradeParty setCountry(String country) {
|
||||||
this.country = country;
|
this.taxScheme = country;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,6 +723,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
public IZUGFeRDTradeSettlement[] getAsTradeSettlement() {
|
public IZUGFeRDTradeSettlement[] getAsTradeSettlement() {
|
||||||
if (bankDetails.isEmpty() && debitDetails.isEmpty()) {
|
if (bankDetails.isEmpty() && debitDetails.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -4,9 +4,13 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
public class XMLTools extends XMLWriter {
|
public class XMLTools extends XMLWriter {
|
||||||
@Override
|
@Override
|
||||||
@@ -21,7 +25,7 @@ public class XMLTools extends XMLWriter {
|
|||||||
|
|
||||||
public static String nDigitFormat(BigDecimal value, int scale) {
|
public static String nDigitFormat(BigDecimal value, int scale) {
|
||||||
/*
|
/*
|
||||||
* I needed 123,45, locale independent.I tried
|
* I needed 123.45, locale independent.I tried
|
||||||
* NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is locale
|
* NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is locale
|
||||||
* specific.I also tried DecimalFormat df = new DecimalFormat( "0,00" );
|
* specific.I also tried DecimalFormat df = new DecimalFormat( "0,00" );
|
||||||
* df.setDecimalSeparatorAlwaysShown(true); df.setGroupingUsed(false);
|
* df.setDecimalSeparatorAlwaysShown(true); df.setGroupingUsed(false);
|
||||||
@@ -39,6 +43,105 @@ public class XMLTools extends XMLWriter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the value of an node
|
||||||
|
*
|
||||||
|
* @param node the Node to get the value from
|
||||||
|
* @return A String or empty String, if no value was found
|
||||||
|
*/
|
||||||
|
public static String getNodeValue(Node node) {
|
||||||
|
if (node != null && node.getFirstChild() != null) {
|
||||||
|
return node.getFirstChild().getNodeValue();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tries to convert a String to BigDecimal.
|
||||||
|
*
|
||||||
|
* @param nodeValue The value as String
|
||||||
|
* @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs
|
||||||
|
*/
|
||||||
|
public static BigDecimal tryBigDecimal(String nodeValue) {
|
||||||
|
try {
|
||||||
|
return new BigDecimal(nodeValue);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
try {
|
||||||
|
return BigDecimal.valueOf(Float.valueOf(nodeValue));
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
return new BigDecimal("0.00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tries to convert a Node to a BigDecimal.
|
||||||
|
*
|
||||||
|
* @param node The value as String
|
||||||
|
* @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs
|
||||||
|
*/
|
||||||
|
public static BigDecimal tryBigDecimal(Node node) {
|
||||||
|
final String nodeValue = XMLTools.getNodeValue(node);
|
||||||
|
if (nodeValue.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return XMLTools.tryBigDecimal(nodeValue);
|
||||||
|
}
|
||||||
|
/***
|
||||||
|
* formats a number so that at least minDecimals are displayed but at the maximum maxDecimals are there, i.e.
|
||||||
|
* cuts potential 0s off the end until minDecimals
|
||||||
|
* @param value
|
||||||
|
* @param maxDecimals number of maximal scale
|
||||||
|
* @param minDecimals number of minimal scale
|
||||||
|
* @return value as String with decimals in the specified range
|
||||||
|
*/
|
||||||
|
public static String nDigitFormatDecimalRange(BigDecimal value, int maxDecimals, int minDecimals) {
|
||||||
|
if ((maxDecimals<minDecimals)||(maxDecimals<0)||(minDecimals<0)) {
|
||||||
|
throw new IllegalArgumentException("Invalid scale range provided");
|
||||||
|
}
|
||||||
|
int curDecimals=maxDecimals;
|
||||||
|
while ( (curDecimals>minDecimals) && (value.setScale(curDecimals, RoundingMode.HALF_UP).compareTo(value.setScale(curDecimals-1, RoundingMode.HALF_UP))==0)) {
|
||||||
|
curDecimals--;
|
||||||
|
}
|
||||||
|
return value.setScale(curDecimals, RoundingMode.HALF_UP).toPlainString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* returns a util.Date from a 102 String yyyymmdd in a node
|
||||||
|
* @param node the node
|
||||||
|
* @return a util.Date, or null, if not parseable
|
||||||
|
*/
|
||||||
|
public static Date tryDate(Node node) {
|
||||||
|
final String nodeValue = XMLTools.getNodeValue(node);
|
||||||
|
if (nodeValue.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return tryDate(nodeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* returns a util.Date from a 102 String yyyymmdd
|
||||||
|
* @param toParse the string
|
||||||
|
* @return a util.Date, or null, if not parseable
|
||||||
|
*/
|
||||||
|
public static Date tryDate(String toParse) {
|
||||||
|
final SimpleDateFormat formatter = ZUGFeRDDateFormat.DATE.getFormatter();
|
||||||
|
try {
|
||||||
|
return formatter.parse(toParse);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* relplaces some entities like < , > and & with their escaped pendant like <
|
||||||
|
* @param s the string
|
||||||
|
* @return the "safe" string
|
||||||
|
*/
|
||||||
public static String encodeXML(CharSequence s) {
|
public static String encodeXML(CharSequence s) {
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return "";
|
return "";
|
||||||
@@ -111,4 +214,16 @@ public class XMLTools extends XMLWriter {
|
|||||||
return IOUtils.toByteArray (fileinput);
|
return IOUtils.toByteArray (fileinput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String trimOrNull(Node node) {
|
||||||
|
if (node != null) {
|
||||||
|
String textContent = node.getTextContent();
|
||||||
|
if (textContent != null) {
|
||||||
|
return textContent.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,17 @@ public class LineCalculator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal vatPercent = currentItem.getProduct().getVATPercent();
|
BigDecimal vatPercent = null;
|
||||||
if (vatPercent == null)
|
if (currentItem.getProduct()!=null) {
|
||||||
|
vatPercent = currentItem.getProduct().getVATPercent();
|
||||||
|
}
|
||||||
|
if (vatPercent == null) {
|
||||||
vatPercent = BigDecimal.ZERO;
|
vatPercent = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
BigDecimal multiplicator = vatPercent.divide(BigDecimal.valueOf(100));
|
BigDecimal multiplicator = vatPercent.divide(BigDecimal.valueOf(100));
|
||||||
priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159
|
priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159
|
||||||
price = priceGross.subtract(allowance).add(charge);
|
price = priceGross.subtract(allowance).add(charge);
|
||||||
itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity(), RoundingMode.HALF_UP)
|
itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity(), 18, RoundingMode.HALF_UP)
|
||||||
.subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP);
|
.subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP);
|
||||||
itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator);
|
itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator);
|
||||||
|
|
||||||
|
|||||||
@@ -76,11 +76,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String priceFormat(BigDecimal value) {
|
protected String priceFormat(BigDecimal value) {
|
||||||
return XMLTools.nDigitFormat(value, 18);
|
// 18 decimals are max for price and qty due to xml restrictions,
|
||||||
|
// see Chapter 3.2.3 of https://www.w3.org/TR/xmlschema-2/
|
||||||
|
return XMLTools.nDigitFormatDecimalRange(value, 18, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String quantityFormat(BigDecimal value) {
|
protected String quantityFormat(BigDecimal value) {
|
||||||
return XMLTools.nDigitFormat(value, 18);
|
return XMLTools.nDigitFormatDecimalRange(value, 18, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -332,7 +334,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
this.trans = trans;
|
this.trans = trans;
|
||||||
this.calc = new TransactionCalculator(trans);
|
this.calc = new TransactionCalculator(trans);
|
||||||
|
|
||||||
boolean hasDueDate = false;
|
boolean hasDueDate = trans.getDueDate()!=null;
|
||||||
final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
|
final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
|
||||||
|
|
||||||
String exemptionReason = "";
|
String exemptionReason = "";
|
||||||
@@ -816,7 +818,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((trans.getPaymentTerms() == null) && (getProfile() != Profiles.getByName("Minimum")) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || (hasDueDate))) {
|
if ((trans.getPaymentTerms() == null) && (getProfile() != Profiles.getByName("Minimum")) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || (hasDueDate))) {
|
||||||
xml += "<ram:SpecifiedTradePaymentTerms>";
|
xml += "<ram:SpecifiedTradePaymentTerms>";
|
||||||
|
|
||||||
@@ -832,7 +833,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasDueDate && (trans.getDueDate() != null)) {
|
if (trans.getDueDate() != null) {
|
||||||
xml += "<ram:DueDateDateTime>" // $NON-NLS-2$
|
xml += "<ram:DueDateDateTime>" // $NON-NLS-2$
|
||||||
+ DATE.udtFormat(trans.getDueDate())
|
+ DATE.udtFormat(trans.getDueDate())
|
||||||
+ "</ram:DueDateDateTime>";// 20130704
|
+ "</ram:DueDateDateTime>";// 20130704
|
||||||
|
|||||||
@@ -13,92 +13,34 @@ package org.mustangproject.ZUGFeRD;
|
|||||||
* @version 1.1.0
|
* @version 1.1.0
|
||||||
* @author jstaerk
|
* @author jstaerk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
import javax.xml.xpath.XPathExpression;
|
import javax.xml.xpath.XPathExpression;
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
|
|
||||||
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.*;
|
import org.mustangproject.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
public class ZUGFeRDImporter {
|
public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDImporter.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDImporter.class);
|
||||||
|
|
||||||
/**
|
public ZUGFeRDImporter() {
|
||||||
* if metadata has been found
|
super();
|
||||||
*/
|
|
||||||
protected boolean containsMeta = false;
|
|
||||||
/**
|
|
||||||
* map filenames of additional XML files to their contents
|
|
||||||
*/
|
|
||||||
private final HashMap<String, byte[]> additionalXMLs = new HashMap<>();
|
|
||||||
/**
|
|
||||||
* map filenames of all embedded files in the respective PDF
|
|
||||||
*/
|
|
||||||
private final ArrayList<FileAttachment> PDFAttachments = new ArrayList<>();
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
private Integer version;
|
|
||||||
|
|
||||||
|
|
||||||
protected ZUGFeRDImporter() {
|
|
||||||
//constructor for extending classes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZUGFeRDImporter(String pdfFilename) {
|
public ZUGFeRDImporter(String filename) {
|
||||||
try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) {
|
super(filename);
|
||||||
extractLowLevel(bis);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
LOGGER.error("Failed to extract ZUGFeRD data", e);
|
|
||||||
throw new ZUGFeRDExportException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZUGFeRDImporter(InputStream stream) {
|
||||||
public ZUGFeRDImporter(InputStream pdfStream) {
|
super(stream);
|
||||||
try {
|
|
||||||
extractLowLevel(pdfStream);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
LOGGER.error("Failed to extract ZUGFeRD data", e);
|
|
||||||
throw new ZUGFeRDExportException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,169 +55,21 @@ public class ZUGFeRDImporter {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
////////////////////////////////////
|
||||||
* Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling.
|
|
||||||
*
|
|
||||||
* @param inStream a inputstream of a pdf file
|
|
||||||
*/
|
|
||||||
private void extractLowLevel(InputStream inStream) throws IOException {
|
|
||||||
BufferedInputStream pdfStream = new BufferedInputStream(inStream);
|
|
||||||
byte[] pad = new byte[4];
|
|
||||||
pdfStream.mark(0);
|
|
||||||
pdfStream.read(pad);
|
|
||||||
pdfStream.reset();
|
|
||||||
byte[] pdfSignature = {'%', 'P', 'D', 'F'};
|
|
||||||
if (Arrays.equals(pad, pdfSignature)) { // we have a pdf
|
|
||||||
|
|
||||||
|
|
||||||
try (PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream))) {
|
|
||||||
// PDDocumentInformation info = doc.getDocumentInformation();
|
|
||||||
final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
|
|
||||||
//start
|
|
||||||
|
|
||||||
if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) {
|
|
||||||
LOGGER.info("no-xmlpart");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata();
|
|
||||||
xmpString = convertStreamToString(XMP);
|
|
||||||
|
|
||||||
final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles();
|
|
||||||
if (etn == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String, PDComplexFileSpecification> efMap = etn.getNames();
|
|
||||||
// String filePath = "/tmp/";
|
|
||||||
|
|
||||||
if (efMap != null) {
|
|
||||||
extractFiles(efMap); // see
|
|
||||||
// https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/
|
|
||||||
} else {
|
|
||||||
|
|
||||||
final List<PDNameTreeNode<PDComplexFileSpecification>> kids = etn.getKids();
|
|
||||||
if (kids == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (final PDNameTreeNode<PDComplexFileSpecification> node : kids) {
|
|
||||||
final Map<String, PDComplexFileSpecification> namesL = node.getNames();
|
|
||||||
extractFiles(namesL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no PDF probably XML
|
|
||||||
containsMeta = true;
|
|
||||||
setRawXML(XMLTools.getBytesFromStream(pdfStream));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
|
|
||||||
for (final String alias : names.keySet()) {
|
|
||||||
|
|
||||||
final PDComplexFileSpecification fileSpec = names.get(alias);
|
|
||||||
final String filename = fileSpec.getFilename();
|
|
||||||
/**
|
|
||||||
* filenames for invoice data (ZUGFeRD v1 and v2, Factur-X)
|
|
||||||
*/
|
|
||||||
|
|
||||||
final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
|
|
||||||
if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) {
|
|
||||||
containsMeta = true;
|
|
||||||
|
|
||||||
// String embeddedFilename = filePath + filename;
|
|
||||||
// File file = new File(filePath + filename);
|
|
||||||
// System.out.println("Writing " + embeddedFilename);
|
|
||||||
// ByteArrayOutputStream fileBytes=new
|
|
||||||
// ByteArrayOutputStream();
|
|
||||||
// FileOutputStream fos = new FileOutputStream(file);
|
|
||||||
|
|
||||||
setRawXML(embeddedFile.toByteArray());
|
|
||||||
|
|
||||||
// fos.write(embeddedFile.getByteArray());
|
|
||||||
// fos.close();
|
|
||||||
}
|
|
||||||
if (filename.startsWith("additional_data")) {
|
|
||||||
additionalXMLs.put(filename, embeddedFile.toByteArray());
|
|
||||||
}
|
|
||||||
PDFAttachments.add(new FileAttachment(filename, embeddedFile.getSubtype(), "Data", embeddedFile.toByteArray()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected Document getDocument() {
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setDocument() throws ParserConfigurationException, IOException, SAXException {
|
|
||||||
final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
|
|
||||||
xmlFact.setNamespaceAware(true);
|
|
||||||
final DocumentBuilder builder = xmlFact.newDocumentBuilder();
|
|
||||||
final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
|
|
||||||
/// is.skip(guessBOMSize(is));
|
|
||||||
document = builder.parse(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setRawXML(byte[] rawXML) throws IOException {
|
|
||||||
this.containsMeta = true;
|
|
||||||
this.rawXML = rawXML;
|
|
||||||
this.version = null;
|
|
||||||
try {
|
|
||||||
setDocument();
|
|
||||||
} catch (ParserConfigurationException | SAXException e) {
|
|
||||||
LOGGER.error("Failed to parse XML", e);
|
|
||||||
throw new ZUGFeRDExportException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected String extractString(String xpathStr) {
|
|
||||||
if (!containsMeta) {
|
|
||||||
throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found.");
|
|
||||||
}
|
|
||||||
final String result;
|
|
||||||
try {
|
|
||||||
final Document document = getDocument();
|
|
||||||
final XPathFactory xpathFact = XPathFactory.newInstance();
|
|
||||||
final XPath xpath = xpathFact.newXPath();
|
|
||||||
result = xpath.evaluate(xpathStr, document);
|
|
||||||
} catch (final XPathExpressionException e) {
|
|
||||||
LOGGER.error("Failed to evaluate XPath", e);
|
|
||||||
throw new ZUGFeRDExportException(e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Wrapper for protected method extractString
|
|
||||||
* @param xpathStr the xpath expression to be evaluated
|
|
||||||
* @return the extracted String for the specific path in the document
|
|
||||||
*/
|
|
||||||
public String wExtractString(String xpathStr) {
|
|
||||||
return extractString(xpathStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the reference (purpose) the sender specified for this invoice
|
* @return the reference (purpose) the sender specified for this invoice
|
||||||
*/
|
*/
|
||||||
public String getForeignReference() {
|
public String getForeignReference() {
|
||||||
String result = extractString("//*[local-name() = 'ApplicableHeaderTradeSettlement']/*[local-name() = 'PaymentReference']");
|
|
||||||
if (result == null || result.isEmpty()) {
|
return importedInvoice.getNumber();
|
||||||
result = extractString("//*[local-name() = 'ApplicableSupplyChainTradeSettlement']/*[local-name() = 'PaymentReference']");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the ZUGFeRD Profile
|
* @return the ZUGFeRD Profile
|
||||||
*/
|
*/
|
||||||
public String getZUGFeRDProfil() {
|
public String getZUGFeRDProfil() {
|
||||||
|
|
||||||
String guideline = extractString("//*[local-name() = 'GuidelineSpecifiedDocumentContextParameter']//*[local-name() = 'ID']");
|
String guideline = extractString("//*[local-name() = 'GuidelineSpecifiedDocumentContextParameter']//*[local-name() = 'ID']");
|
||||||
if (guideline.contains("xrechnung")) {
|
if (guideline.contains("xrechnung")) {
|
||||||
return "XRECHNUNG";
|
return "XRECHNUNG";
|
||||||
@@ -299,21 +93,6 @@ public class ZUGFeRDImporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the Invoice Currency Code
|
|
||||||
*/
|
|
||||||
public String getInvoiceCurrencyCode() {
|
|
||||||
try {
|
|
||||||
if (getVersion() == 1) {
|
|
||||||
return extractString("//*[local-name() = 'ApplicableSupplyChainTradeSettlement']//*[local-name() = 'InvoiceCurrencyCode']");
|
|
||||||
} else {
|
|
||||||
return extractString("//*[local-name() = 'ApplicableHeaderTradeSettlement']//*[local-name() = 'InvoiceCurrencyCode']");
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// Exception was already logged
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the IssuerAssigned ID
|
* @return the IssuerAssigned ID
|
||||||
@@ -336,57 +115,6 @@ public class ZUGFeRDImporter {
|
|||||||
return extractIssuerAssignedID("ContractReferencedDocument");
|
return extractIssuerAssignedID("ContractReferencedDocument");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractIssuerAssignedID(String propertyName) {
|
|
||||||
try {
|
|
||||||
if (getVersion() == 1) {
|
|
||||||
return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'ID']");
|
|
||||||
} else {
|
|
||||||
return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'IssuerAssignedID']");
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// Exception was already logged
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the BuyerTradeParty ID
|
|
||||||
*/
|
|
||||||
public String getBuyerTradePartyID() {
|
|
||||||
return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'ID']");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the Issue Date()
|
|
||||||
*/
|
|
||||||
public String getIssueDate() {
|
|
||||||
try {
|
|
||||||
if (getVersion() == 1) {
|
|
||||||
return extractString("//*[local-name() = 'HeaderExchangedDocument']//*[local-name() = 'IssueDateTime']//*[local-name() = 'DateTimeString']");
|
|
||||||
} else {
|
|
||||||
return extractString("//*[local-name() = 'ExchangedDocument']//*[local-name() = 'IssueDateTime']//*[local-name() = 'DateTimeString']");
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// Exception was already logged
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDetailedDeliveryPeriodFrom() {
|
|
||||||
final String toParse = extractString(
|
|
||||||
"//*[local-name() = 'ApplicableHeaderTradeSettlement']" +
|
|
||||||
"//*[local-name() = 'BillingSpecifiedPeriod']" +
|
|
||||||
"//*[local-name() = 'StartDateTime']//*[local-name() = 'DateTimeString']");
|
|
||||||
return tryDate(toParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDetailedDeliveryPeriodTo() {
|
|
||||||
final String toParse = extractString(
|
|
||||||
"//*[local-name() = 'ApplicableHeaderTradeSettlement']" +
|
|
||||||
"//*[local-name() = 'BillingSpecifiedPeriod']" +
|
|
||||||
"//*[local-name() = 'EndDateTime']//*[local-name() = 'DateTimeString']");
|
|
||||||
return tryDate(toParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the TaxBasisTotalAmount
|
* @return the TaxBasisTotalAmount
|
||||||
@@ -470,7 +198,16 @@ public class ZUGFeRDImporter {
|
|||||||
* @return the BuyerTradeParty SpecifiedTaxRegistration ID
|
* @return the BuyerTradeParty SpecifiedTaxRegistration ID
|
||||||
*/
|
*/
|
||||||
public String getBuyertradePartySpecifiedTaxRegistrationID() {
|
public String getBuyertradePartySpecifiedTaxRegistrationID() {
|
||||||
return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'SpecifiedTaxRegistration']//*[local-name() = 'ID']");
|
String id = null;
|
||||||
|
if ((importedInvoice.getRecipient()!=null) && (importedInvoice.getRecipient().getLegalOrganisation()!=null)) {
|
||||||
|
// this *should* be the official result
|
||||||
|
id = importedInvoice.getRecipient().getLegalOrganisation().getSchemedID().getID();
|
||||||
|
}
|
||||||
|
// but also provide some fallback
|
||||||
|
if (id == null) {
|
||||||
|
id = getBuyerTradePartyID();
|
||||||
|
}
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -494,14 +231,14 @@ public class ZUGFeRDImporter {
|
|||||||
* @return the BuyerTradeParty Name
|
* @return the BuyerTradeParty Name
|
||||||
*/
|
*/
|
||||||
public String getBuyerTradePartyName() {
|
public String getBuyerTradePartyName() {
|
||||||
return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'Name']");
|
return importedInvoice.getRecipient().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the BuyerTradeParty Name
|
* @return the BuyerTradeParty Name
|
||||||
*/
|
*/
|
||||||
public String getDeliveryTradePartyName() {
|
public String getDeliveryTradePartyName() {
|
||||||
return extractString("//*[local-name() = 'ShipToTradeParty']//*[local-name() = 'Name']");
|
return importedInvoice.getDeliveryAddress().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -548,16 +285,7 @@ public class ZUGFeRDImporter {
|
|||||||
* @return the Invoice ID
|
* @return the Invoice ID
|
||||||
*/
|
*/
|
||||||
public String getInvoiceID() {
|
public String getInvoiceID() {
|
||||||
try {
|
return importedInvoice.getNumber();
|
||||||
if (getVersion() == 1) {
|
|
||||||
return extractString("//*[local-name() = 'HeaderExchangedDocument']//*[local-name() = 'ID']");
|
|
||||||
} else {
|
|
||||||
return extractString("//*[local-name() = 'ExchangedDocument']//*[local-name() = 'ID']");
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// Exception was already logged
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -615,11 +343,21 @@ public class ZUGFeRDImporter {
|
|||||||
* @return the sender's account IBAN code
|
* @return the sender's account IBAN code
|
||||||
*/
|
*/
|
||||||
public String getIBAN() {
|
public String getIBAN() {
|
||||||
return extractString("//*[local-name() = 'PayeePartyCreditorFinancialAccount']/*[local-name() = 'IBANID']");
|
for (IZUGFeRDTradeSettlement settlement : importedInvoice.getTradeSettlement()) {
|
||||||
|
if (settlement instanceof IZUGFeRDTradeSettlementDebit) {
|
||||||
|
return ((IZUGFeRDTradeSettlementDebit) settlement).getIBAN();
|
||||||
|
}
|
||||||
|
if (settlement instanceof IZUGFeRDTradeSettlementPayment) {
|
||||||
|
return ((IZUGFeRDTradeSettlementPayment) settlement).getOwnIBAN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getHolder() {
|
public String getHolder() {
|
||||||
|
|
||||||
|
|
||||||
return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']");
|
return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,14 +366,8 @@ public class ZUGFeRDImporter {
|
|||||||
* @return the total payable amount
|
* @return the total payable amount
|
||||||
*/
|
*/
|
||||||
public String getAmount() {
|
public String getAmount() {
|
||||||
String result = extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']/*[local-name() = 'DuePayableAmount']");
|
|
||||||
if (result == null || result.isEmpty()) {
|
|
||||||
|
|
||||||
/* fx/zf would be SpecifiedTradeSettlementMonetarySummation
|
return importedInvoice.getGrandTotal().toPlainString();
|
||||||
* but ox is SpecifiedTradeSettlementHeaderMonetarySummation...*/
|
|
||||||
result = extractString("//*[local-name() = 'GrandTotalAmount']");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -643,7 +375,60 @@ public class ZUGFeRDImporter {
|
|||||||
* @return when the payment is due
|
* @return when the payment is due
|
||||||
*/
|
*/
|
||||||
public String getDueDate() {
|
public String getDueDate() {
|
||||||
return extractString("//*[local-name() = 'SpecifiedTradePaymentTerms']/*[local-name() = 'DueDateDateTime']/*[local-name() = 'DateTimeString']");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
||||||
|
return sdf.format(importedInvoice.getDueDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Invoice Currency Code
|
||||||
|
*/
|
||||||
|
public String getInvoiceCurrencyCode() {
|
||||||
|
return importedInvoice.getCurrency();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String extractIssuerAssignedID(String propertyName) {
|
||||||
|
try {
|
||||||
|
if (getVersion() == 1) {
|
||||||
|
return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'ID']");
|
||||||
|
} else {
|
||||||
|
return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'IssuerAssignedID']");
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// Exception was already logged
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the BuyerTradeParty ID
|
||||||
|
*/
|
||||||
|
public String getBuyerTradePartyID() {
|
||||||
|
String id = importedInvoice.getRecipient().getID();
|
||||||
|
if (id == null) {
|
||||||
|
// provide some fallback
|
||||||
|
id = importedInvoice.getRecipient().getVATID();
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Issue Date()
|
||||||
|
*/
|
||||||
|
public String getIssueDate() {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
||||||
|
return sdf.format(importedInvoice.getIssueDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDetailedDeliveryPeriodFrom() {
|
||||||
|
return importedInvoice.getDetailedDeliveryPeriodFrom();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDetailedDeliveryPeriodTo() {
|
||||||
|
return importedInvoice.getDetailedDeliveryPeriodTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -691,28 +476,6 @@ public class ZUGFeRDImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public EStandard getStandard() throws Exception {
|
|
||||||
if (!containsMeta) {
|
|
||||||
throw new Exception("Not yet parsed");
|
|
||||||
}
|
|
||||||
final String head = getUTF8();
|
|
||||||
String rootNode = extractString("local-name(/*)");
|
|
||||||
if (rootNode.equals("CrossIndustryDocument")) {
|
|
||||||
return EStandard.zugferd;
|
|
||||||
} else if (rootNode.equals("Invoice")) {
|
|
||||||
return EStandard.ubl;
|
|
||||||
} else if (rootNode.equals("CrossIndustryInvoice")) {
|
|
||||||
return EStandard.facturx;
|
|
||||||
} else if (rootNode.equals("SCRDMCCBDACIDAMessageStructure")) {
|
|
||||||
return EStandard.despatchadvice;
|
|
||||||
} else if (head.contains("<rsm:SCRDMCCBDACIOMessageStructure")) {
|
|
||||||
return EStandard.orderx;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception("ZUGFeRD version could not be determined");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVersion() throws Exception {
|
public int getVersion() throws Exception {
|
||||||
if (!containsMeta) {
|
if (!containsMeta) {
|
||||||
throw new Exception("Not yet parsed");
|
throw new Exception("Not yet parsed");
|
||||||
@@ -736,35 +499,6 @@ public class ZUGFeRDImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return return UTF8 XML (without BOM) of the invoice
|
|
||||||
*/
|
|
||||||
public String getUTF8() {
|
|
||||||
if (rawXML == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (rawXML.length < 3) {
|
|
||||||
return new String(rawXML);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
final byte[] bomlessData;
|
|
||||||
|
|
||||||
if ((rawXML[0] == (byte) 0xEF)
|
|
||||||
&& (rawXML[1] == (byte) 0xBB)
|
|
||||||
&& (rawXML[2] == (byte) 0xBF)) {
|
|
||||||
// I don't like BOMs, lets remove it
|
|
||||||
bomlessData = new byte[rawXML.length - 3];
|
|
||||||
System.arraycopy(rawXML, 3, bomlessData, 0,
|
|
||||||
rawXML.length - 3);
|
|
||||||
} else {
|
|
||||||
bomlessData = rawXML;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(bomlessData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the raw XML data as extracted from the ZUGFeRD PDF file.
|
* Returns the raw XML data as extracted from the ZUGFeRD PDF file.
|
||||||
*
|
*
|
||||||
@@ -790,14 +524,6 @@ public class ZUGFeRDImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static String convertStreamToString(java.io.InputStream is) {
|
|
||||||
try {
|
|
||||||
return IOUtils.toString(is, StandardCharsets.UTF_8);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UncheckedIOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns an instance of PostalTradeAddress for SellerTradeParty section
|
* returns an instance of PostalTradeAddress for SellerTradeParty section
|
||||||
*
|
*
|
||||||
@@ -809,7 +535,7 @@ public class ZUGFeRDImporter {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
nl = getNodeListByPath("//*[local-name() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']/*[local-name() = 'ApplicableSupplyChainTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']");
|
nl = getNodeListByPath("//*[localname() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']/*[local-name() = 'ApplicableSupplyChainTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']");
|
||||||
} else {
|
} else {
|
||||||
nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']");
|
nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']");
|
||||||
}
|
}
|
||||||
@@ -953,7 +679,7 @@ public class ZUGFeRDImporter {
|
|||||||
if (node != null) {
|
if (node != null) {
|
||||||
final NodeList tradeAgreementChildren = node.getChildNodes();
|
final NodeList tradeAgreementChildren = node.getChildNodes();
|
||||||
node = getNodeByName(tradeAgreementChildren, "ChargeAmount");
|
node = getNodeByName(tradeAgreementChildren, "ChargeAmount");
|
||||||
lineItem.setPrice(tryBigDecimal(getNodeValue(node)));
|
lineItem.setPrice(XMLTools.tryBigDecimal(node));
|
||||||
node = getNodeByName(tradeAgreementChildren, "BasisQuantity");
|
node = getNodeByName(tradeAgreementChildren, "BasisQuantity");
|
||||||
if (node != null && node.getAttributes() != null) {
|
if (node != null && node.getAttributes() != null) {
|
||||||
final Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode");
|
final Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode");
|
||||||
@@ -966,48 +692,55 @@ public class ZUGFeRDImporter {
|
|||||||
node = getNodeByName(nn.getChildNodes(), "GrossPriceProductTradePrice");
|
node = getNodeByName(nn.getChildNodes(), "GrossPriceProductTradePrice");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "ChargeAmount");
|
node = getNodeByName(node.getChildNodes(), "ChargeAmount");
|
||||||
lineItem.setGrossPrice(tryBigDecimal(getNodeValue(node)));
|
lineItem.setGrossPrice(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "AssociatedDocumentLineDocument":
|
case "AssociatedDocumentLineDocument":
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "LineID");
|
node = getNodeByName(nn.getChildNodes(), "LineID");
|
||||||
lineItem.setId(getNodeValue(node));
|
lineItem.setId(XMLTools.getNodeValue(node));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "SpecifiedTradeProduct":
|
case "SpecifiedTradeProduct":
|
||||||
|
node = getNodeByName(nn.getChildNodes(), "GlobalID");
|
||||||
|
if (node != null) {
|
||||||
|
SchemedID globalId = new SchemedID()
|
||||||
|
.setScheme(node.getAttributes()
|
||||||
|
.getNamedItem("schemeID").getNodeValue())
|
||||||
|
.setId(XMLTools.getNodeValue(node));
|
||||||
|
lineItem.getProduct().addGlobalID(globalId);
|
||||||
|
}
|
||||||
node = getNodeByName(nn.getChildNodes(), "SellerAssignedID");
|
node = getNodeByName(nn.getChildNodes(), "SellerAssignedID");
|
||||||
lineItem.getProduct().setSellerAssignedID(getNodeValue(node));
|
lineItem.getProduct().setSellerAssignedID(XMLTools.getNodeValue(node));
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "BuyerAssignedID");
|
node = getNodeByName(nn.getChildNodes(), "BuyerAssignedID");
|
||||||
lineItem.getProduct().setBuyerAssignedID(getNodeValue(node));
|
lineItem.getProduct().setBuyerAssignedID(XMLTools.getNodeValue(node));
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "Name");
|
node = getNodeByName(nn.getChildNodes(), "Name");
|
||||||
lineItem.getProduct().setName(getNodeValue(node));
|
lineItem.getProduct().setName(XMLTools.getNodeValue(node));
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "Description");
|
node = getNodeByName(nn.getChildNodes(), "Description");
|
||||||
lineItem.getProduct().setDescription(getNodeValue(node));
|
lineItem.getProduct().setDescription(XMLTools.getNodeValue(node));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "SpecifiedLineTradeDelivery":
|
case "SpecifiedLineTradeDelivery":
|
||||||
case "SpecifiedSupplyChainTradeDelivery":
|
case "SpecifiedSupplyChainTradeDelivery":
|
||||||
node = getNodeByName(nn.getChildNodes(), "BilledQuantity");
|
node = getNodeByName(nn.getChildNodes(), "BilledQuantity");
|
||||||
lineItem.setQuantity(tryBigDecimal(getNodeValue(node)));
|
lineItem.setQuantity(XMLTools.tryBigDecimal(node));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "SpecifiedLineTradeSettlement":
|
case "SpecifiedLineTradeSettlement":
|
||||||
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "RateApplicablePercent");
|
node = getNodeByName(node.getChildNodes(), "RateApplicablePercent");
|
||||||
lineItem.getProduct().setVATPercent(tryBigDecimal(getNodeValue(node)));
|
lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "CalculatedAmount");
|
node = getNodeByName(node.getChildNodes(), "CalculatedAmount");
|
||||||
lineItem.setTax(tryBigDecimal(getNodeValue(node)));
|
lineItem.setTax(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
node = getNodeByName(nn.getChildNodes(), "BillingSpecifiedPeriod");
|
node = getNodeByName(nn.getChildNodes(), "BillingSpecifiedPeriod");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
@@ -1021,13 +754,13 @@ public class ZUGFeRDImporter {
|
|||||||
if (end != null) {
|
if (end != null) {
|
||||||
dateTimeEnd = getNodeByName(end.getChildNodes(), "DateTimeString");
|
dateTimeEnd = getNodeByName(end.getChildNodes(), "DateTimeString");
|
||||||
}
|
}
|
||||||
lineItem.setDetailedDeliveryPeriod(tryDate(dateTimeStart), tryDate(dateTimeEnd));
|
lineItem.setDetailedDeliveryPeriod(XMLTools.tryDate(dateTimeStart), XMLTools.tryDate(dateTimeEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementLineMonetarySummation");
|
node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementLineMonetarySummation");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "LineTotalAmount");
|
node = getNodeByName(node.getChildNodes(), "LineTotalAmount");
|
||||||
lineItem.setLineTotalAmount(tryBigDecimal(getNodeValue(node)));
|
lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "SpecifiedSupplyChainTradeSettlement":
|
case "SpecifiedSupplyChainTradeSettlement":
|
||||||
@@ -1036,19 +769,19 @@ public class ZUGFeRDImporter {
|
|||||||
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "ApplicablePercent");
|
node = getNodeByName(node.getChildNodes(), "ApplicablePercent");
|
||||||
lineItem.getProduct().setVATPercent(tryBigDecimal(getNodeValue(node)));
|
lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "CalculatedAmount");
|
node = getNodeByName(node.getChildNodes(), "CalculatedAmount");
|
||||||
lineItem.setTax(tryBigDecimal(getNodeValue(node)));
|
lineItem.setTax(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementMonetarySummation");
|
node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementMonetarySummation");
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node = getNodeByName(node.getChildNodes(), "LineTotalAmount");
|
node = getNodeByName(node.getChildNodes(), "LineTotalAmount");
|
||||||
lineItem.setLineTotalAmount(tryBigDecimal(getNodeValue(node)));
|
lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1123,51 +856,4 @@ public class ZUGFeRDImporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the value of an node
|
|
||||||
*
|
|
||||||
* @param node the Node to get the value from
|
|
||||||
* @return A String or empty String, if no value was found
|
|
||||||
*/
|
|
||||||
private String getNodeValue(Node node) {
|
|
||||||
if (node != null && node.getFirstChild() != null) {
|
|
||||||
return node.getFirstChild().getNodeValue();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tries to convert an String to BigDecimal.
|
|
||||||
*
|
|
||||||
* @param nodeValue The value as String
|
|
||||||
* @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs
|
|
||||||
*/
|
|
||||||
private BigDecimal tryBigDecimal(String nodeValue) {
|
|
||||||
try {
|
|
||||||
return new BigDecimal(nodeValue);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
try {
|
|
||||||
return BigDecimal.valueOf(Float.valueOf(nodeValue));
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
return new BigDecimal("0.00");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Date tryDate(Node node) {
|
|
||||||
final String nodeValue = getNodeValue(node);
|
|
||||||
if (nodeValue.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return tryDate(nodeValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Date tryDate(String toParse) {
|
|
||||||
final SimpleDateFormat formatter = ZUGFeRDDateFormat.DATE.getFormatter();
|
|
||||||
try {
|
|
||||||
return formatter.parse(toParse);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,277 @@
|
|||||||
package org.mustangproject.ZUGFeRD;
|
package org.mustangproject.ZUGFeRD;
|
||||||
|
|
||||||
import java.io.IOException;
|
import org.apache.commons.io.IOUtils;
|
||||||
import java.io.InputStream;
|
import org.apache.pdfbox.Loader;
|
||||||
import java.math.BigDecimal;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import java.nio.charset.StandardCharsets;
|
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
|
||||||
import java.text.ParseException;
|
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
|
||||||
import java.text.SimpleDateFormat;
|
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
|
||||||
import java.util.ArrayList;
|
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
|
||||||
import java.util.Base64;
|
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.xml.xpath.XPath;
|
|
||||||
import javax.xml.xpath.XPathConstants;
|
|
||||||
import javax.xml.xpath.XPathExpression;
|
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
|
||||||
import javax.xml.xpath.XPathFactory;
|
|
||||||
|
|
||||||
import org.mustangproject.*;
|
import org.mustangproject.*;
|
||||||
|
import org.mustangproject.Exceptions.ArithmetricException;
|
||||||
|
import org.mustangproject.Exceptions.StructureException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.xpath.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ZUGFeRDInvoiceImporter {
|
||||||
|
|
||||||
public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDInvoiceImporter.class.getCanonicalName()); // log
|
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDInvoiceImporter.class.getCanonicalName()); // log
|
||||||
private boolean recalcPrice = false;
|
/**
|
||||||
private boolean ignoreCalculationErrors = false;
|
* map filenames of additional XML files to their contents
|
||||||
private ArrayList<FileAttachment> fileAttachments=new ArrayList<>();
|
*/
|
||||||
|
protected final HashMap<String, byte[]> additionalXMLs = new HashMap<>();
|
||||||
|
/**
|
||||||
|
* map filenames of all embedded files in the respective PDF
|
||||||
|
*/
|
||||||
|
protected final ArrayList<FileAttachment> PDFAttachments = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* if metadata has been found
|
||||||
|
*/
|
||||||
|
protected boolean containsMeta = false;
|
||||||
|
/**
|
||||||
|
* Raw XML form of the extracted data - may be directly obtained.
|
||||||
|
*/
|
||||||
|
protected byte[] rawXML = null;
|
||||||
|
/**
|
||||||
|
* XMP metadata
|
||||||
|
*/
|
||||||
|
protected String xmpString = null; // XMP metadata
|
||||||
|
/**
|
||||||
|
* parsed Document
|
||||||
|
*/
|
||||||
|
protected Document document;
|
||||||
|
/***
|
||||||
|
* automatically parse into importedInvoice
|
||||||
|
*/
|
||||||
|
protected boolean parseAutomatically = true;
|
||||||
|
protected Integer version;
|
||||||
|
protected CalculatedInvoice importedInvoice = null;
|
||||||
|
protected boolean recalcPrice = false;
|
||||||
|
protected boolean ignoreCalculationErrors = false;
|
||||||
|
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<>();
|
||||||
|
|
||||||
public ZUGFeRDInvoiceImporter() {
|
public ZUGFeRDInvoiceImporter() {
|
||||||
super();
|
//constructor for extending classes
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZUGFeRDInvoiceImporter(String filename) {
|
public ZUGFeRDInvoiceImporter(String pdfFilename) {
|
||||||
super(filename);
|
setPDFFilename(pdfFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZUGFeRDInvoiceImporter(InputStream stream) {
|
public ZUGFeRDInvoiceImporter(InputStream pdfStream) {
|
||||||
super(stream);
|
setInputStream(pdfStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fromXML(String XML) {
|
public void setPDFFilename(String pdfFilename) {
|
||||||
try {
|
try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) {
|
||||||
containsMeta = true;
|
extractLowLevel(bis);
|
||||||
setRawXML(XML.getBytes(StandardCharsets.UTF_8));
|
} catch (final IOException e) {
|
||||||
} catch (IOException e) {
|
LOGGER.error("Failed to extract ZUGFeRD data", e);
|
||||||
LOGGER.error(e.getMessage(), e);
|
throw new ZUGFeRDExportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInputStream(InputStream pdfStream) {
|
||||||
|
try {
|
||||||
|
extractLowLevel(pdfStream);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
LOGGER.error("Failed to extract ZUGFeRD data", e);
|
||||||
|
throw new ZUGFeRDExportException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* return the file names of all files embedded into the PDF
|
||||||
|
* @see for XML embedded files please use ZUGFeRDInvoiceImporter.getFileAttachmentsXML
|
||||||
|
* @return a ArrayList of FileAttachments, empty if none
|
||||||
|
*/
|
||||||
|
public List<FileAttachment> getFileAttachmentsPDF() {
|
||||||
|
return PDFAttachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling.
|
||||||
|
*
|
||||||
|
* @param inStream a inputstream of a pdf file
|
||||||
|
*/
|
||||||
|
private void extractLowLevel(InputStream inStream) throws IOException {
|
||||||
|
BufferedInputStream pdfStream = new BufferedInputStream(inStream);
|
||||||
|
byte[] pad = new byte[4];
|
||||||
|
pdfStream.mark(0);
|
||||||
|
pdfStream.read(pad);
|
||||||
|
pdfStream.reset();
|
||||||
|
byte[] pdfSignature = {'%', 'P', 'D', 'F'};
|
||||||
|
if (Arrays.equals(pad, pdfSignature)) { // we have a pdf
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream));
|
||||||
|
// PDDocumentInformation info = doc.getDocumentInformation();
|
||||||
|
final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
|
||||||
|
//start
|
||||||
|
|
||||||
|
if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) {
|
||||||
|
LOGGER.info("no-xmlpart");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata();
|
||||||
|
|
||||||
|
xmpString = new String(XMLTools.getBytesFromStream(XMP), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles();
|
||||||
|
if (etn == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, PDComplexFileSpecification> efMap = etn.getNames();
|
||||||
|
// String filePath = "/tmp/";
|
||||||
|
|
||||||
|
if (efMap != null) {
|
||||||
|
extractFiles(efMap); // see
|
||||||
|
// https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/
|
||||||
|
} else {
|
||||||
|
|
||||||
|
final List<PDNameTreeNode<PDComplexFileSpecification>> kids = etn.getKids();
|
||||||
|
if (kids == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (final PDNameTreeNode<PDComplexFileSpecification> node : kids) {
|
||||||
|
final Map<String, PDComplexFileSpecification> namesL = node.getNames();
|
||||||
|
extractFiles(namesL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Failed to parse PDF", e);
|
||||||
|
//ignore otherwise
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no PDF probably XML
|
||||||
|
containsMeta = true;
|
||||||
|
setRawXML(XMLTools.getBytesFromStream(pdfStream));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* have the item prices be determined from the line total.
|
||||||
|
* That's a workaround for some invoices which just put 0 as item price
|
||||||
|
*/
|
||||||
|
public void doRecalculateItemPricesFromLineTotals() {
|
||||||
|
recalcPrice = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* do not raise ParseExceptions even if the reproduced invoice total does not match the given value
|
||||||
|
*/
|
||||||
|
public void doIgnoreCalculationErrors() {
|
||||||
|
ignoreCalculationErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* sets th pdf attachments, and if a file is recognized (e.g. a factur-x.xml) triggers processing
|
||||||
|
* @param names the Hashmap of String, PDComplexFileSpecification
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
|
||||||
|
for (final String alias : names.keySet()) {
|
||||||
|
|
||||||
|
final PDComplexFileSpecification fileSpec = names.get(alias);
|
||||||
|
final String filename = fileSpec.getFilename();
|
||||||
|
/**
|
||||||
|
* filenames for invoice data (ZUGFeRD v1 and v2, Factur-X)
|
||||||
|
*/
|
||||||
|
|
||||||
|
final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
|
||||||
|
if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) {
|
||||||
|
containsMeta = true;
|
||||||
|
|
||||||
|
// String embeddedFilename = filePath + filename;
|
||||||
|
// File file = new File(filePath + filename);
|
||||||
|
// System.out.println("Writing " + embeddedFilename);
|
||||||
|
// ByteArrayOutputStream fileBytes=new
|
||||||
|
// ByteArrayOutputStream();
|
||||||
|
// FileOutputStream fos = new FileOutputStream(file);
|
||||||
|
|
||||||
|
setRawXML(embeddedFile.toByteArray());
|
||||||
|
|
||||||
|
// fos.write(embeddedFile.getByteArray());
|
||||||
|
// fos.close();
|
||||||
|
}
|
||||||
|
if (filename.startsWith("additional_data")) {
|
||||||
|
additionalXMLs.put(filename, embeddedFile.toByteArray());
|
||||||
|
}
|
||||||
|
PDFAttachments.add(new FileAttachment(filename, embeddedFile.getSubtype(), "Data", embeddedFile.toByteArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* set the xml of a CII invoice
|
||||||
|
* @param rawXML the xml string
|
||||||
|
* @param doParse automatically parse input for zugferdImporter (not ZUGFeRDInvoiceImporter)
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void setRawXML(byte[] rawXML, boolean doParse) throws IOException {
|
||||||
|
this.containsMeta = true;
|
||||||
|
this.rawXML = rawXML;
|
||||||
|
this.version = null;
|
||||||
|
parseAutomatically = doParse;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setDocument();
|
||||||
|
} catch (ParserConfigurationException | SAXException e) {
|
||||||
|
LOGGER.error("Failed to parse XML", e);
|
||||||
|
throw new ZUGFeRDExportException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* set the xml of a CII invoice, simple version
|
||||||
|
* @param rawXML the cii(?) as a string
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void setRawXML(byte[] rawXML) throws IOException {
|
||||||
|
setRawXML(rawXML, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDocument() throws ParserConfigurationException, IOException, SAXException {
|
||||||
|
final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
|
||||||
|
xmlFact.setNamespaceAware(true);
|
||||||
|
final DocumentBuilder builder = xmlFact.newDocumentBuilder();
|
||||||
|
final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
|
||||||
|
/// is.skip(guessBOMSize(is));
|
||||||
|
document = builder.parse(is);
|
||||||
|
if (parseAutomatically) {
|
||||||
|
try {
|
||||||
|
importedInvoice = new CalculatedInvoice();
|
||||||
|
extractInto(importedInvoice);
|
||||||
|
} catch (XPathExpressionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* This will parse a XML into the given invoice object
|
* This will parse a XML into the given invoice object
|
||||||
@@ -63,6 +284,8 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
|
|
||||||
String number = "";
|
String number = "";
|
||||||
String typeCode = null;
|
String typeCode = null;
|
||||||
|
String deliveryPeriodStart = null;
|
||||||
|
String deliveryPeriodEnd = null;
|
||||||
/*
|
/*
|
||||||
* dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate
|
* dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate
|
||||||
* setSender setRecipient setnumber bspw. due date
|
* setSender setRecipient setnumber bspw. due date
|
||||||
@@ -72,6 +295,12 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
XPath xpath = xpathFact.newXPath();
|
XPath xpath = xpathFact.newXPath();
|
||||||
XPathExpression xpr = xpath.compile("//*[local-name()=\"SellerTradeParty\"]|//*[local-name()=\"AccountingSupplierParty\"]/*");
|
XPathExpression xpr = xpath.compile("//*[local-name()=\"SellerTradeParty\"]|//*[local-name()=\"AccountingSupplierParty\"]/*");
|
||||||
NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
|
XPathExpression shipEx = xpath.compile("//*[local-name()=\"ShipToTradeParty\"]");
|
||||||
|
NodeList deliveryNodes = (NodeList) shipEx.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
|
if (deliveryNodes != null) {
|
||||||
|
zpp.setDeliveryAddress(new TradeParty(deliveryNodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*");
|
xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*");
|
||||||
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
@@ -86,13 +315,19 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
BigDecimal expectedGrandTotal = null;
|
BigDecimal expectedGrandTotal = null;
|
||||||
NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
if (totalNodes.getLength() > 0) {
|
if (totalNodes.getLength() > 0) {
|
||||||
expectedGrandTotal = new BigDecimal(totalNodes.item(0).getTextContent());
|
expectedGrandTotal = new BigDecimal(XMLTools.trimOrNull(totalNodes.item(0)));
|
||||||
|
if (zpp instanceof CalculatedInvoice) {
|
||||||
|
// usually we would re-calculate the invoice to get expectedGrandTotal
|
||||||
|
// however, for "minimal" invoices or other invoices without lines
|
||||||
|
// this will not work
|
||||||
|
((CalculatedInvoice) zpp).setGrandTotal(expectedGrandTotal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xpr = xpath.compile("//*[local-name()=\"PrepaidAmount\"]");
|
xpr = xpath.compile("//*[local-name()=\"PrepaidAmount\"]");
|
||||||
NodeList prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
if (prepaidNodes.getLength() > 0) {
|
if (prepaidNodes.getLength() > 0) {
|
||||||
zpp.setTotalPrepaidAmount(new BigDecimal(prepaidNodes.item(0).getTextContent()));
|
zpp.setTotalPrepaidAmount(new BigDecimal(XMLTools.trimOrNull(prepaidNodes.item(0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Date issueDate = null;
|
Date issueDate = null;
|
||||||
@@ -100,24 +335,22 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
Date deliveryDate = null;
|
Date deliveryDate = null;
|
||||||
String despatchAdviceReferencedDocument = null;
|
String despatchAdviceReferencedDocument = null;
|
||||||
for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) {
|
for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) {
|
||||||
|
|
||||||
// nodes.item(i).getTextContent())) {
|
|
||||||
Node exchangedDocumentNode = ExchangedDocumentNodes.item(i);
|
Node exchangedDocumentNode = ExchangedDocumentNodes.item(i);
|
||||||
NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes();
|
NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes();
|
||||||
for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) {
|
for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) {
|
||||||
Node item = exchangedDocumentChilds.item(documentChildIndex);
|
Node item = exchangedDocumentChilds.item(documentChildIndex);
|
||||||
if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) {
|
if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) {
|
||||||
number = item.getTextContent();
|
number = XMLTools.trimOrNull(item);
|
||||||
}
|
}
|
||||||
if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) {
|
if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) {
|
||||||
typeCode = item.getTextContent();
|
typeCode = XMLTools.trimOrNull(item);
|
||||||
}
|
}
|
||||||
if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) {
|
if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) {
|
||||||
NodeList issueDateTimeChilds = item.getChildNodes();
|
NodeList issueDateTimeChilds = item.getChildNodes();
|
||||||
for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) {
|
for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) {
|
||||||
if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null)
|
if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null)
|
||||||
&& (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) {
|
&& (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) {
|
||||||
issueDate = new SimpleDateFormat("yyyyMMdd").parse(issueDateTimeChilds.item(issueDateChildIndex).getTextContent());
|
issueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(issueDateTimeChilds.item(issueDateChildIndex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,6 +360,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
if (rootNode.equals("Invoice")) {
|
if (rootNode.equals("Invoice")) {
|
||||||
// UBL...
|
// UBL...
|
||||||
number = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"ID\"]").trim();
|
number = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"ID\"]").trim();
|
||||||
|
typeCode = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"InvoiceTypeCode\"]").trim();
|
||||||
issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim());
|
issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim());
|
||||||
String dueDt = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim();
|
String dueDt = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim();
|
||||||
if (dueDt.length() > 0) {
|
if (dueDt.length() > 0) {
|
||||||
@@ -141,7 +375,6 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
|
|
||||||
for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) {
|
for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) {
|
||||||
// nodes.item(i).getTextContent())) {
|
|
||||||
Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i);
|
Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i);
|
||||||
NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes();
|
NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes();
|
||||||
for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) {
|
for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) {
|
||||||
@@ -155,7 +388,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) {
|
for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) {
|
||||||
if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null)
|
if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null)
|
||||||
&& (occurenceChilds.item(occurenceChildIndex).getLocalName().equals("DateTimeString"))) {
|
&& (occurenceChilds.item(occurenceChildIndex).getLocalName().equals("DateTimeString"))) {
|
||||||
deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(occurenceChilds.item(occurenceChildIndex).getTextContent());
|
deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(occurenceChilds.item(occurenceChildIndex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,7 +400,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
for (int despatchAdviceChildIndex = 0; despatchAdviceChildIndex < despatchAdviceChilds.getLength(); despatchAdviceChildIndex++) {
|
for (int despatchAdviceChildIndex = 0; despatchAdviceChildIndex < despatchAdviceChilds.getLength(); despatchAdviceChildIndex++) {
|
||||||
if (despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName() != null
|
if (despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName() != null
|
||||||
&& despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName().equals("IssuerAssignedID")) {
|
&& despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName().equals("IssuerAssignedID")) {
|
||||||
despatchAdviceReferencedDocument = despatchAdviceChilds.item(despatchAdviceChildIndex).getTextContent();
|
despatchAdviceReferencedDocument = XMLTools.trimOrNull(despatchAdviceChilds.item(despatchAdviceChildIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,7 +413,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
String buyerOrderIssuerAssignedID = null;
|
String buyerOrderIssuerAssignedID = null;
|
||||||
String sellerOrderIssuerAssignedID = null;
|
String sellerOrderIssuerAssignedID = null;
|
||||||
for (int i = 0; i < headerTradeAgreementNodes.getLength(); i++) {
|
for (int i = 0; i < headerTradeAgreementNodes.getLength(); i++) {
|
||||||
// nodes.item(i).getTextContent())) {
|
// XMLTools.trimOrNull(nodes.item(i)))) {
|
||||||
Node headerTradeAgreementNode = headerTradeAgreementNodes.item(i);
|
Node headerTradeAgreementNode = headerTradeAgreementNodes.item(i);
|
||||||
NodeList headerTradeAgreementChilds = headerTradeAgreementNode.getChildNodes();
|
NodeList headerTradeAgreementChilds = headerTradeAgreementNode.getChildNodes();
|
||||||
for (int agreementChildIndex = 0; agreementChildIndex < headerTradeAgreementChilds.getLength(); agreementChildIndex++) {
|
for (int agreementChildIndex = 0; agreementChildIndex < headerTradeAgreementChilds.getLength(); agreementChildIndex++) {
|
||||||
@@ -190,7 +423,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
for (int buyerOrderChildIndex = 0; buyerOrderChildIndex < buyerOrderChilds.getLength(); buyerOrderChildIndex++) {
|
for (int buyerOrderChildIndex = 0; buyerOrderChildIndex < buyerOrderChilds.getLength(); buyerOrderChildIndex++) {
|
||||||
if ((buyerOrderChilds.item(buyerOrderChildIndex).getLocalName() != null)
|
if ((buyerOrderChilds.item(buyerOrderChildIndex).getLocalName() != null)
|
||||||
&& (buyerOrderChilds.item(buyerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) {
|
&& (buyerOrderChilds.item(buyerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) {
|
||||||
buyerOrderIssuerAssignedID = buyerOrderChilds.item(buyerOrderChildIndex).getTextContent();
|
buyerOrderIssuerAssignedID = XMLTools.trimOrNull(buyerOrderChilds.item(buyerOrderChildIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,7 +433,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
for (int sellerOrderChildIndex = 0; sellerOrderChildIndex < sellerOrderChilds.getLength(); sellerOrderChildIndex++) {
|
for (int sellerOrderChildIndex = 0; sellerOrderChildIndex < sellerOrderChilds.getLength(); sellerOrderChildIndex++) {
|
||||||
if ((sellerOrderChilds.item(sellerOrderChildIndex).getLocalName() != null)
|
if ((sellerOrderChilds.item(sellerOrderChildIndex).getLocalName() != null)
|
||||||
&& (sellerOrderChilds.item(sellerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) {
|
&& (sellerOrderChilds.item(sellerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) {
|
||||||
sellerOrderIssuerAssignedID = sellerOrderChilds.item(sellerOrderChildIndex).getTextContent();
|
sellerOrderIssuerAssignedID = XMLTools.trimOrNull(sellerOrderChilds.item(sellerOrderChildIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,13 +443,19 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String currency = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"InvoiceCurrencyCode\"]|//*[local-name()=\"DocumentCurrencyCode\"]") ;
|
||||||
|
zpp.setCurrency(currency);
|
||||||
|
|
||||||
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]");
|
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]");
|
||||||
NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
List<BankDetails> bankDetails = new ArrayList<>();
|
List<BankDetails> bankDetails = new ArrayList<>();
|
||||||
|
String directDebitMandateID = null;
|
||||||
|
String IBAN = null, BIC = null;
|
||||||
|
|
||||||
for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) {
|
for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) {
|
||||||
// nodes.item(i).getTextContent())) {
|
// XMLTools.trimOrNull(nodes.item(i)))) {
|
||||||
Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i);
|
Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i);
|
||||||
|
|
||||||
NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes();
|
NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes();
|
||||||
for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) {
|
for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) {
|
||||||
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null)
|
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null)
|
||||||
@@ -227,52 +466,86 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes();
|
NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes();
|
||||||
for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) {
|
for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) {
|
||||||
if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) {
|
if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) {
|
||||||
dueDate = new SimpleDateFormat("yyyyMMdd").parse(dueDateChilds.item(dueDateChildIndex).getTextContent());
|
dueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(dueDateChilds.item(dueDateChildIndex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DirectDebitMandateID"))) {
|
||||||
|
directDebitMandateID = paymentTermChilds.item(paymentTermChildIndex).getTextContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null)
|
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null)
|
||||||
&& (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradeSettlementPaymentMeans"))) {
|
&& (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradeSettlementPaymentMeans"))) {
|
||||||
NodeList paymentMeansChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes();
|
NodeList paymentMeansChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes();
|
||||||
|
IBAN = null;
|
||||||
|
BIC = null;
|
||||||
for (int paymentMeansChildIndex = 0; paymentMeansChildIndex < paymentMeansChilds.getLength(); paymentMeansChildIndex++) {
|
for (int paymentMeansChildIndex = 0; paymentMeansChildIndex < paymentMeansChilds.getLength(); paymentMeansChildIndex++) {
|
||||||
String IBAN = null, BIC = null;
|
|
||||||
if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialAccount"))) {
|
if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialAccount") || paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayerPartyDebtorFinancialAccount"))) {
|
||||||
NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes();
|
NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes();
|
||||||
for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) {
|
for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) {
|
||||||
if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("IBANID"))) {//CII
|
if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("IBANID"))) {//CII
|
||||||
IBAN = accountChilds.item(accountChildIndex).getTextContent();
|
IBAN = XMLTools.trimOrNull(accountChilds.item(accountChildIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialInstitution"))) {
|
if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeeSpecifiedCreditorFinancialInstitution"))) {
|
||||||
NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes();
|
NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes();
|
||||||
for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) {
|
for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) {
|
||||||
if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("BICID"))) {//CII
|
if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("BICID"))) {//CII
|
||||||
BIC = accountChilds.item(accountChildIndex).getTextContent();
|
BIC = XMLTools.trimOrNull(accountChilds.item(accountChildIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IBAN != null) {
|
|
||||||
BankDetails bd = new BankDetails(IBAN);
|
}
|
||||||
if (BIC != null) {
|
if (IBAN != null) {
|
||||||
bd.setBIC(BIC);
|
BankDetails bd = new BankDetails(IBAN);
|
||||||
|
if (BIC != null) {
|
||||||
|
bd.setBIC(BIC);
|
||||||
|
}
|
||||||
|
bankDetails.add(bd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null)
|
||||||
|
&& (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("BillingSpecifiedPeriod"))) {
|
||||||
|
NodeList periodChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes();
|
||||||
|
for (int periodChildIndex = 0; periodChildIndex < periodChilds.getLength(); periodChildIndex++) {
|
||||||
|
if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("StartDateTime"))) {
|
||||||
|
|
||||||
|
NodeList startPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes();
|
||||||
|
for (int startPeriodIndex = 0; startPeriodIndex < startPeriodChilds.getLength(); startPeriodIndex++) {
|
||||||
|
if ((startPeriodChilds.item(startPeriodIndex).getLocalName() != null) && (startPeriodChilds.item(startPeriodIndex).getLocalName().equals("DateTimeString"))) {//CII
|
||||||
|
deliveryPeriodStart = XMLTools.trimOrNull(startPeriodChilds.item(startPeriodIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("EndDateTime"))) {
|
||||||
|
NodeList endPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes();
|
||||||
|
for (int endPeriodIndex = 0; endPeriodIndex < endPeriodChilds.getLength(); endPeriodIndex++) {
|
||||||
|
if ((endPeriodChilds.item(endPeriodIndex).getLocalName() != null) && (endPeriodChilds.item(endPeriodIndex).getLocalName().equals("DateTimeString"))) {//CII
|
||||||
|
deliveryPeriodEnd = XMLTools.trimOrNull(endPeriodChilds.item(endPeriodIndex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bankDetails.add(bd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((deliveryPeriodStart != null) && (deliveryPeriodEnd != null)) {
|
||||||
|
zpp.setDetailedDeliveryPeriod(XMLTools.tryDate(deliveryPeriodStart), XMLTools.tryDate(deliveryPeriodEnd));
|
||||||
|
} else if (deliveryPeriodStart != null) {
|
||||||
|
zpp.setDeliveryDate(XMLTools.tryDate(deliveryPeriodStart));
|
||||||
|
}
|
||||||
|
|
||||||
xpr = xpath.compile("//*[local-name()=\"PaymentMeans\"]"); //UBL only
|
xpr = xpath.compile("//*[local-name()=\"PaymentMeans\"]"); //UBL only
|
||||||
NodeList paymentMeansNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList paymentMeansNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
|
|
||||||
for (int i = 0; i < paymentMeansNodes.getLength(); i++) {
|
for (int i = 0; i < paymentMeansNodes.getLength(); i++) {
|
||||||
// nodes.item(i).getTextContent())) {
|
// XMLTools.trimOrNull(nodes.item(i)))) {
|
||||||
Node paymentMeansNode = paymentMeansNodes.item(i);
|
Node paymentMeansNode = paymentMeansNodes.item(i);
|
||||||
NodeList paymentMeansChilds = paymentMeansNode.getChildNodes();
|
NodeList paymentMeansChilds = paymentMeansNode.getChildNodes();
|
||||||
for (int meansChildIndex = 0; meansChildIndex < paymentMeansChilds.getLength(); meansChildIndex++) {
|
for (int meansChildIndex = 0; meansChildIndex < paymentMeansChilds.getLength(); meansChildIndex++) {
|
||||||
@@ -281,7 +554,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
NodeList paymentTermChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes();
|
NodeList paymentTermChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes();
|
||||||
for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) {
|
for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) {
|
||||||
if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("ID"))) {
|
if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("ID"))) {
|
||||||
String IBAN = paymentTermChilds.item(paymentTermChildIndex).getTextContent();
|
IBAN = XMLTools.trimOrNull(paymentTermChilds.item(paymentTermChildIndex));
|
||||||
if (IBAN != null) {
|
if (IBAN != null) {
|
||||||
BankDetails bd = new BankDetails(IBAN);
|
BankDetails bd = new BankDetails(IBAN);
|
||||||
bankDetails.add(bd);
|
bankDetails.add(bd);
|
||||||
@@ -294,6 +567,11 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
|
|
||||||
zpp.setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode);
|
zpp.setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode);
|
||||||
|
|
||||||
|
if ((directDebitMandateID != null) && (IBAN != null)) {
|
||||||
|
DirectDebit d = new DirectDebit(IBAN, directDebitMandateID);
|
||||||
|
zpp.getSender().addDebitDetails(d);
|
||||||
|
}
|
||||||
|
|
||||||
bankDetails.forEach(bankDetail -> zpp.getSender().addBankDetails(bankDetail));
|
bankDetails.forEach(bankDetail -> zpp.getSender().addBankDetails(bankDetail));
|
||||||
|
|
||||||
if (payeeNodes.getLength() > 0) {
|
if (payeeNodes.getLength() > 0) {
|
||||||
@@ -303,6 +581,9 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
if (buyerOrderIssuerAssignedID != null) {
|
if (buyerOrderIssuerAssignedID != null) {
|
||||||
zpp.setBuyerOrderReferencedDocumentID(buyerOrderIssuerAssignedID);
|
zpp.setBuyerOrderReferencedDocumentID(buyerOrderIssuerAssignedID);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
zpp.setBuyerOrderReferencedDocumentID(extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"ID\"]"));
|
||||||
|
}
|
||||||
if (sellerOrderIssuerAssignedID != null) {
|
if (sellerOrderIssuerAssignedID != null) {
|
||||||
zpp.setSellerOrderReferencedDocumentID(sellerOrderIssuerAssignedID);
|
zpp.setSellerOrderReferencedDocumentID(sellerOrderIssuerAssignedID);
|
||||||
}
|
}
|
||||||
@@ -316,7 +597,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
String buyerReference = null;
|
String buyerReference = null;
|
||||||
prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
if (prepaidNodes.getLength() > 0) {
|
if (prepaidNodes.getLength() > 0) {
|
||||||
buyerReference = prepaidNodes.item(0).getTextContent();
|
buyerReference = XMLTools.trimOrNull(prepaidNodes.item(0));
|
||||||
}
|
}
|
||||||
if (buyerReference != null) {
|
if (buyerReference != null) {
|
||||||
zpp.setReferenceNumber(buyerReference);
|
zpp.setReferenceNumber(buyerReference);
|
||||||
@@ -338,9 +619,9 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
xpr = xpath.compile("//*[local-name()=\"AttachmentBinaryObject\"]|//*[local-name()=\"EmbeddedDocumentBinaryObject\"]");
|
xpr = xpath.compile("//*[local-name()=\"AttachmentBinaryObject\"]|//*[local-name()=\"EmbeddedDocumentBinaryObject\"]");
|
||||||
NodeList attachmentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
NodeList attachmentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
for (int i = 0; i < attachmentNodes.getLength(); i++) {
|
for (int i = 0; i < attachmentNodes.getLength(); i++) {
|
||||||
FileAttachment fa=new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(),attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(),"Data", Base64.getDecoder().decode(attachmentNodes.item(i).getTextContent()));
|
FileAttachment fa = new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(), attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(), "Data", Base64.getDecoder().decode(XMLTools.trimOrNull(attachmentNodes.item(i))));
|
||||||
fileAttachments.add(fa);
|
fileAttachments.add(fa);
|
||||||
// filename = "Aufmass.png" mimeCode = "image/png"
|
// filename = "Aufmass.png" mimeCode = "image/png"
|
||||||
//EmbeddedDocumentBinaryObject cbc:EmbeddedDocumentBinaryObject mimeCode="image/png" filename="Aufmass.png"
|
//EmbeddedDocumentBinaryObject cbc:EmbeddedDocumentBinaryObject mimeCode="image/png" filename="Aufmass.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,21 +647,21 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) {
|
for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) {
|
||||||
if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null)
|
if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null)
|
||||||
&& (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) {
|
&& (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) {
|
||||||
isCharge = indicatorChilds.item(indicatorChildIndex).getTextContent().equalsIgnoreCase("true");
|
isCharge = XMLTools.trimOrNull(indicatorChilds.item(indicatorChildIndex)).equalsIgnoreCase("true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (chargeChildName.equals("ActualAmount")) {
|
} else if (chargeChildName.equals("ActualAmount")) {
|
||||||
chargeAmount = chargeNodeChilds.item(chargeChildIndex).getTextContent();
|
chargeAmount = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex));
|
||||||
} else if (chargeChildName.equals("Reason")) {
|
} else if (chargeChildName.equals("Reason")) {
|
||||||
reason = chargeNodeChilds.item(chargeChildIndex).getTextContent();
|
reason = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex));
|
||||||
} else if (chargeChildName.equals("ReasonCode")) {
|
} else if (chargeChildName.equals("ReasonCode")) {
|
||||||
reasonCode = chargeNodeChilds.item(chargeChildIndex).getTextContent();
|
reasonCode = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex));
|
||||||
} else if (chargeChildName.equals("CategoryTradeTax")) {
|
} else if (chargeChildName.equals("CategoryTradeTax")) {
|
||||||
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
|
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
|
||||||
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
|
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
|
||||||
String taxItemName = taxChilds.item(taxChildIndex).getLocalName();
|
String taxItemName = taxChilds.item(taxChildIndex).getLocalName();
|
||||||
if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent") || taxItemName.equals("ApplicablePercent"))) {
|
if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent") || taxItemName.equals("ApplicablePercent"))) {
|
||||||
taxPercent = taxChilds.item(taxChildIndex).getTextContent();
|
taxPercent = XMLTools.trimOrNull(taxChilds.item(taxChildIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -422,21 +703,92 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
try {
|
try {
|
||||||
whichType = getStandard();
|
whichType = getStandard();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ParseException("Could not find out if it's an invoice, order, or delivery advice", 0);
|
throw new StructureException("Could not find out if it's an invoice, order, or delivery advice", 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((whichType != EStandard.despatchadvice)
|
if ((whichType != EStandard.despatchadvice)
|
||||||
&& ((!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2)))
|
&& ((!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2)))
|
||||||
&& (!ignoreCalculationErrors))) {
|
&& (!ignoreCalculationErrors))) {
|
||||||
throw new ParseException(
|
throw new ArithmetricException();
|
||||||
"Could not reproduce the invoice, this could mean that it could not be read properly", 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return zpp;
|
return zpp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Document getDocument() {
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String extractString(String xpathStr) {
|
||||||
|
if (!containsMeta) {
|
||||||
|
throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found.");
|
||||||
|
}
|
||||||
|
final String result;
|
||||||
|
try {
|
||||||
|
final Document document = getDocument();
|
||||||
|
final XPathFactory xpathFact = XPathFactory.newInstance();
|
||||||
|
final XPath xpath = xpathFact.newXPath();
|
||||||
|
result = xpath.evaluate(xpathStr, document);
|
||||||
|
} catch (final XPathExpressionException e) {
|
||||||
|
LOGGER.error("Failed to evaluate XPath", e);
|
||||||
|
throw new ZUGFeRDExportException(e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EStandard getStandard() throws Exception {
|
||||||
|
if (!containsMeta) {
|
||||||
|
throw new Exception("Not yet parsed");
|
||||||
|
}
|
||||||
|
final String head = getUTF8();
|
||||||
|
String rootNode = extractString("local-name(/*)");
|
||||||
|
if (rootNode.equals("CrossIndustryDocument")) {
|
||||||
|
return EStandard.zugferd;
|
||||||
|
} else if (rootNode.equals("Invoice")) {
|
||||||
|
return EStandard.ubl;
|
||||||
|
} else if (rootNode.equals("CreditNote")) {
|
||||||
|
return EStandard.ubl;
|
||||||
|
} else if (rootNode.equals("CrossIndustryInvoice")) {
|
||||||
|
return EStandard.facturx;
|
||||||
|
} else if (rootNode.equals("SCRDMCCBDACIDAMessageStructure")) {
|
||||||
|
return EStandard.despatchadvice;
|
||||||
|
} else if (head.contains("<rsm:SCRDMCCBDACIOMessageStructure")) {
|
||||||
|
return EStandard.orderx;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("ZUGFeRD version could not be determined");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return return UTF8 XML (without BOM) of the invoice
|
||||||
|
*/
|
||||||
|
public String getUTF8() {
|
||||||
|
if (rawXML == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (rawXML.length < 3) {
|
||||||
|
return new String(rawXML);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final byte[] bomlessData;
|
||||||
|
|
||||||
|
if ((rawXML[0] == (byte) 0xEF)
|
||||||
|
&& (rawXML[1] == (byte) 0xBB)
|
||||||
|
&& (rawXML[2] == (byte) 0xBF)) {
|
||||||
|
// I don't like BOMs, lets remove it
|
||||||
|
bomlessData = new byte[rawXML.length - 3];
|
||||||
|
System.arraycopy(rawXML, 3, bomlessData, 0,
|
||||||
|
rawXML.length - 3);
|
||||||
|
} else {
|
||||||
|
bomlessData = rawXML;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(bomlessData);
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*
|
*
|
||||||
* @return the file attachments embedded in XML (using base64) decoded as byte array,
|
* @return the file attachments embedded in XML (using base64) decoded as byte array,
|
||||||
@@ -460,18 +812,18 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
* have the item prices be determined from the line total.
|
|
||||||
* That's a workaround for some invoices which just put 0 as item price
|
|
||||||
*/
|
|
||||||
public void doRecalculateItemPricesFromLineTotals() {
|
|
||||||
recalcPrice = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* do not raise ParseExceptions even if the reproduced invoice total does not match the given value
|
* sets the XML for the importer to parse
|
||||||
|
* @param XML the UBL or CII
|
||||||
*/
|
*/
|
||||||
public void doIgnoreCalculationErrors() {
|
public void fromXML(String XML) {
|
||||||
ignoreCalculationErrors = true;
|
try {
|
||||||
|
containsMeta = true;
|
||||||
|
setRawXML(XML.getBytes(StandardCharsets.UTF_8));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,7 +198,7 @@
|
|||||||
<entry key="xr:Third_party_payment_type" id="BT-DEX-001">Art der Fremdforderung</entry>
|
<entry key="xr:Third_party_payment_type" id="BT-DEX-001">Art der Fremdforderung</entry>
|
||||||
<entry key="xr:Third_party_payment_amount" id="BT-DEX-002">Betrag der Fremdforderung</entry>
|
<entry key="xr:Third_party_payment_amount" id="BT-DEX-002">Betrag der Fremdforderung</entry>
|
||||||
<entry key="xr:Third_party_payment_description" id="BT-DEX-003">Beschreibung der Fremdforderung</entry>
|
<entry key="xr:Third_party_payment_description" id="BT-DEX-003">Beschreibung der Fremdforderung</entry>
|
||||||
<entry key="uebersicht">Übersicht</entry>
|
<entry key="uebersicht">Daten der E-Rechnung</entry>
|
||||||
<entry key="uebersichtKaeufer" id="BG-7">Informationen zum Käufer</entry>
|
<entry key="uebersichtKaeufer" id="BG-7">Informationen zum Käufer</entry>
|
||||||
<entry key="uebersichtVerkaeufer" id="BG-4">Informationen zum Verkäufer</entry>
|
<entry key="uebersichtVerkaeufer" id="BG-4">Informationen zum Verkäufer</entry>
|
||||||
<entry key="uebersichtRechnungsInfo" id="invoice-data">Rechnungsdaten</entry>
|
<entry key="uebersichtRechnungsInfo" id="invoice-data">Rechnungsdaten</entry>
|
||||||
@@ -214,7 +214,7 @@
|
|||||||
<entry key="uebersichtZahlungLastschrift" id="BG-19">Lastschrift</entry>
|
<entry key="uebersichtZahlungLastschrift" id="BG-19">Lastschrift</entry>
|
||||||
<entry key="uebersichtZahlungUeberweisung" id="BG-17">Überweisung</entry>
|
<entry key="uebersichtZahlungUeberweisung" id="BG-17">Überweisung</entry>
|
||||||
<entry key="uebersichtBemerkungen" id="BG-1">Bemerkungen zur Rechnung</entry>
|
<entry key="uebersichtBemerkungen" id="BG-1">Bemerkungen zur Rechnung</entry>
|
||||||
<entry key="details">Details</entry>
|
<entry key="details">Rechnungspositionen</entry>
|
||||||
<entry key="detailsPositionAbrechnungszeitraum" id="BG-26">Abrechnungszeitraum</entry>
|
<entry key="detailsPositionAbrechnungszeitraum" id="BG-26">Abrechnungszeitraum</entry>
|
||||||
<entry key="detailsPositionPreiseinzelheiten" id="BG-29">Preiseinzelheiten</entry>
|
<entry key="detailsPositionPreiseinzelheiten" id="BG-29">Preiseinzelheiten</entry>
|
||||||
<entry key="detailsPositionNachlaesse" id="BG-27">Nachlässe auf Ebene der Rechnungsposition</entry>
|
<entry key="detailsPositionNachlaesse" id="BG-27">Nachlässe auf Ebene der Rechnungsposition</entry>
|
||||||
|
|||||||
@@ -807,10 +807,11 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template name="zusaetzeVertrag">
|
<xsl:template name="zusaetzeVertrag">
|
||||||
<xsl:call-template name="box">
|
<xsl:call-template name="spanned-box">
|
||||||
<xsl:with-param name="identifier" select="'zusaetzeVertrag'"/>
|
<xsl:with-param name="identifier" select="'zusaetzeVertrag'"/>
|
||||||
<xsl:with-param name="content">
|
<xsl:with-param name="content">
|
||||||
<xsl:call-template name="list">
|
<xsl:call-template name="list">
|
||||||
|
<xsl:with-param name="layout" select="'einspaltig'"/>
|
||||||
<xsl:with-param name="content">
|
<xsl:with-param name="content">
|
||||||
<xsl:apply-templates mode="list-entry" select="xr:Tender_or_lot_reference"/>
|
<xsl:apply-templates mode="list-entry" select="xr:Tender_or_lot_reference"/>
|
||||||
<xsl:apply-templates mode="list-entry" select="xr:Receiving_advice_reference"/>
|
<xsl:apply-templates mode="list-entry" select="xr:Receiving_advice_reference"/>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
||||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
<dc:title><xsl:value-of select="xr:Invoice_number"/></dc:title>
|
<dc:title><rdf:Alt><rdf:li xml:lang="x-default"><xsl:value-of select="xr:Invoice_number"/></rdf:li></rdf:Alt></dc:title>
|
||||||
<!--
|
<!--
|
||||||
<dc:creator></dc:creator>
|
<dc:creator></dc:creator>
|
||||||
<dc:description></dc:description>
|
<dc:description></dc:description>
|
||||||
|
|||||||
@@ -52,6 +52,15 @@ public class BaseTest extends TestCase {
|
|||||||
assertEquals("12.00", XMLTools.nDigitFormat(new BigDecimal("12"),2));
|
assertEquals("12.00", XMLTools.nDigitFormat(new BigDecimal("12"),2));
|
||||||
assertEquals("12", XMLTools.nDigitFormat(new BigDecimal("12"),0));
|
assertEquals("12", XMLTools.nDigitFormat(new BigDecimal("12"),0));
|
||||||
assertEquals("20000123.342", XMLTools.nDigitFormat(new BigDecimal("20000123.3419"),3));
|
assertEquals("20000123.342", XMLTools.nDigitFormat(new BigDecimal("20000123.3419"),3));
|
||||||
|
|
||||||
|
assertEquals("0.00", XMLTools.nDigitFormatDecimalRange(BigDecimal.ZERO,2, 2));
|
||||||
|
assertEquals("-1.10", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.100000"), 4,2));
|
||||||
|
assertEquals("-1.101", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.101000"),10, 3));
|
||||||
|
assertEquals("-1.10", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.103"), 2,2));
|
||||||
|
assertEquals("4", XMLTools.nDigitFormatDecimalRange(new BigDecimal("4"),2, 0));
|
||||||
|
assertEquals("3.14", XMLTools.nDigitFormatDecimalRange(new BigDecimal("3.141526"),2, 0));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ public class CalculationTest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* LineCalculator should not throw an exception when calculating a non-terminating decimal expansion
|
* LineCalculator should not throw an exception when calculating a non-terminating decimal expansion
|
||||||
*/
|
* */
|
||||||
@Test
|
@Test
|
||||||
public void testNonTerminatingDecimalExpansion() {
|
public void testNonTerminatingDecimalExpansion() {
|
||||||
final Product product = new Product();
|
final Product product = new Product();
|
||||||
|
|||||||
@@ -49,4 +49,141 @@ public class DeSerializationTest extends TestCase {
|
|||||||
assertEquals("info@company.com", fromJSON.getSender().getUriUniversalCommunicationID());
|
assertEquals("info@company.com", fromJSON.getSender().getUriUniversalCommunicationID());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAllowanceRead() throws JsonProcessingException {
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// [{"stringValue":"a","intValue":1,"booleanValue":true},
|
||||||
|
// {"stringValue":"bc","intValue":3,"booleanValue":false}]
|
||||||
|
|
||||||
|
Invoice fromJSON = mapper.readValue("{\n" +
|
||||||
|
" \"documentCode\": \"380\",\n" +
|
||||||
|
" \"number\": \"471102\",\n" +
|
||||||
|
" \"ownOrganisationName\": \"Lieferant GmbH\",\n" +
|
||||||
|
" \"currency\": \"EUR\",\n" +
|
||||||
|
" \"issueDate\": \"2018-03-03T23:00:00.000+00:00\",\n" +
|
||||||
|
" \"deliveryDate\": \"2018-03-03T23:00:00.000+00:00\",\n" +
|
||||||
|
" \"sender\": {\n" +
|
||||||
|
" \"name\": \"Lieferant GmbH\",\n" +
|
||||||
|
" \"zip\": \"80333\",\n" +
|
||||||
|
" \"street\": \"Lieferantenstraße 20\",\n" +
|
||||||
|
" \"location\": \"München\",\n" +
|
||||||
|
" \"country\": \"DE\",\n" +
|
||||||
|
" \"taxID\": \"201/113/40209\",\n" +
|
||||||
|
" \"vatID\": \"DE123456789\",\n" +
|
||||||
|
" \"vatid\": \"DE123456789\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"recipient\": {\n" +
|
||||||
|
" \"name\": \"Kunden AG Mitte\",\n" +
|
||||||
|
" \"zip\": \"69876\",\n" +
|
||||||
|
" \"street\": \"Kundenstraße 15\",\n" +
|
||||||
|
" \"location\": \"Frankfurt\",\n" +
|
||||||
|
" \"country\": \"DE\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"grandTotal\": 234.43,\n" +
|
||||||
|
" \"zfitems\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"price\": 9.9,\n" +
|
||||||
|
" \"quantity\": 20,\n" +
|
||||||
|
" \"tax\": null,\n" +
|
||||||
|
" \"grossPrice\": null,\n" +
|
||||||
|
" \"lineTotalAmount\": null,\n" +
|
||||||
|
" \"basisQuantity\": 1,\n" +
|
||||||
|
" \"detailedDeliveryPeriodFrom\": null,\n" +
|
||||||
|
" \"detailedDeliveryPeriodTo\": null,\n" +
|
||||||
|
" \"id\": null,\n" +
|
||||||
|
" \"product\": {\n" +
|
||||||
|
" \"unit\": \"H87\",\n" +
|
||||||
|
" \"name\": \"Trennblätter A4\",\n" +
|
||||||
|
" \"taxCategoryCode\": \"S\",\n" +
|
||||||
|
" \"attributes\": null,\n" +
|
||||||
|
" \"vatpercent\": 19\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"value\": 9.9\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"tradeSettlement\": null,\n" +
|
||||||
|
" \"ownTaxID\": \"201/113/40209\",\n" +
|
||||||
|
" \"ownVATID\": \"DE123456789\",\n" +
|
||||||
|
" \"ownStreet\": \"Lieferantenstraße 20\",\n" +
|
||||||
|
" \"ownZIP\": \"80333\",\n" +
|
||||||
|
" \"ownLocation\": \"München\",\n" +
|
||||||
|
" \"ownCountry\": \"DE\",\n" +
|
||||||
|
" \"zfallowances\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"totalAmount\": 1,\n" +
|
||||||
|
" \"taxPercent\": 19,\n" +
|
||||||
|
" \"reason\": \"Sondernachlass\",\n" +
|
||||||
|
" \"reasonCode\": null,\n" +
|
||||||
|
" \"categoryCode\": \"S\",\n" +
|
||||||
|
" \"charge\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
"}", Invoice.class);
|
||||||
|
TransactionCalculator tc=new TransactionCalculator(fromJSON);
|
||||||
|
assertEquals(tc.getGrandTotal(),new BigDecimal("234.43"));
|
||||||
|
assertEquals(fromJSON.getNumber(), fromJSON.getNumber());
|
||||||
|
assertEquals(fromJSON.getZFItems().length, fromJSON.getZFItems().length);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void testDueDateRoundtrip() throws JsonProcessingException {
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// [{"stringValue":"a","intValue":1,"booleanValue":true},
|
||||||
|
// {"stringValue":"bc","intValue":3,"booleanValue":false}]
|
||||||
|
|
||||||
|
Invoice fromJSON = mapper.readValue("{\n" +
|
||||||
|
" \"number\": \"RE - 228\",\n" +
|
||||||
|
" \"currency\": \"EUR\",\n" +
|
||||||
|
" \"issueDate\": \"2024-10-24\",\n" +
|
||||||
|
" \"dueDate\": \"2024-10-26\",\n" +
|
||||||
|
" \"deliveryDate\": \"2024-10-25\",\n" +
|
||||||
|
" \"sender\": {\n" +
|
||||||
|
" \"name\": \"Amazing Company\",\n" +
|
||||||
|
" \"zip\": \"10000\",\n" +
|
||||||
|
" \"street\": \"Straße der Kosmonauten 20\",\n" +
|
||||||
|
" \"location\": \"Berlin\",\n" +
|
||||||
|
" \"country\": \"DE\",\n" +
|
||||||
|
" \"taxID\": \"201/113/40209\",\n" +
|
||||||
|
" \"vatID\": \"DE123456789\",\n" +
|
||||||
|
" \"globalID\": \"4000001123452\",\n" +
|
||||||
|
" \"globalIDScheme\": \"0088\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"recipient\": {\n" +
|
||||||
|
" \"name\": \"Amazing Company\",\n" +
|
||||||
|
" \"zip\": \"1000\",\n" +
|
||||||
|
" \"street\": \"Straße der Kosmonauten 10\",\n" +
|
||||||
|
" \"location\": \"Berlin\",\n" +
|
||||||
|
" \"taxID\": \"201/113/40209\",\n" +
|
||||||
|
" \"vatID\": \"DE123456789\",\n" +
|
||||||
|
" \"country\": \"DE\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"zfitems\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"price\": 99.9,\n" +
|
||||||
|
" \"quantity\": 10,\n" +
|
||||||
|
" \"product\": {\n" +
|
||||||
|
" \"unit\": \"H87\",\n" +
|
||||||
|
" \"name\": \"Amazing Archives\",\n" +
|
||||||
|
" \"description\": \"123\",\n" +
|
||||||
|
" \"vatpercent\": \"19\",\n" +
|
||||||
|
" \"taxCategoryCode\": \"3\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ]\n" +
|
||||||
|
"}\n", Invoice.class);
|
||||||
|
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||||
|
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||||
|
zf2p.generateXML(fromJSON);
|
||||||
|
String theXML = new String(zf2p.getXML());
|
||||||
|
assertTrue(theXML.contains("<udt:DateTimeString format=\"102\">20241026</udt:DateTimeString>"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,8 +214,10 @@ public class MustangReaderWriterTest extends MustangReaderTestCase {
|
|||||||
|
|
||||||
public void testForeignImport() {
|
public void testForeignImport() {
|
||||||
InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf");
|
InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf");
|
||||||
ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
|
ZUGFeRDImporter zi = new ZUGFeRDImporter();
|
||||||
|
zi.doRecalculateItemPricesFromLineTotals();
|
||||||
|
zi.doIgnoreCalculationErrors();
|
||||||
|
zi.setInputStream(inputStream);
|
||||||
// Reading ZUGFeRD
|
// Reading ZUGFeRD
|
||||||
String amount = zi.getAmount();
|
String amount = zi.getAmount();
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public class ProfilesMinimumBasicWLTest extends TestCase {
|
|||||||
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_INV);
|
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_INV);
|
||||||
|
|
||||||
// Reading ZUGFeRD
|
// Reading ZUGFeRD
|
||||||
assertEquals("145.37",zi.getAmount());
|
assertEquals("146.37",zi.getAmount());
|
||||||
// assertEquals(zi.getBIC(), ownBIC);
|
// assertEquals(zi.getBIC(), ownBIC);
|
||||||
// assertEquals(zi.getIBAN(), ownIBAN);
|
// assertEquals(zi.getIBAN(), ownIBAN);
|
||||||
assertEquals(ownOrgName, zi.getHolder());
|
assertEquals(ownOrgName, zi.getHolder());
|
||||||
|
|||||||
@@ -129,13 +129,12 @@ public class XRTest extends TestCase {
|
|||||||
Invoice readInvoice = new Invoice();
|
Invoice readInvoice = new Invoice();
|
||||||
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
|
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
|
||||||
try {
|
try {
|
||||||
|
zii.setRawXML(zf2p.getXML(), false);
|
||||||
zii.setRawXML(zf2p.getXML());
|
|
||||||
zii.extractInto(readInvoice);
|
zii.extractInto(readInvoice);
|
||||||
} catch (ParseException | XPathExpressionException xp) {
|
} catch (ParseException | XPathExpressionException xp) {
|
||||||
fail("Exception not expected");
|
fail("ParseException not expected");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
fail("IOException not expected");
|
||||||
}
|
}
|
||||||
List<FileAttachment> attachedFiles=zii.getFileAttachmentsXML();
|
List<FileAttachment> attachedFiles=zii.getFileAttachmentsXML();
|
||||||
assertNotNull(attachedFiles);
|
assertNotNull(attachedFiles);
|
||||||
|
|||||||
@@ -297,7 +297,8 @@ public class ZF2EdgeTest extends MustangReaderTestCase {
|
|||||||
InputStream SOURCE_PDF = this.getClass()
|
InputStream SOURCE_PDF = this.getClass()
|
||||||
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
|
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
|
||||||
|
|
||||||
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1();ze.ignorePDFAErrors();
|
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1();
|
||||||
|
ze.ignorePDFAErrors();
|
||||||
ze.load(SOURCE_PDF);
|
ze.load(SOURCE_PDF);
|
||||||
ze.setProducer("My Application")
|
ze.setProducer("My Application")
|
||||||
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("Extended"));
|
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("Extended"));
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
|
|
||||||
/** **********************************************************************
|
/**
|
||||||
*
|
* *********************************************************************
|
||||||
|
* <p>
|
||||||
* Copyright 2019 Jochen Staerk
|
* Copyright 2019 Jochen Staerk
|
||||||
*
|
* <p>
|
||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy
|
* use this file except in compliance with the License. You may obtain a copy
|
||||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
*
|
* <p>
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* <p>
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
* <p>
|
||||||
*********************************************************************** */
|
* **********************************************************************
|
||||||
|
*/
|
||||||
package org.mustangproject.ZUGFeRD;
|
package org.mustangproject.ZUGFeRD;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -99,9 +101,9 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
public IZUGFeRDExportableItem[] getZFItems() {
|
public IZUGFeRDExportableItem[] getZFItems() {
|
||||||
final Item[] allItems = new Item[3];
|
final Item[] allItems = new Item[3];
|
||||||
final Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR",
|
final Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR",
|
||||||
new BigDecimal("7.000000"));
|
new BigDecimal("7.000000"));
|
||||||
final Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62",
|
final Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62",
|
||||||
new BigDecimal("19.000000"));// test for issue 103
|
new BigDecimal("19.000000"));// test for issue 103
|
||||||
final Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000"));
|
final 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[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct);
|
||||||
@@ -166,12 +168,12 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
// the writing part
|
// the writing part
|
||||||
|
|
||||||
try (InputStream SOURCE_PDF = this.getClass()
|
try (InputStream SOURCE_PDF = this.getClass()
|
||||||
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf");
|
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf");
|
||||||
|
|
||||||
ZUGFeRDExporterFromA3 ze = new ZUGFeRDExporterFromA3().setProducer("My Application")
|
ZUGFeRDExporterFromA3 ze = new ZUGFeRDExporterFromA3().setProducer("My Application")
|
||||||
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("EN16931")
|
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("EN16931")
|
||||||
.load(SOURCE_PDF)) {
|
.load(SOURCE_PDF)) {
|
||||||
|
|
||||||
ze.setTransaction(this);
|
ze.setTransaction(this);
|
||||||
final String theXML = new String(ze.getProvider().getXML());
|
final String theXML = new String(ze.getProvider().getXML());
|
||||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||||
@@ -190,13 +192,13 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
assertEquals(zi.getInvoiceID(), "RE-20170509/505");
|
assertEquals(zi.getInvoiceID(), "RE-20170509/505");
|
||||||
assertEquals(zi.getZUGFeRDProfil(), "COMFORT");
|
assertEquals(zi.getZUGFeRDProfil(), "COMFORT");
|
||||||
assertEquals(zi.getInvoiceCurrencyCode(), "EUR");
|
assertEquals(zi.getInvoiceCurrencyCode(), "EUR");
|
||||||
assertEquals(zi.getIssuerAssignedID(),"");
|
assertEquals(zi.getIssuerAssignedID(), "");
|
||||||
assertEquals(zi.getIssueDate(), "20170509");
|
assertEquals(zi.getIssueDate(), "20170509");
|
||||||
assertEquals(zi.getTaxPointDate(), "20170507");
|
assertEquals(zi.getTaxPointDate(), "20170507");
|
||||||
assertEquals(zi.getPaymentTerms(), "Zahlbar ohne Abzug bis zum 30.05.2017");
|
assertEquals(zi.getPaymentTerms(), "Zahlbar ohne Abzug bis zum 30.05.2017");
|
||||||
assertEquals(zi.getLineTotalAmount(), "496.00");
|
assertEquals(zi.getLineTotalAmount(), "496.00");
|
||||||
assertEquals(zi.getTaxBasisTotalAmount(), "496.00");
|
assertEquals(zi.getTaxBasisTotalAmount(), "496.00");
|
||||||
assertEquals(zi.getTaxTotalAmount(),"75.04");
|
assertEquals(zi.getTaxTotalAmount(), "75.04");
|
||||||
assertEquals(zi.getRoundingAmount(), "");
|
assertEquals(zi.getRoundingAmount(), "");
|
||||||
assertEquals(zi.getPaidAmount(), "0.00");
|
assertEquals(zi.getPaidAmount(), "0.00");
|
||||||
assertEquals(zi.getBuyerTradePartyName(), "Theodor Est");
|
assertEquals(zi.getBuyerTradePartyName(), "Theodor Est");
|
||||||
@@ -206,8 +208,8 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
assertEquals(zi.getBuyertradePartySpecifiedTaxRegistrationID(), "DE999999999");
|
assertEquals(zi.getBuyertradePartySpecifiedTaxRegistrationID(), "DE999999999");
|
||||||
assertEquals(zi.getIncludedNote(), "");
|
assertEquals(zi.getIncludedNote(), "");
|
||||||
assertEquals(zi.getHolder(), getOwnOrganisationName());
|
assertEquals(zi.getHolder(), getOwnOrganisationName());
|
||||||
assertEquals(zi.getDocumentCode(),"380");
|
assertEquals(zi.getDocumentCode(), "380");
|
||||||
assertEquals(zi.getReference(),"AB321");
|
assertEquals(zi.getReference(), "AB321");
|
||||||
assertEquals(zi.getAmount(), "571.04");
|
assertEquals(zi.getAmount(), "571.04");
|
||||||
assertEquals(zi.getBIC(), "COBADEFFXXX");
|
assertEquals(zi.getBIC(), "COBADEFFXXX");
|
||||||
assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00");
|
assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00");
|
||||||
@@ -244,7 +246,9 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} /**
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* The exporter test bases on @{code
|
* The exporter test bases on @{code
|
||||||
* ./src/test/MustangBeispiel20221026.pdf}, adds
|
* ./src/test/MustangBeispiel20221026.pdf}, adds
|
||||||
* metadata, writes to @{code ./target/testout-*} and then imports to check the
|
* metadata, writes to @{code ./target/testout-*} and then imports to check the
|
||||||
@@ -264,7 +268,7 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
assertEquals("Innerhalb von 30 Tagen 2% Skonto, 60 Tage ohne Abzug", zi.getPaymentTerms());
|
assertEquals("Innerhalb von 30 Tagen 2% Skonto, 60 Tage ohne Abzug", zi.getPaymentTerms());
|
||||||
assertEquals("804.35", zi.getLineTotalAmount());
|
assertEquals("804.35", zi.getLineTotalAmount());
|
||||||
assertEquals("809.34", zi.getTaxBasisTotalAmount());
|
assertEquals("809.34", zi.getTaxBasisTotalAmount());
|
||||||
assertEquals("153.77",zi.getTaxTotalAmount());
|
assertEquals("153.77", zi.getTaxTotalAmount());
|
||||||
assertEquals("", zi.getRoundingAmount());
|
assertEquals("", zi.getRoundingAmount());
|
||||||
assertEquals("0.00", zi.getPaidAmount());
|
assertEquals("0.00", zi.getPaidAmount());
|
||||||
assertEquals("Beispiel AG", zi.getBuyerTradePartyName());
|
assertEquals("Beispiel AG", zi.getBuyerTradePartyName());
|
||||||
@@ -273,8 +277,8 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
assertEquals("10000", zi.getBuyerTradePartyID());
|
assertEquals("10000", zi.getBuyerTradePartyID());
|
||||||
assertEquals("\n weclapp.com\nSomestreet 42\n08155 Some city\nDE\n ", zi.getIncludedNote());
|
assertEquals("\n weclapp.com\nSomestreet 42\n08155 Some city\nDE\n ", zi.getIncludedNote());
|
||||||
assertEquals("weclapp.com", zi.getHolder());
|
assertEquals("weclapp.com", zi.getHolder());
|
||||||
assertEquals("380",zi.getDocumentCode());
|
assertEquals("380", zi.getDocumentCode());
|
||||||
assertEquals("01-95",zi.getReference());
|
assertEquals("01-95", zi.getReference());
|
||||||
assertEquals("RE1001", zi.getForeignReference());
|
assertEquals("RE1001", zi.getForeignReference());
|
||||||
assertEquals("54321", zi.getBuyerTradePartyAddress().getPostcodeCode());
|
assertEquals("54321", zi.getBuyerTradePartyAddress().getPostcodeCode());
|
||||||
assertEquals("Feldstraße 34", zi.getBuyerTradePartyAddress().getLineOne());
|
assertEquals("Feldstraße 34", zi.getBuyerTradePartyAddress().getLineOne());
|
||||||
@@ -284,13 +288,13 @@ public class ZF2Test extends MustangReaderTestCase {
|
|||||||
assertEquals("DE", zi.getBuyerTradePartyAddress().getCountryID());
|
assertEquals("DE", zi.getBuyerTradePartyAddress().getCountryID());
|
||||||
assertEquals("Hithausen", zi.getBuyerTradePartyAddress().getCityName());
|
assertEquals("Hithausen", zi.getBuyerTradePartyAddress().getCityName());
|
||||||
assertEquals("Beispiel Lager AG", zi.getDeliveryTradePartyName());
|
assertEquals("Beispiel Lager AG", zi.getDeliveryTradePartyName());
|
||||||
assertEquals("54321", zi.getDeliveryTradePartyAddress().getPostcodeCode());
|
assertEquals("54321", zi.getDeliveryTradePartyAddress().getPostcodeCode());
|
||||||
assertEquals("Feldstraße 39", zi.getDeliveryTradePartyAddress().getLineOne());
|
assertEquals("Feldstraße 39", zi.getDeliveryTradePartyAddress().getLineOne());
|
||||||
assertEquals(null, zi.getDeliveryTradePartyAddress().getLineTwo());
|
assertEquals(null, zi.getDeliveryTradePartyAddress().getLineTwo());
|
||||||
assertEquals(null, zi.getDeliveryTradePartyAddress().getLineThree());
|
assertEquals(null, zi.getDeliveryTradePartyAddress().getLineThree());
|
||||||
assertEquals(null, zi.getDeliveryTradePartyAddress().getCountrySubDivisionName());
|
assertEquals(null, zi.getDeliveryTradePartyAddress().getCountrySubDivisionName());
|
||||||
assertEquals("DE", zi.getDeliveryTradePartyAddress().getCountryID());
|
assertEquals("DE", zi.getDeliveryTradePartyAddress().getCountryID());
|
||||||
assertEquals("Hithausen", zi.getDeliveryTradePartyAddress().getCityName());
|
assertEquals("Hithausen", zi.getDeliveryTradePartyAddress().getCityName());
|
||||||
assertEquals("08155", zi.getSellerTradePartyAddress().getPostcodeCode());
|
assertEquals("08155", zi.getSellerTradePartyAddress().getPostcodeCode());
|
||||||
assertEquals("Somestreet 42", zi.getSellerTradePartyAddress().getLineOne());
|
assertEquals("Somestreet 42", zi.getSellerTradePartyAddress().getLineOne());
|
||||||
assertEquals(null, zi.getSellerTradePartyAddress().getLineTwo());
|
assertEquals(null, zi.getSellerTradePartyAddress().getLineTwo());
|
||||||
|
|||||||
@@ -21,8 +21,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mustangproject.ZUGFeRD;
|
package org.mustangproject.ZUGFeRD;
|
||||||
|
|
||||||
import org.mustangproject.FileAttachment;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import org.mustangproject.Invoice;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.mustangproject.*;
|
||||||
|
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@@ -33,6 +34,7 @@ import java.nio.file.Paths;
|
|||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -42,23 +44,9 @@ import java.util.Arrays;
|
|||||||
public class ZF2ZInvoiceImporterTest extends ResourceCase {
|
public class ZF2ZInvoiceImporterTest extends ResourceCase {
|
||||||
|
|
||||||
|
|
||||||
public void testInvoiceImportSupportCase145() {
|
public void testInvoiceImport() {
|
||||||
|
|
||||||
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("C:\\Users\\jstaerk\\workspace\\XMLExamples\\zfdiverses\\20241004_\\IGEPA-Rechnung_41102839_00200_20240918.PDF");
|
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2new.pdf");
|
||||||
boolean hasExceptions = false;
|
|
||||||
Invoice invoice = null;
|
|
||||||
try {
|
|
||||||
invoice = zii.extractInvoice();
|
|
||||||
} catch (XPathExpressionException | ParseException e) {
|
|
||||||
hasExceptions = true;
|
|
||||||
}
|
|
||||||
assertFalse(hasExceptions);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testInvoiceImport() {
|
|
||||||
|
|
||||||
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2new.pdf");
|
|
||||||
|
|
||||||
boolean hasExceptions = false;
|
boolean hasExceptions = false;
|
||||||
Invoice invoice = null;
|
Invoice invoice = null;
|
||||||
@@ -301,6 +289,12 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
|
|||||||
assertFalse(hasExceptions);
|
assertFalse(hasExceptions);
|
||||||
TransactionCalculator tc = new TransactionCalculator(invoice);
|
TransactionCalculator tc = new TransactionCalculator(invoice);
|
||||||
assertEquals(new BigDecimal("1.00"), tc.getGrandTotal());
|
assertEquals(new BigDecimal("1.00"), tc.getGrandTotal());
|
||||||
|
assertTrue(invoice.getTradeSettlement().length==1);
|
||||||
|
assertTrue(invoice.getTradeSettlement()[0] instanceof IZUGFeRDTradeSettlementPayment);
|
||||||
|
IZUGFeRDTradeSettlementPayment paym=(IZUGFeRDTradeSettlementPayment)invoice.getTradeSettlement()[0];
|
||||||
|
assertEquals("DE12500105170648489890", paym.getOwnIBAN());
|
||||||
|
assertEquals("COBADEFXXX", paym.getOwnBIC());
|
||||||
|
|
||||||
|
|
||||||
assertTrue(invoice.getPayee() != null);
|
assertTrue(invoice.getPayee() != null);
|
||||||
assertEquals("VR Factoring GmbH", invoice.getPayee().getName());
|
assertEquals("VR Factoring GmbH", invoice.getPayee().getName());
|
||||||
@@ -333,52 +327,105 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void testEEISI_300_cii_Import() {
|
public void testImportDebit() {
|
||||||
boolean hasExceptions = false;
|
File CIIinputFile = getResourceAsFile("cii/minimalDebit.xml");
|
||||||
File input = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel2.ubl.xml");
|
|
||||||
File inputCorrect = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel2.cii.xml");
|
|
||||||
|
|
||||||
|
|
||||||
ZUGFeRDInvoiceImporter cii = new ZUGFeRDInvoiceImporter();
|
|
||||||
try {
|
try {
|
||||||
cii.fromXML(new String(Files.readAllBytes(inputCorrect.toPath()), StandardCharsets.UTF_8));
|
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile));
|
||||||
|
Invoice i=zii.extractInvoice();
|
||||||
|
|
||||||
|
assertEquals("DE21860000000086001055", i.getSender().getBankDetails().get(0).getIBAN());
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
String jsonArray = mapper.writeValueAsString(i);
|
||||||
|
|
||||||
|
// assertEquals("",jsonArray);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
hasExceptions = true;
|
fail("IOException not expected");
|
||||||
}
|
|
||||||
|
|
||||||
Invoice ciiinvoice = null;
|
|
||||||
try {
|
|
||||||
ciiinvoice = cii.extractInvoice();
|
|
||||||
|
|
||||||
} catch (XPathExpressionException e) {
|
} catch (XPathExpressionException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void testImportMinimum() {
|
||||||
|
File CIIinputFile = getResourceAsFile("cii/facturFrMinimum.xml");
|
||||||
|
try {
|
||||||
|
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile));
|
||||||
|
|
||||||
|
|
||||||
|
CalculatedInvoice i=new CalculatedInvoice();
|
||||||
|
zii.extractInto(i);
|
||||||
|
assertEquals("671.15", i.getGrandTotal().toString());
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail("IOException not expected");
|
||||||
|
} catch (XPathExpressionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
this would test if for all elements/attributes
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void testEEISI_300_cii_Import() throws XPathExpressionException, ParseException {
|
||||||
|
boolean hasExceptions = false;
|
||||||
|
File inputCII = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml");
|
||||||
|
File inputUBL = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.ubl.xml");
|
||||||
|
|
||||||
|
|
||||||
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
|
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
|
||||||
try {
|
try {
|
||||||
zii.fromXML(new String(Files.readAllBytes(input.toPath()), StandardCharsets.UTF_8));
|
zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8));
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
hasExceptions = true;
|
hasExceptions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoice invoice = null;
|
Invoice invoiceUBL = null;
|
||||||
|
invoiceUBL = zii.extractInvoice();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
invoice = zii.extractInvoice();
|
zii.fromXML(new String(Files.readAllBytes(inputUBL.toPath()), StandardCharsets.UTF_8));
|
||||||
assertEquals("Seller name",invoice.getSender().getName());
|
|
||||||
assertEquals(ciiinvoice.getRecipient().getID(),invoice.getRecipient().getID());
|
} catch (IOException e) {
|
||||||
|
hasExceptions = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoice invoiceCII = null;
|
||||||
|
try {
|
||||||
|
invoiceCII = zii.extractInvoice();
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
String ubl=mapper.writeValueAsString(invoiceUBL).replace("," ,"\n");
|
||||||
|
String cii=mapper.writeValueAsString(invoiceCII).replace("," ,"\n");
|
||||||
|
|
||||||
|
assertEquals(cii,ubl);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<cbc:Name>Seller contact point</cbc:Name>
|
<cbc:Name>Seller contact point</cbc:Name>
|
||||||
<cbc:Telephone>+41 345 654455</cbc:Telephone>
|
<cbc:Telephone>+41 345 654455</cbc:Telephone>
|
||||||
<cbc:ElectronicMail>seller@contact.de);*/
|
<cbc:ElectronicMail>seller@contact.de);*/
|
||||||
} catch (XPathExpressionException | ParseException e) {
|
} catch (XPathExpressionException | ParseException e) {
|
||||||
hasExceptions = true;
|
hasExceptions = true;
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
assertFalse(hasExceptions);
|
assertFalse(hasExceptions);
|
||||||
TransactionCalculator tc = new TransactionCalculator(invoice);
|
|
||||||
assertEquals(new BigDecimal("205.00"), tc.getGrandTotal());
|
// TransactionCalculator tc = new TransactionCalculator(invoiceCII);
|
||||||
|
// assertEquals(new BigDecimal("205.00"), tc.getGrandTotal());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
56
library/src/test/resources/cii/facturFrMinimum.xml
Normal file
56
library/src/test/resources/cii/facturFrMinimum.xml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<rsm:CrossIndustryInvoice xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<rsm:ExchangedDocumentContext>
|
||||||
|
<ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
|
<ram:ID>urn:factur-x.eu:1p0:minimum</ram:ID>
|
||||||
|
</ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
|
</rsm:ExchangedDocumentContext>
|
||||||
|
<rsm:ExchangedDocument>
|
||||||
|
<ram:ID>FA-2017-0010</ram:ID>
|
||||||
|
<ram:TypeCode>380</ram:TypeCode>
|
||||||
|
<ram:IssueDateTime>
|
||||||
|
<udt:DateTimeString format="102">20171113</udt:DateTimeString>
|
||||||
|
</ram:IssueDateTime>
|
||||||
|
</rsm:ExchangedDocument>
|
||||||
|
<rsm:SupplyChainTradeTransaction>
|
||||||
|
<ram:ApplicableHeaderTradeAgreement>
|
||||||
|
<ram:SellerTradeParty>
|
||||||
|
<ram:Name>Au bon moulin</ram:Name>
|
||||||
|
<ram:SpecifiedLegalOrganization>
|
||||||
|
<ram:ID schemeID="0002">99999999800010</ram:ID>
|
||||||
|
</ram:SpecifiedLegalOrganization>
|
||||||
|
<ram:PostalTradeAddress>
|
||||||
|
<ram:CountryID>FR</ram:CountryID>
|
||||||
|
</ram:PostalTradeAddress>
|
||||||
|
<ram:SpecifiedTaxRegistration>
|
||||||
|
<ram:ID schemeID="VA">FR11999999998</ram:ID>
|
||||||
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
</ram:SellerTradeParty>
|
||||||
|
<ram:BuyerTradeParty>
|
||||||
|
<ram:Name>Ma jolie boutique</ram:Name>
|
||||||
|
<ram:SpecifiedLegalOrganization>
|
||||||
|
<ram:ID schemeID="0002">78787878400035</ram:ID>
|
||||||
|
</ram:SpecifiedLegalOrganization>
|
||||||
|
<ram:PostalTradeAddress>
|
||||||
|
<ram:CountryID>FR</ram:CountryID>
|
||||||
|
</ram:PostalTradeAddress>
|
||||||
|
<ram:SpecifiedTaxRegistration>
|
||||||
|
<ram:ID schemeID="VA">FR19787878784</ram:ID>
|
||||||
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
</ram:BuyerTradeParty>
|
||||||
|
<ram:BuyerOrderReferencedDocument>
|
||||||
|
<ram:IssuerAssignedID>PO445</ram:IssuerAssignedID>
|
||||||
|
</ram:BuyerOrderReferencedDocument>
|
||||||
|
</ram:ApplicableHeaderTradeAgreement>
|
||||||
|
<ram:ApplicableHeaderTradeDelivery/>
|
||||||
|
<ram:ApplicableHeaderTradeSettlement>
|
||||||
|
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
||||||
|
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
<ram:TaxBasisTotalAmount currencyID="EUR">624.90</ram:TaxBasisTotalAmount>
|
||||||
|
<ram:TaxTotalAmount currencyID="EUR">46.25</ram:TaxTotalAmount>
|
||||||
|
<ram:GrandTotalAmount currencyID="EUR">671.15</ram:GrandTotalAmount>
|
||||||
|
<ram:DuePayableAmount currencyID="EUR">470.15</ram:DuePayableAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
</ram:ApplicableHeaderTradeSettlement>
|
||||||
|
</rsm:SupplyChainTradeTransaction>
|
||||||
|
</rsm:CrossIndustryInvoice>
|
||||||
143
library/src/test/resources/cii/minimalDebit.xml
Normal file
143
library/src/test/resources/cii/minimalDebit.xml
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
|
||||||
|
<!-- generated by: mustangproject.org vnull-->
|
||||||
|
<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:TypeCode>380</ram:TypeCode>
|
||||||
|
<ram:IssueDateTime>
|
||||||
|
<udt:DateTimeString format="102">20180304</udt:DateTimeString>
|
||||||
|
</ram:IssueDateTime>
|
||||||
|
</rsm:ExchangedDocument>
|
||||||
|
<rsm:SupplyChainTradeTransaction>
|
||||||
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:LineID>1</ram:LineID>
|
||||||
|
</ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:SpecifiedTradeProduct>
|
||||||
|
<ram:Name>Trennblätter A4</ram:Name>
|
||||||
|
</ram:SpecifiedTradeProduct>
|
||||||
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:NetPriceProductTradePrice>
|
||||||
|
<ram:ChargeAmount>9.9000</ram:ChargeAmount>
|
||||||
|
<ram:BasisQuantity unitCode="H87">1.0000</ram:BasisQuantity>
|
||||||
|
</ram:NetPriceProductTradePrice>
|
||||||
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
|
<ram:BilledQuantity unitCode="H87">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>198.00</ram:LineTotalAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:LineID>2</ram:LineID>
|
||||||
|
</ram:AssociatedDocumentLineDocument>
|
||||||
|
<ram:SpecifiedTradeProduct>
|
||||||
|
<ram:Name>Joghurt Banane</ram:Name>
|
||||||
|
</ram:SpecifiedTradeProduct>
|
||||||
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:NetPriceProductTradePrice>
|
||||||
|
<ram:ChargeAmount>5.5000</ram:ChargeAmount>
|
||||||
|
<ram:BasisQuantity unitCode="H87">1.0000</ram:BasisQuantity>
|
||||||
|
</ram:NetPriceProductTradePrice>
|
||||||
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
|
<ram:BilledQuantity unitCode="H87">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>275.00</ram:LineTotalAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
|
<ram:ApplicableHeaderTradeAgreement>
|
||||||
|
<ram:SellerTradeParty>
|
||||||
|
<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="VA">DE123456789</ram:ID>
|
||||||
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
<ram:SpecifiedTaxRegistration>
|
||||||
|
<ram:ID schemeID="FC">201/113/40209</ram:ID>
|
||||||
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
</ram:SellerTradeParty>
|
||||||
|
<ram:BuyerTradeParty>
|
||||||
|
<ram:Name>Kunden AG Mitte</ram:Name>
|
||||||
|
<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">20180304</udt:DateTimeString>
|
||||||
|
</ram:OccurrenceDateTime>
|
||||||
|
</ram:ActualDeliverySupplyChainEvent>
|
||||||
|
</ram:ApplicableHeaderTradeDelivery>
|
||||||
|
<ram:ApplicableHeaderTradeSettlement>
|
||||||
|
<ram:CreditorReferenceID>DE98ZZZ09999999999</ram:CreditorReferenceID>
|
||||||
|
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
||||||
|
<ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
|
<ram:TypeCode>59</ram:TypeCode>
|
||||||
|
<ram:PayerPartyDebtorFinancialAccount>
|
||||||
|
<ram:IBANID>DE21860000000086001055</ram:IBANID></ram:PayerPartyDebtorFinancialAccount>
|
||||||
|
</ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
|
<ram:ApplicableTradeTax>
|
||||||
|
<ram:CalculatedAmount>19.25</ram:CalculatedAmount>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:BasisAmount>275.00</ram:BasisAmount>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
|
||||||
|
</ram:ApplicableTradeTax>
|
||||||
|
<ram:ApplicableTradeTax>
|
||||||
|
<ram:CalculatedAmount>37.62</ram:CalculatedAmount>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:BasisAmount>198.00</ram:BasisAmount>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
|
||||||
|
</ram:ApplicableTradeTax>
|
||||||
|
<ram:SpecifiedTradePaymentTerms>
|
||||||
|
<ram:Description>Der Betrag in Höhe von EUR 529,87 wird am 20.03.2018 von Ihrem Konto per SEPA-Lastschrift eingezogen.
|
||||||
|
</ram:Description>
|
||||||
|
<ram:DirectDebitMandateID>REF A-123</ram:DirectDebitMandateID>
|
||||||
|
</ram:SpecifiedTradePaymentTerms>
|
||||||
|
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
<ram:LineTotalAmount>473.00</ram:LineTotalAmount>
|
||||||
|
<ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
|
||||||
|
<ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
|
||||||
|
<ram:TaxBasisTotalAmount>473.00</ram:TaxBasisTotalAmount>
|
||||||
|
<ram:TaxTotalAmount currencyID="EUR">56.87</ram:TaxTotalAmount>
|
||||||
|
<ram:GrandTotalAmount>529.87</ram:GrandTotalAmount>
|
||||||
|
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
|
||||||
|
<ram:DuePayableAmount>529.87</ram:DuePayableAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
</ram:ApplicableHeaderTradeSettlement>
|
||||||
|
</rsm:SupplyChainTradeTransaction>
|
||||||
|
</rsm:CrossIndustryInvoice>
|
||||||
@@ -1,411 +1,415 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
|
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
|
||||||
<rsm:ExchangedDocumentContext>
|
xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
|
||||||
<ram:BusinessProcessSpecifiedDocumentContextParameter>
|
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
|
||||||
<ram:ID>BT-23 Business Process Type</ram:ID>
|
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
|
||||||
</ram:BusinessProcessSpecifiedDocumentContextParameter>
|
<rsm:ExchangedDocumentContext>
|
||||||
<ram:GuidelineSpecifiedDocumentContextParameter>
|
<ram:BusinessProcessSpecifiedDocumentContextParameter>
|
||||||
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
|
<ram:ID>BT-23 Business Process Type</ram:ID>
|
||||||
</ram:GuidelineSpecifiedDocumentContextParameter>
|
</ram:BusinessProcessSpecifiedDocumentContextParameter>
|
||||||
</rsm:ExchangedDocumentContext>
|
<ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
<rsm:ExchangedDocument>
|
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
|
||||||
<ram:ID>Test_EeISI_100</ram:ID>
|
</ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
<ram:TypeCode>380</ram:TypeCode>
|
</rsm:ExchangedDocumentContext>
|
||||||
<ram:IssueDateTime>
|
<rsm:ExchangedDocument>
|
||||||
<udt:DateTimeString format="102">20181112</udt:DateTimeString>
|
<ram:ID>Test_EeISI_100</ram:ID>
|
||||||
</ram:IssueDateTime>
|
<ram:TypeCode>380</ram:TypeCode>
|
||||||
<ram:IncludedNote>
|
<ram:IssueDateTime>
|
||||||
<ram:Content>invoice note text</ram:Content>
|
|
||||||
<ram:SubjectCode>#AAA#</ram:SubjectCode>
|
|
||||||
</ram:IncludedNote>
|
|
||||||
<ram:IncludedNote>
|
|
||||||
<ram:Content>invoice note text 2</ram:Content>
|
|
||||||
<ram:SubjectCode>#AAA#</ram:SubjectCode>
|
|
||||||
</ram:IncludedNote>
|
|
||||||
</rsm:ExchangedDocument>
|
|
||||||
<rsm:SupplyChainTradeTransaction>
|
|
||||||
<ram:IncludedSupplyChainTradeLineItem>
|
|
||||||
<ram:AssociatedDocumentLineDocument>
|
|
||||||
<ram:LineID>1a</ram:LineID>
|
|
||||||
<ram:IncludedNote>
|
|
||||||
<ram:Content>Invoice line note</ram:Content>
|
|
||||||
</ram:IncludedNote>
|
|
||||||
</ram:AssociatedDocumentLineDocument>
|
|
||||||
<ram:SpecifiedTradeProduct>
|
|
||||||
<ram:GlobalID>Item standar identifier</ram:GlobalID>
|
|
||||||
<ram:SellerAssignedID>Item seller's identifier</ram:SellerAssignedID>
|
|
||||||
<ram:BuyerAssignedID>Item buyer's identifier</ram:BuyerAssignedID>
|
|
||||||
<ram:Name>Item name</ram:Name>
|
|
||||||
<ram:Description>Item description</ram:Description>
|
|
||||||
<ram:ApplicableProductCharacteristic>
|
|
||||||
<ram:Description>Color</ram:Description>
|
|
||||||
<ram:Value>Red</ram:Value>
|
|
||||||
</ram:ApplicableProductCharacteristic>
|
|
||||||
<ram:ApplicableProductCharacteristic>
|
|
||||||
<ram:Description>Size</ram:Description>
|
|
||||||
<ram:Value>L</ram:Value>
|
|
||||||
</ram:ApplicableProductCharacteristic>
|
|
||||||
<ram:DesignatedProductClassification>
|
|
||||||
<ram:ClassCode listID="ZZZ" listVersionID="version0">Item classification identifier0</ram:ClassCode>
|
|
||||||
</ram:DesignatedProductClassification>
|
|
||||||
<ram:OriginTradeCountry>
|
|
||||||
<ram:ID>IT</ram:ID>
|
|
||||||
</ram:OriginTradeCountry>
|
|
||||||
</ram:SpecifiedTradeProduct>
|
|
||||||
<ram:SpecifiedLineTradeAgreement>
|
|
||||||
<ram:BuyerOrderReferencedDocument>
|
|
||||||
<ram:LineID>12345</ram:LineID>
|
|
||||||
</ram:BuyerOrderReferencedDocument>
|
|
||||||
<ram:GrossPriceProductTradePrice>
|
|
||||||
<ram:ChargeAmount>11.00</ram:ChargeAmount>
|
|
||||||
<ram:BasisQuantity unitCode="EA">1.00</ram:BasisQuantity>
|
|
||||||
<ram:AppliedTradeAllowanceCharge>
|
|
||||||
<ram:ChargeIndicator>
|
|
||||||
<udt:Indicator>false</udt:Indicator>
|
|
||||||
</ram:ChargeIndicator>
|
|
||||||
<ram:ActualAmount>1.00</ram:ActualAmount>
|
|
||||||
</ram:AppliedTradeAllowanceCharge>
|
|
||||||
</ram:GrossPriceProductTradePrice>
|
|
||||||
<ram:NetPriceProductTradePrice>
|
|
||||||
<ram:ChargeAmount>10.00</ram:ChargeAmount>
|
|
||||||
<ram:BasisQuantity unitCode="EA">1.00</ram:BasisQuantity>
|
|
||||||
</ram:NetPriceProductTradePrice>
|
|
||||||
</ram:SpecifiedLineTradeAgreement>
|
|
||||||
<ram:SpecifiedLineTradeDelivery>
|
|
||||||
<ram:BilledQuantity unitCode="EA">10.00</ram:BilledQuantity>
|
|
||||||
</ram:SpecifiedLineTradeDelivery>
|
|
||||||
<ram:SpecifiedLineTradeSettlement>
|
|
||||||
<ram:ApplicableTradeTax>
|
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
|
||||||
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
|
||||||
</ram:ApplicableTradeTax>
|
|
||||||
<ram:BillingSpecifiedPeriod>
|
|
||||||
<ram:StartDateTime>
|
|
||||||
<udt:DateTimeString format="102">20181112</udt:DateTimeString>
|
<udt:DateTimeString format="102">20181112</udt:DateTimeString>
|
||||||
</ram:StartDateTime>
|
</ram:IssueDateTime>
|
||||||
<ram:EndDateTime>
|
<ram:IncludedNote>
|
||||||
<udt:DateTimeString format="102">20181130</udt:DateTimeString>
|
<ram:Content>invoice note text</ram:Content>
|
||||||
</ram:EndDateTime>
|
<ram:SubjectCode>AAA</ram:SubjectCode>
|
||||||
</ram:BillingSpecifiedPeriod>
|
</ram:IncludedNote>
|
||||||
<ram:SpecifiedTradeAllowanceCharge>
|
<ram:IncludedNote>
|
||||||
<ram:ChargeIndicator>
|
<ram:Content>invoice note text 2</ram:Content>
|
||||||
<udt:Indicator>false</udt:Indicator>
|
<ram:SubjectCode>AAA</ram:SubjectCode>
|
||||||
</ram:ChargeIndicator>
|
</ram:IncludedNote>
|
||||||
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
</rsm:ExchangedDocument>
|
||||||
<ram:BasisAmount>1000.00</ram:BasisAmount>
|
<rsm:SupplyChainTradeTransaction>
|
||||||
<ram:ActualAmount>10.00</ram:ActualAmount>
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:ReasonCode>55</ram:ReasonCode>
|
<ram:AssociatedDocumentLineDocument>
|
||||||
<ram:Reason>Invoice line allowance reason</ram:Reason>
|
<ram:LineID>1a</ram:LineID>
|
||||||
</ram:SpecifiedTradeAllowanceCharge>
|
<ram:IncludedNote>
|
||||||
<ram:SpecifiedTradeAllowanceCharge>
|
<ram:Content>Invoice line note</ram:Content>
|
||||||
<ram:ChargeIndicator>
|
</ram:IncludedNote>
|
||||||
<udt:Indicator>true</udt:Indicator>
|
</ram:AssociatedDocumentLineDocument>
|
||||||
</ram:ChargeIndicator>
|
<ram:SpecifiedTradeProduct>
|
||||||
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
<ram:GlobalID schemeID="0060">Item standar identifier
|
||||||
<ram:BasisAmount>1000.00</ram:BasisAmount>
|
</ram:GlobalID>
|
||||||
<ram:ActualAmount>10.00</ram:ActualAmount>
|
|
||||||
<ram:ReasonCode>AAA</ram:ReasonCode>
|
<ram:SellerAssignedID>Item seller's identifier</ram:SellerAssignedID>
|
||||||
<ram:Reason>Invoice line charge reason</ram:Reason>
|
<ram:BuyerAssignedID>Item buyer's identifier</ram:BuyerAssignedID>
|
||||||
</ram:SpecifiedTradeAllowanceCharge>
|
<ram:Name>Item name</ram:Name>
|
||||||
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
<ram:Description>Item description</ram:Description>
|
||||||
<ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
|
<ram:ApplicableProductCharacteristic>
|
||||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
<ram:Description>Color</ram:Description>
|
||||||
<ram:AdditionalReferencedDocument>
|
<ram:Value>Red</ram:Value>
|
||||||
<ram:IssuerAssignedID>Line object identifier</ram:IssuerAssignedID>
|
</ram:ApplicableProductCharacteristic>
|
||||||
<ram:TypeCode>130</ram:TypeCode>
|
<ram:ApplicableProductCharacteristic>
|
||||||
<ram:ReferenceTypeCode />
|
<ram:Description>Size</ram:Description>
|
||||||
</ram:AdditionalReferencedDocument>
|
<ram:Value>L</ram:Value>
|
||||||
<ram:ReceivableSpecifiedTradeAccountingAccount>
|
</ram:ApplicableProductCharacteristic>
|
||||||
<ram:ID>6789</ram:ID>
|
<ram:DesignatedProductClassification>
|
||||||
</ram:ReceivableSpecifiedTradeAccountingAccount>
|
<ram:ClassCode listID="ZZZ" listVersionID="version0">Item classification identifier0</ram:ClassCode>
|
||||||
</ram:SpecifiedLineTradeSettlement>
|
</ram:DesignatedProductClassification>
|
||||||
</ram:IncludedSupplyChainTradeLineItem>
|
<ram:OriginTradeCountry>
|
||||||
<ram:IncludedSupplyChainTradeLineItem>
|
<ram:ID>IT</ram:ID>
|
||||||
<ram:AssociatedDocumentLineDocument>
|
</ram:OriginTradeCountry>
|
||||||
<ram:LineID>1b</ram:LineID>
|
</ram:SpecifiedTradeProduct>
|
||||||
</ram:AssociatedDocumentLineDocument>
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:SpecifiedTradeProduct>
|
<ram:BuyerOrderReferencedDocument>
|
||||||
<ram:Name>Item name 2</ram:Name>
|
<ram:LineID>12345</ram:LineID>
|
||||||
</ram:SpecifiedTradeProduct>
|
</ram:BuyerOrderReferencedDocument>
|
||||||
<ram:SpecifiedLineTradeAgreement>
|
<ram:GrossPriceProductTradePrice>
|
||||||
<ram:NetPriceProductTradePrice>
|
<ram:ChargeAmount>11.00</ram:ChargeAmount>
|
||||||
<ram:ChargeAmount>10.00</ram:ChargeAmount>
|
<ram:BasisQuantity unitCode="EA">1.00</ram:BasisQuantity>
|
||||||
</ram:NetPriceProductTradePrice>
|
<ram:AppliedTradeAllowanceCharge>
|
||||||
</ram:SpecifiedLineTradeAgreement>
|
<ram:ChargeIndicator>
|
||||||
<ram:SpecifiedLineTradeDelivery>
|
<udt:Indicator>false</udt:Indicator>
|
||||||
<ram:BilledQuantity unitCode="EA">10.00</ram:BilledQuantity>
|
</ram:ChargeIndicator>
|
||||||
</ram:SpecifiedLineTradeDelivery>
|
<ram:ActualAmount>1.00</ram:ActualAmount>
|
||||||
<ram:SpecifiedLineTradeSettlement>
|
</ram:AppliedTradeAllowanceCharge>
|
||||||
<ram:ApplicableTradeTax>
|
</ram:GrossPriceProductTradePrice>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:NetPriceProductTradePrice>
|
||||||
<ram:CategoryCode>E</ram:CategoryCode>
|
<ram:ChargeAmount>10.00</ram:ChargeAmount>
|
||||||
<ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
|
<ram:BasisQuantity unitCode="EA">1.00</ram:BasisQuantity>
|
||||||
</ram:ApplicableTradeTax>
|
</ram:NetPriceProductTradePrice>
|
||||||
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
<ram:BilledQuantity unitCode="EA">10.00</ram:BilledQuantity>
|
||||||
</ram:SpecifiedLineTradeSettlement>
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
</ram:IncludedSupplyChainTradeLineItem>
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
<ram:ApplicableHeaderTradeAgreement>
|
<ram:ApplicableTradeTax>
|
||||||
<ram:BuyerReference>123</ram:BuyerReference>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
<ram:SellerTradeParty>
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
<ram:GlobalID schemeID="0100">Seller identifier 1</ram:GlobalID>
|
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
||||||
<ram:GlobalID schemeID="0110">Seller identifier 2</ram:GlobalID>
|
</ram:ApplicableTradeTax>
|
||||||
<ram:Name>Seller name</ram:Name>
|
<ram:BillingSpecifiedPeriod>
|
||||||
<ram:Description>Seller additional legal information</ram:Description>
|
<ram:StartDateTime>
|
||||||
<ram:SpecifiedLegalOrganization>
|
<udt:DateTimeString format="102">20181112</udt:DateTimeString>
|
||||||
<ram:ID schemeID="0310">Seller legal identifier</ram:ID>
|
</ram:StartDateTime>
|
||||||
<ram:TradingBusinessName>Seller trading name</ram:TradingBusinessName>
|
<ram:EndDateTime>
|
||||||
</ram:SpecifiedLegalOrganization>
|
<udt:DateTimeString format="102">20181130</udt:DateTimeString>
|
||||||
<ram:DefinedTradeContact>
|
</ram:EndDateTime>
|
||||||
<ram:PersonName>Seller contact point</ram:PersonName>
|
</ram:BillingSpecifiedPeriod>
|
||||||
<ram:TelephoneUniversalCommunication>
|
<ram:SpecifiedTradeAllowanceCharge>
|
||||||
<ram:CompleteNumber>+41 345 654455</ram:CompleteNumber>
|
<ram:ChargeIndicator>
|
||||||
</ram:TelephoneUniversalCommunication>
|
<udt:Indicator>false</udt:Indicator>
|
||||||
<ram:EmailURIUniversalCommunication>
|
</ram:ChargeIndicator>
|
||||||
<ram:URIID>seller@contact.de</ram:URIID>
|
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
||||||
</ram:EmailURIUniversalCommunication>
|
<ram:BasisAmount>100.00</ram:BasisAmount>
|
||||||
</ram:DefinedTradeContact>
|
<ram:ActualAmount>10.00</ram:ActualAmount>
|
||||||
<ram:PostalTradeAddress>
|
<ram:ReasonCode>95</ram:ReasonCode>
|
||||||
<ram:PostcodeCode>12345</ram:PostcodeCode>
|
<ram:Reason>Invoice line allowance reason</ram:Reason>
|
||||||
<ram:LineOne>Seller address line 1</ram:LineOne>
|
</ram:SpecifiedTradeAllowanceCharge>
|
||||||
<ram:LineTwo>Seller address line 2</ram:LineTwo>
|
<ram:SpecifiedTradeAllowanceCharge>
|
||||||
<ram:LineThree>Seller address line 3</ram:LineThree>
|
<ram:ChargeIndicator>
|
||||||
<ram:CityName>Seller city</ram:CityName>
|
<udt:Indicator>true</udt:Indicator>
|
||||||
<ram:CountryID>DE</ram:CountryID>
|
</ram:ChargeIndicator>
|
||||||
<ram:CountrySubDivisionName>Seller country subdivision</ram:CountrySubDivisionName>
|
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
||||||
</ram:PostalTradeAddress>
|
<ram:BasisAmount>100.00</ram:BasisAmount>
|
||||||
<ram:URIUniversalCommunication>
|
<ram:ActualAmount>10.00</ram:ActualAmount>
|
||||||
<ram:URIID schemeID="SMTP">Seller electronic address</ram:URIID>
|
<ram:ReasonCode>AAA</ram:ReasonCode>
|
||||||
</ram:URIUniversalCommunication>
|
<ram:Reason>Invoice line charge reason</ram:Reason>
|
||||||
<ram:SpecifiedTaxRegistration>
|
</ram:SpecifiedTradeAllowanceCharge>
|
||||||
<ram:ID schemeID="VA">DE12345677</ram:ID>
|
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
</ram:SpecifiedTaxRegistration>
|
<ram:LineTotalAmount>100.00</ram:LineTotalAmount>
|
||||||
<ram:SpecifiedTaxRegistration>
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
<ram:ID schemeID="FC">DE49294093</ram:ID>
|
<ram:AdditionalReferencedDocument>
|
||||||
</ram:SpecifiedTaxRegistration>
|
<ram:IssuerAssignedID>Line object identifier</ram:IssuerAssignedID>
|
||||||
</ram:SellerTradeParty>
|
<ram:TypeCode>130</ram:TypeCode>
|
||||||
<ram:BuyerTradeParty>
|
</ram:AdditionalReferencedDocument>
|
||||||
<ram:GlobalID schemeID="0190">Buyer identifier</ram:GlobalID>
|
<ram:ReceivableSpecifiedTradeAccountingAccount>
|
||||||
<ram:Name>Buyer name</ram:Name>
|
<ram:ID>6789</ram:ID>
|
||||||
<ram:SpecifiedLegalOrganization>
|
</ram:ReceivableSpecifiedTradeAccountingAccount>
|
||||||
<ram:ID schemeID="0089">Buyer legal registration identifier</ram:ID>
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
<ram:TradingBusinessName>Buyer trading name</ram:TradingBusinessName>
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
</ram:SpecifiedLegalOrganization>
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:DefinedTradeContact>
|
<ram:AssociatedDocumentLineDocument>
|
||||||
<ram:PersonName>Buyer contact point</ram:PersonName>
|
<ram:LineID>1b</ram:LineID>
|
||||||
<ram:TelephoneUniversalCommunication>
|
</ram:AssociatedDocumentLineDocument>
|
||||||
<ram:CompleteNumber>+353 2948584</ram:CompleteNumber>
|
<ram:SpecifiedTradeProduct>
|
||||||
</ram:TelephoneUniversalCommunication>
|
<ram:Name>Item name 2</ram:Name>
|
||||||
<ram:EmailURIUniversalCommunication>
|
</ram:SpecifiedTradeProduct>
|
||||||
<ram:URIID>buyer@contact.ie</ram:URIID>
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
</ram:EmailURIUniversalCommunication>
|
<ram:NetPriceProductTradePrice>
|
||||||
</ram:DefinedTradeContact>
|
<ram:ChargeAmount>10.00</ram:ChargeAmount>
|
||||||
<ram:PostalTradeAddress>
|
</ram:NetPriceProductTradePrice>
|
||||||
<ram:PostcodeCode>34562</ram:PostcodeCode>
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:LineOne>Buyer address line 1</ram:LineOne>
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:LineTwo>Buyer address line 2</ram:LineTwo>
|
<ram:BilledQuantity unitCode="EA">10.00</ram:BilledQuantity>
|
||||||
<ram:LineThree>Buyer address line 3</ram:LineThree>
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:CityName>Buyer city</ram:CityName>
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
<ram:CountryID>IE</ram:CountryID>
|
<ram:ApplicableTradeTax>
|
||||||
<ram:CountrySubDivisionName>Buyer country subdivision</ram:CountrySubDivisionName>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
</ram:PostalTradeAddress>
|
<ram:CategoryCode>E</ram:CategoryCode>
|
||||||
<ram:URIUniversalCommunication>
|
<ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
|
||||||
<ram:URIID schemeID="DE:SMTP">Buyer electronic address</ram:URIID>
|
</ram:ApplicableTradeTax>
|
||||||
</ram:URIUniversalCommunication>
|
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
<ram:SpecifiedTaxRegistration>
|
<ram:LineTotalAmount>100.00</ram:LineTotalAmount>
|
||||||
<ram:ID schemeID="VA">IE394838894</ram:ID>
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
</ram:SpecifiedTaxRegistration>
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
</ram:BuyerTradeParty>
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:SellerTaxRepresentativeTradeParty>
|
<ram:ApplicableHeaderTradeAgreement>
|
||||||
<ram:Name>Tax representative name</ram:Name>
|
<ram:BuyerReference>123</ram:BuyerReference>
|
||||||
<ram:PostalTradeAddress>
|
<ram:SellerTradeParty>
|
||||||
<ram:PostcodeCode>23455</ram:PostcodeCode>
|
<ram:GlobalID schemeID="0100">Seller identifier 1</ram:GlobalID>
|
||||||
<ram:LineOne>Tax representative address line 1</ram:LineOne>
|
<ram:GlobalID schemeID="0110">Seller identifier 2</ram:GlobalID>
|
||||||
<ram:LineTwo>Tax representative address line 2</ram:LineTwo>
|
<ram:Name>Seller name</ram:Name>
|
||||||
<ram:LineThree>Tax representative address line 3</ram:LineThree>
|
<ram:Description>Seller additional legal information</ram:Description>
|
||||||
<ram:CityName>Tax representative city</ram:CityName>
|
<ram:SpecifiedLegalOrganization>
|
||||||
<ram:CountryID>DE</ram:CountryID>
|
<!-- <ram:ID schemeID="0310">Seller legal identifier</ram:ID> -->
|
||||||
<ram:CountrySubDivisionName>Tax representative country subdivision</ram:CountrySubDivisionName>
|
<ram:TradingBusinessName>Seller trading name</ram:TradingBusinessName>
|
||||||
</ram:PostalTradeAddress>
|
</ram:SpecifiedLegalOrganization>
|
||||||
<ram:SpecifiedTaxRegistration>
|
<ram:DefinedTradeContact>
|
||||||
<ram:ID schemeID="VA">DE3949053</ram:ID>
|
<ram:PersonName>Seller contact point</ram:PersonName>
|
||||||
</ram:SpecifiedTaxRegistration>
|
<ram:TelephoneUniversalCommunication>
|
||||||
</ram:SellerTaxRepresentativeTradeParty>
|
<ram:CompleteNumber>+41 345 654455</ram:CompleteNumber>
|
||||||
<ram:SellerOrderReferencedDocument>
|
</ram:TelephoneUniversalCommunication>
|
||||||
<ram:IssuerAssignedID>def</ram:IssuerAssignedID>
|
<ram:EmailURIUniversalCommunication>
|
||||||
</ram:SellerOrderReferencedDocument>
|
<ram:URIID>seller@contact.de</ram:URIID>
|
||||||
<ram:BuyerOrderReferencedDocument>
|
</ram:EmailURIUniversalCommunication>
|
||||||
<ram:IssuerAssignedID>abc</ram:IssuerAssignedID>
|
</ram:DefinedTradeContact>
|
||||||
</ram:BuyerOrderReferencedDocument>
|
<ram:PostalTradeAddress>
|
||||||
<ram:ContractReferencedDocument>
|
<ram:PostcodeCode>12345</ram:PostcodeCode>
|
||||||
<ram:IssuerAssignedID>789</ram:IssuerAssignedID>
|
<ram:LineOne>Seller address line 1</ram:LineOne>
|
||||||
</ram:ContractReferencedDocument>
|
<ram:LineTwo>Seller address line 2</ram:LineTwo>
|
||||||
<ram:AdditionalReferencedDocument>
|
<ram:LineThree>Seller address line 3</ram:LineThree>
|
||||||
<ram:IssuerAssignedID>Supporting document ref</ram:IssuerAssignedID>
|
<ram:CityName>Seller city</ram:CityName>
|
||||||
<ram:URIID>External document location</ram:URIID>
|
<ram:CountryID>DE</ram:CountryID>
|
||||||
<ram:TypeCode>916</ram:TypeCode>
|
<ram:CountrySubDivisionName>Seller country subdivision</ram:CountrySubDivisionName>
|
||||||
<ram:Name>Supporting document descr</ram:Name>
|
</ram:PostalTradeAddress>
|
||||||
<ram:AttachmentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</ram:AttachmentBinaryObject>
|
<ram:URIUniversalCommunication>
|
||||||
</ram:AdditionalReferencedDocument>
|
<ram:URIID schemeID="EM">Seller electronic address</ram:URIID>
|
||||||
<ram:AdditionalReferencedDocument>
|
</ram:URIUniversalCommunication>
|
||||||
<ram:IssuerAssignedID>rst</ram:IssuerAssignedID>
|
<ram:SpecifiedTaxRegistration>
|
||||||
<ram:TypeCode>130</ram:TypeCode>
|
<ram:ID schemeID="VA">DE12345677</ram:ID>
|
||||||
<ram:ReferenceTypeCode>0090</ram:ReferenceTypeCode>
|
</ram:SpecifiedTaxRegistration>
|
||||||
</ram:AdditionalReferencedDocument>
|
<ram:SpecifiedTaxRegistration>
|
||||||
<ram:SpecifiedProcuringProject>
|
<ram:ID schemeID="FC">DE49294093</ram:ID>
|
||||||
<ram:ID>456</ram:ID>
|
</ram:SpecifiedTaxRegistration>
|
||||||
<ram:Name>Project reference</ram:Name>
|
</ram:SellerTradeParty>
|
||||||
</ram:SpecifiedProcuringProject>
|
<ram:BuyerTradeParty>
|
||||||
</ram:ApplicableHeaderTradeAgreement>
|
<ram:GlobalID schemeID="0190">Buyer identifier</ram:GlobalID>
|
||||||
<ram:ApplicableHeaderTradeDelivery>
|
<ram:Name>Buyer name</ram:Name>
|
||||||
<ram:ShipToTradeParty>
|
<ram:SpecifiedLegalOrganization>
|
||||||
<ram:GlobalID schemeID="0045">deliver location identifier</ram:GlobalID>
|
<ram:ID schemeID="0089">Buyer legal registration identifier</ram:ID>
|
||||||
<ram:Name>Deliver to party name</ram:Name>
|
<ram:TradingBusinessName>Buyer trading name</ram:TradingBusinessName>
|
||||||
<ram:PostalTradeAddress>
|
</ram:SpecifiedLegalOrganization>
|
||||||
<ram:PostcodeCode>98765</ram:PostcodeCode>
|
<ram:DefinedTradeContact>
|
||||||
<ram:LineOne>Deliver to address line 1</ram:LineOne>
|
<ram:PersonName>Buyer contact point</ram:PersonName>
|
||||||
<ram:LineTwo>Deliver to address line 2</ram:LineTwo>
|
<ram:TelephoneUniversalCommunication>
|
||||||
<ram:LineThree>Deliver to address line 3</ram:LineThree>
|
<ram:CompleteNumber>+353 2948584</ram:CompleteNumber>
|
||||||
<ram:CityName>Deliver to city</ram:CityName>
|
</ram:TelephoneUniversalCommunication>
|
||||||
<ram:CountryID>IE</ram:CountryID>
|
<ram:EmailURIUniversalCommunication>
|
||||||
<ram:CountrySubDivisionName>Deliver to country subdivision</ram:CountrySubDivisionName>
|
<ram:URIID>buyer@contact.ie</ram:URIID>
|
||||||
</ram:PostalTradeAddress>
|
</ram:EmailURIUniversalCommunication>
|
||||||
</ram:ShipToTradeParty>
|
</ram:DefinedTradeContact>
|
||||||
<ram:ActualDeliverySupplyChainEvent>
|
<ram:PostalTradeAddress>
|
||||||
<ram:OccurrenceDateTime>
|
<ram:PostcodeCode>34562</ram:PostcodeCode>
|
||||||
<udt:DateTimeString format="102">20181204</udt:DateTimeString>
|
<ram:LineOne>Buyer address line 1</ram:LineOne>
|
||||||
</ram:OccurrenceDateTime>
|
<ram:LineTwo>Buyer address line 2</ram:LineTwo>
|
||||||
</ram:ActualDeliverySupplyChainEvent>
|
<ram:LineThree>Buyer address line 3</ram:LineThree>
|
||||||
<ram:DespatchAdviceReferencedDocument>
|
<ram:CityName>Buyer city</ram:CityName>
|
||||||
<ram:IssuerAssignedID>lmn</ram:IssuerAssignedID>
|
<ram:CountryID>IE</ram:CountryID>
|
||||||
</ram:DespatchAdviceReferencedDocument>
|
<ram:CountrySubDivisionName>Buyer country subdivision</ram:CountrySubDivisionName>
|
||||||
<ram:ReceivingAdviceReferencedDocument>
|
</ram:PostalTradeAddress>
|
||||||
<ram:IssuerAssignedID>ghi</ram:IssuerAssignedID>
|
<ram:URIUniversalCommunication>
|
||||||
</ram:ReceivingAdviceReferencedDocument>
|
<ram:URIID schemeID="EM">Buyer electronic address</ram:URIID>
|
||||||
</ram:ApplicableHeaderTradeDelivery>
|
</ram:URIUniversalCommunication>
|
||||||
<ram:ApplicableHeaderTradeSettlement>
|
<ram:SpecifiedTaxRegistration>
|
||||||
<ram:CreditorReferenceID>Bank assigned creditor identifier</ram:CreditorReferenceID>
|
<ram:ID schemeID="VA">IE394838894</ram:ID>
|
||||||
<ram:PaymentReference>Remittance information</ram:PaymentReference>
|
</ram:SpecifiedTaxRegistration>
|
||||||
<ram:TaxCurrencyCode>NOK</ram:TaxCurrencyCode>
|
</ram:BuyerTradeParty>
|
||||||
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
<ram:SellerTaxRepresentativeTradeParty>
|
||||||
<ram:PayeeTradeParty>
|
<ram:Name>Tax representative name</ram:Name>
|
||||||
<ram:GlobalID schemeID="0098">Payee identifier</ram:GlobalID>
|
<ram:PostalTradeAddress>
|
||||||
<ram:Name>Payee name</ram:Name>
|
<ram:PostcodeCode>23455</ram:PostcodeCode>
|
||||||
<ram:SpecifiedLegalOrganization>
|
<ram:LineOne>Tax representative address line 1</ram:LineOne>
|
||||||
<ram:ID schemeID="0099">Payee legal registration identifier</ram:ID>
|
<ram:LineTwo>Tax representative address line 2</ram:LineTwo>
|
||||||
</ram:SpecifiedLegalOrganization>
|
<ram:LineThree>Tax representative address line 3</ram:LineThree>
|
||||||
</ram:PayeeTradeParty>
|
<ram:CityName>Tax representative city</ram:CityName>
|
||||||
<ram:SpecifiedTradeSettlementPaymentMeans>
|
<ram:CountryID>DE</ram:CountryID>
|
||||||
<ram:TypeCode>4</ram:TypeCode>
|
<ram:CountrySubDivisionName>Tax representative country subdivision</ram:CountrySubDivisionName>
|
||||||
<ram:Information>SEPA</ram:Information>
|
</ram:PostalTradeAddress>
|
||||||
<ram:ApplicableTradeSettlementFinancialCard>
|
<ram:SpecifiedTaxRegistration>
|
||||||
<ram:ID>1234</ram:ID>
|
<ram:ID schemeID="VA">DE3949053</ram:ID>
|
||||||
<ram:CardholderName>Payment card holder name</ram:CardholderName>
|
</ram:SpecifiedTaxRegistration>
|
||||||
</ram:ApplicableTradeSettlementFinancialCard>
|
</ram:SellerTaxRepresentativeTradeParty>
|
||||||
<ram:PayerPartyDebtorFinancialAccount>
|
<ram:SellerOrderReferencedDocument>
|
||||||
<ram:IBANID>Debited account identifier</ram:IBANID>
|
<ram:IssuerAssignedID>def</ram:IssuerAssignedID>
|
||||||
</ram:PayerPartyDebtorFinancialAccount>
|
</ram:SellerOrderReferencedDocument>
|
||||||
<ram:PayeePartyCreditorFinancialAccount>
|
<ram:BuyerOrderReferencedDocument>
|
||||||
<ram:IBANID>IT1212341234123412</ram:IBANID>
|
<ram:IssuerAssignedID>abc</ram:IssuerAssignedID>
|
||||||
<ram:AccountName>Payment account name</ram:AccountName>
|
</ram:BuyerOrderReferencedDocument>
|
||||||
</ram:PayeePartyCreditorFinancialAccount>
|
<ram:ContractReferencedDocument>
|
||||||
<ram:PayerSpecifiedDebtorFinancialInstitution>
|
<ram:IssuerAssignedID>789</ram:IssuerAssignedID>
|
||||||
<ram:BICID>BSCTCH22</ram:BICID>
|
</ram:ContractReferencedDocument>
|
||||||
</ram:PayerSpecifiedDebtorFinancialInstitution>
|
<ram:AdditionalReferencedDocument>
|
||||||
<ram:PayeePartyCreditorFinancialAccount>
|
<ram:IssuerAssignedID>Supporting document ref</ram:IssuerAssignedID>
|
||||||
<ram:IBANID>IT1212341234123413</ram:IBANID>
|
<ram:URIID>External document location</ram:URIID>
|
||||||
<ram:AccountName>Payment account name 2</ram:AccountName>
|
<ram:TypeCode>916</ram:TypeCode>
|
||||||
</ram:PayeePartyCreditorFinancialAccount>
|
<ram:Name>Supporting document descr</ram:Name>
|
||||||
<ram:PayerSpecifiedDebtorFinancialInstitution>
|
<ram:AttachmentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</ram:AttachmentBinaryObject>
|
||||||
<ram:BICID>BSCTCH22</ram:BICID>
|
</ram:AdditionalReferencedDocument>
|
||||||
</ram:PayerSpecifiedDebtorFinancialInstitution>
|
<ram:AdditionalReferencedDocument>
|
||||||
</ram:SpecifiedTradeSettlementPaymentMeans>
|
<ram:IssuerAssignedID>rst</ram:IssuerAssignedID>
|
||||||
<ram:ApplicableTradeTax>
|
<ram:TypeCode>130</ram:TypeCode>
|
||||||
<ram:CalculatedAmount>50.00</ram:CalculatedAmount>
|
<ram:ReferenceTypeCode>AAA</ram:ReferenceTypeCode>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
</ram:AdditionalReferencedDocument>
|
||||||
<ram:BasisAmount>1000.00</ram:BasisAmount>
|
<ram:SpecifiedProcuringProject>
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
<ram:ID>456</ram:ID>
|
||||||
<ram:DueDateTypeCode>29</ram:DueDateTypeCode>
|
<ram:Name>Project reference</ram:Name>
|
||||||
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
</ram:SpecifiedProcuringProject>
|
||||||
</ram:ApplicableTradeTax>
|
</ram:ApplicableHeaderTradeAgreement>
|
||||||
<ram:ApplicableTradeTax>
|
<ram:ApplicableHeaderTradeDelivery>
|
||||||
<ram:CalculatedAmount>0.00</ram:CalculatedAmount>
|
<ram:ShipToTradeParty>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:GlobalID schemeID="0045">deliver location identifier</ram:GlobalID>
|
||||||
<ram:ExemptionReason>Exemtion reason text</ram:ExemptionReason>
|
<ram:Name>Deliver to party name</ram:Name>
|
||||||
<ram:BasisAmount>1000.00</ram:BasisAmount>
|
<ram:PostalTradeAddress>
|
||||||
<ram:CategoryCode>E</ram:CategoryCode>
|
<ram:PostcodeCode>98765</ram:PostcodeCode>
|
||||||
<ram:ExemptionReasonCode>Exemption reason code</ram:ExemptionReasonCode>
|
<ram:LineOne>Deliver to address line 1</ram:LineOne>
|
||||||
<ram:DueDateTypeCode>29</ram:DueDateTypeCode>
|
<ram:LineTwo>Deliver to address line 2</ram:LineTwo>
|
||||||
<ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
|
<ram:LineThree>Deliver to address line 3</ram:LineThree>
|
||||||
</ram:ApplicableTradeTax>
|
<ram:CityName>Deliver to city</ram:CityName>
|
||||||
<ram:BillingSpecifiedPeriod>
|
<ram:CountryID>IE</ram:CountryID>
|
||||||
<ram:StartDateTime>
|
<ram:CountrySubDivisionName>Deliver to country subdivision</ram:CountrySubDivisionName>
|
||||||
<udt:DateTimeString format="102">20181112</udt:DateTimeString>
|
</ram:PostalTradeAddress>
|
||||||
</ram:StartDateTime>
|
</ram:ShipToTradeParty>
|
||||||
<ram:EndDateTime>
|
<ram:ActualDeliverySupplyChainEvent>
|
||||||
<udt:DateTimeString format="102">20181130</udt:DateTimeString>
|
<ram:OccurrenceDateTime>
|
||||||
</ram:EndDateTime>
|
<udt:DateTimeString format="102">20181204</udt:DateTimeString>
|
||||||
</ram:BillingSpecifiedPeriod>
|
</ram:OccurrenceDateTime>
|
||||||
<ram:SpecifiedTradeAllowanceCharge>
|
</ram:ActualDeliverySupplyChainEvent>
|
||||||
<ram:ChargeIndicator>
|
<ram:DespatchAdviceReferencedDocument>
|
||||||
<udt:Indicator>false</udt:Indicator>
|
<ram:IssuerAssignedID>lmn</ram:IssuerAssignedID>
|
||||||
</ram:ChargeIndicator>
|
</ram:DespatchAdviceReferencedDocument>
|
||||||
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
<ram:ReceivingAdviceReferencedDocument>
|
||||||
<ram:BasisAmount>1000.00</ram:BasisAmount>
|
<ram:IssuerAssignedID>ghi</ram:IssuerAssignedID>
|
||||||
<ram:ActualAmount>10.00</ram:ActualAmount>
|
</ram:ReceivingAdviceReferencedDocument>
|
||||||
<ram:ReasonCode>55</ram:ReasonCode>
|
</ram:ApplicableHeaderTradeDelivery>
|
||||||
<ram:Reason>Doc allowance reason text</ram:Reason>
|
<ram:ApplicableHeaderTradeSettlement>
|
||||||
<ram:CategoryTradeTax>
|
<ram:CreditorReferenceID>Bank assigned creditor identifier</ram:CreditorReferenceID>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:PaymentReference>Remittance information</ram:PaymentReference>
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
<ram:TaxCurrencyCode>NOK</ram:TaxCurrencyCode>
|
||||||
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
||||||
</ram:CategoryTradeTax>
|
<ram:PayeeTradeParty>
|
||||||
</ram:SpecifiedTradeAllowanceCharge>
|
<ram:GlobalID schemeID="0098">Payee identifier</ram:GlobalID>
|
||||||
<ram:SpecifiedTradeAllowanceCharge>
|
<ram:Name>Payee name</ram:Name>
|
||||||
<ram:ChargeIndicator>
|
<ram:SpecifiedLegalOrganization>
|
||||||
<udt:Indicator>true</udt:Indicator>
|
<ram:ID schemeID="0099">Payee legal registration identifier</ram:ID>
|
||||||
</ram:ChargeIndicator>
|
</ram:SpecifiedLegalOrganization>
|
||||||
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
</ram:PayeeTradeParty>
|
||||||
<ram:BasisAmount>1000.00</ram:BasisAmount>
|
<ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
<ram:ActualAmount>10.00</ram:ActualAmount>
|
<ram:TypeCode>4</ram:TypeCode>
|
||||||
<ram:ReasonCode>AAA</ram:ReasonCode>
|
<ram:Information>SEPA</ram:Information>
|
||||||
<ram:Reason>Doc charge reason text</ram:Reason>
|
<ram:ApplicableTradeSettlementFinancialCard>
|
||||||
<ram:CategoryTradeTax>
|
<ram:ID>1234</ram:ID>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:CardholderName>Payment card holder name</ram:CardholderName>
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
</ram:ApplicableTradeSettlementFinancialCard>
|
||||||
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
<ram:PayerPartyDebtorFinancialAccount>
|
||||||
</ram:CategoryTradeTax>
|
<ram:IBANID>Debited account identifier</ram:IBANID>
|
||||||
</ram:SpecifiedTradeAllowanceCharge>
|
</ram:PayerPartyDebtorFinancialAccount>
|
||||||
<ram:SpecifiedTradePaymentTerms>
|
<ram:PayeePartyCreditorFinancialAccount>
|
||||||
<ram:Description>total amount</ram:Description>
|
<ram:IBANID>IT1212341234123412</ram:IBANID>
|
||||||
<ram:DueDateDateTime>
|
<ram:AccountName>Payment account name</ram:AccountName>
|
||||||
<udt:DateTimeString format="102">20181130</udt:DateTimeString>
|
</ram:PayeePartyCreditorFinancialAccount>
|
||||||
</ram:DueDateDateTime>
|
<!-- <ram:BICID>BSCTCH22</ram:BICID> -->
|
||||||
<ram:DirectDebitMandateID>Mandate reference identifier</ram:DirectDebitMandateID>
|
<!-- <ram:PayerSpecifiedDebtorFinancialInstitution>
|
||||||
</ram:SpecifiedTradePaymentTerms>
|
</ram:PayerSpecifiedDebtorFinancialInstitution> -->
|
||||||
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
<!-- <ram:PayeePartyCreditorFinancialAccount>
|
||||||
<ram:LineTotalAmount>2000.00</ram:LineTotalAmount>
|
<ram:IBANID>IT1212341234123413</ram:IBANID>
|
||||||
<ram:ChargeTotalAmount>10.00</ram:ChargeTotalAmount>
|
<ram:AccountName>Payment account name 2</ram:AccountName>
|
||||||
<ram:AllowanceTotalAmount>10.00</ram:AllowanceTotalAmount>
|
</ram:PayeePartyCreditorFinancialAccount>
|
||||||
<ram:TaxBasisTotalAmount>2000.00</ram:TaxBasisTotalAmount>
|
<ram:PayerSpecifiedDebtorFinancialInstitution>
|
||||||
<ram:TaxTotalAmount currencyID="EUR">50.00</ram:TaxTotalAmount>
|
<ram:BICID>BSCTCH22</ram:BICID>
|
||||||
<ram:TaxTotalAmount currencyID="NOK">46.00</ram:TaxTotalAmount>
|
</ram:PayerSpecifiedDebtorFinancialInstitution> -->
|
||||||
<ram:RoundingAmount>0.00</ram:RoundingAmount>
|
</ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
<ram:GrandTotalAmount>2050.00</ram:GrandTotalAmount>
|
<ram:ApplicableTradeTax>
|
||||||
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
|
<ram:CalculatedAmount>5.00</ram:CalculatedAmount>
|
||||||
<ram:DuePayableAmount>2050.00</ram:DuePayableAmount>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
<ram:BasisAmount>100.00</ram:BasisAmount>
|
||||||
<ram:InvoiceReferencedDocument>
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
<ram:IssuerAssignedID>abc123</ram:IssuerAssignedID>
|
<!-- <ram:DueDateTypeCode>29</ram:DueDateTypeCode> -->
|
||||||
<ram:FormattedIssueDateTime>
|
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
||||||
<qdt:DateTimeString format="102">20181004</qdt:DateTimeString>
|
</ram:ApplicableTradeTax>
|
||||||
</ram:FormattedIssueDateTime>
|
<ram:ApplicableTradeTax>
|
||||||
</ram:InvoiceReferencedDocument>
|
<ram:CalculatedAmount>0.00</ram:CalculatedAmount>
|
||||||
<ram:ReceivableSpecifiedTradeAccountingAccount>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
<ram:ID>uvz</ram:ID>
|
<ram:ExemptionReason>Exemtion reason text</ram:ExemptionReason>
|
||||||
</ram:ReceivableSpecifiedTradeAccountingAccount>
|
<ram:BasisAmount>100.00</ram:BasisAmount>
|
||||||
</ram:ApplicableHeaderTradeSettlement>
|
<ram:CategoryCode>E</ram:CategoryCode>
|
||||||
</rsm:SupplyChainTradeTransaction>
|
<ram:ExemptionReasonCode>VATEX-EU-O</ram:ExemptionReasonCode>
|
||||||
|
<ram:DueDateTypeCode>29</ram:DueDateTypeCode>
|
||||||
|
<ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
|
||||||
|
</ram:ApplicableTradeTax>
|
||||||
|
<ram:BillingSpecifiedPeriod>
|
||||||
|
<ram:StartDateTime>
|
||||||
|
<udt:DateTimeString format="102">20181112</udt:DateTimeString>
|
||||||
|
</ram:StartDateTime>
|
||||||
|
<ram:EndDateTime>
|
||||||
|
<udt:DateTimeString format="102">20181130</udt:DateTimeString>
|
||||||
|
</ram:EndDateTime>
|
||||||
|
</ram:BillingSpecifiedPeriod>
|
||||||
|
<ram:SpecifiedTradeAllowanceCharge>
|
||||||
|
<ram:ChargeIndicator>
|
||||||
|
<udt:Indicator>false</udt:Indicator>
|
||||||
|
</ram:ChargeIndicator>
|
||||||
|
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
||||||
|
<ram:BasisAmount>100.00</ram:BasisAmount>
|
||||||
|
<ram:ActualAmount>10.00</ram:ActualAmount>
|
||||||
|
<ram:ReasonCode>95</ram:ReasonCode>
|
||||||
|
<ram:Reason>Doc allowance reason text</ram:Reason>
|
||||||
|
<ram:CategoryTradeTax>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
||||||
|
</ram:CategoryTradeTax>
|
||||||
|
</ram:SpecifiedTradeAllowanceCharge>
|
||||||
|
<ram:SpecifiedTradeAllowanceCharge>
|
||||||
|
<ram:ChargeIndicator>
|
||||||
|
<udt:Indicator>true</udt:Indicator>
|
||||||
|
</ram:ChargeIndicator>
|
||||||
|
<ram:CalculationPercent>1.00</ram:CalculationPercent>
|
||||||
|
<ram:BasisAmount>100.00</ram:BasisAmount>
|
||||||
|
<ram:ActualAmount>10.00</ram:ActualAmount>
|
||||||
|
<ram:ReasonCode>AAA</ram:ReasonCode>
|
||||||
|
<ram:Reason>Doc charge reason text</ram:Reason>
|
||||||
|
<ram:CategoryTradeTax>
|
||||||
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
|
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
|
||||||
|
</ram:CategoryTradeTax>
|
||||||
|
</ram:SpecifiedTradeAllowanceCharge>
|
||||||
|
<ram:SpecifiedTradePaymentTerms>
|
||||||
|
<ram:Description>total amount</ram:Description>
|
||||||
|
<ram:DueDateDateTime>
|
||||||
|
<udt:DateTimeString format="102">20181130</udt:DateTimeString>
|
||||||
|
</ram:DueDateDateTime>
|
||||||
|
<ram:DirectDebitMandateID>Mandate reference identifier</ram:DirectDebitMandateID>
|
||||||
|
</ram:SpecifiedTradePaymentTerms>
|
||||||
|
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
<ram:LineTotalAmount>200.00</ram:LineTotalAmount>
|
||||||
|
<ram:ChargeTotalAmount>10.00</ram:ChargeTotalAmount>
|
||||||
|
<ram:AllowanceTotalAmount>10.00</ram:AllowanceTotalAmount>
|
||||||
|
<ram:TaxBasisTotalAmount>200.00</ram:TaxBasisTotalAmount>
|
||||||
|
<ram:TaxTotalAmount currencyID="EUR">5.00</ram:TaxTotalAmount>
|
||||||
|
<ram:TaxTotalAmount currencyID="NOK">4.60</ram:TaxTotalAmount>
|
||||||
|
<ram:RoundingAmount>0.00</ram:RoundingAmount>
|
||||||
|
<ram:GrandTotalAmount>205.00</ram:GrandTotalAmount>
|
||||||
|
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
|
||||||
|
<ram:DuePayableAmount>205.00</ram:DuePayableAmount>
|
||||||
|
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
|
<ram:InvoiceReferencedDocument>
|
||||||
|
<ram:IssuerAssignedID>abc123</ram:IssuerAssignedID>
|
||||||
|
<ram:FormattedIssueDateTime>
|
||||||
|
<qdt:DateTimeString format="102">20181004</qdt:DateTimeString>
|
||||||
|
</ram:FormattedIssueDateTime>
|
||||||
|
</ram:InvoiceReferencedDocument>
|
||||||
|
<ram:ReceivableSpecifiedTradeAccountingAccount>
|
||||||
|
<ram:ID>uvz</ram:ID>
|
||||||
|
</ram:ReceivableSpecifiedTradeAccountingAccount>
|
||||||
|
</ram:ApplicableHeaderTradeSettlement>
|
||||||
|
</rsm:SupplyChainTradeTransaction>
|
||||||
</rsm:CrossIndustryInvoice>
|
</rsm:CrossIndustryInvoice>
|
||||||
|
|||||||
@@ -1,404 +1,365 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2" xmlns:udt="urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2">
|
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||||
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
|
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
|
||||||
<cbc:ProfileID>BT-23 Business Process Type</cbc:ProfileID>
|
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
|
||||||
<cbc:ID>Test_EeISI_100</cbc:ID>
|
<cbc:ID>Test_EeISI_100</cbc:ID>
|
||||||
<cbc:IssueDate>2018-11-12</cbc:IssueDate>
|
<cbc:IssueDate>2018-11-12</cbc:IssueDate>
|
||||||
<cbc:DueDate>2018-11-30</cbc:DueDate>
|
<cbc:DueDate>2018-11-30</cbc:DueDate>
|
||||||
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
|
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
|
||||||
<cbc:Note>##AAA##invoice note text</cbc:Note>
|
<cbc:Note>#AAA#invoice note text</cbc:Note>
|
||||||
<cbc:Note>##AAA##invoice note text 2</cbc:Note>
|
<cbc:Note>#AAA#invoice note text 2</cbc:Note>
|
||||||
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
|
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
|
||||||
<cbc:TaxCurrencyCode>NOK</cbc:TaxCurrencyCode>
|
<cbc:TaxCurrencyCode>NOK</cbc:TaxCurrencyCode>
|
||||||
<cbc:AccountingCost>uvz</cbc:AccountingCost>
|
<cbc:AccountingCost>uvz</cbc:AccountingCost>
|
||||||
<cbc:BuyerReference>123</cbc:BuyerReference>
|
<cbc:BuyerReference>123</cbc:BuyerReference>
|
||||||
<cac:InvoicePeriod>
|
<cac:InvoicePeriod>
|
||||||
<cbc:StartDate>2018-11-12</cbc:StartDate>
|
<cbc:StartDate>2018-11-12</cbc:StartDate>
|
||||||
<cbc:EndDate>2018-11-30</cbc:EndDate>
|
<cbc:EndDate>2018-11-30</cbc:EndDate>
|
||||||
<cbc:DescriptionCode>35</cbc:DescriptionCode>
|
</cac:InvoicePeriod>
|
||||||
</cac:InvoicePeriod>
|
<cac:OrderReference>
|
||||||
<cac:OrderReference>
|
<cbc:ID>abc</cbc:ID>
|
||||||
<cbc:ID>abc</cbc:ID>
|
<cbc:SalesOrderID>def</cbc:SalesOrderID>
|
||||||
<cbc:SalesOrderID>def</cbc:SalesOrderID>
|
</cac:OrderReference>
|
||||||
</cac:OrderReference>
|
<cac:BillingReference>
|
||||||
<cac:BillingReference>
|
<cac:InvoiceDocumentReference>
|
||||||
<cac:InvoiceDocumentReference>
|
<cbc:ID>abc123</cbc:ID>
|
||||||
<cbc:ID>abc123</cbc:ID>
|
<cbc:IssueDate>2018-10-04</cbc:IssueDate>
|
||||||
<cbc:IssueDate>2018-10-04</cbc:IssueDate>
|
</cac:InvoiceDocumentReference>
|
||||||
</cac:InvoiceDocumentReference>
|
</cac:BillingReference>
|
||||||
</cac:BillingReference>
|
<cac:DespatchDocumentReference>
|
||||||
<cac:DespatchDocumentReference>
|
<cbc:ID>lmn</cbc:ID>
|
||||||
<cbc:ID>lmn</cbc:ID>
|
</cac:DespatchDocumentReference>
|
||||||
</cac:DespatchDocumentReference>
|
<cac:ReceiptDocumentReference>
|
||||||
<cac:ReceiptDocumentReference>
|
<cbc:ID>ghi</cbc:ID>
|
||||||
<cbc:ID>ghi</cbc:ID>
|
</cac:ReceiptDocumentReference>
|
||||||
</cac:ReceiptDocumentReference>
|
<cac:ContractDocumentReference>
|
||||||
<cac:OriginatorDocumentReference>
|
<cbc:ID>789</cbc:ID>
|
||||||
<cbc:ID>opq</cbc:ID>
|
</cac:ContractDocumentReference>
|
||||||
</cac:OriginatorDocumentReference>
|
<cac:AdditionalDocumentReference>
|
||||||
<cac:ContractDocumentReference>
|
<cbc:ID>Supporting document ref</cbc:ID>
|
||||||
<cbc:ID>789</cbc:ID>
|
<cbc:DocumentDescription>Supporting document descr</cbc:DocumentDescription>
|
||||||
</cac:ContractDocumentReference>
|
<cac:Attachment>
|
||||||
<cac:AdditionalDocumentReference>
|
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</cbc:EmbeddedDocumentBinaryObject>
|
||||||
<cbc:ID schemeID="0090">rst</cbc:ID>
|
<cac:ExternalReference>
|
||||||
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
|
<cbc:URI>External document location</cbc:URI>
|
||||||
</cac:AdditionalDocumentReference>
|
</cac:ExternalReference>
|
||||||
<cac:AdditionalDocumentReference>
|
</cac:Attachment>
|
||||||
<cbc:ID>Supporting document ref</cbc:ID>
|
</cac:AdditionalDocumentReference>
|
||||||
<cbc:DocumentDescription>Supporting document descr</cbc:DocumentDescription>
|
<cac:AdditionalDocumentReference>
|
||||||
<cac:Attachment>
|
<cbc:ID schemeID="AAA">rst</cbc:ID>
|
||||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</cbc:EmbeddedDocumentBinaryObject>
|
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
|
||||||
<cac:ExternalReference>
|
</cac:AdditionalDocumentReference>
|
||||||
<cbc:URI>External document location</cbc:URI>
|
<cac:ProjectReference>
|
||||||
</cac:ExternalReference>
|
<cbc:ID>456</cbc:ID>
|
||||||
</cac:Attachment>
|
</cac:ProjectReference>
|
||||||
</cac:AdditionalDocumentReference>
|
<cac:AccountingSupplierParty>
|
||||||
<cac:ProjectReference>
|
<cac:Party>
|
||||||
<cbc:ID>456</cbc:ID>
|
<cbc:EndpointID schemeID="EM">Seller electronic address</cbc:EndpointID>
|
||||||
</cac:ProjectReference>
|
<cac:PartyIdentification>
|
||||||
<cac:AccountingSupplierParty>
|
<cbc:ID schemeID="0100">Seller identifier 1</cbc:ID>
|
||||||
<cac:Party>
|
</cac:PartyIdentification>
|
||||||
<cbc:EndpointID schemeID="SMTP">Seller electronic address</cbc:EndpointID>
|
<cac:PartyIdentification>
|
||||||
|
<cbc:ID schemeID="0110">Seller identifier 2</cbc:ID>
|
||||||
|
</cac:PartyIdentification>
|
||||||
|
<cac:PartyName>
|
||||||
|
<cbc:Name>Seller trading name</cbc:Name>
|
||||||
|
</cac:PartyName>
|
||||||
|
<cac:PostalAddress>
|
||||||
|
<cbc:StreetName>Seller address line 1</cbc:StreetName>
|
||||||
|
<cbc:AdditionalStreetName>Seller address line 2</cbc:AdditionalStreetName>
|
||||||
|
<cbc:CityName>Seller city</cbc:CityName>
|
||||||
|
<cbc:PostalZone>12345</cbc:PostalZone>
|
||||||
|
<cbc:CountrySubentity>Seller country subdivision</cbc:CountrySubentity>
|
||||||
|
<cac:AddressLine>
|
||||||
|
<cbc:Line>Seller address line 3</cbc:Line>
|
||||||
|
</cac:AddressLine>
|
||||||
|
<cac:Country>
|
||||||
|
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
|
||||||
|
</cac:Country>
|
||||||
|
</cac:PostalAddress>
|
||||||
|
<cac:PartyTaxScheme>
|
||||||
|
<cbc:CompanyID>DE12345677</cbc:CompanyID>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:PartyTaxScheme>
|
||||||
|
<cac:PartyTaxScheme>
|
||||||
|
<cbc:CompanyID>DE49294093</cbc:CompanyID>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>FC</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:PartyTaxScheme>
|
||||||
|
<cac:PartyLegalEntity>
|
||||||
|
<cbc:RegistrationName>Seller name</cbc:RegistrationName>
|
||||||
|
<cbc:CompanyLegalForm>Seller additional legal information</cbc:CompanyLegalForm>
|
||||||
|
</cac:PartyLegalEntity>
|
||||||
|
<cac:Contact>
|
||||||
|
<cbc:Name>Seller contact point</cbc:Name>
|
||||||
|
<cbc:Telephone>+41 345 654455</cbc:Telephone>
|
||||||
|
<cbc:ElectronicMail>seller@contact.de</cbc:ElectronicMail>
|
||||||
|
</cac:Contact>
|
||||||
|
</cac:Party>
|
||||||
|
</cac:AccountingSupplierParty>
|
||||||
|
<cac:AccountingCustomerParty>
|
||||||
|
<cac:Party>
|
||||||
|
<cbc:EndpointID schemeID="EM">Buyer electronic address</cbc:EndpointID>
|
||||||
|
<cac:PartyIdentification>
|
||||||
|
<cbc:ID schemeID="0190">Buyer identifier</cbc:ID>
|
||||||
|
</cac:PartyIdentification>
|
||||||
|
<cac:PartyName>
|
||||||
|
<cbc:Name>Buyer trading name</cbc:Name>
|
||||||
|
</cac:PartyName>
|
||||||
|
<cac:PostalAddress>
|
||||||
|
<cbc:StreetName>Buyer address line 1</cbc:StreetName>
|
||||||
|
<cbc:AdditionalStreetName>Buyer address line 2</cbc:AdditionalStreetName>
|
||||||
|
<cbc:CityName>Buyer city</cbc:CityName>
|
||||||
|
<cbc:PostalZone>34562</cbc:PostalZone>
|
||||||
|
<cbc:CountrySubentity>Buyer country subdivision</cbc:CountrySubentity>
|
||||||
|
<cac:AddressLine>
|
||||||
|
<cbc:Line>Buyer address line 3</cbc:Line>
|
||||||
|
</cac:AddressLine>
|
||||||
|
<cac:Country>
|
||||||
|
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
|
||||||
|
</cac:Country>
|
||||||
|
</cac:PostalAddress>
|
||||||
|
<cac:PartyTaxScheme>
|
||||||
|
<cbc:CompanyID>IE394838894</cbc:CompanyID>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:PartyTaxScheme>
|
||||||
|
<cac:PartyLegalEntity>
|
||||||
|
<cbc:RegistrationName>Buyer name</cbc:RegistrationName>
|
||||||
|
<cbc:CompanyID schemeID="0089">Buyer legal registration identifier</cbc:CompanyID>
|
||||||
|
</cac:PartyLegalEntity>
|
||||||
|
<cac:Contact>
|
||||||
|
<cbc:Name>Buyer contact point</cbc:Name>
|
||||||
|
<cbc:Telephone>+353 2948584</cbc:Telephone>
|
||||||
|
<cbc:ElectronicMail>buyer@contact.ie</cbc:ElectronicMail>
|
||||||
|
</cac:Contact>
|
||||||
|
</cac:Party>
|
||||||
|
</cac:AccountingCustomerParty>
|
||||||
|
<cac:PayeeParty>
|
||||||
<cac:PartyIdentification>
|
<cac:PartyIdentification>
|
||||||
<cbc:ID schemeID="0100">Seller identifier 1</cbc:ID>
|
<cbc:ID schemeID="0098">Payee identifier</cbc:ID>
|
||||||
</cac:PartyIdentification>
|
|
||||||
<cac:PartyIdentification>
|
|
||||||
<cbc:ID schemeID="0110">Seller identifier 2</cbc:ID>
|
|
||||||
</cac:PartyIdentification>
|
|
||||||
<cac:PartyIdentification>
|
|
||||||
<cbc:ID schemeID="SEPA">Bank assigned creditor identifier</cbc:ID>
|
|
||||||
</cac:PartyIdentification>
|
</cac:PartyIdentification>
|
||||||
<cac:PartyName>
|
<cac:PartyName>
|
||||||
<cbc:Name>Seller trading name</cbc:Name>
|
<cbc:Name>Payee name</cbc:Name>
|
||||||
|
</cac:PartyName>
|
||||||
|
</cac:PayeeParty>
|
||||||
|
<cac:TaxRepresentativeParty>
|
||||||
|
<cac:PartyName>
|
||||||
|
<cbc:Name>Tax representative name</cbc:Name>
|
||||||
</cac:PartyName>
|
</cac:PartyName>
|
||||||
<cac:PostalAddress>
|
<cac:PostalAddress>
|
||||||
<cbc:StreetName>Seller address line 1</cbc:StreetName>
|
<cbc:StreetName>Tax representative address line 1</cbc:StreetName>
|
||||||
<cbc:AdditionalStreetName>Seller address line 2</cbc:AdditionalStreetName>
|
<cbc:AdditionalStreetName>Tax representative address line 2</cbc:AdditionalStreetName>
|
||||||
<cbc:CityName>Seller city</cbc:CityName>
|
<cbc:CityName>Tax representative city</cbc:CityName>
|
||||||
<cbc:PostalZone>12345</cbc:PostalZone>
|
<cbc:PostalZone>23455</cbc:PostalZone>
|
||||||
<cbc:CountrySubentity>Seller country subdivision</cbc:CountrySubentity>
|
<cbc:CountrySubentity>Tax representative country subdivision</cbc:CountrySubentity>
|
||||||
<cac:AddressLine>
|
<cac:AddressLine>
|
||||||
<cbc:Line>Seller address line 3</cbc:Line>
|
<cbc:Line>Tax representative address line 3</cbc:Line>
|
||||||
</cac:AddressLine>
|
</cac:AddressLine>
|
||||||
<cac:Country>
|
<cac:Country>
|
||||||
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
|
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
|
||||||
</cac:Country>
|
</cac:Country>
|
||||||
</cac:PostalAddress>
|
</cac:PostalAddress>
|
||||||
<cac:PartyTaxScheme>
|
<cac:PartyTaxScheme>
|
||||||
<cbc:CompanyID>DE12345677</cbc:CompanyID>
|
<cbc:CompanyID>DE3949053</cbc:CompanyID>
|
||||||
<cac:TaxScheme>
|
<cac:TaxScheme>
|
||||||
<cbc:ID>VAT</cbc:ID>
|
<cbc:ID>VAT</cbc:ID>
|
||||||
</cac:TaxScheme>
|
</cac:TaxScheme>
|
||||||
</cac:PartyTaxScheme>
|
</cac:PartyTaxScheme>
|
||||||
<cac:PartyTaxScheme>
|
</cac:TaxRepresentativeParty>
|
||||||
<cbc:CompanyID>DE49294093</cbc:CompanyID>
|
<cac:Delivery>
|
||||||
<cac:TaxScheme>
|
<cbc:ActualDeliveryDate>2018-12-04</cbc:ActualDeliveryDate>
|
||||||
<cbc:ID>NOVAT</cbc:ID>
|
<cac:DeliveryLocation>
|
||||||
</cac:TaxScheme>
|
<cbc:ID schemeID="0045">deliver location identifier</cbc:ID>
|
||||||
</cac:PartyTaxScheme>
|
<cac:Address>
|
||||||
<cac:PartyLegalEntity>
|
<cbc:StreetName>Deliver to address line 1</cbc:StreetName>
|
||||||
<cbc:RegistrationName>Seller name</cbc:RegistrationName>
|
<cbc:AdditionalStreetName>Deliver to address line 2</cbc:AdditionalStreetName>
|
||||||
<cbc:CompanyID schemeID="0310">Seller legal identifier</cbc:CompanyID>
|
<cbc:CityName>Deliver to city</cbc:CityName>
|
||||||
<cbc:CompanyLegalForm>Seller additional legal information</cbc:CompanyLegalForm>
|
<cbc:PostalZone>98765</cbc:PostalZone>
|
||||||
</cac:PartyLegalEntity>
|
<cbc:CountrySubentity>Deliver to country subdivision</cbc:CountrySubentity>
|
||||||
<cac:Contact>
|
<cac:AddressLine>
|
||||||
<cbc:Name>Seller contact point</cbc:Name>
|
<cbc:Line>Deliver to address line 3</cbc:Line>
|
||||||
<cbc:Telephone>+41 345 654455</cbc:Telephone>
|
</cac:AddressLine>
|
||||||
<cbc:ElectronicMail>seller@contact.de</cbc:ElectronicMail>
|
<cac:Country>
|
||||||
</cac:Contact>
|
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
|
||||||
</cac:Party>
|
</cac:Country>
|
||||||
</cac:AccountingSupplierParty>
|
</cac:Address>
|
||||||
<cac:AccountingCustomerParty>
|
</cac:DeliveryLocation>
|
||||||
<cac:Party>
|
<cac:DeliveryParty>
|
||||||
<cbc:EndpointID schemeID="DE:SMTP">Buyer electronic address</cbc:EndpointID>
|
<cac:PartyName>
|
||||||
<cac:PartyIdentification>
|
<cbc:Name>Deliver to party name</cbc:Name>
|
||||||
<cbc:ID>0190:Buyer identifier</cbc:ID>
|
</cac:PartyName>
|
||||||
</cac:PartyIdentification>
|
</cac:DeliveryParty>
|
||||||
<cac:PartyName>
|
</cac:Delivery>
|
||||||
<cbc:Name>Buyer trading name</cbc:Name>
|
<cac:PaymentTerms>
|
||||||
</cac:PartyName>
|
<cbc:Note>total amount</cbc:Note>
|
||||||
<cac:PostalAddress>
|
</cac:PaymentTerms>
|
||||||
<cbc:StreetName>Buyer address line 1</cbc:StreetName>
|
|
||||||
<cbc:AdditionalStreetName>Buyer address line 2</cbc:AdditionalStreetName>
|
|
||||||
<cbc:CityName>Buyer city</cbc:CityName>
|
|
||||||
<cbc:PostalZone>34562</cbc:PostalZone>
|
|
||||||
<cbc:CountrySubentity>Buyer country subdivision</cbc:CountrySubentity>
|
|
||||||
<cac:AddressLine>
|
|
||||||
<cbc:Line>Buyer address line 3</cbc:Line>
|
|
||||||
</cac:AddressLine>
|
|
||||||
<cac:Country>
|
|
||||||
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
|
|
||||||
</cac:Country>
|
|
||||||
</cac:PostalAddress>
|
|
||||||
<cac:PartyTaxScheme>
|
|
||||||
<cbc:CompanyID>IE394838894</cbc:CompanyID>
|
|
||||||
<cac:TaxScheme>
|
|
||||||
<cbc:ID>VAT</cbc:ID>
|
|
||||||
</cac:TaxScheme>
|
|
||||||
</cac:PartyTaxScheme>
|
|
||||||
<cac:PartyLegalEntity>
|
|
||||||
<cbc:RegistrationName>Buyer name</cbc:RegistrationName>
|
|
||||||
<cbc:CompanyID>Buyer legal registration identifier</cbc:CompanyID>
|
|
||||||
</cac:PartyLegalEntity>
|
|
||||||
<cac:Contact>
|
|
||||||
<cbc:Name>Buyer contact point</cbc:Name>
|
|
||||||
<cbc:Telephone>+353 2948584</cbc:Telephone>
|
|
||||||
<cbc:ElectronicMail>buyer@contact.ie</cbc:ElectronicMail>
|
|
||||||
</cac:Contact>
|
|
||||||
</cac:Party>
|
|
||||||
</cac:AccountingCustomerParty>
|
|
||||||
<cac:PayeeParty>
|
|
||||||
<cac:PartyIdentification>
|
|
||||||
<cbc:ID schemeID="0098">Payee identifier</cbc:ID>
|
|
||||||
</cac:PartyIdentification>
|
|
||||||
<cac:PartyName>
|
|
||||||
<cbc:Name>Payee name</cbc:Name>
|
|
||||||
</cac:PartyName>
|
|
||||||
<cac:PartyLegalEntity>
|
|
||||||
<cbc:CompanyID schemeID="0099">Payee legal registration identifier</cbc:CompanyID>
|
|
||||||
</cac:PartyLegalEntity>
|
|
||||||
</cac:PayeeParty>
|
|
||||||
<cac:TaxRepresentativeParty>
|
|
||||||
<cac:PartyName>
|
|
||||||
<cbc:Name>Tax representative name</cbc:Name>
|
|
||||||
</cac:PartyName>
|
|
||||||
<cac:PostalAddress>
|
|
||||||
<cbc:StreetName>Tax representative address line 1</cbc:StreetName>
|
|
||||||
<cbc:AdditionalStreetName>Tax representative address line 2</cbc:AdditionalStreetName>
|
|
||||||
<cbc:CityName>Tax representative city</cbc:CityName>
|
|
||||||
<cbc:PostalZone>23455</cbc:PostalZone>
|
|
||||||
<cbc:CountrySubentity>Tax representative country subdivision</cbc:CountrySubentity>
|
|
||||||
<cac:AddressLine>
|
|
||||||
<cbc:Line>Tax representative address line 3</cbc:Line>
|
|
||||||
</cac:AddressLine>
|
|
||||||
<cac:Country>
|
|
||||||
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
|
|
||||||
</cac:Country>
|
|
||||||
</cac:PostalAddress>
|
|
||||||
<cac:PartyTaxScheme>
|
|
||||||
<cbc:CompanyID>DE3949053</cbc:CompanyID>
|
|
||||||
<cac:TaxScheme>
|
|
||||||
<cbc:ID>VAT</cbc:ID>
|
|
||||||
</cac:TaxScheme>
|
|
||||||
</cac:PartyTaxScheme>
|
|
||||||
</cac:TaxRepresentativeParty>
|
|
||||||
<cac:Delivery>
|
|
||||||
<cbc:ActualDeliveryDate>2018-12-04</cbc:ActualDeliveryDate>
|
|
||||||
<cac:DeliveryLocation>
|
|
||||||
<cbc:ID schemeID="0045">deliver location identifier</cbc:ID>
|
|
||||||
<cac:Address>
|
|
||||||
<cbc:StreetName>Deliver to address line 1</cbc:StreetName>
|
|
||||||
<cbc:AdditionalStreetName>Deliver to address line 2</cbc:AdditionalStreetName>
|
|
||||||
<cbc:CityName>Deliver to city</cbc:CityName>
|
|
||||||
<cbc:PostalZone>98765</cbc:PostalZone>
|
|
||||||
<cbc:CountrySubentity>Deliver to country subdivision</cbc:CountrySubentity>
|
|
||||||
<cac:AddressLine>
|
|
||||||
<cbc:Line>Deliver to address line 3</cbc:Line>
|
|
||||||
</cac:AddressLine>
|
|
||||||
<cac:Country>
|
|
||||||
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
|
|
||||||
</cac:Country>
|
|
||||||
</cac:Address>
|
|
||||||
</cac:DeliveryLocation>
|
|
||||||
<cac:DeliveryParty>
|
|
||||||
<cac:PartyName>
|
|
||||||
<cbc:Name>Deliver to party name</cbc:Name>
|
|
||||||
</cac:PartyName>
|
|
||||||
</cac:DeliveryParty>
|
|
||||||
</cac:Delivery>
|
|
||||||
<cac:PaymentMeans>
|
|
||||||
<cbc:PaymentMeansCode name="SEPA">4</cbc:PaymentMeansCode>
|
|
||||||
<cbc:PaymentID>Remittance information</cbc:PaymentID>
|
|
||||||
<cac:CardAccount>
|
|
||||||
<cbc:PrimaryAccountNumberID>1234</cbc:PrimaryAccountNumberID>
|
|
||||||
<cbc:NetworkID>mandatory network id</cbc:NetworkID>
|
|
||||||
<cbc:HolderName>Payment card holder name</cbc:HolderName>
|
|
||||||
</cac:CardAccount>
|
|
||||||
<cac:PayeeFinancialAccount>
|
|
||||||
<cbc:ID>IT1212341234123412</cbc:ID>
|
|
||||||
<cbc:Name>Payment account name</cbc:Name>
|
|
||||||
<cac:FinancialInstitutionBranch>
|
|
||||||
<cbc:ID>BSCTCH22</cbc:ID>
|
|
||||||
</cac:FinancialInstitutionBranch>
|
|
||||||
</cac:PayeeFinancialAccount>
|
|
||||||
<cac:PayeeFinancialAccount>
|
|
||||||
<cbc:ID>IT1212341234123413</cbc:ID>
|
|
||||||
<cbc:Name>Payment account name 2</cbc:Name>
|
|
||||||
<cac:FinancialInstitutionBranch>
|
|
||||||
<cbc:ID>BSCTCH22</cbc:ID>
|
|
||||||
</cac:FinancialInstitutionBranch>
|
|
||||||
</cac:PayeeFinancialAccount>
|
|
||||||
<cac:PaymentMandate>
|
|
||||||
<cbc:ID>Mandate reference identifier</cbc:ID>
|
|
||||||
<cac:PayerFinancialAccount>
|
|
||||||
<cbc:ID>Debited account identifier</cbc:ID>
|
|
||||||
</cac:PayerFinancialAccount>
|
|
||||||
</cac:PaymentMandate>
|
|
||||||
</cac:PaymentMeans>
|
|
||||||
<cac:PaymentTerms>
|
|
||||||
<cbc:Note>total amount</cbc:Note>
|
|
||||||
</cac:PaymentTerms>
|
|
||||||
<cac:AllowanceCharge>
|
|
||||||
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
|
|
||||||
<cbc:AllowanceChargeReasonCode>55</cbc:AllowanceChargeReasonCode>
|
|
||||||
<cbc:AllowanceChargeReason>Doc allowance reason text</cbc:AllowanceChargeReason>
|
|
||||||
<cbc:MultiplierFactorNumeric>1.0000</cbc:MultiplierFactorNumeric>
|
|
||||||
<cbc:Amount currencyID="EUR">10.00</cbc:Amount>
|
|
||||||
<cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount>
|
|
||||||
<cac:TaxCategory>
|
|
||||||
<cbc:ID>S</cbc:ID>
|
|
||||||
<cbc:Percent>5.00</cbc:Percent>
|
|
||||||
<cac:TaxScheme>
|
|
||||||
<cbc:ID>VAT</cbc:ID>
|
|
||||||
</cac:TaxScheme>
|
|
||||||
</cac:TaxCategory>
|
|
||||||
</cac:AllowanceCharge>
|
|
||||||
<cac:AllowanceCharge>
|
|
||||||
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
|
|
||||||
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
|
|
||||||
<cbc:AllowanceChargeReason>Doc charge reason text</cbc:AllowanceChargeReason>
|
|
||||||
<cbc:MultiplierFactorNumeric>1.0000</cbc:MultiplierFactorNumeric>
|
|
||||||
<cbc:Amount currencyID="EUR">10.00</cbc:Amount>
|
|
||||||
<cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount>
|
|
||||||
<cac:TaxCategory>
|
|
||||||
<cbc:ID>S</cbc:ID>
|
|
||||||
<cbc:Percent>5.00</cbc:Percent>
|
|
||||||
<cac:TaxScheme>
|
|
||||||
<cbc:ID>VAT</cbc:ID>
|
|
||||||
</cac:TaxScheme>
|
|
||||||
</cac:TaxCategory>
|
|
||||||
</cac:AllowanceCharge>
|
|
||||||
<cac:TaxTotal>
|
|
||||||
<cbc:TaxAmount currencyID="NOK">46.00</cbc:TaxAmount>
|
|
||||||
</cac:TaxTotal>
|
|
||||||
<cac:TaxTotal>
|
|
||||||
<cbc:TaxAmount currencyID="EUR">50.00</cbc:TaxAmount>
|
|
||||||
<cac:TaxSubtotal>
|
|
||||||
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
|
|
||||||
<cbc:TaxAmount currencyID="EUR">50.00</cbc:TaxAmount>
|
|
||||||
<cac:TaxCategory>
|
|
||||||
<cbc:ID>S</cbc:ID>
|
|
||||||
<cbc:Percent>5.00</cbc:Percent>
|
|
||||||
<cac:TaxScheme>
|
|
||||||
<cbc:ID>VAT</cbc:ID>
|
|
||||||
</cac:TaxScheme>
|
|
||||||
</cac:TaxCategory>
|
|
||||||
</cac:TaxSubtotal>
|
|
||||||
<cac:TaxSubtotal>
|
|
||||||
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
|
|
||||||
<cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount>
|
|
||||||
<cac:TaxCategory>
|
|
||||||
<cbc:ID>E</cbc:ID>
|
|
||||||
<cbc:Percent>0.00</cbc:Percent>
|
|
||||||
<cbc:TaxExemptionReasonCode>Exemption reason code</cbc:TaxExemptionReasonCode>
|
|
||||||
<cbc:TaxExemptionReason>Exemtion reason text</cbc:TaxExemptionReason>
|
|
||||||
<cac:TaxScheme>
|
|
||||||
<cbc:ID>VAT</cbc:ID>
|
|
||||||
</cac:TaxScheme>
|
|
||||||
</cac:TaxCategory>
|
|
||||||
</cac:TaxSubtotal>
|
|
||||||
</cac:TaxTotal>
|
|
||||||
<cac:LegalMonetaryTotal>
|
|
||||||
<cbc:LineExtensionAmount currencyID="EUR">2000.00</cbc:LineExtensionAmount>
|
|
||||||
<cbc:TaxExclusiveAmount currencyID="EUR">2000.00</cbc:TaxExclusiveAmount>
|
|
||||||
<cbc:TaxInclusiveAmount currencyID="EUR">2050.00</cbc:TaxInclusiveAmount>
|
|
||||||
<cbc:AllowanceTotalAmount currencyID="EUR">10.00</cbc:AllowanceTotalAmount>
|
|
||||||
<cbc:ChargeTotalAmount currencyID="EUR">10.00</cbc:ChargeTotalAmount>
|
|
||||||
<cbc:PayableAmount currencyID="EUR">2050.00</cbc:PayableAmount>
|
|
||||||
</cac:LegalMonetaryTotal>
|
|
||||||
<cac:InvoiceLine>
|
|
||||||
<cbc:ID>1a</cbc:ID>
|
|
||||||
<cbc:Note>Invoice line note</cbc:Note>
|
|
||||||
<cbc:InvoicedQuantity unitCode="EA">10.00000000</cbc:InvoicedQuantity>
|
|
||||||
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
|
|
||||||
<cbc:AccountingCost>6789</cbc:AccountingCost>
|
|
||||||
<cac:InvoicePeriod>
|
|
||||||
<cbc:StartDate>2018-11-12</cbc:StartDate>
|
|
||||||
<cbc:EndDate>2018-11-30</cbc:EndDate>
|
|
||||||
</cac:InvoicePeriod>
|
|
||||||
<cac:OrderLineReference>
|
|
||||||
<cbc:LineID>12345</cbc:LineID>
|
|
||||||
</cac:OrderLineReference>
|
|
||||||
<cac:DocumentReference>
|
|
||||||
<cbc:ID schemeID="ZZZ">Line object identifier</cbc:ID>
|
|
||||||
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
|
|
||||||
</cac:DocumentReference>
|
|
||||||
<cac:AllowanceCharge>
|
<cac:AllowanceCharge>
|
||||||
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
|
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
|
||||||
<cbc:AllowanceChargeReasonCode>55</cbc:AllowanceChargeReasonCode>
|
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
|
||||||
<cbc:AllowanceChargeReason>Invoice line allowance reason</cbc:AllowanceChargeReason>
|
<cbc:AllowanceChargeReason>Doc allowance reason text</cbc:AllowanceChargeReason>
|
||||||
<cbc:MultiplierFactorNumeric>1</cbc:MultiplierFactorNumeric>
|
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
|
||||||
<cbc:Amount currencyID="EUR">10</cbc:Amount>
|
<cbc:Amount currencyID="EUR">10</cbc:Amount>
|
||||||
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
|
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
|
||||||
|
<cac:TaxCategory>
|
||||||
|
<cbc:ID>S</cbc:ID>
|
||||||
|
<cbc:Percent>5</cbc:Percent>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:TaxCategory>
|
||||||
</cac:AllowanceCharge>
|
</cac:AllowanceCharge>
|
||||||
<cac:AllowanceCharge>
|
<cac:AllowanceCharge>
|
||||||
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
|
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
|
||||||
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
|
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
|
||||||
<cbc:AllowanceChargeReason>Invoice line charge reason</cbc:AllowanceChargeReason>
|
<cbc:AllowanceChargeReason>Doc charge reason text</cbc:AllowanceChargeReason>
|
||||||
<cbc:MultiplierFactorNumeric>1</cbc:MultiplierFactorNumeric>
|
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
|
||||||
<cbc:Amount currencyID="EUR">10</cbc:Amount>
|
<cbc:Amount currencyID="EUR">10</cbc:Amount>
|
||||||
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
|
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
|
||||||
</cac:AllowanceCharge>
|
<cac:TaxCategory>
|
||||||
<cac:Item>
|
|
||||||
<cbc:Description>Item description</cbc:Description>
|
|
||||||
<cbc:Name>Item name</cbc:Name>
|
|
||||||
<cac:BuyersItemIdentification>
|
|
||||||
<cbc:ID>Item buyer's identifier</cbc:ID>
|
|
||||||
</cac:BuyersItemIdentification>
|
|
||||||
<cac:SellersItemIdentification>
|
|
||||||
<cbc:ID>Item seller's identifier</cbc:ID>
|
|
||||||
</cac:SellersItemIdentification>
|
|
||||||
<cac:StandardItemIdentification>
|
|
||||||
<cbc:ID>Item standar identifier</cbc:ID>
|
|
||||||
</cac:StandardItemIdentification>
|
|
||||||
<cac:OriginCountry>
|
|
||||||
<cbc:IdentificationCode>IT</cbc:IdentificationCode>
|
|
||||||
</cac:OriginCountry>
|
|
||||||
<cac:CommodityClassification>
|
|
||||||
<cbc:ItemClassificationCode listID="ZZZ" listVersionID="version0">Item classification identifier0</cbc:ItemClassificationCode>
|
|
||||||
</cac:CommodityClassification>
|
|
||||||
<cac:ClassifiedTaxCategory>
|
|
||||||
<cbc:ID>S</cbc:ID>
|
<cbc:ID>S</cbc:ID>
|
||||||
<cbc:Percent>5.00</cbc:Percent>
|
<cbc:Percent>5</cbc:Percent>
|
||||||
<cac:TaxScheme>
|
<cac:TaxScheme>
|
||||||
<cbc:ID>VAT</cbc:ID>
|
<cbc:ID>VAT</cbc:ID>
|
||||||
</cac:TaxScheme>
|
</cac:TaxScheme>
|
||||||
</cac:ClassifiedTaxCategory>
|
</cac:TaxCategory>
|
||||||
<cac:AdditionalItemProperty>
|
</cac:AllowanceCharge>
|
||||||
<cbc:Name>Color</cbc:Name>
|
<cac:TaxTotal>
|
||||||
<cbc:Value>Red</cbc:Value>
|
<cbc:TaxAmount currencyID="EUR">50</cbc:TaxAmount>
|
||||||
</cac:AdditionalItemProperty>
|
<cac:TaxSubtotal>
|
||||||
<cac:AdditionalItemProperty>
|
<cbc:TaxableAmount currencyID="EUR">1000</cbc:TaxableAmount>
|
||||||
<cbc:Name>Size</cbc:Name>
|
<cbc:TaxAmount currencyID="EUR">50</cbc:TaxAmount>
|
||||||
<cbc:Value>L</cbc:Value>
|
<cac:TaxCategory>
|
||||||
</cac:AdditionalItemProperty>
|
<cbc:ID>S</cbc:ID>
|
||||||
</cac:Item>
|
<cbc:Percent>5</cbc:Percent>
|
||||||
<cac:Price>
|
<cac:TaxScheme>
|
||||||
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
|
<cbc:ID>VAT</cbc:ID>
|
||||||
<cbc:BaseQuantity unitCode="EA">1.00</cbc:BaseQuantity>
|
</cac:TaxScheme>
|
||||||
|
</cac:TaxCategory>
|
||||||
|
</cac:TaxSubtotal>
|
||||||
|
<cac:TaxSubtotal>
|
||||||
|
<cbc:TaxableAmount currencyID="EUR">1000</cbc:TaxableAmount>
|
||||||
|
<cbc:TaxAmount currencyID="EUR">0</cbc:TaxAmount>
|
||||||
|
<cac:TaxCategory>
|
||||||
|
<cbc:ID>E</cbc:ID>
|
||||||
|
<cbc:Percent>0</cbc:Percent>
|
||||||
|
<cbc:TaxExemptionReasonCode>VATEX-EU-O</cbc:TaxExemptionReasonCode>
|
||||||
|
<cbc:TaxExemptionReason>Exemtion reason text</cbc:TaxExemptionReason>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:TaxCategory>
|
||||||
|
</cac:TaxSubtotal>
|
||||||
|
</cac:TaxTotal>
|
||||||
|
<cac:TaxTotal>
|
||||||
|
<cbc:TaxAmount currencyID="NOK">46</cbc:TaxAmount>
|
||||||
|
</cac:TaxTotal>
|
||||||
|
<cac:LegalMonetaryTotal>
|
||||||
|
<cbc:LineExtensionAmount currencyID="EUR">200</cbc:LineExtensionAmount>
|
||||||
|
<cbc:TaxExclusiveAmount currencyID="EUR">200</cbc:TaxExclusiveAmount>
|
||||||
|
<cbc:TaxInclusiveAmount currencyID="EUR">205</cbc:TaxInclusiveAmount>
|
||||||
|
<cbc:AllowanceTotalAmount currencyID="EUR">10</cbc:AllowanceTotalAmount>
|
||||||
|
<cbc:ChargeTotalAmount currencyID="EUR">10</cbc:ChargeTotalAmount>
|
||||||
|
<cbc:PrepaidAmount currencyID="EUR">0</cbc:PrepaidAmount>
|
||||||
|
<cbc:PayableAmount currencyID="EUR">205</cbc:PayableAmount>
|
||||||
|
</cac:LegalMonetaryTotal>
|
||||||
|
<cac:InvoiceLine>
|
||||||
|
<cbc:ID>1a</cbc:ID>
|
||||||
|
<cbc:Note>Invoice line note</cbc:Note>
|
||||||
|
<cbc:InvoicedQuantity unitCode="EA">10</cbc:InvoicedQuantity>
|
||||||
|
<cbc:LineExtensionAmount currencyID="EUR">1000</cbc:LineExtensionAmount>
|
||||||
|
<cbc:AccountingCost>6789</cbc:AccountingCost>
|
||||||
|
<cac:InvoicePeriod>
|
||||||
|
<cbc:StartDate>2018-11-12</cbc:StartDate>
|
||||||
|
<cbc:EndDate>2018-11-30</cbc:EndDate>
|
||||||
|
</cac:InvoicePeriod>
|
||||||
|
<cac:OrderLineReference>
|
||||||
|
<cbc:LineID>12345</cbc:LineID>
|
||||||
|
</cac:OrderLineReference>
|
||||||
|
<cac:DocumentReference>
|
||||||
|
<cbc:ID>Line object identifier</cbc:ID>
|
||||||
|
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
|
||||||
|
</cac:DocumentReference>
|
||||||
<cac:AllowanceCharge>
|
<cac:AllowanceCharge>
|
||||||
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
|
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
|
||||||
<cbc:Amount currencyID="EUR">1</cbc:Amount>
|
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
|
||||||
<cbc:BaseAmount currencyID="EUR">11</cbc:BaseAmount>
|
<cbc:AllowanceChargeReason>Invoice line allowance reason</cbc:AllowanceChargeReason>
|
||||||
|
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
|
||||||
|
<cbc:Amount currencyID="EUR">10</cbc:Amount>
|
||||||
|
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
|
||||||
</cac:AllowanceCharge>
|
</cac:AllowanceCharge>
|
||||||
</cac:Price>
|
<cac:AllowanceCharge>
|
||||||
</cac:InvoiceLine>
|
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
|
||||||
<cac:InvoiceLine>
|
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
|
||||||
<cbc:ID>1b</cbc:ID>
|
<cbc:AllowanceChargeReason>Invoice line charge reason</cbc:AllowanceChargeReason>
|
||||||
<cbc:InvoicedQuantity unitCode="EA">10.00000000</cbc:InvoicedQuantity>
|
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
|
||||||
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
|
<cbc:Amount currencyID="EUR">10</cbc:Amount>
|
||||||
<cac:Item>
|
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
|
||||||
<cbc:Name>Item name 2</cbc:Name>
|
</cac:AllowanceCharge>
|
||||||
<cac:ClassifiedTaxCategory>
|
<cac:Item>
|
||||||
<cbc:ID>E</cbc:ID>
|
<cbc:Description>Item description</cbc:Description>
|
||||||
<cbc:Percent>0.00</cbc:Percent>
|
<cbc:Name>Item name</cbc:Name>
|
||||||
<cac:TaxScheme>
|
<cac:BuyersItemIdentification>
|
||||||
<cbc:ID>VAT</cbc:ID>
|
<cbc:ID>Item buyer's identifier</cbc:ID>
|
||||||
</cac:TaxScheme>
|
</cac:BuyersItemIdentification>
|
||||||
</cac:ClassifiedTaxCategory>
|
<cac:SellersItemIdentification>
|
||||||
</cac:Item>
|
<cbc:ID>Item seller's identifier</cbc:ID>
|
||||||
<cac:Price>
|
</cac:SellersItemIdentification>
|
||||||
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
|
<cac:StandardItemIdentification>
|
||||||
</cac:Price>
|
<cbc:ID schemeID="0060">Item standar identifier</cbc:ID>
|
||||||
</cac:InvoiceLine>
|
</cac:StandardItemIdentification>
|
||||||
</Invoice>
|
<cac:OriginCountry>
|
||||||
|
<cbc:IdentificationCode>IT</cbc:IdentificationCode>
|
||||||
|
</cac:OriginCountry>
|
||||||
|
<cac:CommodityClassification>
|
||||||
|
<cbc:ItemClassificationCode listID="ZZZ" listVersionID="version0">Item classification identifier0</cbc:ItemClassificationCode>
|
||||||
|
</cac:CommodityClassification>
|
||||||
|
<cac:ClassifiedTaxCategory>
|
||||||
|
<cbc:ID>S</cbc:ID>
|
||||||
|
<cbc:Percent>5</cbc:Percent>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:ClassifiedTaxCategory>
|
||||||
|
<cac:AdditionalItemProperty>
|
||||||
|
<cbc:Name>Color</cbc:Name>
|
||||||
|
<cbc:Value>Red</cbc:Value>
|
||||||
|
</cac:AdditionalItemProperty>
|
||||||
|
<cac:AdditionalItemProperty>
|
||||||
|
<cbc:Name>Size</cbc:Name>
|
||||||
|
<cbc:Value>L</cbc:Value>
|
||||||
|
</cac:AdditionalItemProperty>
|
||||||
|
</cac:Item>
|
||||||
|
<cac:Price>
|
||||||
|
<cbc:PriceAmount currencyID="EUR">10</cbc:PriceAmount>
|
||||||
|
<cbc:BaseQuantity unitCode="EA">1</cbc:BaseQuantity>
|
||||||
|
<cac:AllowanceCharge>
|
||||||
|
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
|
||||||
|
<cbc:Amount currencyID="EUR">1</cbc:Amount>
|
||||||
|
<cbc:BaseAmount currencyID="EUR">11</cbc:BaseAmount>
|
||||||
|
</cac:AllowanceCharge>
|
||||||
|
</cac:Price>
|
||||||
|
</cac:InvoiceLine>
|
||||||
|
<cac:InvoiceLine>
|
||||||
|
<cbc:ID>1b</cbc:ID>
|
||||||
|
<cbc:InvoicedQuantity unitCode="EA">10</cbc:InvoicedQuantity>
|
||||||
|
<cbc:LineExtensionAmount currencyID="EUR">1000</cbc:LineExtensionAmount>
|
||||||
|
<cac:Item>
|
||||||
|
<cbc:Name>Item name 2</cbc:Name>
|
||||||
|
<cac:ClassifiedTaxCategory>
|
||||||
|
<cbc:ID>E</cbc:ID>
|
||||||
|
<cbc:Percent>0</cbc:Percent>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:ClassifiedTaxCategory>
|
||||||
|
</cac:Item>
|
||||||
|
<cac:Price>
|
||||||
|
<cbc:PriceAmount currencyID="EUR">10</cbc:PriceAmount>
|
||||||
|
</cac:Price>
|
||||||
|
</cac:InvoiceLine>
|
||||||
|
</Invoice>
|
||||||
|
|||||||
@@ -54,7 +54,6 @@
|
|||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>pdfbox</artifactId>
|
<artifactId>pdfbox</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.0.2</version>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.xml.bind</groupId>
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class PDFValidator extends Validator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(PDFValidator.class.getCanonicalName()); // log output
|
private static final Logger LOGGER = LoggerFactory.getLogger(PDFValidator.class.getCanonicalName()); // log output
|
||||||
private static final PDFAFlavour[] PDF_A_3_FLAVOURS = {PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_A};
|
private static final PDFAFlavour[] PDF_A_3_FLAVOURS = {PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_3_U};
|
||||||
|
|
||||||
private String pdfFilename;
|
private String pdfFilename;
|
||||||
|
|
||||||
@@ -239,7 +239,8 @@ public class PDFValidator extends Validator {
|
|||||||
|
|
||||||
boolean versionValid = false;
|
boolean versionValid = false;
|
||||||
for (int i = 0; i < nodes.getLength(); i++) {
|
for (int i = 0; i < nodes.getLength(); i++) {
|
||||||
final String[] valueArray = {"1.0", "2p0", "1.2", "2.0", "2.1"}; //1.2, 2.0 and 2.1 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1
|
final String[] valueArray = {"1.0", "2p0", "1.2", "2.0", "2.1", "2.2", "2.3", "3.0"}; //1.2, 2.0, 2.1, 2.2, 2.3 and 3.0 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1
|
||||||
|
|
||||||
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
|
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
|
||||||
versionValid = true;
|
versionValid = true;
|
||||||
} // e.g. 1.0
|
} // e.g. 1.0
|
||||||
@@ -263,6 +264,7 @@ public class PDFValidator extends Validator {
|
|||||||
final byte[] konikSignature = "Konik".getBytes(StandardCharsets.UTF_8);
|
final byte[] konikSignature = "Konik".getBytes(StandardCharsets.UTF_8);
|
||||||
final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8);
|
final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8);
|
||||||
final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8);
|
final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8);
|
||||||
|
final byte[] cibpdfbrewerSignature = "CIB pdf brewer".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
if (ByteArraySearcher.contains(fileContents, symtraxSignature)) {
|
if (ByteArraySearcher.contains(fileContents, symtraxSignature)) {
|
||||||
Signature = "Symtrax";
|
Signature = "Symtrax";
|
||||||
@@ -278,6 +280,8 @@ public class PDFValidator extends Validator {
|
|||||||
Signature = "pdfMachine";
|
Signature = "pdfMachine";
|
||||||
} else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) {
|
} else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) {
|
||||||
Signature = "Ghostscript";
|
Signature = "Ghostscript";
|
||||||
|
} else if (ByteArraySearcher.contains(fileContents, cibpdfbrewerSignature)) {
|
||||||
|
Signature = "CIB pdf brewer";
|
||||||
}
|
}
|
||||||
|
|
||||||
context.setSignature(Signature);
|
context.setSignature(Signature);
|
||||||
@@ -297,8 +301,10 @@ public class PDFValidator extends Validator {
|
|||||||
if (!processorResult.getValidationResult().isCompliant()) {
|
if (!processorResult.getValidationResult().isCompliant()) {
|
||||||
context.setInvalid();
|
context.setInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFAFlavour pdfaFlavourFromValidationResult = processorResult.getValidationResult().getPDFAFlavour();
|
||||||
if (Arrays.stream(PDF_A_3_FLAVOURS)
|
if (Arrays.stream(PDF_A_3_FLAVOURS)
|
||||||
.anyMatch(pdfaFlavour -> processorResult.getValidationResult().getPDFAFlavour().equals(pdfaFlavour))) {
|
.noneMatch(pdfaFlavourFromValidationResult::equals)) {
|
||||||
context.addResultItem(
|
context.addResultItem(
|
||||||
new ValidationResultItem(ESeverity.error, "Not a PDF/A-3").setSection(23).setPart(EPart.pdf));
|
new ValidationResultItem(ESeverity.error, "Not a PDF/A-3").setSection(23).setPart(EPart.pdf));
|
||||||
|
|
||||||
|
|||||||
@@ -269,14 +269,14 @@ public class XMLValidator extends Validator {
|
|||||||
// saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s
|
// saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s
|
||||||
// tcdl2.0.tsdtf.sch iso_svrl.xsl
|
// tcdl2.0.tsdtf.sch iso_svrl.xsl
|
||||||
|
|
||||||
} else if (root.getLocalName().equalsIgnoreCase("Invoice")) {
|
} else if (root.getLocalName().equalsIgnoreCase("Invoice") || root.getLocalName().equalsIgnoreCase("CreditNote") ) {
|
||||||
context.setGeneration("2");
|
context.setGeneration("2");
|
||||||
context.setFormat("UBL");
|
context.setFormat("UBL");
|
||||||
isXRechnung = context.getProfile().contains("xrechnung");
|
isXRechnung = context.getProfile().contains("xrechnung");
|
||||||
// UBL
|
// UBL
|
||||||
LOGGER.debug("UBL");
|
LOGGER.debug("UBL");
|
||||||
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-Invoice-2.1.xsd", 18, EPart.fx);
|
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-"+root.getLocalName()+"-2.1.xsd", 18, EPart.fx);
|
||||||
xsltFilename = "/xslt/UBL_21/EN16931-UBL-validation.xslt";
|
xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt";
|
||||||
|
|
||||||
mainSchematronSectionErrorTypeCode=24;
|
mainSchematronSectionErrorTypeCode=24;
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ public class XMLValidator extends Validator {
|
|||||||
if (context.getGeneration().equals("2")
|
if (context.getGeneration().equals("2")
|
||||||
&& (isBasic || isEN16931 || isXRechnung)) {
|
&& (isBasic || isEN16931 || isXRechnung)) {
|
||||||
//additionally validate against CEN
|
//additionally validate against CEN
|
||||||
validateSchematron(zfXML, "/xslt/cii16931schematron/EN16931-CII-validation.xslt", 24, ESeverity.error);
|
validateSchematron(zfXML, "/xslt/en16931schematron/EN16931-CII-validation.xslt", 24, ESeverity.error);
|
||||||
if (!disableNotices || XrechnungSeverity != ESeverity.notice) {
|
if (!disableNotices || XrechnungSeverity != ESeverity.notice) {
|
||||||
validateXR(zfXML, XrechnungSeverity);
|
validateXR(zfXML, XrechnungSeverity);
|
||||||
}
|
}
|
||||||
@@ -419,11 +419,16 @@ public class XMLValidator extends Validator {
|
|||||||
* @param xml the xml to be checked
|
* @param xml the xml to be checked
|
||||||
* @param xsltFilename the filename of the intermediate XSLT file
|
* @param xsltFilename the filename of the intermediate XSLT file
|
||||||
* @param section the error type code, if one arises
|
* @param section the error type code, if one arises
|
||||||
* @param severity how serious a error should be treated - may only be notice
|
* @param defaultSeverity how serious a error should be treated - may only be notice
|
||||||
* @throws IrrecoverableValidationError if anything happened that prevents further checks
|
* @throws IrrecoverableValidationError if anything happened that prevents further checks
|
||||||
*/
|
*/
|
||||||
public void validateSchematron(String xml, String xsltFilename, int section, ESeverity severity) throws IrrecoverableValidationError {
|
public void validateSchematron(String xml, String xsltFilename, int section, ESeverity defaultSeverity) throws IrrecoverableValidationError {
|
||||||
ISchematronResource aResSCH = null;
|
ISchematronResource aResSCH = null;
|
||||||
|
ESeverity severity=defaultSeverity;
|
||||||
|
if (defaultSeverity!=ESeverity.notice) {
|
||||||
|
severity=ESeverity.error;
|
||||||
|
}
|
||||||
|
|
||||||
aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename);
|
aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename);
|
||||||
|
|
||||||
if (aResSCH != null) {
|
if (aResSCH != null) {
|
||||||
@@ -465,6 +470,16 @@ public class XMLValidator extends Validator {
|
|||||||
thisFailLocation = currentFailNode.getAttributes().getNamedItem("location").getNodeValue();
|
thisFailLocation = currentFailNode.getAttributes().getNamedItem("location").getNodeValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentFailNode.getAttributes().getNamedItem("flag") != null) {
|
||||||
|
// the XR issues warnings with flag=warning
|
||||||
|
if (currentFailNode.getAttributes().getNamedItem("flag").getNodeValue().equals("warning")) {
|
||||||
|
if (defaultSeverity!=ESeverity.notice) {
|
||||||
|
severity=ESeverity.warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
NodeList failChilds = currentFailNode.getChildNodes();
|
NodeList failChilds = currentFailNode.getChildNodes();
|
||||||
for (int failChildIndex = 0; failChildIndex < failChilds.getLength(); failChildIndex++) {
|
for (int failChildIndex = 0; failChildIndex < failChilds.getLength(); failChildIndex++) {
|
||||||
if (failChilds.item(failChildIndex).getLocalName() != null) {
|
if (failChilds.item(failChildIndex).getLocalName() != null) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -106,7 +106,7 @@ public class PDFValidatorTest extends ResourceCase {
|
|||||||
|
|
||||||
public void testPDFXMLValidation() {
|
public void testPDFXMLValidation() {
|
||||||
final ValidationContext vc = new ValidationContext(null);
|
final ValidationContext vc = new ValidationContext(null);
|
||||||
try {
|
/*@todo try {
|
||||||
final PDFValidator pv = new PDFValidator(vc);
|
final PDFValidator pv = new PDFValidator(vc);
|
||||||
// need a more
|
// need a more
|
||||||
// invalid file here
|
// invalid file here
|
||||||
@@ -141,7 +141,7 @@ public class PDFValidatorTest extends ResourceCase {
|
|||||||
assertEquals(true, xmlvres.contains("valid") && !xmlvres.contains("invalid"));
|
assertEquals(true, xmlvres.contains("valid") && !xmlvres.contains("invalid"));
|
||||||
} catch (final IrrecoverableValidationError e) {
|
} catch (final IrrecoverableValidationError e) {
|
||||||
// ignore, will be in XML output anyway
|
// ignore, will be in XML output anyway
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,22 @@ public class XMLValidatorTest extends ResourceCase {
|
|||||||
noExceptions = false;
|
noExceptions = false;
|
||||||
}
|
}
|
||||||
assertTrue(noExceptions);
|
assertTrue(noExceptions);
|
||||||
|
tempFile = getResourceAsFile("ubl-tc434-creditnote1.xml");
|
||||||
|
try {
|
||||||
|
xv.setFilename(tempFile.getAbsolutePath());
|
||||||
|
xv.validate();
|
||||||
|
|
||||||
|
Source source = Input.fromString("<validation>" + xv.getXMLResult() + "</validation>").build();
|
||||||
|
String content = xpath.evaluate("/validation/summary/@status", source);
|
||||||
|
assertEquals("valid", content);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (IrrecoverableValidationError e) {
|
||||||
|
|
||||||
|
noExceptions = false;
|
||||||
|
}
|
||||||
|
assertTrue(noExceptions);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,15 @@ package org.mustangproject.validator;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.xmlunit.builder.Input;
|
||||||
|
import org.xmlunit.xpath.JAXPXPathEngine;
|
||||||
|
import org.xmlunit.xpath.XPathEngine;
|
||||||
|
|
||||||
import static org.xmlunit.assertj.XmlAssert.assertThat;
|
import static org.xmlunit.assertj.XmlAssert.assertThat;
|
||||||
|
|
||||||
@@ -132,6 +141,17 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPDFA3AValidation() {
|
||||||
|
File tempFile = getResourceAsFile("zugferd_2p1_EXTENDED_PDFA-3A.pdf");
|
||||||
|
|
||||||
|
ZUGFeRDValidator zfv = new ZUGFeRDValidator();
|
||||||
|
|
||||||
|
String res = zfv.validate(tempFile.getAbsolutePath());
|
||||||
|
|
||||||
|
assertThat(res).valueByXPath("/validation/pdf/summary/@status")
|
||||||
|
.isEqualTo("valid");
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* the XMLValidatorTests only cover the <xml></xml> part, this one includes the root element and
|
* the XMLValidatorTests only cover the <xml></xml> part, this one includes the root element and
|
||||||
* the global <summary></summary> part as well
|
* the global <summary></summary> part as well
|
||||||
@@ -205,6 +225,9 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
|
|||||||
assertThat(res).valueByXPath("count(//error)")
|
assertThat(res).valueByXPath("count(//error)")
|
||||||
.asInt()
|
.asInt()
|
||||||
.isEqualTo(3);
|
.isEqualTo(3);
|
||||||
|
assertThat(res).valueByXPath("count(//warning)")
|
||||||
|
.asInt()
|
||||||
|
.isEqualTo(1);
|
||||||
|
|
||||||
assertThat(res).valueByXPath("count(//notice)")
|
assertThat(res).valueByXPath("count(//notice)")
|
||||||
.asInt()
|
.asInt()
|
||||||
|
|||||||
@@ -115,9 +115,6 @@
|
|||||||
<ram:CityName>[Seller city]</ram:CityName>
|
<ram:CityName>[Seller city]</ram:CityName>
|
||||||
<ram:CountryID>DE</ram:CountryID>
|
<ram:CountryID>DE</ram:CountryID>
|
||||||
</ram:PostalTradeAddress>
|
</ram:PostalTradeAddress>
|
||||||
<ram:URIUniversalCommunication>
|
|
||||||
<ram:URIID schemeID="EM">seller@email.de</ram:URIID>
|
|
||||||
</ram:URIUniversalCommunication>
|
|
||||||
<ram:SpecifiedTaxRegistration>
|
<ram:SpecifiedTaxRegistration>
|
||||||
<ram:ID schemeID="VA">DE 123456789</ram:ID>
|
<ram:ID schemeID="VA">DE 123456789</ram:ID>
|
||||||
</ram:SpecifiedTaxRegistration>
|
</ram:SpecifiedTaxRegistration>
|
||||||
|
|||||||
136
validator/src/test/resources/ubl-tc434-creditnote1.xml
Normal file
136
validator/src/test/resources/ubl-tc434-creditnote1.xml
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed under European Union Public Licence (EUPL) version 1.2.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<CreditNote xmlns="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
|
||||||
|
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
|
||||||
|
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||||
|
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
|
||||||
|
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
|
||||||
|
<cbc:ID>018304 / 28865</cbc:ID>
|
||||||
|
<cbc:IssueDate>2019-09-23</cbc:IssueDate>
|
||||||
|
<cbc:CreditNoteTypeCode>381</cbc:CreditNoteTypeCode>
|
||||||
|
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
|
||||||
|
<cbc:BuyerReference>018304 / 28865</cbc:BuyerReference>
|
||||||
|
<cac:InvoicePeriod>
|
||||||
|
<cbc:StartDate>2019-02-01</cbc:StartDate>
|
||||||
|
<cbc:EndDate>2019-02-28</cbc:EndDate>
|
||||||
|
</cac:InvoicePeriod>
|
||||||
|
<cac:AccountingSupplierParty>
|
||||||
|
<cac:Party>
|
||||||
|
<cbc:EndpointID schemeID="0201">0000000196</cbc:EndpointID>
|
||||||
|
<cac:PartyName>
|
||||||
|
<cbc:Name>My Supplier Company N.V.</cbc:Name>
|
||||||
|
</cac:PartyName>
|
||||||
|
<cac:PostalAddress>
|
||||||
|
<cbc:StreetName>De Grote Meir 22</cbc:StreetName>
|
||||||
|
<cbc:CityName>ANTWERPEN</cbc:CityName>
|
||||||
|
<cbc:PostalZone>2000</cbc:PostalZone>
|
||||||
|
<cac:Country>
|
||||||
|
<cbc:IdentificationCode>BE</cbc:IdentificationCode>
|
||||||
|
</cac:Country>
|
||||||
|
</cac:PostalAddress>
|
||||||
|
<cac:PartyTaxScheme>
|
||||||
|
<cbc:CompanyID>BE0000000196</cbc:CompanyID>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:PartyTaxScheme>
|
||||||
|
<cac:PartyLegalEntity>
|
||||||
|
<cbc:RegistrationName>My Supplier Company</cbc:RegistrationName>
|
||||||
|
<cbc:CompanyID>0000000196</cbc:CompanyID>
|
||||||
|
</cac:PartyLegalEntity>
|
||||||
|
<cac:Contact>
|
||||||
|
<cbc:ElectronicMail>john.doole@mysuppliercompany.be</cbc:ElectronicMail>
|
||||||
|
</cac:Contact>
|
||||||
|
</cac:Party>
|
||||||
|
</cac:AccountingSupplierParty>
|
||||||
|
<cac:AccountingCustomerParty>
|
||||||
|
<cac:Party>
|
||||||
|
<cbc:EndpointID schemeID="0201">0000000295</cbc:EndpointID>
|
||||||
|
<cac:PartyName>
|
||||||
|
<cbc:Name>My Customer Company S.A.</cbc:Name>
|
||||||
|
</cac:PartyName>
|
||||||
|
<cac:PostalAddress>
|
||||||
|
<cbc:StreetName>Boulevard Sint Michel 53</cbc:StreetName>
|
||||||
|
<cbc:CityName>BRUXELLES</cbc:CityName>
|
||||||
|
<cbc:PostalZone>1000</cbc:PostalZone>
|
||||||
|
<cac:Country>
|
||||||
|
<cbc:IdentificationCode>BE</cbc:IdentificationCode>
|
||||||
|
</cac:Country>
|
||||||
|
</cac:PostalAddress>
|
||||||
|
<cac:PartyTaxScheme>
|
||||||
|
<cbc:CompanyID>BE0000000295</cbc:CompanyID>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:PartyTaxScheme>
|
||||||
|
<cac:PartyLegalEntity>
|
||||||
|
<cbc:RegistrationName>My Customer Company</cbc:RegistrationName>
|
||||||
|
<cbc:CompanyID>0000000295</cbc:CompanyID>
|
||||||
|
</cac:PartyLegalEntity>
|
||||||
|
<cac:Contact>
|
||||||
|
<cbc:ElectronicMail>pete.smith@mycustomercompany.be</cbc:ElectronicMail>
|
||||||
|
</cac:Contact>
|
||||||
|
</cac:Party>
|
||||||
|
</cac:AccountingCustomerParty>
|
||||||
|
<cac:PaymentMeans>
|
||||||
|
<cbc:PaymentMeansCode>1</cbc:PaymentMeansCode>
|
||||||
|
<cbc:PaymentID>010676609538</cbc:PaymentID>
|
||||||
|
<cac:PayeeFinancialAccount>
|
||||||
|
<cbc:ID>BE91000000143476</cbc:ID>
|
||||||
|
<cac:FinancialInstitutionBranch>
|
||||||
|
<cbc:ID>BPOTBEB1</cbc:ID>
|
||||||
|
</cac:FinancialInstitutionBranch>
|
||||||
|
</cac:PayeeFinancialAccount>
|
||||||
|
</cac:PaymentMeans>
|
||||||
|
<cac:TaxTotal>
|
||||||
|
<cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount>
|
||||||
|
<cac:TaxSubtotal>
|
||||||
|
<cbc:TaxableAmount currencyID="EUR">100.11</cbc:TaxableAmount>
|
||||||
|
<cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount>
|
||||||
|
<cac:TaxCategory>
|
||||||
|
<cbc:ID>E</cbc:ID>
|
||||||
|
<cbc:Percent>0.00</cbc:Percent>
|
||||||
|
<cbc:TaxExemptionReason>Taxes are not applicable</cbc:TaxExemptionReason>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:TaxCategory>
|
||||||
|
</cac:TaxSubtotal>
|
||||||
|
</cac:TaxTotal>
|
||||||
|
<cac:LegalMonetaryTotal>
|
||||||
|
<cbc:LineExtensionAmount currencyID="EUR">100.11</cbc:LineExtensionAmount>
|
||||||
|
<cbc:TaxExclusiveAmount currencyID="EUR">100.11</cbc:TaxExclusiveAmount>
|
||||||
|
<cbc:TaxInclusiveAmount currencyID="EUR">100.11</cbc:TaxInclusiveAmount>
|
||||||
|
<cbc:PayableAmount currencyID="EUR">100.11</cbc:PayableAmount>
|
||||||
|
</cac:LegalMonetaryTotal>
|
||||||
|
<cac:CreditNoteLine>
|
||||||
|
<cbc:ID>1</cbc:ID>
|
||||||
|
<cbc:CreditedQuantity unitCode="C62">1.00</cbc:CreditedQuantity>
|
||||||
|
<cbc:LineExtensionAmount currencyID="EUR">100.11</cbc:LineExtensionAmount>
|
||||||
|
<cac:Item>
|
||||||
|
<cbc:Description>Exonération du versement du PP</cbc:Description>
|
||||||
|
<cbc:Name>Exonération du versement du PP</cbc:Name>
|
||||||
|
<cac:SellersItemIdentification>
|
||||||
|
<cbc:ID>V55</cbc:ID>
|
||||||
|
</cac:SellersItemIdentification>
|
||||||
|
<cac:ClassifiedTaxCategory>
|
||||||
|
<cbc:ID>E</cbc:ID>
|
||||||
|
<cbc:Percent>0.00</cbc:Percent>
|
||||||
|
<cac:TaxScheme>
|
||||||
|
<cbc:ID>VAT</cbc:ID>
|
||||||
|
</cac:TaxScheme>
|
||||||
|
</cac:ClassifiedTaxCategory>
|
||||||
|
<cac:AdditionalItemProperty>
|
||||||
|
<cbc:Name>2</cbc:Name>
|
||||||
|
<cbc:Value>Contributions - précompte professionnel</cbc:Value>
|
||||||
|
</cac:AdditionalItemProperty>
|
||||||
|
</cac:Item>
|
||||||
|
<cac:Price>
|
||||||
|
<cbc:PriceAmount currencyID="EUR">100.11</cbc:PriceAmount>
|
||||||
|
</cac:Price>
|
||||||
|
</cac:CreditNoteLine>
|
||||||
|
</CreditNote>
|
||||||
BIN
validator/src/test/resources/zugferd_2p1_EXTENDED_PDFA-3A.pdf
Normal file
BIN
validator/src/test/resources/zugferd_2p1_EXTENDED_PDFA-3A.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user