/** ********************************************************************** * * 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 junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class MustangReaderWriterTest extends MustangReaderTestCase { @Override public Date getDeliveryDate() { return new GregorianCalendar(2017, Calendar.NOVEMBER, 17).getTime(); } @Override public Date getDueDate() { return new GregorianCalendar(2017, Calendar.DECEMBER, 9).getTime(); } @Override public Date getIssueDate() { return new GregorianCalendar(2017, Calendar.NOVEMBER, 18).getTime(); } @Override public String getNumber() { return "RE-20171118/506"; } @Override public String getOwnCountry() { return "DE"; } @Override public String getOwnLocation() { return "Stadthausen"; } @Override public String getOwnOrganisationName() { return "Bei Spiel GmbH"; } @Override public String getOwnStreet() { return "Ecke 12"; } @Override public String getOwnTaxID() { return "22/815/0815/4"; } @Override public String getOwnVATID() { return "DE136695976"; } @Override public String getOwnZIP() { return "12345"; } @Override public IZUGFeRDExportableContact getRecipient() { return new Contact(); } @Override public String getOwnOrganisationFullPlaintextInfo() { return null; } @Override public String getCurrency() { return "EUR"; } @Override public IZUGFeRDExportableItem[] getZFItems() { Item[] allItems = new Item[3]; Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", new BigDecimal("7.000000")); Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000")); Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); return allItems; } @Override public String getPaymentTermDescription() { SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); } @Override public IZUGFeRDAllowanceCharge[] getZFAllowances() { return null; // throw new UnsupportedOperationException("Not supported yet."); //To change // body of generated methods, choose Tools | Templates. } @Override public IZUGFeRDAllowanceCharge[] getZFCharges() { return null; // throw new UnsupportedOperationException("Not supported yet."); //To change // body of generated methods, choose Tools | Templates. } @Override public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { return null; // throw new UnsupportedOperationException("Not supported yet."); //To change // body of generated methods, choose Tools | Templates. } @Override public String getReferenceNumber() { return null; } /** * Create the test case * * @param testName name of the test case */ public MustangReaderWriterTest(String testName) { super(testName); } /** * @return the suite of tests being tested */ public static Test suite() { return new TestSuite(MustangReaderWriterTest.class); } // //////// TESTS // ////////////////////////////////////////////////////////////////////////////////////////// /** * The importer test imports from * ./src/test/MustangGnuaccountingBeispielRE-20170509_505.pdf to check the * values. --> as only Name Ascending is supported for Test Unit sequence, I * renamed the this test-A-Export to run before testZExport * * @throws IOException */ public void testAImport() throws IOException { InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf"); ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); // Reading ZUGFeRD assertEquals(zi.getAmount(), "571.04"); assertEquals(zi.getBLZ(), getTradeSettlementPayment()[0].getOwnBLZ()); assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); assertEquals(zi.getIBAN(),getTradeSettlementPayment()[0].getOwnIBAN()); assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto()); assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getForeignReference(), "RE-20170509/505"); } public void testForeignImport() throws IOException { InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf"); ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); // Reading ZUGFeRD String amount = zi.getAmount(); assertEquals("\n" + " \n" + " \n" + " \n" + " uuid:6776DD95-DAF6-768E-DAE6-2697750D95C5\n" + " uuid:47380404-5938-FE2C-8F0B-B505DCE43BF5\n" + " \n" + " \n" + " BASIC\n" + " ZUGFeRD-invoice.xml\n" + " INVOICE\n" + " 1.0\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " ZUGFeRD PDFA Extension Schema\n" + " urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#\n" + " zf\n" + " \n" + " \n" + " \n" + " DocumentFileName\n" + " Text\n" + " external\n" + " name of the embedded XML invoice file\n" + " \n" + " \n" + " DocumentType\n" + " Text\n" + " external\n" + " INVOICE\n" + " \n" + " \n" + " Version\n" + " Text\n" + " external\n" + " The actual version of the ZUGFeRD XML schema\n" + " \n" + " \n" + " ConformanceLevel\n" + " Text\n" + " external\n" + " The conformance level of the embedded ZUGFeRD data\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " 3\n" + " B\n" + " \n" + " \n" + " 2014-07-11T13:39:46+02:00\n" + " 2014-07-11T13:39:46+02:00\n" + " zugferd_invoice.java\n" + " 2014-07-11T13:39:46+02:00\n" + " \n" + " \n" + " PDFlib Personalization Server 9.0.3 (JDK 1.6/Mac OS X-10.6 64)\n" + " \n" + " \n" + " \n" + " \n" + " ZUGFeRD Rechnung $Revision: 1.13 $\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "", zi.getXMP()); // this resembles the data written in MustangReaderWriterCustomXMLTest assertEquals(amount, "1005.55"); } public void testMigratePDFA1ToA3() throws IOException { // just make sure there is no Exception InputStream SOURCE_PDF = this.getClass() .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF); File tempFile = File.createTempFile("ZUGFeRD-", "-test"); ze.export(tempFile.getName()); tempFile.deleteOnExit(); } /** * The exporter test bases on @{code * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds * metadata, writes to @{code ./target/testout-*} and then imports to check the * values. It would not make sense to have it run before the less complex * importer test (which is probably redundant) --> as only Name Ascending is * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export */ public void testZExport() throws Exception { final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf"; // the writing part try (InputStream SOURCE_PDF = this.getClass() .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(2).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).load(SOURCE_PDF)) { ze.PDFattachZugferdFile(this); ze.disableAutoClose(true); ze.export(TARGET_PDF); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ze.export(baos); ze.close(); String pdfContent = baos.toString("UTF-8"); assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); // check for pdf-a schema extension // assertFalse(pdfContent.indexOf("EN 16931") == -1); // assertFalse(pdfContent.indexOf("zf") == -1); // assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); } // now check the contents (like MustangReaderTest) ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); // Reading ZUGFeRD assertEquals(zi.getAmount(), "571.04"); assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto()); assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getForeignReference(), getNumber()); } public void testFXExport() throws Exception { final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506fx.pdf"; // the writing part try (InputStream SOURCE_PDF = this.getClass() .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().setZUGFeRDVersion(2).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).load(SOURCE_PDF)) { ze.setFacturX(); ze.PDFattachZugferdFile(this); ze.disableAutoClose(true); ze.export(TARGET_PDF); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ze.export(baos); ze.close(); String pdfContent = baos.toString("UTF-8"); assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); // check for pdf-a schema extension assertFalse(pdfContent.indexOf("EN 16931") == -1); assertFalse(pdfContent.indexOf("fx") == -1); assertFalse(pdfContent.indexOf("urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931") == -1); } // now check the contents (like MustangReaderTest) ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); // Reading ZUGFeRD assertEquals(zi.getAmount(), "571.04"); assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); assertEquals(zi.getKTO(), getTradeSettlementPayment()[0].getOwnKto()); assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getForeignReference(), getNumber()); } /** * @throws Exception * @Test(expected = IndexOutOfBoundsException.class) */ public void testExceptionOnPDF14() throws Exception { final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505new.pdf"; boolean exceptionThrown = false; // the writing part try (InputStream SOURCE_PDF = this.getClass() .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDF14.pdf"); ZUGFeRDExporter ze = new ZUGFeRDExporterFromA1Factory().load(SOURCE_PDF)) { ze.PDFattachZugferdFile(this); ze.export(TARGET_PDF); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ze.export(baos); } catch (IOException ex) { // should throw a java.io.IOException: File is not a valid PDF/A-1 input file exceptionThrown = true; } assertTrue(exceptionThrown); } }