Merge remote-tracking branch 'remotes/origin/master'
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
2.1.1
|
||||
=======
|
||||
2020-02-09
|
||||
|
||||
- PR #217 seller order referenced document
|
||||
- PR #217 seller order referenced document thanks to weclapp-dev
|
||||
- PR #218 allow recipient contact in XRechnung thanks to seeeeew
|
||||
- PR #221 remove outdated dependency thanks to heisej
|
||||
- PR #223 allow XRechnung without street thanks to murygin
|
||||
- only deploy library and validator to maven central, not core nor cli
|
||||
- a correction should reference the original invoice via invoiceReferencedDocument, not buyerOrderReferencedDocument
|
||||
- upgraded CEN Schematron validation (codes 24) to v1.3.4
|
||||
- added unit tests for ubl conversion and visualization
|
||||
|
||||
2.1.0
|
||||
=======
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
<parent>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>Mustang-CLI</artifactId>
|
||||
<name>e-invoices commandline tool, allowing to create(embed), split and validate Factur-X/ZUGFeRD files. Validation should also work for XRechnung/CII. </name>
|
||||
<packaging>jar</packaging>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- for jargs -->
|
||||
@@ -31,7 +31,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>validator</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
<!-- prototypes of new mustangproject versions can be installed by referring to them and installed to the local repo from a jar file with
|
||||
mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true
|
||||
-->
|
||||
@@ -140,6 +140,8 @@
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>LICENSE</exclude>
|
||||
<exclude>NOTICE</exclude>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.mustangproject.validator.Validator;
|
||||
import org.mustangproject.validator.ZUGFeRDValidator;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -48,6 +50,7 @@ public class Main {
|
||||
|
||||
private static String getUsage() {
|
||||
return "Usage: --action metrics|combine|extract|a3only|ubl|validate|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] | [-h,--help] \r\n"
|
||||
+ " --action=license display open source license and notice\n"
|
||||
+ " --action=metrics\n"
|
||||
+ " -d, --directory count ZUGFeRD files in directory to be scanned\n"
|
||||
+ " If it is a directory, it will recurse.\n"
|
||||
@@ -288,6 +291,37 @@ public class Main {
|
||||
c2u.convert(new File(xmlName), new File(outName));
|
||||
System.out.println("Written to " + outName);
|
||||
|
||||
}
|
||||
|
||||
public static void printLicense() {
|
||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("LICENSE");
|
||||
System.out.println(convertInputStreamToString(is));
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("NOTICE");
|
||||
System.out.println(convertInputStreamToString(is));
|
||||
|
||||
}
|
||||
|
||||
// Plain Java
|
||||
// based on https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/
|
||||
private static String convertInputStreamToString(InputStream is) {
|
||||
int DEFAULT_BUFFER_SIZE = 8192;
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int length;
|
||||
try {
|
||||
while ((length = is.read(buffer)) != -1) {
|
||||
result.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
// Java 1.1
|
||||
return result.toString(StandardCharsets.UTF_8.name());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
// Java 10
|
||||
// return result.toString(StandardCharsets.UTF_8);
|
||||
|
||||
}
|
||||
/***
|
||||
* the main function of the commandline tool...
|
||||
@@ -295,9 +329,9 @@ public class Main {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
|
||||
CmdLineParser parser = new CmdLineParser();
|
||||
|
||||
|
||||
// Option: Help
|
||||
Option<Boolean> helpOption = parser.addBooleanOption('h', "help");
|
||||
// Option: Action
|
||||
@@ -344,8 +378,9 @@ public class Main {
|
||||
String action = parser.getOptionValue(actionOption);
|
||||
String directoryName = parser.getOptionValue(dirnameOption);
|
||||
Boolean filesFromStdIn = parser.getOptionValue(filesFromStdInOption, Boolean.FALSE);
|
||||
Boolean helpRequested = parser.getOptionValue(helpOption, Boolean.FALSE) || ((action!=null)&&(action.equals("help")));
|
||||
Boolean ignoreFileExt = parser.getOptionValue(ignoreFileExtOption, Boolean.FALSE);
|
||||
Boolean helpRequested = parser.getOptionValue(helpOption, Boolean.FALSE) || ((action!=null)&&(action.equals("help")));
|
||||
|
||||
String sourceName = parser.getOptionValue(sourceOption);
|
||||
String sourceXMLName = parser.getOptionValue(sourceXmlOption);
|
||||
String outName = parser.getOptionValue(outOption);
|
||||
@@ -358,7 +393,10 @@ public class Main {
|
||||
if (helpRequested) {
|
||||
printHelp();
|
||||
optionsRecognized=true;
|
||||
} else if ((action!=null)&&(action.equals("metrics"))) {
|
||||
} /* else if ((action!=null)&&(action.equals("license"))) {
|
||||
printLicense();
|
||||
optionsRecognized=true;
|
||||
} */ else if ((action!=null)&&(action.equals("metrics"))) {
|
||||
performMetrics(directoryName, filesFromStdIn, ignoreFileExt);
|
||||
optionsRecognized=true;
|
||||
} else if ((action!=null)&&(action.equals("combine"))) {
|
||||
|
||||
1
NOTICE
1
NOTICE
@@ -31,3 +31,4 @@ Based on https://github.com/itplr-kosit/xrechnung-schematron licensed under the
|
||||
Based on https://github.com/itplr-kosit/xrechnung-visualization licensed under the APL2.0
|
||||
Based on Saxon-HE https://sourceforge.net/projects/saxon/ licensed under the MPL 2.0
|
||||
Based on DOM4j https://dom4j.github.io/ licensed under the BSD license
|
||||
Based on EN16931 validation artefacts https://github.com/ConnectingEurope/eInvoicing-EN16931 licensed under the EUPL 2.0
|
||||
|
||||
@@ -25,7 +25,7 @@ If you setup a Maven project, you can grab the artifacts using
|
||||
<dependency>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>library</artifactId>
|
||||
<version>2.0.2</version>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<parent>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>library</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>Library to write, read and validate e-invoices (Factur-X, ZUGFeRD and to a limited extend XRechnung/CII). </name>
|
||||
<description>The Mustang project is a java library to read, write and validate Factur-X/ZUGFeRD meta data inside your invoice PDFs. To write files, a provided PDF/A will be combined with generated or provided XML.
|
||||
@@ -117,12 +117,6 @@
|
||||
<artifactId>xmlunit-assertj</artifactId>
|
||||
<version>2.6.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.helger</groupId>
|
||||
<artifactId>ph-commons</artifactId>
|
||||
<version>9.1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- API -->
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*********************************************************************** */
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class CustomXMLProvider implements IXMLProvider {
|
||||
|
||||
protected byte[] zugferdData;
|
||||
@@ -29,7 +31,7 @@ public class CustomXMLProvider implements IXMLProvider {
|
||||
}
|
||||
|
||||
public void setXML(byte[] newData) {
|
||||
String zf = new String(newData);
|
||||
String zf = new String(newData, StandardCharsets.UTF_8);
|
||||
if (!zf.contains("CrossIndustry")) {
|
||||
throw new RuntimeException("ZUGFeRD XML does not contain (<rsm:)CrossIndustry and can thus not be valid");
|
||||
}
|
||||
|
||||
@@ -156,9 +156,11 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
||||
}
|
||||
xml += " <ram:PostalTradeAddress>\n"
|
||||
+ " <ram:PostcodeCode>" + XMLTools.encodeXML(party.getZIP())
|
||||
+ "</ram:PostcodeCode>\n"
|
||||
+ " <ram:LineOne>" + XMLTools.encodeXML(party.getStreet())
|
||||
+ "</ram:LineOne>\n";
|
||||
+ "</ram:PostcodeCode>\n";
|
||||
if (party.getStreet() != null) {
|
||||
xml += " <ram:LineOne>" + XMLTools.encodeXML(party.getStreet())
|
||||
+ "</ram:LineOne>\n";
|
||||
}
|
||||
if (party.getAdditionalAddress() != null) {
|
||||
xml += " <ram:LineTwo>" + XMLTools.encodeXML(party.getAdditionalAddress())
|
||||
+ "</ram:LineTwo>\n";
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
@@ -77,7 +78,7 @@ public class ZUGFeRDVisualizer {
|
||||
FileInputStream fis=new FileInputStream(xmlFilename);
|
||||
String fileContent="";
|
||||
try {
|
||||
fileContent = new String(Files.readAllBytes(Paths.get(xmlFilename)));
|
||||
fileContent = new String(Files.readAllBytes(Paths.get(xmlFilename)), StandardCharsets.UTF_8);
|
||||
} catch (IOException e2) {
|
||||
LOG.log(Level.SEVERE, null, e2);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
@@ -270,7 +271,7 @@ public class MustangReaderWriterEdgeTest extends MustangReaderTestCase {
|
||||
.setZUGFeRDVersion(1)
|
||||
.load(inputStream);
|
||||
ze.setTransaction(this);
|
||||
String theXML = new String(ze.getProvider().getXML());
|
||||
String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8);
|
||||
assertTrue(theXML.contains("<rsm:CrossIndustryDocument"));
|
||||
ze.export(targetPath);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ResourceCase extends TestCase {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is
|
||||
|
||||
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) {
|
||||
LOGGER.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
/**
|
||||
* *********************************************************************
|
||||
* <p>
|
||||
* Copyright 2019 Jochen Staerk
|
||||
* <p>
|
||||
* Use is subject to license terms.
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* <p>
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* <p>
|
||||
* **********************************************************************
|
||||
*/
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.mustangproject.CII.CIIToUBL;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class UBLTest extends ResourceCase {
|
||||
|
||||
public void testUBLBasic() {
|
||||
|
||||
// the writing part
|
||||
CIIToUBL c2u = new CIIToUBL();
|
||||
String sourceFilename = "factur-x.xml";
|
||||
File input = getResourceAsFile(sourceFilename);
|
||||
File expectedFile = getResourceAsFile("ubl-conv-ubl-output-factur-x.xml");
|
||||
String expected = null;
|
||||
String result = null;
|
||||
try {
|
||||
File tempFile = File.createTempFile("ZUGFeRD-UBL-", "-test");
|
||||
c2u.convert(input, tempFile);
|
||||
expected = ResourceUtilities.readFile(StandardCharsets.UTF_8, expectedFile.getAbsolutePath());
|
||||
result = ResourceUtilities.readFile(StandardCharsets.UTF_8, tempFile.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
fail("Exception should not happen: "+e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
/** **********************************************************************
|
||||
*
|
||||
* Copyright 2019 Jochen Staerk
|
||||
*
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*********************************************************************** */
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.mustangproject.CII.CIIToUBL;
|
||||
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class VisualizationTest extends ResourceCase {
|
||||
|
||||
public void testVisualizationBasic() {
|
||||
|
||||
// the writing part
|
||||
CIIToUBL c2u = new CIIToUBL();
|
||||
String sourceFilename = "factur-x.xml";
|
||||
File input = getResourceAsFile(sourceFilename);
|
||||
|
||||
String expected = null;
|
||||
String result = null;
|
||||
try {
|
||||
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
|
||||
/* remove file endings so that tests can also pass after checking
|
||||
out from git with arbitrary options (which may include CSRF changes)
|
||||
*/
|
||||
result = zvi.visualize(input.getAbsolutePath()).replace("\r","").replace("\n","");
|
||||
|
||||
File expectedResult=getResourceAsFile("factur-x.html");
|
||||
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n","");
|
||||
// remove linebreaks as well...
|
||||
|
||||
} catch (TransformerException e) {
|
||||
fail("Exception should not happen: "+e.getMessage());
|
||||
} catch (IOException e) {
|
||||
fail("Exception should not happen: "+e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
assertNotNull(result);
|
||||
// Reading ZUGFeRD
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.xmlunit.assertj.XmlAssert.assertThat;
|
||||
@@ -43,22 +44,13 @@ public class XRTest extends TestCase {
|
||||
public void testXRExport() {
|
||||
|
||||
// the writing part
|
||||
|
||||
String orgname = "Test company";
|
||||
String number = "123";
|
||||
String amountStr = "1.00";
|
||||
BigDecimal amount = new BigDecimal(amountStr);
|
||||
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
|
||||
.setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890","COBADEFXXX")))
|
||||
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
|
||||
.setReferenceNumber("991-01484-64")//leitweg-id
|
||||
// not using any VAT, this is also a test of zero-rated goods:
|
||||
.setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), amount, new BigDecimal(1.0)));
|
||||
TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE");
|
||||
Invoice i = createInvoice(recipient);
|
||||
|
||||
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||
zf2p.generateXML(i);
|
||||
String theXML = new String(zf2p.getXML());
|
||||
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||
assertThat(theXML).valueByXPath("count(//*[local-name()='IncludedSupplyChainTradeLineItem'])")
|
||||
.asInt()
|
||||
@@ -77,6 +69,7 @@ public class XRTest extends TestCase {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testXREdgeExport() {
|
||||
|
||||
// the writing part
|
||||
@@ -101,7 +94,7 @@ public class XRTest extends TestCase {
|
||||
|
||||
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||
zf2p.generateXML(i);
|
||||
String theXML = new String(zf2p.getXML());
|
||||
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||
assertThat(theXML).valueByXPath("count(//*[local-name()='IncludedSupplyChainTradeLineItem'])")
|
||||
.asInt()
|
||||
@@ -121,4 +114,46 @@ public class XRTest extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
public void testXRExportWithoutStreet() {
|
||||
|
||||
// the writing part
|
||||
TradeParty recipient = new TradeParty("Franz Müller", null, "55232", "Entenhausen", "DE");
|
||||
Invoice i = createInvoice(recipient);
|
||||
|
||||
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||
zf2p.generateXML(i);
|
||||
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||
assertThat(theXML).valueByXPath("count(//*[local-name()='IncludedSupplyChainTradeLineItem'])")
|
||||
.asInt()
|
||||
.isEqualTo(1); //2 errors are OK because there is a known bug
|
||||
|
||||
|
||||
assertThat(theXML).valueByXPath("//*[local-name()='DuePayableAmount']")
|
||||
.asDouble()
|
||||
.isEqualTo(1);
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(TARGET_XML));
|
||||
writer.write(theXML);
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private org.mustangproject.Invoice createInvoice(TradeParty recipient) {
|
||||
String orgname = "Test company";
|
||||
String number = "123";
|
||||
String amountStr = "1.00";
|
||||
BigDecimal amount = new BigDecimal(amountStr);
|
||||
return new Invoice().setDueDate(new java.util.Date()).setIssueDate(new java.util.Date()).setDeliveryDate(new java.util.Date())
|
||||
.setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new org.mustangproject.Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new org.mustangproject.BankDetails("DE12500105170648489890","COBADEFXXX")))
|
||||
.setRecipient(recipient)
|
||||
.setReferenceNumber("991-01484-64")//leitweg-id
|
||||
// not using any VAT, this is also a test of zero-rated goods:
|
||||
.setNumber(number).addItem(new org.mustangproject.Item(new org.mustangproject.Product("Testprodukt", "", "C62", java.math.BigDecimal.ZERO), amount, new java.math.BigDecimal(1.0)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@@ -266,7 +267,7 @@ public class ZF2EdgeTest extends MustangReaderTestCase implements IExportableTra
|
||||
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).ignorePDFAErrors()
|
||||
.load(SOURCE_PDF)) {
|
||||
ze.setTransaction(this);
|
||||
String theXML = new String(ze.getProvider().getXML());
|
||||
String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8);
|
||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||
ze.export(TARGET_PDF);
|
||||
} catch (IOException e) {
|
||||
@@ -314,7 +315,7 @@ public class ZF2EdgeTest extends MustangReaderTestCase implements IExportableTra
|
||||
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).disableFacturX()
|
||||
.load(SOURCE_PDF)) {
|
||||
ze.setTransaction(this);
|
||||
String theXML = new String(ze.getProvider().getXML());
|
||||
String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8);
|
||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||
ze.export(bos);
|
||||
} catch (IOException e) {
|
||||
|
||||
1150
library/src/test/resources/factur-x.html
Normal file
1150
library/src/test/resources/factur-x.html
Normal file
File diff suppressed because it is too large
Load Diff
191
library/src/test/resources/factur-x.xml
Normal file
191
library/src/test/resources/factur-x.xml
Normal file
@@ -0,0 +1,191 @@
|
||||
<?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">
|
||||
<rsm:ExchangedDocumentContext>
|
||||
<ram:GuidelineSpecifiedDocumentContextParameter>
|
||||
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
|
||||
</ram:GuidelineSpecifiedDocumentContextParameter>
|
||||
</rsm:ExchangedDocumentContext>
|
||||
<rsm:ExchangedDocument>
|
||||
<ram:ID>RE-20201121/508</ram:ID>
|
||||
<ram:TypeCode>380</ram:TypeCode>
|
||||
<ram:IssueDateTime>
|
||||
<udt:DateTimeString format="102">20201121</udt:DateTimeString>
|
||||
</ram:IssueDateTime>
|
||||
</rsm:ExchangedDocument>
|
||||
<rsm:SupplyChainTradeTransaction>
|
||||
<ram:IncludedSupplyChainTradeLineItem>
|
||||
<ram:AssociatedDocumentLineDocument>
|
||||
<ram:LineID>1</ram:LineID>
|
||||
</ram:AssociatedDocumentLineDocument>
|
||||
<ram:SpecifiedTradeProduct>
|
||||
<ram:Name>Design (hours)</ram:Name>
|
||||
<ram:Description>Of a sample invoice</ram:Description>
|
||||
</ram:SpecifiedTradeProduct>
|
||||
<ram:SpecifiedLineTradeAgreement>
|
||||
<ram:GrossPriceProductTradePrice>
|
||||
<ram:ChargeAmount>160.0000</ram:ChargeAmount>
|
||||
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
|
||||
</ram:GrossPriceProductTradePrice>
|
||||
<ram:NetPriceProductTradePrice>
|
||||
<ram:ChargeAmount>160.0000</ram:ChargeAmount>
|
||||
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
|
||||
</ram:NetPriceProductTradePrice>
|
||||
</ram:SpecifiedLineTradeAgreement>
|
||||
<ram:SpecifiedLineTradeDelivery>
|
||||
<ram:BilledQuantity unitCode="HUR">1.0000</ram:BilledQuantity>
|
||||
</ram:SpecifiedLineTradeDelivery>
|
||||
<ram:SpecifiedLineTradeSettlement>
|
||||
<ram:ApplicableTradeTax>
|
||||
<ram:TypeCode>VAT</ram:TypeCode>
|
||||
<ram:CategoryCode>S</ram:CategoryCode>
|
||||
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
|
||||
</ram:ApplicableTradeTax>
|
||||
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||
<ram:LineTotalAmount>160.00</ram:LineTotalAmount>
|
||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||
</ram:SpecifiedLineTradeSettlement>
|
||||
</ram:IncludedSupplyChainTradeLineItem>
|
||||
<ram:IncludedSupplyChainTradeLineItem>
|
||||
<ram:AssociatedDocumentLineDocument>
|
||||
<ram:LineID>2</ram:LineID>
|
||||
</ram:AssociatedDocumentLineDocument>
|
||||
<ram:SpecifiedTradeProduct>
|
||||
<ram:Name>Ballons</ram:Name>
|
||||
<ram:Description>various colors, ~2000ml</ram:Description>
|
||||
</ram:SpecifiedTradeProduct>
|
||||
<ram:SpecifiedLineTradeAgreement>
|
||||
<ram:GrossPriceProductTradePrice>
|
||||
<ram:ChargeAmount>0.7900</ram:ChargeAmount>
|
||||
<ram:BasisQuantity unitCode="H87">1.0000</ram:BasisQuantity>
|
||||
</ram:GrossPriceProductTradePrice>
|
||||
<ram:NetPriceProductTradePrice>
|
||||
<ram:ChargeAmount>0.7900</ram:ChargeAmount>
|
||||
<ram:BasisQuantity unitCode="H87">1.0000</ram:BasisQuantity>
|
||||
</ram:NetPriceProductTradePrice>
|
||||
</ram:SpecifiedLineTradeAgreement>
|
||||
<ram:SpecifiedLineTradeDelivery>
|
||||
<ram:BilledQuantity unitCode="H87">400.0000</ram:BilledQuantity>
|
||||
</ram:SpecifiedLineTradeDelivery>
|
||||
<ram:SpecifiedLineTradeSettlement>
|
||||
<ram:ApplicableTradeTax>
|
||||
<ram:TypeCode>VAT</ram:TypeCode>
|
||||
<ram:CategoryCode>S</ram:CategoryCode>
|
||||
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
|
||||
</ram:ApplicableTradeTax>
|
||||
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||
<ram:LineTotalAmount>316.00</ram:LineTotalAmount>
|
||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||
</ram:SpecifiedLineTradeSettlement>
|
||||
</ram:IncludedSupplyChainTradeLineItem>
|
||||
<ram:IncludedSupplyChainTradeLineItem>
|
||||
<ram:AssociatedDocumentLineDocument>
|
||||
<ram:LineID>3</ram:LineID>
|
||||
</ram:AssociatedDocumentLineDocument>
|
||||
<ram:SpecifiedTradeProduct>
|
||||
<ram:Name>Hot air „heiße Luft“ (litres)</ram:Name>
|
||||
<ram:Description/>
|
||||
</ram:SpecifiedTradeProduct>
|
||||
<ram:SpecifiedLineTradeAgreement>
|
||||
<ram:GrossPriceProductTradePrice>
|
||||
<ram:ChargeAmount>0.0250</ram:ChargeAmount>
|
||||
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
|
||||
</ram:GrossPriceProductTradePrice>
|
||||
<ram:NetPriceProductTradePrice>
|
||||
<ram:ChargeAmount>0.0250</ram:ChargeAmount>
|
||||
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
|
||||
</ram:NetPriceProductTradePrice>
|
||||
</ram:SpecifiedLineTradeAgreement>
|
||||
<ram:SpecifiedLineTradeDelivery>
|
||||
<ram:BilledQuantity unitCode="LTR">800.0000</ram:BilledQuantity>
|
||||
</ram:SpecifiedLineTradeDelivery>
|
||||
<ram:SpecifiedLineTradeSettlement>
|
||||
<ram:ApplicableTradeTax>
|
||||
<ram:TypeCode>VAT</ram:TypeCode>
|
||||
<ram:CategoryCode>S</ram:CategoryCode>
|
||||
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
|
||||
</ram:ApplicableTradeTax>
|
||||
<ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||
<ram:LineTotalAmount>20.00</ram:LineTotalAmount>
|
||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||
</ram:SpecifiedLineTradeSettlement>
|
||||
</ram:IncludedSupplyChainTradeLineItem>
|
||||
<ram:ApplicableHeaderTradeAgreement>
|
||||
<ram:BuyerReference>AB321</ram:BuyerReference>
|
||||
<ram:SellerTradeParty>
|
||||
<ram:Name>Bei Spiel GmbH</ram:Name>
|
||||
<ram:PostalTradeAddress>
|
||||
<ram:PostcodeCode>12345</ram:PostcodeCode>
|
||||
<ram:LineOne>Ecke 12</ram:LineOne>
|
||||
<ram:CityName>Stadthausen</ram:CityName>
|
||||
<ram:CountryID>DE</ram:CountryID>
|
||||
</ram:PostalTradeAddress>
|
||||
<ram:SpecifiedTaxRegistration>
|
||||
<ram:ID schemeID="VA">DE136695976</ram:ID>
|
||||
</ram:SpecifiedTaxRegistration>
|
||||
</ram:SellerTradeParty>
|
||||
<ram:BuyerTradeParty>
|
||||
<ram:ID>2</ram:ID>
|
||||
<ram:Name>Theodor Est</ram:Name>
|
||||
<ram:PostalTradeAddress>
|
||||
<ram:PostcodeCode>88802</ram:PostcodeCode>
|
||||
<ram:LineOne>Bahnstr. 42</ram:LineOne>
|
||||
<ram:CityName>Spielkreis</ram:CityName>
|
||||
<ram:CountryID>DE</ram:CountryID>
|
||||
</ram:PostalTradeAddress>
|
||||
</ram:BuyerTradeParty>
|
||||
</ram:ApplicableHeaderTradeAgreement>
|
||||
<ram:ApplicableHeaderTradeDelivery>
|
||||
<ram:ActualDeliverySupplyChainEvent>
|
||||
<ram:OccurrenceDateTime>
|
||||
<udt:DateTimeString format="102">20201110</udt:DateTimeString>
|
||||
</ram:OccurrenceDateTime>
|
||||
</ram:ActualDeliverySupplyChainEvent>
|
||||
</ram:ApplicableHeaderTradeDelivery>
|
||||
<ram:ApplicableHeaderTradeSettlement>
|
||||
<ram:PaymentReference>RE-20201121/508</ram:PaymentReference>
|
||||
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
||||
<ram:SpecifiedTradeSettlementPaymentMeans>
|
||||
<ram:TypeCode>42</ram:TypeCode>
|
||||
<ram:Information>Bank transfer</ram:Information>
|
||||
<ram:PayeePartyCreditorFinancialAccount>
|
||||
<ram:IBANID>DE88200800000970375700</ram:IBANID>
|
||||
<ram:AccountName>Max Mustermann</ram:AccountName>
|
||||
</ram:PayeePartyCreditorFinancialAccount>
|
||||
<ram:PayeeSpecifiedCreditorFinancialInstitution>
|
||||
<ram:BICID>COBADEFFXXX</ram:BICID>
|
||||
</ram:PayeeSpecifiedCreditorFinancialInstitution>
|
||||
</ram:SpecifiedTradeSettlementPaymentMeans>
|
||||
<ram:ApplicableTradeTax>
|
||||
<ram:CalculatedAmount>11.20</ram:CalculatedAmount>
|
||||
<ram:TypeCode>VAT</ram:TypeCode>
|
||||
<ram:BasisAmount>160.00</ram:BasisAmount>
|
||||
<ram:CategoryCode>S</ram:CategoryCode>
|
||||
<ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>
|
||||
</ram:ApplicableTradeTax>
|
||||
<ram:ApplicableTradeTax>
|
||||
<ram:CalculatedAmount>63.84</ram:CalculatedAmount>
|
||||
<ram:TypeCode>VAT</ram:TypeCode>
|
||||
<ram:BasisAmount>336.00</ram:BasisAmount>
|
||||
<ram:CategoryCode>S</ram:CategoryCode>
|
||||
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
|
||||
</ram:ApplicableTradeTax>
|
||||
<ram:SpecifiedTradePaymentTerms>
|
||||
<ram:Description>Zahlbar ohne Abzug bis 12.12.2020</ram:Description>
|
||||
<ram:DueDateDateTime>
|
||||
<udt:DateTimeString format="102">20201212</udt:DateTimeString>
|
||||
</ram:DueDateDateTime>
|
||||
</ram:SpecifiedTradePaymentTerms>
|
||||
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||
<ram:LineTotalAmount>496.00</ram:LineTotalAmount>
|
||||
<ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
|
||||
<ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
|
||||
<ram:TaxBasisTotalAmount>496.00</ram:TaxBasisTotalAmount>
|
||||
<ram:TaxTotalAmount currencyID="EUR">75.04</ram:TaxTotalAmount>
|
||||
<ram:GrandTotalAmount>571.04</ram:GrandTotalAmount>
|
||||
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
|
||||
<ram:DuePayableAmount>571.04</ram:DuePayableAmount>
|
||||
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||
</ram:ApplicableHeaderTradeSettlement>
|
||||
</rsm:SupplyChainTradeTransaction>
|
||||
</rsm:CrossIndustryInvoice>
|
||||
156
library/src/test/resources/ubl-conv-ubl-output-factur-x.xml
Normal file
156
library/src/test/resources/ubl-conv-ubl-output-factur-x.xml
Normal file
@@ -0,0 +1,156 @@
|
||||
<?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: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:extended:urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
|
||||
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
|
||||
<cbc:ID>RE-20201121/508</cbc:ID>
|
||||
<cbc:IssueDate>2020-11-21</cbc:IssueDate>
|
||||
<cbc:DueDate>2020-12-12</cbc:DueDate>
|
||||
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
|
||||
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
|
||||
<cbc:BuyerReference>AB321</cbc:BuyerReference>
|
||||
<cac:AccountingSupplierParty>
|
||||
<cac:Party>
|
||||
<cac:PartyName>
|
||||
<cbc:Name>Bei Spiel GmbH</cbc:Name>
|
||||
</cac:PartyName>
|
||||
<cac:PostalAddress>
|
||||
<cbc:StreetName>Ecke 12</cbc:StreetName>
|
||||
<cbc:CityName>Stadthausen</cbc:CityName>
|
||||
<cbc:PostalZone>12345</cbc:PostalZone>
|
||||
<cac:Country>
|
||||
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
|
||||
</cac:Country>
|
||||
</cac:PostalAddress>
|
||||
<cac:PartyTaxScheme>
|
||||
<cbc:CompanyID>DE136695976</cbc:CompanyID>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID>VAT</cbc:ID>
|
||||
</cac:TaxScheme>
|
||||
</cac:PartyTaxScheme>
|
||||
<cac:PartyLegalEntity>
|
||||
<cbc:RegistrationName>Bei Spiel GmbH</cbc:RegistrationName>
|
||||
</cac:PartyLegalEntity>
|
||||
</cac:Party>
|
||||
</cac:AccountingSupplierParty>
|
||||
<cac:AccountingCustomerParty>
|
||||
<cac:Party>
|
||||
<cac:PartyIdentification>
|
||||
<cbc:ID>2</cbc:ID>
|
||||
</cac:PartyIdentification>
|
||||
<cac:PartyName>
|
||||
<cbc:Name>Theodor Est</cbc:Name>
|
||||
</cac:PartyName>
|
||||
<cac:PostalAddress>
|
||||
<cbc:StreetName>Bahnstr. 42</cbc:StreetName>
|
||||
<cbc:CityName>Spielkreis</cbc:CityName>
|
||||
<cbc:PostalZone>88802</cbc:PostalZone>
|
||||
<cac:Country>
|
||||
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
|
||||
</cac:Country>
|
||||
</cac:PostalAddress>
|
||||
<cac:PartyLegalEntity>
|
||||
<cbc:RegistrationName>Theodor Est</cbc:RegistrationName>
|
||||
</cac:PartyLegalEntity>
|
||||
</cac:Party>
|
||||
</cac:AccountingCustomerParty>
|
||||
<cac:Delivery>
|
||||
<cbc:ActualDeliveryDate>2020-11-10</cbc:ActualDeliveryDate>
|
||||
</cac:Delivery>
|
||||
<cac:PaymentTerms>
|
||||
<cbc:Note>Zahlbar ohne Abzug bis 12.12.2020</cbc:Note>
|
||||
</cac:PaymentTerms>
|
||||
<cac:TaxTotal>
|
||||
<cbc:TaxAmount currencyID="EUR">75.04</cbc:TaxAmount>
|
||||
<cac:TaxSubtotal>
|
||||
<cbc:TaxableAmount currencyID="EUR">160.00</cbc:TaxableAmount>
|
||||
<cbc:TaxAmount currencyID="EUR">11.20</cbc:TaxAmount>
|
||||
<cac:TaxCategory>
|
||||
<cbc:ID>S</cbc:ID>
|
||||
<cbc:Percent>7.00</cbc:Percent>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID>VAT</cbc:ID>
|
||||
</cac:TaxScheme>
|
||||
</cac:TaxCategory>
|
||||
</cac:TaxSubtotal>
|
||||
<cac:TaxSubtotal>
|
||||
<cbc:TaxableAmount currencyID="EUR">336.00</cbc:TaxableAmount>
|
||||
<cbc:TaxAmount currencyID="EUR">63.84</cbc:TaxAmount>
|
||||
<cac:TaxCategory>
|
||||
<cbc:ID>S</cbc:ID>
|
||||
<cbc:Percent>19.00</cbc:Percent>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID>VAT</cbc:ID>
|
||||
</cac:TaxScheme>
|
||||
</cac:TaxCategory>
|
||||
</cac:TaxSubtotal>
|
||||
</cac:TaxTotal>
|
||||
<cac:LegalMonetaryTotal>
|
||||
<cbc:LineExtensionAmount currencyID="EUR">496.00</cbc:LineExtensionAmount>
|
||||
<cbc:TaxExclusiveAmount currencyID="EUR">496.00</cbc:TaxExclusiveAmount>
|
||||
<cbc:TaxInclusiveAmount currencyID="EUR">571.04</cbc:TaxInclusiveAmount>
|
||||
<cbc:AllowanceTotalAmount currencyID="EUR">0.00</cbc:AllowanceTotalAmount>
|
||||
<cbc:ChargeTotalAmount currencyID="EUR">0.00</cbc:ChargeTotalAmount>
|
||||
<cbc:PrepaidAmount currencyID="EUR">0.00</cbc:PrepaidAmount>
|
||||
<cbc:PayableAmount currencyID="EUR">571.04</cbc:PayableAmount>
|
||||
</cac:LegalMonetaryTotal>
|
||||
<cac:InvoiceLine>
|
||||
<cbc:ID>1</cbc:ID>
|
||||
<cbc:InvoicedQuantity unitCode="HUR">1.0000</cbc:InvoicedQuantity>
|
||||
<cbc:LineExtensionAmount currencyID="EUR">160.00</cbc:LineExtensionAmount>
|
||||
<cac:Item>
|
||||
<cbc:Description>Of a sample invoice</cbc:Description>
|
||||
<cbc:Name>Design (hours)</cbc:Name>
|
||||
<cac:ClassifiedTaxCategory>
|
||||
<cbc:ID>S</cbc:ID>
|
||||
<cbc:Percent>7.00</cbc:Percent>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID>VAT</cbc:ID>
|
||||
</cac:TaxScheme>
|
||||
</cac:ClassifiedTaxCategory>
|
||||
</cac:Item>
|
||||
<cac:Price>
|
||||
<cbc:PriceAmount currencyID="EUR">160.0000</cbc:PriceAmount>
|
||||
<cbc:BaseQuantity unitCode="HUR">1.0000</cbc:BaseQuantity>
|
||||
</cac:Price>
|
||||
</cac:InvoiceLine>
|
||||
<cac:InvoiceLine>
|
||||
<cbc:ID>2</cbc:ID>
|
||||
<cbc:InvoicedQuantity unitCode="H87">400.0000</cbc:InvoicedQuantity>
|
||||
<cbc:LineExtensionAmount currencyID="EUR">316.00</cbc:LineExtensionAmount>
|
||||
<cac:Item>
|
||||
<cbc:Description>various colors, ~2000ml</cbc:Description>
|
||||
<cbc:Name>Ballons</cbc:Name>
|
||||
<cac:ClassifiedTaxCategory>
|
||||
<cbc:ID>S</cbc:ID>
|
||||
<cbc:Percent>19.00</cbc:Percent>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID>VAT</cbc:ID>
|
||||
</cac:TaxScheme>
|
||||
</cac:ClassifiedTaxCategory>
|
||||
</cac:Item>
|
||||
<cac:Price>
|
||||
<cbc:PriceAmount currencyID="EUR">0.7900</cbc:PriceAmount>
|
||||
<cbc:BaseQuantity unitCode="H87">1.0000</cbc:BaseQuantity>
|
||||
</cac:Price>
|
||||
</cac:InvoiceLine>
|
||||
<cac:InvoiceLine>
|
||||
<cbc:ID>3</cbc:ID>
|
||||
<cbc:InvoicedQuantity unitCode="LTR">800.0000</cbc:InvoicedQuantity>
|
||||
<cbc:LineExtensionAmount currencyID="EUR">20.00</cbc:LineExtensionAmount>
|
||||
<cac:Item>
|
||||
<cbc:Description></cbc:Description>
|
||||
<cbc:Name>Hot air „heiße Luft“ (litres)</cbc:Name>
|
||||
<cac:ClassifiedTaxCategory>
|
||||
<cbc:ID>S</cbc:ID>
|
||||
<cbc:Percent>19.00</cbc:Percent>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID>VAT</cbc:ID>
|
||||
</cac:TaxScheme>
|
||||
</cac:ClassifiedTaxCategory>
|
||||
</cac:Item>
|
||||
<cac:Price>
|
||||
<cbc:PriceAmount currencyID="EUR">0.0250</cbc:PriceAmount>
|
||||
<cbc:BaseQuantity unitCode="LTR">1.0000</cbc:BaseQuantity>
|
||||
</cac:Price>
|
||||
</cac:InvoiceLine>
|
||||
</Invoice>
|
||||
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Mustang</name>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
@@ -11,7 +11,7 @@
|
||||
<name>Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung)</name>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- for jargs -->
|
||||
@@ -77,7 +77,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>library</artifactId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
<version>2.1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xmlunit</groupId>
|
||||
@@ -176,6 +176,8 @@
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>LICENSE</exclude>
|
||||
<exclude>NOTICE</exclude>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
|
||||
@@ -62,7 +62,7 @@ public class XMLValidator extends Validator {
|
||||
// file existence must have been checked before
|
||||
|
||||
try {
|
||||
zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Paths.get(name))));
|
||||
zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Paths.get(name))), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
|
||||
ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.mustangproject.validator;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -166,7 +167,7 @@ public class ZUGFeRDValidator {
|
||||
|
||||
byte[] content=Files.readAllBytes(file.toPath());
|
||||
content= XMLTools.removeBOM(content);
|
||||
String s=new String(content);
|
||||
String s=new String(content, StandardCharsets.UTF_8);
|
||||
InputSource is = new InputSource(new StringReader(s));
|
||||
Document doc = db.parse(is);
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user