diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 9a974d6a..2179cfe7 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -1,421 +1,452 @@ -/** ********************************************************************** - * - * 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 - * ZUGFeRD importer - * Licensed under the APLv2 - * @date 2014-07-07 - * @version 1.1.0 - * @author jstaerk - * */ - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; -import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; -import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class ZUGFeRDImporter { - - /** - * if metadata has been found - */ - private boolean containsMeta = false; - /** - * map filenames of additional XML files to their contents - */ - private HashMap additionalXMLs = new HashMap<>(); - /** - * Raw XML form of the extracted data - may be directly obtained. - */ - private byte[] rawXML = null; - /** - * XMP metadata - */ - private String xmpString = null; // XMP metadata - /** - * parsed Document - */ - private Document document; - - public ZUGFeRDImporter(String pdfFilename) { - try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { - extractLowLevel(bis); - } catch (IOException e) { - Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); - throw new ZUGFeRDExportException(e); - } - } - - public ZUGFeRDImporter(InputStream pdfStream) { - try { - extractLowLevel(pdfStream); - } catch (IOException e) { - Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); - throw new ZUGFeRDExportException(e); - } - } - - /** - * Extracts a ZUGFeRD invoice from a PDF document represented by an input - * stream. Errors are reported via exception handling. - * - * @param pdfStream a inputstream of a pdf file - */ - private void extractLowLevel(InputStream pdfStream) throws IOException { - try (PDDocument doc = PDDocument.load(pdfStream)) { - // PDDocumentInformation info = doc.getDocumentInformation(); - PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); - //start - InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); - - xmpString = convertStreamToString(XMP); - - PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); - if (etn == null) { - return; - } - - Map efMap = etn.getNames(); - // String filePath = "/tmp/"; - - if (efMap != null) { - extractFiles(efMap); // see - // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ - } else { - - List> kids = etn.getKids(); - for (PDNameTreeNode node : kids) { - Map namesL = node.getNames(); - extractFiles(namesL); - } - } - } - } - - - private void extractFiles(Map names) throws IOException { - for (String alias : names.keySet()) { - - PDComplexFileSpecification fileSpec = names.get(alias); - String filename=fileSpec.getFilename(); - /** - * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) - */ - if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml"))) { //$NON-NLS-1$ - containsMeta = true; - - PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); - // String embeddedFilename = filePath + filename; - // File file = new File(filePath + filename); - // System.out.println("Writing " + embeddedFilename); - // ByteArrayOutputStream fileBytes=new - // ByteArrayOutputStream(); - // FileOutputStream fos = new FileOutputStream(file); - - setRawXML(embeddedFile.toByteArray()); - - // fos.write(embeddedFile.getByteArray()); - // fos.close(); - } - if (filename.startsWith("additional_data")) { - PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); - additionalXMLs.put(filename, embeddedFile.toByteArray()); - } - } - } - - private Document getDocument() { return document; } - - private void setDocument() throws ParserConfigurationException, IOException, SAXException { - DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); - xmlFact.setNamespaceAware(false); - DocumentBuilder builder = xmlFact.newDocumentBuilder(); - ByteArrayInputStream is = new ByteArrayInputStream(rawXML); - is.skip(guessBOMSize(is)); - document = builder.parse(is); - } - - public void setRawXML(byte[] rawXML) throws IOException { - this.rawXML = rawXML; - try { - setDocument(); - } catch (ParserConfigurationException | SAXException e) { - Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); - throw new ZUGFeRDExportException(e); - } - } - - /** - * Skips over a BOM at the beginning of the given ByteArrayInputStream, if one exists. - * @param is the ByteArrayInputStream used - * @throws IOException if can not be read from is - * @see Autodetection of Character Encodings - */ - private int guessBOMSize(ByteArrayInputStream is) throws IOException { - byte[] pad = new byte[4]; - is.read(pad); - is.reset(); - int test2 = ((pad[0] & 0xFF) << 8) | (pad[1] & 0xFF); - int test3 = ((test2 & 0xFFFF) << 8) | (pad[2] & 0xFF); - int test4 = ((test3 & 0xFFFFFF) << 8) | (pad[3] & 0xFF); - // - if (test4 == 0x0000FEFF || test4 == 0xFFFE0000 || test4 == 0x0000FFFE || test4 == 0xFEFF0000) { - // UCS-4: BOM takes 4 bytes - return 4; - } else if (test3 == 0xEFBBFF) { - // UTF-8: BOM takes 3 bytes - return 3; - } else if (test2 == 0xFEFF || test2 == 0xFFFE) { - // UTF-16: BOM takes 2 bytes - return 2; - } - return 0; - } - - private String extractString(String xpathStr) { - if (!containsMeta) { - throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); - } - String result; - try { - Document document = getDocument(); - XPathFactory xpathFact = XPathFactory.newInstance(); - XPath xpath = xpathFact.newXPath(); - result = xpath.evaluate(xpathStr, document); - } catch (XPathExpressionException e) { - Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); - throw new ZUGFeRDExportException(e); - } - return result; - } - - /** - * @return the reference (purpose) the sender specified for this invoice - */ - public String getForeignReference() { - String result = extractString("//ApplicableHeaderTradeSettlement/PaymentReference"); - if(result == null || result.isEmpty()) - result = extractString("//ApplicableSupplyChainTradeSettlement/PaymentReference"); - return result; - } - - /** - * @return the document code - */ - public String getDocumentCode() { - return extractString("//HeaderExchangedDocument/TypeCode"); - } - - /** - * @return the referred document - */ - public String getReference() { - return extractString("//ApplicableHeaderTradeAgreement/BuyerReference"); - } - - /** - * @return the sender's bank's BLZ code - * @deprecated use BIC and IBAN instead of BLZ and KTO - */ - @Deprecated - public String getBLZ() { - return extractString("//PayeeSpecifiedCreditorFinancialInstitution/GermanBankleitzahlID"); - } - - /** - * @return the sender's account number - * @deprecated use BIC and IBAN instead of BLZ and KTO - */ - @Deprecated - public String getKTO() { - return extractString("//PayeePartyCreditorFinancialAccount/ProprietaryID"); - } - - /** - * @return the sender's bank's BIC code - */ - public String getBIC() { - return extractString("//PayeeSpecifiedCreditorFinancialInstitution/BICID"); - } - - - /** - * @return the sender's bank name - */ - public String getBankName() { - return extractString("//PayeeSpecifiedCreditorFinancialInstitution/Name"); - } - - /** - * @return the sender's account IBAN code - */ - public String getIBAN() { - return extractString("//PayeePartyCreditorFinancialAccount/IBANID"); - } - - public String getHolder() { - return extractString("//SellerTradeParty/Name"); - } - - /** - * @return the total payable amount - */ - public String getAmount() { - String result = extractString("//SpecifiedTradeSettlementHeaderMonetarySummation/DuePayableAmount"); - if(result == null || result.isEmpty()) - result = extractString("//SpecifiedTradeSettlementMonetarySummation/GrandTotalAmount"); - return result; - } - - /** - * @return when the payment is due - */ - public String getDueDate() { - return extractString("//SpecifiedTradePaymentTerms/DueDateDateTime/DateTimeString"); - } - - public HashMap getAdditionalData() { - return additionalXMLs; - } - - /** - * get xmp metadata of the PDF, null if not available - * - * @return string - */ - public String getXMP() { - return xmpString; - } - - - /** - * @return if export found parseable ZUGFeRD data - */ - public boolean containsMeta() { - return containsMeta; - } - - /** - * @param meta raw XML to be set - * @throws IOException if raw can not be set - */ - public void setMeta(String meta) throws IOException { - setRawXML(meta.getBytes()); - } - - /** - * @return raw XML of the invoice - */ - public String getMeta() { - if (rawXML == null) { - return null; - } - - return new String(rawXML); - } - - - public int getVersion() throws Exception { - if (!containsMeta) throw new Exception("Not yet parsed"); - if (getUTF8().contains(" 0) && ((meta.contains("SpecifiedExchangedDocumentContext") //$NON-NLS-1$ - /* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */)); - } - - static String convertStreamToString(java.io.InputStream is) { - // source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to - // https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks - Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; - } - -} +/** + * ********************************************************************** 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 ZUGFeRD importer Licensed under the APLv2 + * + * @date 2014-07-07 + * @version 1.1.0 + * @author jstaerk + */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; +import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; +import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; +import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; +import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +public class ZUGFeRDImporter { + + /** + * if metadata has been found + */ + private boolean containsMeta = false; + /** + * map filenames of additional XML files to their contents + */ + private HashMap additionalXMLs = new HashMap<>(); + /** + * Raw XML form of the extracted data - may be directly obtained. + */ + private byte[] rawXML = null; + /** + * XMP metadata + */ + private String xmpString = null; // XMP metadata + /** + * parsed Document + */ + private Document document; + + + public ZUGFeRDImporter(String pdfFilename) { + try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { + extractLowLevel(bis); + } catch (IOException e) { + Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); + throw new ZUGFeRDExportException(e); + } + } + + + public ZUGFeRDImporter(InputStream pdfStream) { + try { + extractLowLevel(pdfStream); + } catch (IOException e) { + Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); + throw new ZUGFeRDExportException(e); + } + } + + + /** + * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling. + * + * @param pdfStream a inputstream of a pdf file + */ + private void extractLowLevel(InputStream pdfStream) throws IOException { + try (PDDocument doc = PDDocument.load(pdfStream)) { + // PDDocumentInformation info = doc.getDocumentInformation(); + PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + //start + + if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) { + Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.INFO, "no-xmlpart"); + return; + } + + InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); + xmpString = convertStreamToString(XMP); + + PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); + if (etn == null) { + return; + } + + Map efMap = etn.getNames(); + // String filePath = "/tmp/"; + + if (efMap != null) { + extractFiles(efMap); // see + // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ + } else { + + List> kids = etn.getKids(); + for (PDNameTreeNode node : kids) { + Map namesL = node.getNames(); + extractFiles(namesL); + } + } + } + } + + + private void extractFiles(Map names) throws IOException { + for (String alias : names.keySet()) { + + PDComplexFileSpecification fileSpec = names.get(alias); + String filename = fileSpec.getFilename(); + /** + * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) + */ + if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml"))) { //$NON-NLS-1$ + containsMeta = true; + + PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); + // String embeddedFilename = filePath + filename; + // File file = new File(filePath + filename); + // System.out.println("Writing " + embeddedFilename); + // ByteArrayOutputStream fileBytes=new + // ByteArrayOutputStream(); + // FileOutputStream fos = new FileOutputStream(file); + + setRawXML(embeddedFile.toByteArray()); + + // fos.write(embeddedFile.getByteArray()); + // fos.close(); + } + if (filename.startsWith("additional_data")) { + PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); + additionalXMLs.put(filename, embeddedFile.toByteArray()); + } + } + } + + + private Document getDocument() { + return document; + } + + + private void setDocument() throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); + xmlFact.setNamespaceAware(false); + DocumentBuilder builder = xmlFact.newDocumentBuilder(); + ByteArrayInputStream is = new ByteArrayInputStream(rawXML); + is.skip(guessBOMSize(is)); + document = builder.parse(is); + } + + + public void setRawXML(byte[] rawXML) throws IOException { + this.rawXML = rawXML; + try { + setDocument(); + } catch (ParserConfigurationException | SAXException e) { + Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); + throw new ZUGFeRDExportException(e); + } + } + + + /** + * Skips over a BOM at the beginning of the given ByteArrayInputStream, if one exists. + * + * @param is the ByteArrayInputStream used + * @throws IOException if can not be read from is + * @see Autodetection of Character Encodings + */ + private int guessBOMSize(ByteArrayInputStream is) throws IOException { + byte[] pad = new byte[4]; + is.read(pad); + is.reset(); + int test2 = ((pad[0] & 0xFF) << 8) | (pad[1] & 0xFF); + int test3 = ((test2 & 0xFFFF) << 8) | (pad[2] & 0xFF); + int test4 = ((test3 & 0xFFFFFF) << 8) | (pad[3] & 0xFF); + // + if (test4 == 0x0000FEFF || test4 == 0xFFFE0000 || test4 == 0x0000FFFE || test4 == 0xFEFF0000) { + // UCS-4: BOM takes 4 bytes + return 4; + } else if (test3 == 0xEFBBFF) { + // UTF-8: BOM takes 3 bytes + return 3; + } else if (test2 == 0xFEFF || test2 == 0xFFFE) { + // UTF-16: BOM takes 2 bytes + return 2; + } + return 0; + } + + + private String extractString(String xpathStr) { + if (!containsMeta) { + throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); + } + String result; + try { + Document document = getDocument(); + XPathFactory xpathFact = XPathFactory.newInstance(); + XPath xpath = xpathFact.newXPath(); + result = xpath.evaluate(xpathStr, document); + } catch (XPathExpressionException e) { + Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e); + throw new ZUGFeRDExportException(e); + } + return result; + } + + + /** + * @return the reference (purpose) the sender specified for this invoice + */ + public String getForeignReference() { + String result = extractString("//ApplicableHeaderTradeSettlement/PaymentReference"); + if (result == null || result.isEmpty()) { + result = extractString("//ApplicableSupplyChainTradeSettlement/PaymentReference"); + } + return result; + } + + + /** + * @return the document code + */ + public String getDocumentCode() { + return extractString("//HeaderExchangedDocument/TypeCode"); + } + + + /** + * @return the referred document + */ + public String getReference() { + return extractString("//ApplicableHeaderTradeAgreement/BuyerReference"); + } + + + /** + * @return the sender's bank's BLZ code + * @deprecated use BIC and IBAN instead of BLZ and KTO + */ + @Deprecated + public String getBLZ() { + return extractString("//PayeeSpecifiedCreditorFinancialInstitution/GermanBankleitzahlID"); + } + + + /** + * @return the sender's account number + * @deprecated use BIC and IBAN instead of BLZ and KTO + */ + @Deprecated + public String getKTO() { + return extractString("//PayeePartyCreditorFinancialAccount/ProprietaryID"); + } + + + /** + * @return the sender's bank's BIC code + */ + public String getBIC() { + return extractString("//PayeeSpecifiedCreditorFinancialInstitution/BICID"); + } + + + /** + * @return the sender's bank name + */ + public String getBankName() { + return extractString("//PayeeSpecifiedCreditorFinancialInstitution/Name"); + } + + + /** + * @return the sender's account IBAN code + */ + public String getIBAN() { + return extractString("//PayeePartyCreditorFinancialAccount/IBANID"); + } + + + public String getHolder() { + return extractString("//SellerTradeParty/Name"); + } + + + /** + * @return the total payable amount + */ + public String getAmount() { + String result = extractString("//SpecifiedTradeSettlementHeaderMonetarySummation/DuePayableAmount"); + if (result == null || result.isEmpty()) { + result = extractString("//SpecifiedTradeSettlementMonetarySummation/GrandTotalAmount"); + } + return result; + } + + + /** + * @return when the payment is due + */ + public String getDueDate() { + return extractString("//SpecifiedTradePaymentTerms/DueDateDateTime/DateTimeString"); + } + + + public HashMap getAdditionalData() { + return additionalXMLs; + } + + + /** + * get xmp metadata of the PDF, null if not available + * + * @return string + */ + public String getXMP() { + return xmpString; + } + + + /** + * @return if export found parseable ZUGFeRD data + */ + public boolean containsMeta() { + return containsMeta; + } + + + /** + * @param meta raw XML to be set + * @throws IOException if raw can not be set + */ + public void setMeta(String meta) throws IOException { + setRawXML(meta.getBytes()); + } + + + /** + * @return raw XML of the invoice + */ + public String getMeta() { + if (rawXML == null) { + return null; + } + + return new String(rawXML); + } + + + public int getVersion() throws Exception { + if (!containsMeta) { + throw new Exception("Not yet parsed"); + } + if (getUTF8().contains(" 0) && ((meta.contains("SpecifiedExchangedDocumentContext") //$NON-NLS-1$ + /* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */)); + } + + + static String convertStreamToString(java.io.InputStream is) { + // source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to + // https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks + Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A"); + return s.hasNext() ? s.next() : ""; + } + +} diff --git a/src/test/java/org/mustangproject/ZUGFeRD/ZF2EdgeTest.java b/src/test/java/org/mustangproject/ZUGFeRD/ZF2EdgeTest.java index d578630c..6a2ff8c5 100644 --- a/src/test/java/org/mustangproject/ZUGFeRD/ZF2EdgeTest.java +++ b/src/test/java/org/mustangproject/ZUGFeRD/ZF2EdgeTest.java @@ -1,244 +1,244 @@ -/** ********************************************************************** - * - * Copyright 2019 Jochen Staerk - * - * Use is subject to license terms. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - * - *********************************************************************** */ -package org.mustangproject.ZUGFeRD; - -import junit.framework.Test; -import junit.framework.TestSuite; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigDecimal; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class ZF2EdgeTest extends MustangReaderTestCase { - final String TARGET_PDF = "./target/testout-ZF2newEdge.pdf"; - - @Override - public Date getDeliveryDate() { - return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); - } - - @Override - public Date getDueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); - } - - @Override - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); - } - - @Override - public String getNumber() { - return "RE-20170509/505"; - } - - @Override - public String getOwnCountry() { - return "DE"; - } - - @Override - public String getOwnLocation() { - return "Stadthausen"; - } - - @Override - public String getOwnOrganisationName() { - return "Bei Spiel GmbH"; - } - - @Override - public String getOwnStreet() { - return "Ecke 12"; - } - - @Override - public IZUGFeRDExportableContact getOwnContact() { - return new SenderContact(); - - } - - @Override - public String getOwnTaxID() { - return "22/815/0815/4"; - } - - @Override - public String getOwnVATID() { - return "DE136695976"; - } - - @Override - public String getOwnZIP() { - return "12345"; - } - - @Override - public IZUGFeRDExportableContact getRecipient() { - return new RecipientContact(); - } - - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return null; - } - - @Override - public String getCurrency() { - return "EUR"; - } - - @Override - public IZUGFeRDExportableItem[] getZFItems() { - Item[] allItems = new Item[3]; - Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", - new BigDecimal("7.000000")); - Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62", - new BigDecimal("19.000000"));// test for issue 103 - Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); - - allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); - return allItems; - } - - @Override - public String getPaymentTermDescription() { - SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); - } - - @Override - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } - - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } - - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } - - @Override - public String getReferenceNumber() { - return "AB321"; - } - - /** - * Create the test case - * - * @param testName name of the test case - */ - public ZF2EdgeTest(String testName) { - super(testName); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(ZF2EdgeTest.class); - } - - // //////// TESTS - // ////////////////////////////////////////////////////////////////////////////////////////// - - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. - */ - public void testEdgeExport() { - - // the writing part - - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); - - ZUGFeRDExporter ze = new ZUGFeRDExporterFromA3Factory().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).ignorePDFAErrors() - .load(SOURCE_PDF)) { - ze.PDFattachZugferdFile(this); - String theXML = new String(ze.getProvider().getXML()); - assertTrue(theXML.contains("