diff --git a/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 2179cfe7..7d6eb52e 100644 --- a/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -1,452 +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 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() : ""; - } - -} +/** + * ********************************************************************** 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()); + } + } + } + + + protected 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; + } + + + protected 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/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java new file mode 100644 index 00000000..7960e9ce --- /dev/null +++ b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -0,0 +1,71 @@ +package org.mustangproject.ZUGFeRD; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.*; +import java.math.BigDecimal; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { + public ZUGFeRDInvoiceImporter(String filename) { + super(filename); + } + public ZUGFeRD2PushProvider extractInvoice() { + + String number="AB123"; + ZUGFeRD2PushProvider zpp=new ZUGFeRD2PushProvider().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setOwnStreet("teststr").setOwnZIP("55232").setOwnLocation("teststadt").setOwnCountry("DE").setOwnTaxID("4711").setOwnVATID("0815").setRecipient(new Contact("Franz Müller", "0177123456", "fmueller@test.com", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number); +//.addItem(new Item(new Product("Testprodukt","","C62",new BigDecimal(0)),amount,new BigDecimal(1.0))) + zpp.setOwnOrganisationName(extractString("//SellerTradeParty/Name")); + + XPathFactory xpathFact = XPathFactory.newInstance(); + XPath xpath = xpathFact.newXPath(); + try { + + XPathExpression xpr = xpath.compile( + "//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]"); + NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + + if (nodes.getLength() == 0) { + } else { + for (int i = 0; i < nodes.getLength(); i++) { + //nodes.item(i).getTextContent())) { + Node currentItemNode=nodes.item(i); + NodeList itemChilds=currentItemNode.getChildNodes(); + String price="0"; + for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) { + if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedLineTradeAgreement")) { + NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes(); + for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) { + if (tradeLineChilds.item(tradeLineChildIndex).getNodeName().equals("ram:NetPriceProductTradePrice")) { + NodeList netChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes(); + for (int netIndex = 0; netIndex < netChilds.getLength(); netIndex++) { + if (netChilds.item(netIndex).getNodeName().equals("ram:ChargeAmount")) { + price = netChilds.item(netIndex).getTextContent();//ram:ChargeAmount + + } + } + } + } + } + } +// Logger.getLogger(ZUGFeRDInvoiceImporter.class.getName()).log(Level.INFO, "deb "+price); + + zpp.addItem(new Item(new Product("Testprodukt","","C62",new BigDecimal(0)),new BigDecimal(price),new BigDecimal(1.0))); + } + + } + + + } catch (XPathExpressionException e) { + e.printStackTrace(); + } + + return zpp; + } + + +} diff --git a/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2InvoiceImporterTest.java b/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2InvoiceImporterTest.java new file mode 100644 index 00000000..12ef39d3 --- /dev/null +++ b/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2InvoiceImporterTest.java @@ -0,0 +1,57 @@ + +/** ********************************************************************** + * + * 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 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; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +import junit.framework.TestCase; +import junit.framework.Test; +import junit.framework.TestSuite; + + + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class ZF2InvoiceImporterTest extends TestCase { + final String TARGET_PDF = "./target/testout-ZF2New.pdf"; + + public void testInvoiceImport() { + + ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF); + + + // Reading ZUGFeRD + assertEquals("Bei Spiel GmbH", zii.extractInvoice().getOwnOrganisationName()); + assertEquals(3, zii.extractInvoice().getZFItems().length); + assertEquals("160.0000", zii.extractInvoice().getZFItems()[0].getPrice().toString()); + + + } + +}