diff --git a/ZUGFeRD2-invoice.xml b/ZUGFeRD2-invoice.xml new file mode 100644 index 00000000..cf4be5c7 --- /dev/null +++ b/ZUGFeRD2-invoice.xml @@ -0,0 +1,202 @@ + + + + false + + + urn:ferd:CrossIndustryDocument:invoice:1p0:extended + + + + RE-20170509/505 + RECHNUNG + 380 + + 20170509 + + + + + + 1 + + + Künstlerische Gestaltung (Stunde): Einer Beispielrechnung + + + + + 160.0000 + 1.0000 + + + 160.0000 + 1.0000 + + + + 1.0000 + + + + VAT + S + 7.00 + + + 160.00 + + + + + + 2 + + + Luftballon: Bunt, ca. 500ml + + + + + 0.7900 + 1.0000 + + + 0.7900 + 1.0000 + + + + 400.0000 + + + + VAT + S + 19.00 + + + 316.00 + + + + + + 3 + + + Heiße Luft pro Liter + + + + + 0.1000 + 1.0000 + + + 0.1000 + 1.0000 + + + + 200.0000 + + + + VAT + S + 19.00 + + + 20.00 + + + + + + Bei Spiel GmbH + + 12345 + Ecke 12 + Stadthausen + DE + + + 22/815/0815/4 + + + DE136695976 + + + + Theodor Est + + 88802 + Bahnstr. 42 + Spielkreis + DE + + + DE999999999 + + + + + + + 20170507 + + + + + RE-20170509/505 + EUR + + 42 + Überweisung + + DE88 2008 0000 0970 3757 00 + + + COBADEFFXXX + Commerzbank + + + + 11.20 + VAT + 160.00 + S + 7.00 + + + 63.84 + VAT + 336.00 + S + 19.00 + + + Zahlbar ohne Abzug bis zum 30.05.2017 + + 20170530 + + + + 496.00 + 0.00 + 0.00 + 496.00 + 75.04 + 571.04 + 571.04 + + + + + diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 9098a2dd..2faa6d2c 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ org.mustangproject.ZUGFeRD mustang Mustang - 1.4.2-SNAPSHOT + 1.5.2-SNAPSHOT The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs http://www.mustangproject.org/ @@ -41,27 +41,22 @@ scm:git:https://github.com/ZUGFeRD/mustangproject.git scm:git:https://github.com/ZUGFeRD/mustangproject.git - v1.4.0 + mustang-1.5.0 https://github.com/ZUGFeRD/mustangproject + + + + maven-release-plugin + 2.5.3 + + + - - maven-assembly-plugin - - - - org.mustangproject.toecount.Toecount - - - - jar-with-dependencies - - - maven-compiler-plugin - 2.3.2 + 3.6.1 @@ -86,7 +81,7 @@ com.github.github site-maven-plugin - 0.11 + 0.12 deploy @@ -125,7 +120,38 @@ + + + org.mustangproject.toecount.Toecount + + true + + + log4j:log4j + + ** + + + + commons-logging:commons-logging + + ** + + + + com.sun.xml.bind:jaxb-impl + + ** + + + + com.sun.xml.bind:jaxb-core + + ** + + + @@ -157,7 +183,7 @@ 2.1 org.mustangproject.ZUGFeRD.model - src/main/schema/ZUGFeRD1p0.xsd + src/main/resources/schema/ZUGFeRD1p0.xsd @@ -175,7 +201,7 @@ junit junit - 4.11 + 4.12 test @@ -202,10 +228,6 @@ ph-jaxb com.helger - - Saxon-HE - net.sf.saxon - diff --git a/pom.xml b/pom.xml index da9dcc67..732427df 100644 --- a/pom.xml +++ b/pom.xml @@ -1,293 +1,298 @@ - 4.0.0 - org.mustangproject.ZUGFeRD - mustang - 1.5.2-SNAPSHOT - jar - Mustang - The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs - http://www.mustangproject.org/ - - scm:git:https://github.com/ZUGFeRD/mustangproject.git - scm:git:https://github.com/ZUGFeRD/mustangproject.git - https://github.com/ZUGFeRD/mustangproject - mustang-1.5.0 - - - - sonatype-oss-public - https://oss.sonatype.org/content/groups/public/ - - true - - - true - - - - - - internal.repo - Temporary Staging Repository - file://${project.build.directory}/mvn-repo - - - - UTF-8 - github - -Xdoclint:none - - 1.7 - 1.7 - 1.7 - - + 4.0.0 + org.mustangproject.ZUGFeRD + mustang + 1.5.2-SNAPSHOT + jar + Mustang + The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs + http://www.mustangproject.org/ + + scm:git:https://github.com/ZUGFeRD/mustangproject.git + scm:git:https://github.com/ZUGFeRD/mustangproject.git + https://github.com/ZUGFeRD/mustangproject + mustang-1.5.0 + + + + sonatype-oss-public + https://oss.sonatype.org/content/groups/public/ + + true + + + true + + + + + + internal.repo + Temporary Staging Repository + file://${project.build.directory}/mvn-repo + + + + UTF-8 + github + -Xdoclint:none + + 1.7 + 1.7 + 1.7 + + + + + net.sf.saxon + Saxon-HE + 9.8.0-11 + + + com.sun.xml.bind + jaxb-impl + 2.2.11 + + + com.sun.xml.bind + jaxb-core + 2.2.11 + + + org.glassfish.jaxb + jaxb-runtime + 2.2.11 + + + org.apache.pdfbox + preflight + 2.0.9 + + + org.apache.pdfbox + pdfbox + 2.0.9 + + + junit + junit + 4.12 + test + + + com.helger + ph-schematron + 4.3.1 + test + + + + com.sanityinc + jargs + 2.0-SNAPSHOT + - - com.sun.xml.bind - jaxb-impl - 2.2.11 - - - com.sun.xml.bind - jaxb-core - 2.2.11 - - - org.glassfish.jaxb - jaxb-runtime - 2.2.11 - - - org.apache.pdfbox - preflight - 2.0.9 - - - org.apache.pdfbox - pdfbox - 2.0.9 - - - junit - junit - 4.11 - test - - - com.helger - ph-schematron - 4.3.1 - test - - - - com.sanityinc - jargs - 2.0-SNAPSHOT - - - - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - - - + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + + + - - - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 - - - - true - org.mustangproject.toecount.Toecount - - - - jar-with-dependencies - - - - 1.7 - 1.7 - - + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + + true + org.mustangproject.toecount.Toecount + + + + jar-with-dependencies + + + + 1.7 + 1.7 + + - - - maven-deploy-plugin - 2.8.2 - - internal.repo::default::file://${project.build.directory}/mvn-repo - - - - com.github.github - site-maven-plugin - 0.12 - - Maven artifacts for ${project.version} - - true - - ${project.build.directory}/mvn-repo - - refs/heads/mvn-repo - - - **/* - - true - mustangproject - - ZUGFeRD - - - - - - - site - - deploy - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.4.3 - - - - org.mustangproject.toecount.Toecount - - - true - - - log4j:log4j - - ** - - - - commons-logging:commons-logging - - ** - - - - com.sun.xml.bind:jaxb-impl - - ** - - - - com.sun.xml.bind:jaxb-core - - ** - - - - - - - package - - shade - - - - - - - - - - - - - org.codehaus.mojo - templating-maven-plugin - 1.0.0 - - - filtering-java-templates - - filter-sources - - - - - - org.codehaus.mojo - jaxb2-maven-plugin - 2.3.1 - - - xjc - - xjc - - - - - 2.1 - org.mustangproject.ZUGFeRD.model - - src/main/resources/schema/ZUGFeRD1p0.xsd - - - - - - - - User List - https://groups.google.com/forum/?hl=de#!forum/mustangproject - - - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - - - - Jochen Stärk - jstaerk@usegroup.de - - architect - developer - - - - Alexander Schmidt - schmidt.alexander@mail.de - - developer - - - + + + maven-deploy-plugin + 2.8.2 + + internal.repo::default::file://${project.build.directory}/mvn-repo + + + + com.github.github + site-maven-plugin + 0.12 + + Maven artifacts for ${project.version} + + true + + ${project.build.directory}/mvn-repo + + refs/heads/mvn-repo + + + **/* + + true + mustangproject + + ZUGFeRD + + + + + + + site + + deploy + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + + org.mustangproject.toecount.Toecount + + + true + + + log4j:log4j + + ** + + + + commons-logging:commons-logging + + ** + + + + com.sun.xml.bind:jaxb-impl + + ** + + + + com.sun.xml.bind:jaxb-core + + ** + + + + + + + package + + shade + + + + + + + + + + + + + org.codehaus.mojo + templating-maven-plugin + 1.0.0 + + + filtering-java-templates + + filter-sources + + + + + + org.codehaus.mojo + jaxb2-maven-plugin + 2.3.1 + + + xjc + + xjc + + + + + 2.1 + org.mustangproject.ZUGFeRD.model + + src/main/resources/schema/ZUGFeRD1p0.xsd + + + + + + + + User List + https://groups.google.com/forum/?hl=de#!forum/mustangproject + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + + Jochen Stärk + jstaerk@usegroup.de + + architect + developer + + + + Alexander Schmidt + schmidt.alexander@mail.de + + developer + + + diff --git a/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java b/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java index 20c918cb..a85d0222 100644 --- a/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java +++ b/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; public final class Version { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java b/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java index 44494ad6..f5b9825c 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java @@ -1,9 +1,27 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; public class CustomXMLProvider implements IXMLProvider { protected byte[] zugferdData; - + @Override public byte[] getXML() { return zugferdData; @@ -14,20 +32,20 @@ public class CustomXMLProvider implements IXMLProvider { if (!zf.contains(" VATPercentAmountMap=getVATPercentAmountMap(); for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); - res=res.add(amount.getCalculated()); + res=res.add(amount.getCalculated()); } - + return res; } @@ -135,13 +153,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { * which taxes have been used with which amounts in this transaction, * empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable * to 19% VAT (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) - * 190 Eur + * 190 Eur * @return * */ private HashMap getVATPercentAmountMap() { HashMap hm=new HashMap (); - + for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { BigDecimal percent=currentItem.getProduct().getVATPercent(); LineCalc lc=new LineCalc(currentItem); @@ -151,14 +169,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { hm.put(percent, itemVATAmount); } else { hm.put(percent, current.add(itemVATAmount)); - + } } return hm; } - + @Override public void generateXML(IZUGFeRDExportableTransaction trans) { @@ -168,7 +186,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { String testBooleanStr="false"; if (isTest) { testBooleanStr="true"; - + } String senderReg=""; if (trans.getOwnOrganisationFullPlaintextInfo()!=null) { @@ -179,11 +197,11 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + " \n" + "REG\n" + "\n"; - + } - - - + + + String xml= "\n" //$NON-NLS-1$ + "\n"; //$NON-NLS-1$ - + HashMap VATPercentAmountMap=getVATPercentAmountMap(); for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); @@ -414,7 +432,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { xml=xml + " \n" //$NON-NLS-1$ + ""; //$NON-NLS-1$ - + byte[] zugferdRaw; try { zugferdRaw = xml.getBytes("UTF-8"); diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDConformanceLevel.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDConformanceLevel.java index 24acf263..432c24c6 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDConformanceLevel.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDConformanceLevel.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; public enum ZUGFeRDConformanceLevel { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java index 232223a4..f5b493c0 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; public class ZUGFeRDExportException extends RuntimeException { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java index 9e7e0417..5a9dea9b 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java @@ -1,3 +1,22 @@ + +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; /* @@ -10,6 +29,18 @@ package org.mustangproject.ZUGFeRD; * */ +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; +import javax.xml.transform.TransformerException; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSDictionary; @@ -30,19 +61,6 @@ import org.apache.xmpbox.schema.XMPBasicSchema; import org.apache.xmpbox.type.BadFieldValueException; import org.apache.xmpbox.xml.XmpSerializer; -import javax.xml.transform.TransformerException; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Map; - public class ZUGFeRDExporter implements Closeable { public static final int DefaultZUGFeRDVersion = 1; @@ -435,7 +453,7 @@ public class ZUGFeRDExporter implements Closeable { * * @param zUGFeRDConformanceLevel * the new conformance level - * + * * @deprecated Use {@link ZUGFeRDExporterFromA1Factory} instead */ @Deprecated @@ -590,7 +608,7 @@ public class ZUGFeRDExporter implements Closeable { public void setPDFA3(boolean ensurePDFisUpgraded) { this.ensurePDFisUpgraded = ensurePDFisUpgraded; } - + public void setAttachZUGFeRDHeaders(boolean attachZUGFeRDHeaders) { this.attachZUGFeRDHeaders=attachZUGFeRDHeaders; } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1Factory.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1Factory.java index e55497f7..7862f53e 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1Factory.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1Factory.java @@ -1,10 +1,28 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; public class ZUGFeRDExporterFromA1Factory extends ZUGFeRDExporterFromA3Factory implements IExporterFactory { public ZUGFeRDExporterFromA1Factory() { ensurePDFisUpgraded=true; - + } } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3Factory.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3Factory.java index 4c07dafb..4062be0f 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3Factory.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3Factory.java @@ -1,5 +1,30 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import javax.activation.DataSource; +import javax.activation.FileDataSource; import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.preflight.PreflightDocument; @@ -7,22 +32,13 @@ import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.parser.PreflightParser; import org.apache.pdfbox.preflight.utils.ByteArrayDataSource; - -import javax.activation.DataSource; -import javax.activation.FileDataSource; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - public class ZUGFeRDExporterFromA3Factory implements IExporterFactory { protected boolean ignorePDFAErrors = false; protected ZUGFeRDConformanceLevel zugferdConformanceLevel = ZUGFeRDConformanceLevel.EXTENDED; protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; protected String producer = "mustangproject"; protected String creator = "mustangproject"; - + protected int ZFVersion=ZUGFeRDExporter.DefaultZUGFeRDVersion; protected boolean ensurePDFisUpgraded=false; private boolean attachZUGFeRDHeaders=true; @@ -34,7 +50,7 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory { * filename of an PDF/A1 compliant document */ public ZUGFeRDExporter load(String pdfFilename) throws IOException { - + ensurePDFIsValidPDFA(new FileDataSource(pdfFilename)); ZUGFeRDExporter zugFeRDExporter; PDDocument doc = PDDocument.load(new File(pdfFilename)); @@ -45,12 +61,12 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory { zugFeRDExporter.setProducer(producer); zugFeRDExporter.setAttachZUGFeRDHeaders(attachZUGFeRDHeaders); zugFeRDExporter.setPDFA3(ensurePDFisUpgraded); - + return zugFeRDExporter; } - - + + /** * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the @@ -70,10 +86,10 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory { zugFeRDExporter.setProducer(producer); zugFeRDExporter.setAttachZUGFeRDHeaders(attachZUGFeRDHeaders); zugFeRDExporter.setPDFA3(ensurePDFisUpgraded); - + return zugFeRDExporter; } - + public ZUGFeRDExporterFromA3Factory () { ensurePDFisUpgraded=false; diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 54ae06c4..d812978a 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; /** * Mustangproject's ZUGFeRD implementation @@ -14,7 +32,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; - import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -39,7 +56,7 @@ public class ZUGFeRDImporter { /* * call extract(importFilename). containsMeta() will return if ZUGFeRD data has * been found, afterwards you can call getBIC(), getIBAN() etc. - * + * */ /** @var if metadata has been found */ @@ -68,7 +85,7 @@ public class ZUGFeRDImporter { bis.close(); } catch (IOException ioe) { ioe.printStackTrace(); - } + } } /** @@ -157,25 +174,25 @@ public class ZUGFeRDImporter { /* * ndList = document .getElementsByTagName("GermanBankleitzahlID"); * //$NON-NLS-1$ - * + * * for (int bookingIndex = 0; bookingIndex < ndList .getLength(); * bookingIndex++) { Node booking = ndList.item(bookingIndex); // if there is a * attribute in the tag number:value setBIC(booking.getTextContent()); - * + * * } - * + * * ndList = document.getElementsByTagName("ProprietaryID"); //$NON-NLS-1$ - * + * * for (int bookingIndex = 0; bookingIndex < ndList .getLength(); * bookingIndex++) { Node booking = ndList.item(bookingIndex); // if there is a * attribute in the tag number:value setIBAN(booking.getTextContent()); - * + * * } DE1234 * * * DE5656565 Commerzbank * - * + * */ /*** diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDMigrator.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDMigrator.java index df5069e5..9f7cbe20 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDMigrator.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDMigrator.java @@ -1,89 +1,98 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; - +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.transform.Source; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; - - public class ZUGFeRDMigrator { - static final ClassLoader cl = ZUGFeRDMigrator.class.getClassLoader(); - private static TransformerFactory factory = null; - private static final String resourcePath = ""; //$NON-NLS-1$ - private static TransformerFactory getTransformerFactory() { - //TransformerFactory fact = new net.sf.saxon.TransformerFactoryImpl(); - TransformerFactory fact = TransformerFactory.newInstance(); - fact.setURIResolver(new ClasspathResourceURIResolver()); - return fact; - } - public String migrateFromV1ToV2(String xmlFilename) { -/*** - * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf - * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf -http://countwordsfree.com/xmlviewer - */ - ByteArrayOutputStream baos=new ByteArrayOutputStream(); - try { - applySchematronXsl(new FileInputStream(xmlFilename), baos); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (TransformerException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String res=null; - try { - res=baos.toString("UTF-8"); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return res; - } + static final ClassLoader CLASS_LOADER = ZUGFeRDMigrator.class.getClassLoader(); + private static final String RESOURCE_PATH = ""; //$NON-NLS-1$ + private static final Logger LOG = Logger.getLogger(ZUGFeRDMigrator.class.getName()); +// private static File createTempFileResult(final Transformer transformer, final StreamSource toTransform, +// final String suffix) throws TransformerException, IOException { +// File result = File.createTempFile("ZUV_", suffix); //$NON-NLS-1$ +// result.deleteOnExit(); +// +// try (FileOutputStream fos = new FileOutputStream(result)) { +// transformer.transform(toTransform, new StreamResult(fos)); +// } +// return result; +// } + private TransformerFactory mFactory = null; + private Templates mXsltTemplate = null; - private static File createTempFileResult(final Transformer transformer, final StreamSource toTransform, - final String suffix) throws TransformerException, IOException { - File result = File.createTempFile("ZUV_", suffix); //$NON-NLS-1$ - result.deleteOnExit(); + public ZUGFeRDMigrator() { + mFactory = new net.sf.saxon.TransformerFactoryImpl(); + //fact = TransformerFactory.newInstance(); + mFactory.setURIResolver(new ClasspathResourceURIResolver()); + try { + mXsltTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "COMFORTtoEN16931.xsl"))); + } catch (TransformerConfigurationException ex) { + LOG.log(Level.SEVERE, null, ex); + } + } - try (FileOutputStream fos = new FileOutputStream(result)) { - transformer.transform(toTransform, new StreamResult(fos)); - } - return result; - } - - private static class ClasspathResourceURIResolver implements URIResolver { - ClasspathResourceURIResolver() { - // Do nothing, just prevents synthetic access warning. - } + public String migrateFromV1ToV2(String xmlFilename) throws FileNotFoundException, TransformerException, UnsupportedEncodingException { + /** + * * + * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf + * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf + * http://countwordsfree.com/xmlviewer + */ + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + applySchematronXsl(new FileInputStream(xmlFilename), baos); + String res = null; + res = baos.toString("UTF-8"); + return res; + } - @Override - public Source resolve(String href, String base) throws TransformerException { - return new StreamSource(cl.getResourceAsStream(resourcePath + href)); - } - } - - public static void applySchematronXsl(final InputStream xmlFile, - final OutputStream EN16931Outstream) throws TransformerException { - factory=getTransformerFactory(); - Transformer transformer = factory.newTransformer(new StreamSource(cl.getResourceAsStream(resourcePath+"COMFORTtoEN16931.xsl"))); - transformer.transform(new StreamSource(xmlFile), new StreamResult(EN16931Outstream)); - } + public void applySchematronXsl(final InputStream xmlFile, + final OutputStream EN16931Outstream) throws TransformerException { + Transformer transformer = mXsltTemplate.newTransformer(); + transformer.transform(new StreamSource(xmlFile), new StreamResult(EN16931Outstream)); + } + private static class ClasspathResourceURIResolver implements URIResolver { + ClasspathResourceURIResolver() { + // Do nothing, just prevents synthetic access warning. + } + + @Override + public Source resolve(String href, String base) throws TransformerException { + return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + href)); + } + } } diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java index ac31953f..a892d746 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverter.java @@ -1,5 +1,33 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import javax.xml.bind.JAXBElement; import org.mustangproject.ZUGFeRD.model.AmountType; import org.mustangproject.ZUGFeRD.model.CodeType; import org.mustangproject.ZUGFeRD.model.CountryIDType; @@ -48,17 +76,6 @@ import org.mustangproject.ZUGFeRD.model.TradeSettlementMonetarySummationType; import org.mustangproject.ZUGFeRD.model.TradeSettlementPaymentMeansType; import org.mustangproject.ZUGFeRD.model.TradeTaxType; -import javax.xml.bind.JAXBElement; -import java.math.BigDecimal; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - class ZUGFeRDTransactionModelConverter { private static final SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); private static final ObjectFactory xmlFactory = new ObjectFactory(); @@ -827,12 +844,12 @@ class ZUGFeRDTransactionModelConverter { * DecimalFormatSymbols(); symbols.setDecimalSeparator(','); * symbols.setGroupingSeparator(' '); * df.setDecimalFormatSymbols(symbols); - * + * * but that would not switch off grouping. Although I liked very much * the (incomplete) "BNF diagram" in * http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html * in the end I decided to calculate myself and take eur+sparator+cents - * + * * This function will cut off, i.e. floor() subcent values Tests: * System.err.println(utils.currencyFormat(new BigDecimal(0), * ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"), @@ -841,7 +858,7 @@ class ZUGFeRDTransactionModelConverter { * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"), * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"), * ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ",")); - * + * * results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00 */ value = value.setScale(scale, BigDecimal.ROUND_HALF_UP); // first, round @@ -944,7 +961,7 @@ class ZUGFeRDTransactionModelConverter { return hm; } - + ZUGFeRDTransactionModelConverter withTest(boolean isTest) { this.isTest = isTest; return this; diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java index ee3dac32..7928a843 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class DateTimeTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java index e3aa9c73..bf1077b8 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class DocumentCodeTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java index 4dfd44fa..57033f6d 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class DocumentContextParameterTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/NoteTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/NoteTypeConstants.java index ac01c71d..dae6317c 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/NoteTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/NoteTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class NoteTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/PaymentMeansCodeTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/PaymentMeansCodeTypeConstants.java index 6cd01ddc..c3d52cfa 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/PaymentMeansCodeTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/PaymentMeansCodeTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class PaymentMeansCodeTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/QuantityTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/QuantityTypeConstants.java index f7a2c8c1..bc05313d 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/QuantityTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/QuantityTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class QuantityTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java index c11c53ac..2fba730a 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class TaxCategoryCodeTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/TaxRegistrationTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/TaxRegistrationTypeConstants.java index 37563fc6..ad48e97b 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/TaxRegistrationTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/TaxRegistrationTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class TaxRegistrationTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/TaxTypeCodeTypeConstants.java b/src/main/java/org/mustangproject/ZUGFeRD/model/TaxTypeCodeTypeConstants.java index 804f5cd3..4bf81037 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/TaxTypeCodeTypeConstants.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/TaxTypeCodeTypeConstants.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; public class TaxTypeCodeTypeConstants { diff --git a/src/main/java/org/mustangproject/ZUGFeRD/model/ZFNamespacePrefixMapper.java b/src/main/java/org/mustangproject/ZUGFeRD/model/ZFNamespacePrefixMapper.java index 37c93585..18e48432 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/model/ZFNamespacePrefixMapper.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/model/ZFNamespacePrefixMapper.java @@ -1,14 +1,31 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD.model; +import com.sun.xml.bind.marshaller.NamespacePrefixMapper; import java.util.HashMap; import java.util.Map; -import com.sun.xml.bind.marshaller.NamespacePrefixMapper; - public class ZFNamespacePrefixMapper extends NamespacePrefixMapper { private Map namespaceMap = new HashMap<>(); - + /** * Create mappings. */ @@ -18,7 +35,7 @@ public class ZFNamespacePrefixMapper extends NamespacePrefixMapper { namespaceMap.put("urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15", "udt"); namespaceMap.put("urn:ferd:CrossIndustryDocument:invoice:1p0", "rsm"); } - + /* (non-Javadoc) * Returning null when not found based on spec. * @see com.sun.xml.bind.marshaller.NamespacePrefixMapper#getPreferredPrefix(java.lang.String, java.lang.String, boolean) diff --git a/src/main/java/org/mustangproject/toecount/FileChecker.java b/src/main/java/org/mustangproject/toecount/FileChecker.java index e0497b41..f7852cf5 100755 --- a/src/main/java/org/mustangproject/toecount/FileChecker.java +++ b/src/main/java/org/mustangproject/toecount/FileChecker.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.toecount; import org.mustangproject.ZUGFeRD.ZUGFeRDImporter; @@ -6,7 +24,7 @@ public class FileChecker { String filename; StatRun thisRun; boolean isPDF=false; - + public FileChecker(String filename, StatRun statistics) { this.filename=filename; thisRun=statistics; @@ -21,12 +39,12 @@ public class FileChecker { thisRun.incPDFCount(); } } - + } else { - thisRun.incPDFCount(); + thisRun.incPDFCount(); } } - + public boolean checkForZUGFeRD() { if ((!isPDF)&&(!thisRun.shallIgnoreFileExt())) { return false; @@ -48,22 +66,22 @@ public class FileChecker { at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extract(ZUGFeRDImporter.java:64) at toecount.FileChecker.checkForZUGFeRD(FileChecker.java:33) at toecount.Toecount.main(Toecount.java:111) - * + * */ // Ignore nevertheless, most likely we're batch processing return false; } catch (Exception e2) { /** - * probably thrown up from + * probably thrown up from AM org.apache.pdfbox.pdfparser.PDFParser parse, most likely INFORMATION: Document is encrypted - but also other internal PDF errors possible like + but also other internal PDF errors possible like ..Okt 23, 2015 11:17:53 AM org.apache.pdfbox.pdfparser.XrefTrailerResolver setStartxref */ return false; } } - + public boolean isPDF() { return isPDF; } @@ -71,5 +89,5 @@ public class FileChecker { public String getOutputLine() { return thisRun.getOutputLine(); } - + } diff --git a/src/main/java/org/mustangproject/toecount/FileTraverser.java b/src/main/java/org/mustangproject/toecount/FileTraverser.java index 5bae999a..aa773318 100755 --- a/src/main/java/org/mustangproject/toecount/FileTraverser.java +++ b/src/main/java/org/mustangproject/toecount/FileTraverser.java @@ -1,9 +1,26 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.toecount; -import static java.nio.file.FileVisitResult.CONTINUE; - import java.io.IOException; import java.nio.file.FileVisitResult; +import static java.nio.file.FileVisitResult.CONTINUE; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; @@ -29,7 +46,7 @@ public class FileTraverser extends SimpleFileVisitor { fc.checkForZUGFeRD(); System.out.print(fc.getOutputLine()); - } + } return CONTINUE; } diff --git a/src/main/java/org/mustangproject/toecount/StatRun.java b/src/main/java/org/mustangproject/toecount/StatRun.java index 04769479..eaa82683 100755 --- a/src/main/java/org/mustangproject/toecount/StatRun.java +++ b/src/main/java/org/mustangproject/toecount/StatRun.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.toecount; public class StatRun { @@ -10,7 +28,7 @@ public class StatRun { public void ignoreFileExtension() { checkFileExt=false; } - + public boolean shallIgnoreFileExt() { return !checkFileExt; } @@ -51,11 +69,11 @@ public class StatRun { * @return */ public String getSummaryLine() { - + return "\r\n===================================================================\r\n"+String.format( "Files:\t%d\tDirs:\t%d\tPDF:\t%d\tZUGFeRD:\t%d\r\n", getFileCount(), getDirCount(), getPDFCount(), getZUGFeRDCount()); - + } /*** * show that something is happening @@ -65,5 +83,5 @@ public class StatRun { return "."; } - + } diff --git a/src/main/java/org/mustangproject/toecount/Toecount.java b/src/main/java/org/mustangproject/toecount/Toecount.java index fea91d50..31de9a2c 100755 --- a/src/main/java/org/mustangproject/toecount/Toecount.java +++ b/src/main/java/org/mustangproject/toecount/Toecount.java @@ -1,18 +1,42 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.toecount; /*** * This is the command line interface to mustangproject - * + * */ +import com.sanityinc.jargs.CmdLineParser; +import com.sanityinc.jargs.CmdLineParser.Option; import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; - +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.transform.TransformerException; import org.mustangproject.ZUGFeRD.ZUGFeRDConformanceLevel; import org.mustangproject.ZUGFeRD.ZUGFeRDExporter; import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA1Factory; @@ -20,9 +44,6 @@ import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA3Factory; import org.mustangproject.ZUGFeRD.ZUGFeRDImporter; import org.mustangproject.ZUGFeRD.ZUGFeRDMigrator; -import com.sanityinc.jargs.CmdLineParser; -import com.sanityinc.jargs.CmdLineParser.Option; - public class Toecount { // build with: /opt/local/bin/mvn clean compile assembly:single private static void printUsage() { @@ -53,7 +74,7 @@ public class Toecount { /*** * Asks the user for a String (offering a defaultValue) conforming to a Regex * pattern - * + * * @param prompt * @param defaultValue * @param pattern @@ -98,10 +119,10 @@ public class Toecount { * Prompts the user for a input or output filename * @param prompt * @param defaultFilename - * @param expectedExtension will warn if filename does not match expected file extension + * @param expectedExtension will warn if filename does not match expected file extension * @param ensureFileExists will warn if file does NOT exist (for input files) * @param ensureFileNotExists will warn if file DOES exist (for output files) - * + * * @return String */ protected static String getFilenameFromUser(String prompt, String defaultFilename, String expectedExtension, boolean ensureFileExists, boolean ensureFileNotExists) { @@ -147,7 +168,7 @@ public class Toecount { System.out.println("File does not exist, try again or CTRL+C to cancel"); // discard the input, a scanner.reset is not sufficient fileExistenceOK = false; - } + } } else { fileExistenceOK=true; @@ -158,7 +179,7 @@ public class Toecount { System.out.println("Output file already exists, try again or CTRL+C to cancel"); // discard the input, a scanner.reset is not sufficient - } + } } else { fileExistenceOK=true; } @@ -275,12 +296,12 @@ public class Toecount { String versionInput = ""; try { versionInput = getStringFromUser("ZUGFeRD version (1 or 2)", "1", "1|2"); - + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } - + String profileInput = ""; int zfIntVersion=Integer.valueOf(versionInput); @@ -288,7 +309,7 @@ public class Toecount { if (zfIntVersion==1) { try { profileInput = getStringFromUser("ZUGFeRD profile b)asic, c)omfort or e)xtended", "e", "B|b|C|c|E|e").toLowerCase(); - + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -296,17 +317,17 @@ public class Toecount { if (profileInput.equals("b")) { profile=ZUGFeRDConformanceLevel.BASIC; } else if (profileInput.equals("c")) { - profile=ZUGFeRDConformanceLevel.COMFORT; + profile=ZUGFeRDConformanceLevel.COMFORT; } else if (profileInput.equals("e")) { profile=ZUGFeRDConformanceLevel.EXTENDED; - + } - + } else if (zfIntVersion==2) { try { - profileInput = getStringFromUser("ZUGFeRD profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + + profileInput = getStringFromUser("ZUGFeRD profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, E[X]TENDED", "E", "M|m|W|w|B|b|C|c|E|e|X|x|").toLowerCase(); - + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -314,7 +335,7 @@ public class Toecount { if (profileInput.equals("m")) { profile=ZUGFeRDConformanceLevel.MINIMUM; } else if (profileInput.equals("w")) { - profile=ZUGFeRDConformanceLevel.BASICWL; + profile=ZUGFeRDConformanceLevel.BASICWL; } else if (profileInput.equals("b")) { profile=ZUGFeRDConformanceLevel.BASIC; } else if (profileInput.equals("c")) { @@ -324,13 +345,13 @@ public class Toecount { } else if (profileInput.equals("x")) { profile=ZUGFeRDConformanceLevel.EXTENDED; } - + } - + ZUGFeRDExporter ze = new ZUGFeRDExporterFromA3Factory().setProducer("Toecount") .setCreator(System.getProperty("user.name")).setZUGFeRDConformanceLevel(profile).load(pdfName); ze.setZUGFeRDVersion(zfIntVersion); - + ze.setZUGFeRDXMLData(Files.readAllBytes(Paths.get(xmlName))); ze.export(outName); @@ -373,21 +394,25 @@ public class Toecount { } System.out.println("Written to " + outName); } else if (upgradeRequested) { - String xmlName = ""; - String outName = ""; + try { + String xmlName = ""; + String outName = ""; - try { - xmlName = getFilenameFromUser("ZUGFeRD 1.0 XML source", "ZUGFeRD-invoice.xml", "xml", true, false); - outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.xml", "xml", false, true); - - ZUGFeRDMigrator zmi = new ZUGFeRDMigrator(); - String xml = zmi.migrateFromV1ToV2(xmlName); - Files.write(Paths.get(outName), xml.getBytes()); - } catch (IOException e) { - e.printStackTrace(); - } - System.out.println("Written to " + outName); + xmlName = getFilenameFromUser("ZUGFeRD 1.0 XML source", "ZUGFeRD-invoice.xml", "xml", true, false); + outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.xml", "xml", false, true); + ZUGFeRDMigrator zmi = new ZUGFeRDMigrator(); + String xml = null; + xml = zmi.migrateFromV1ToV2(xmlName); + Files.write(Paths.get(outName), xml.getBytes()); + System.out.println("Written to " + outName); + } catch (FileNotFoundException ex) { + Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, ex); + } catch (TransformerException | UnsupportedEncodingException ex) { + Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, ex); + } } else { // no argument or argument unknown printUsage(); diff --git a/src/main/resources/COMFORTtoEN16931.xsl b/src/main/resources/COMFORTtoEN16931.xsl index 5dfee4f3..d6eb2e03 100644 --- a/src/main/resources/COMFORTtoEN16931.xsl +++ b/src/main/resources/COMFORTtoEN16931.xsl @@ -1,3 +1,19 @@ + \n" + "\n" + "\n" + ""; zea1.setZUGFeRDXMLData(ownZUGFeRDXML.getBytes("UTF-8")); - + ByteArrayOutputStream baos=new ByteArrayOutputStream(); zea1.disableAutoClose(true); zea1.export(TARGET_PDF); diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index c1c2d44b..288a0d81 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; import java.io.IOException; @@ -7,11 +25,9 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; - import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @@ -403,7 +419,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp try(InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); - + ZUGFeRDExporter ze = new ZUGFeRDExporterFromA3Factory() .setProducer("My Application") .setCreator(System.getProperty("user.name")) diff --git a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index bf07283d..d8cde149 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -1,3 +1,21 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; import java.io.ByteArrayOutputStream; @@ -8,13 +26,11 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; - -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExportableTransaction { @@ -367,7 +383,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(2).load(SOURCE_PDF)) { - + ze.PDFattachZugferdFile(this); ze.disableAutoClose(true); ze.export(TARGET_PDF); diff --git a/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java b/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java new file mode 100644 index 00000000..dafbe570 --- /dev/null +++ b/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java @@ -0,0 +1,196 @@ +/** ********************************************************************** + * + * 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 java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.logging.Level; +import java.util.logging.Logger; + + + +/** This test utility class is providing usability functions for test file resources */ +public class ResourceUtilities { + private static final Logger LOG = Logger.getLogger(ResourceUtilities.class.getName()); + + /** Loading a File into a String using a certain encoding and file path */ + public static String readFile(Charset encoding, String path) throws IOException { + byte[] content = Files.readAllBytes(Paths.get(path)); + return new String(content, encoding); + } + + /** Saving a String as a file to a certain file path */ + public static void saveFile(Charset encoding, String path, String content) throws FileNotFoundException { + + // resources will be released automatically + try (PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(path)), encoding), true)) { + out.println(content); + } + } + + + /** The relative path of the test file will be resolved and the absolute will be returned + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return the absolute path of the test file + * @throws FileNotFoundException If the file could not be found + */ + public static String getAbsolutePath(String relativeFilePath) throws FileNotFoundException { + URI uri = null; + try { + uri = ResourceUtilities.class.getClassLoader().getResource(relativeFilePath).toURI(); + uri = new URI(toExternalForm(uri)); + } catch (URISyntaxException ex) { + LOG.log(Level.SEVERE, null, ex); + } + if (uri == null) { + throw new FileNotFoundException("Could not find the file '" + relativeFilePath + "'!"); + } + return uri.getPath(); + } + + /** The relative path of the test file will be resolved and the absolute will be returned + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return the URI created based on the relativeFilePath + * @throws URISyntaxException if no URI could be created from the given relative path + */ + public static URI getURI(String relativeFilePath) throws URISyntaxException { + String filePath = "file:" + ResourceUtilities.class.getClassLoader().getResource(relativeFilePath).getPath(); + filePath = toExternalForm(new URI(filePath)); + return new URI(filePath); + } + + /** The relative path of the test file will be used to determine an absolute + * path to a temporary directory in the output directory. + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return absolute path to a test output + * @throws IOException if no absolute Path could be created. + */ + public static String getTestOutput(String relativeFilePath) throws IOException { + return File.createTempFile(relativeFilePath, null).getAbsolutePath(); + } + + /** The Input of the test file will be resolved and the absolute will be returned + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return the absolute path of the test file + */ + public static InputStream getTestResourceAsStream(String relativeFilePath) { + return ResourceUtilities.class.getClassLoader().getResourceAsStream(relativeFilePath); + } + + /** Relative to the test output directory a test file will be returned dependent on the relativeFilePath provided. + * @param relativeFilePath Path of the test output resource relative to target/test-classes/. + * @return the empty File of the test output (to be filled) + */ + public static File newTestOutputFile(String relativeFilePath) { + String filepath = null; + try { + filepath = ResourceUtilities.class.getClassLoader().getResource("").toURI().getPath() + relativeFilePath; + } catch (URISyntaxException ex) { + LOG.log(Level.SEVERE, null, ex); + } + return new File(filepath); + } + + /** + * @return the absolute path of the test output folder, which is usually target/test-classes/. + */ + public static String getTestOutputFolder() { + String testFolder = null; + try { + testFolder = ResourceUtilities.class.getClassLoader().getResource("").toURI().getPath(); + } catch (URISyntaxException ex) { + LOG.log(Level.SEVERE, null, ex); + } + return testFolder; + } + + public static File getTempTestDirectory() { + File tempDir = new File(ResourceUtilities.getTestOutputFolder() + "temp"); + tempDir.mkdir(); //if it already exist no problem + return tempDir; + } + +/** + * To fix the 3 slashes bug for File URI: For example: + * file:/C:/work/test.txt -> file:///C:/work/test.txt + * + * @param u - the File URI + * @return the String of the URI + */ + public static String toExternalForm(URI u) { + StringBuilder sb = new StringBuilder(); + if (u.getScheme() != null) { + sb.append(u.getScheme()); + sb.append(':'); + } + if (u.isOpaque()) { + sb.append(u.getSchemeSpecificPart()); + } else { + if (u.getHost() != null) { + sb.append("//"); + if (u.getUserInfo() != null) { + sb.append(u.getUserInfo()); + sb.append('@'); + } + boolean needBrackets = ((u.getHost().indexOf(':') >= 0) && !u.getHost().startsWith("[") && !u.getHost().endsWith("]")); + if (needBrackets) + sb.append('['); + sb.append(u.getHost()); + if (needBrackets) + sb.append(']'); + if (u.getPort() != -1) { + sb.append(':'); + sb.append(u.getPort()); + } + } else if (u.getRawAuthority() != null) { + sb.append("//"); + sb.append(u.getRawAuthority()); + } else { + sb.append("//"); + } + if (u.getRawPath() != null) + sb.append(u.getRawPath()); + if (u.getRawQuery() != null) { + sb.append('?'); + sb.append(u.getRawQuery()); + } + } + if (u.getFragment() != null) { + sb.append('#'); + sb.append(u.getFragment()); + } + String ret = null; + try { + ret = new URI(sb.toString()).toASCIIString(); + } catch (URISyntaxException ex) { + LOG.log(Level.SEVERE, null, ex); + } + return ret; + } + private ResourceUtilities() { + } +} diff --git a/src/test/java/org/mustangproject/ZUGFeRD/VersionMigrationTest.java b/src/test/java/org/mustangproject/ZUGFeRD/VersionMigrationTest.java new file mode 100644 index 00000000..081f0ccc --- /dev/null +++ b/src/test/java/org/mustangproject/ZUGFeRD/VersionMigrationTest.java @@ -0,0 +1,144 @@ +/** ********************************************************************** + * + * 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 java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.transform.TransformerException; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + + +/** + * Every ZUGFeRD 1.0 XML file from src/test/resources/migration/input + * will be migrated to src/test/resources/migration/output. + * If there is a similar named file as test reference src/test/resources/migration/reference a test + * will be triggered for every single file. + * + * Note: Any 'ZUGFeRD1' will be exchanged to 'ZUGFeRD2' during migration and adequate reference will be searched for. + */ +@RunWith(Parameterized.class) +public class VersionMigrationTest { + + private static final Logger LOG = Logger.getLogger(VersionMigrationTest.class.getName()); + + private static final String INPUT_DIR = "src" + File.separator + "test" + File.separator + "resources" + File.separator + "migration" + File.separator + "input" + File.separator; + private static final String REFERENCE_DIR = "src" + File.separator + "test" + File.separator + "resources" + File.separator + "migration" + File.separator + "reference" + File.separator; + private static final String OUTPUT_DIR = "target" + File.separator + "test-classes" + File.separator + "migration" + File.separator + "output" + File.separator; + private File mTestFile = null; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + // Creating the output directory for the tests + new File(OUTPUT_DIR).mkdirs(); + } + + public VersionMigrationTest(File testFile) { + mTestFile = testFile; + } + + @Parameterized.Parameters(name = "Test# {index}: {0}") + public static Collection data() { + Collection testSuiteData = new ArrayList(); + addFilesFromFolder(new File(INPUT_DIR), testSuiteData); + return testSuiteData; + } + + private static void addFilesFromFolder(final File folder, Collection testSuiteData) { + String filePath = null; + for (final File fileEntry : folder.listFiles()) { + filePath = fileEntry.getAbsolutePath(); + if (fileEntry.isDirectory()) { + LOG.log(Level.INFO, "*** testDirectory:{0}", filePath); + addFilesFromFolder(fileEntry, testSuiteData); + } else { + LOG.log(Level.INFO, "*** testFile: {0}", filePath); + Object[] testData = new Object[]{fileEntry}; + testSuiteData.add(testData); + } + } + } + + @Test + /** + * ZUGFeRD 1.0 to 2.0 migration test. + * For more information see class description. */ + public void testFile() { + testMigration(mTestFile.getName()); + } + + private void testMigration(String fileName) { + try { + String tmp = new ZUGFeRDMigrator().migrateFromV1ToV2(INPUT_DIR + fileName); + String newName = fileName.replace("ZUGFeRD1", "ZUGFeRD2"); + ResourceUtilities.saveFile(StandardCharsets.UTF_8, OUTPUT_DIR + newName, tmp); + if(new File(REFERENCE_DIR + newName).exists()){ + // we need to save the string and reload it otherwise two bytes are missing (likely EOF related) + String outXML = ResourceUtilities.readFile(StandardCharsets.UTF_8, OUTPUT_DIR + newName); + String refXML = ResourceUtilities.readFile(StandardCharsets.UTF_8, REFERENCE_DIR + newName); + int t = outXML.length(); + int r = refXML.length(); + if (t != r || !(outXML.equals(refXML))) { + LOG.info("There are differences between:" + + "\nZUGFeRD 2.0 Test Output @ " + OUTPUT_DIR + newName + + "\nZUGFeRD 2.0 Test Reference @ " + REFERENCE_DIR + newName); + LOG.info("\n\nFile sizes:\n " + + "\nZUGFeRD 2.0 Test Output character count: " + t + + "\nZUGFeRD 2.0 Test Refer. character count: " + r); + findLineDiffs(outXML, refXML); + Assert.fail("Version update failed, as test result and reference are different!"); + }else{ + LOG.log(Level.INFO,"\n*** Tested successfull migration from ZUGFeRD 1.0 to 2.0: '" + newName + "'' ***\n", OUTPUT_DIR); + } + }else{ + LOG.log(Level.INFO,"\n*** Migrated from ZUGFeRD 1.0 to 2.0 invoice: '" + newName + "'' ***\n", OUTPUT_DIR); + } + } catch (IOException | TransformerException t) { + LOG.log(Level.SEVERE, t.getMessage(), t); + Assert.fail("Failed with " + t.getClass().getName() + ": '" + t.getMessage() + "'"); + } + } + + + + private static void findLineDiffs(String outXML, String refXML){ + Scanner outScanner = new Scanner(outXML); + Scanner refScanner = new Scanner(refXML); + String outLine = null; + String refLine = null; + while (outScanner.hasNextLine() && refScanner.hasNextLine()) { + outLine = outScanner.nextLine(); + refLine = refScanner.nextLine(); + if(!outLine.equals(refLine)){ + LOG.info("First line difference between reference and output file:" + + "\nRefLine: " + refLine + + "\nOutLine: " + outLine + "\n"); + } + } + refScanner.close(); + outScanner.close(); + } +} diff --git a/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverterTest.java b/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverterTest.java index 89a7b6da..4bfac845 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverterTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDTransactionModelConverterTest.java @@ -1,12 +1,29 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; -import org.junit.Test; -import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType; - -import javax.xml.bind.JAXBElement; import java.math.BigDecimal; import java.util.Date; import java.util.GregorianCalendar; +import javax.xml.bind.JAXBElement; +import org.junit.Test; +import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType; public class ZUGFeRDTransactionModelConverterTest { @Test @@ -39,15 +56,15 @@ public class ZUGFeRDTransactionModelConverterTest { .setQuantity(BigDecimal.ONE) .setPrice(BigDecimal.TEN) ); - + // execution final JAXBElement actual = new ZUGFeRDTransactionModelConverter(transaction).convertToModel(); - + // evaluation ZUGFeRDXMLAssert.assertValidZugferd(actual); } - + private static Date createDate(int year, int month, int day) { final GregorianCalendar calendar = new GregorianCalendar(); calendar.set(year, month-1, day); diff --git a/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDXMLAssert.java b/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDXMLAssert.java index df2eb754..0d8413a3 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDXMLAssert.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/ZUGFeRDXMLAssert.java @@ -1,16 +1,33 @@ +/** ********************************************************************** + * + * Copyright 2018 Jochen Staerk + * + * Use is subject to license terms. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + *********************************************************************** */ package org.mustangproject.ZUGFeRD; import com.helger.schematron.ISchematronResource; import com.helger.schematron.pure.SchematronResourcePure; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.parsers.DocumentBuilderFactory; import org.junit.Assert; import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType; import org.w3c.dom.Document; import org.w3c.dom.Node; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.parsers.DocumentBuilderFactory; - public class ZUGFeRDXMLAssert { private static final ISchematronResource SCHEMATRON = loadSchematron(); diff --git a/src/test/resources/migration/input/ZUGFeRD1-invoice-adjusted.xml b/src/test/resources/migration/input/ZUGFeRD1-invoice-adjusted.xml new file mode 100644 index 00000000..f3729478 --- /dev/null +++ b/src/test/resources/migration/input/ZUGFeRD1-invoice-adjusted.xml @@ -0,0 +1,213 @@ + + + + + + false + + + urn:ferd:CrossIndustryDocument:invoice:1p0:extended + + + + RE-20170509/506 + RECHNUNG2 + 380 + + 20170510 + + + + + + Bei Spiel GmbH + + 12345 + Ecke 12 + Stadthausen + DE + + + 22/815/0815/4 + + + DE136695976 + + + + Theodor Est + + 88802 + Bahnstr. 42 + Spielkreis + DE + + + DE999999999 + + + + + + + 20170507 + + + + + RE-20170509/505 + EUR + + 42 + Überweisung + + DE88 2008 0000 0970 3757 00 + + + COBADEFFXXX + Commerzbank + + + + 11.20 + VAT + 160.00 + S + 7.00 + + + 63.84 + VAT + 336.00 + S + 19.00 + + + Zahlbar ohne Abzug bis zum 30.05.2017 + + 20170530 + + + + 496.00 + 0.00 + 0.00 + 496.00 + 75.04 + 571.04 + 571.04 + + + + + 1 + + + + 160.0000 + 1.0000 + + + 160.0000 + 1.0000 + + + + 1.0000 + + + + VAT + S + 7.00 + + + 160.00 + + + + Künstlerische Gestaltung (Stunde): Einer weiteren Beispielrechnung + + + + + + 2 + + + + 0.7900 + 1.0000 + + + 0.7900 + 1.0000 + + + + 400.0000 + + + + VAT + S + 19.00 + + + 316.00 + + + + Luftballon: Bunt, ca. 500ml + + + + + + 3 + + + + 0.1000 + 1.0000 + + + 0.1000 + 1.0000 + + + + 200.0000 + + + + VAT + S + 19.00 + + + 20.00 + + + + Heiße Luft pro Liter + + + + + diff --git a/src/test/resources/migration/input/ZUGFeRD1-invoice.xml b/src/test/resources/migration/input/ZUGFeRD1-invoice.xml new file mode 100644 index 00000000..c9dbbe2c --- /dev/null +++ b/src/test/resources/migration/input/ZUGFeRD1-invoice.xml @@ -0,0 +1,213 @@ + + + + + + false + + + urn:ferd:CrossIndustryDocument:invoice:1p0:extended + + + + RE-20170509/505 + RECHNUNG + 380 + + 20170509 + + + + + + Bei Spiel GmbH + + 12345 + Ecke 12 + Stadthausen + DE + + + 22/815/0815/4 + + + DE136695976 + + + + Theodor Est + + 88802 + Bahnstr. 42 + Spielkreis + DE + + + DE999999999 + + + + + + + 20170507 + + + + + RE-20170509/505 + EUR + + 42 + Überweisung + + DE88 2008 0000 0970 3757 00 + + + COBADEFFXXX + Commerzbank + + + + 11.20 + VAT + 160.00 + S + 7.00 + + + 63.84 + VAT + 336.00 + S + 19.00 + + + Zahlbar ohne Abzug bis zum 30.05.2017 + + 20170530 + + + + 496.00 + 0.00 + 0.00 + 496.00 + 75.04 + 571.04 + 571.04 + + + + + 1 + + + + 160.0000 + 1.0000 + + + 160.0000 + 1.0000 + + + + 1.0000 + + + + VAT + S + 7.00 + + + 160.00 + + + + Künstlerische Gestaltung (Stunde): Einer Beispielrechnung + + + + + + 2 + + + + 0.7900 + 1.0000 + + + 0.7900 + 1.0000 + + + + 400.0000 + + + + VAT + S + 19.00 + + + 316.00 + + + + Luftballon: Bunt, ca. 500ml + + + + + + 3 + + + + 0.1000 + 1.0000 + + + 0.1000 + 1.0000 + + + + 200.0000 + + + + VAT + S + 19.00 + + + 20.00 + + + + Heiße Luft pro Liter + + + + + diff --git a/src/test/resources/migration/reference/ZUGFeRD2-invoice.xml b/src/test/resources/migration/reference/ZUGFeRD2-invoice.xml new file mode 100644 index 00000000..4247df96 --- /dev/null +++ b/src/test/resources/migration/reference/ZUGFeRD2-invoice.xml @@ -0,0 +1,218 @@ + + + + + false + + + urn:ferd:CrossIndustryDocument:invoice:1p0:extended + + + + RE-20170509/505 + RECHNUNG + 380 + + 20170509 + + + + + + 1 + + + Künstlerische Gestaltung (Stunde): Einer Beispielrechnung + + + + + 160.0000 + 1.0000 + + + 160.0000 + 1.0000 + + + + 1.0000 + + + + VAT + S + 7.00 + + + 160.00 + + + + + + 2 + + + Luftballon: Bunt, ca. 500ml + + + + + 0.7900 + 1.0000 + + + 0.7900 + 1.0000 + + + + 400.0000 + + + + VAT + S + 19.00 + + + 316.00 + + + + + + 3 + + + Heiße Luft pro Liter + + + + + 0.1000 + 1.0000 + + + 0.1000 + 1.0000 + + + + 200.0000 + + + + VAT + S + 19.00 + + + 20.00 + + + + + + Bei Spiel GmbH + + 12345 + Ecke 12 + Stadthausen + DE + + + 22/815/0815/4 + + + DE136695976 + + + + Theodor Est + + 88802 + Bahnstr. 42 + Spielkreis + DE + + + DE999999999 + + + + + + + 20170507 + + + + + RE-20170509/505 + EUR + + 42 + Überweisung + + DE88 2008 0000 0970 3757 00 + + + COBADEFFXXX + Commerzbank + + + + 11.20 + VAT + 160.00 + S + 7.00 + + + 63.84 + VAT + 336.00 + S + 19.00 + + + Zahlbar ohne Abzug bis zum 30.05.2017 + + 20170530 + + + + 496.00 + 0.00 + 0.00 + 496.00 + 75.04 + 571.04 + 571.04 + + + + +