diff --git a/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 44c999b9..dccb0d3d 100644 --- a/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -35,12 +35,12 @@ import org.xml.sax.SAXException; public class ZUGFeRDImporter { /* - call extract(importFilename). - containsMeta() will return if ZUGFeRD data has been found, + 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 */ private boolean containsMeta=false; /**@var the reference (i.e. invoice number) of the sender */ @@ -49,16 +49,20 @@ public class ZUGFeRDImporter { private String IBAN; private String holder; private String amount; + private String dueDate; /** Raw XML form of the extracted data - may be directly obtained. */ private byte[] rawXML=null; private String bankName; private boolean amountFound; - + private boolean extracted=false; + private boolean parsed=false; + + /** * Extracts a ZUGFeRD invoice from a PDF document represented by a file name. * Errors are just logged to STDOUT. */ - public void extract(String pdfFilename) + public void extract(String pdfFilename) { try { @@ -67,7 +71,7 @@ public class ZUGFeRDImporter { { ioe.printStackTrace(); } - } + } /** * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. @@ -107,6 +111,7 @@ public class ZUGFeRDImporter { // FileOutputStream fos = new FileOutputStream(file); rawXML = embeddedFile.getByteArray(); setMeta(new String(rawXML)); + extracted=true; // fos.write(embeddedFile.getByteArray()); // fos.close(); } @@ -124,12 +129,16 @@ public class ZUGFeRDImporter { } } - + public void parse() { DocumentBuilderFactory factory = null; DocumentBuilder builder = null; Document document = null; + if (!extracted) { + throw new RuntimeException("extract() or extractLowLevel() must be used before parsing."); + } + factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); //otherwise we can not act namespace independend, i.e. use document.getElementsByTagNameNS("*",... try { @@ -148,17 +157,17 @@ public class ZUGFeRDImporter { ex2.printStackTrace(); } NodeList ndList ; - + // rootNode = document.getDocumentElement(); // ApplicableSupplyChainTradeSettlement ndList = document.getDocumentElement() .getElementsByTagNameNS("*","PaymentReference"); //$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 - + setForeignReference(booking.getTextContent()); } @@ -190,7 +199,7 @@ public class ZUGFeRDImporter { DE5656565 Commerzbank - + */ ndList = document.getElementsByTagNameNS("*","PayeePartyCreditorFinancialAccount"); //$NON-NLS-1$ @@ -201,7 +210,7 @@ public class ZUGFeRDImporter { // there are many "name" elements, so get the one below // SellerTradeParty NodeList bookingDetails = booking.getChildNodes(); - + for (int detailIndex = 0; detailIndex < bookingDetails .getLength(); detailIndex++) { @@ -209,7 +218,7 @@ public class ZUGFeRDImporter { if ((detail.getLocalName()!=null)&&(detail.getLocalName().equals("IBANID"))) { //$NON-NLS-1$ setIBAN(detail.getTextContent()); - } + } } } @@ -267,7 +276,7 @@ public class ZUGFeRDImporter { if (!amountFound) { - /* there is apparently no requirement to mention DuePayableAmount,, + /* there is apparently no requirement to mention DuePayableAmount,, * if it's not there, check for GrandTotalAmount */ ndList = document.getElementsByTagNameNS("*","GrandTotalAmount"); //$NON-NLS-1$ @@ -279,10 +288,28 @@ public class ZUGFeRDImporter { setAmount(booking.getTextContent()); } - - } - + } + + ndList = document.getElementsByTagNameNS("*","SpecifiedTradePaymentTerms"); //$NON-NLS-1$ + + for (int bookingIndex = 0; bookingIndex < ndList + .getLength(); bookingIndex++) { + Node booking = ndList.item(bookingIndex); + // there are many "name" elements, so get the one below + // SellerTradeParty + NodeList bookingDetails = booking.getChildNodes(); + for (int detailIndex = 0; detailIndex < bookingDetails + .getLength(); detailIndex++) { + Node detail = bookingDetails.item(detailIndex); + if ((detail.getLocalName()!=null)&&(detail.getLocalName().equals("DueDateDateTime"))) { //$NON-NLS-1$ + setDueDate(detail.getTextContent().trim()); + } + } + + } + + parsed=true; } @@ -291,7 +318,7 @@ public class ZUGFeRDImporter { } public String getForeignReference() { - if (rawXML==null) { + if (!parsed) { throw new RuntimeException("use parse() before requesting a value"); } return foreignReference; @@ -306,7 +333,7 @@ public class ZUGFeRDImporter { public String getBIC() { - if (rawXML==null) { + if (!parsed) { throw new RuntimeException("use parse() before requesting a value"); } return BIC; @@ -319,6 +346,11 @@ public class ZUGFeRDImporter { } + private void setDueDate(String dueDate) { + this.dueDate = dueDate; + } + + private void setBankName(String bankname) { this.bankName = bankname; } @@ -326,7 +358,7 @@ public class ZUGFeRDImporter { public String getIBAN() { - if (rawXML==null) { + if (!parsed) { throw new RuntimeException("use parse() before requesting a value"); } return IBAN; @@ -334,7 +366,7 @@ public class ZUGFeRDImporter { public String getBankName() { - if (rawXML==null) { + if (!parsed) { throw new RuntimeException("use parse() before requesting a value"); } return bankName; @@ -370,6 +402,12 @@ public class ZUGFeRDImporter { return amount; } + public String getDueDate() { + if (rawXML==null) { + throw new RuntimeException("use parse() before requesting a value"); + } + return dueDate; + } private void setAmount(String amount) { this.amount = amount; @@ -381,7 +419,7 @@ public class ZUGFeRDImporter { public String getMeta() { if (rawXML==null){ - return null; + return null; } else { return new String(rawXML); } @@ -391,7 +429,7 @@ public class ZUGFeRDImporter { /** * Returns the raw XML data as extracted from the ZUGFeRD PDF file. */ - public byte[] getRawXML() + public byte[] getRawXML() { return rawXML; } @@ -400,8 +438,8 @@ public class ZUGFeRDImporter { * will return true if the metadata (just extract-ed or set with setMeta) contains ZUGFeRD XML * */ public boolean canParse() { - - + + //SpecifiedExchangedDocumentContext is in the schema, so a relatively good indication if zugferd is present - better than just invoice String meta=getMeta(); return (meta!=null)&&( meta.length()>0)&&( meta.contains("SpecifiedExchangedDocumentContext")); //$NON-NLS-1$ diff --git a/mustang/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/mustang/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index 14cd4b4f..084ebde8 100644 --- a/mustang/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/mustang/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -49,7 +49,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp @Override public String getOwnBIC() { - return "COBADEFXXX"; + return "COBADEFFXXX"; } @Override @@ -124,7 +124,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp { return "EUR"; } - + @Override public IZUGFeRDExportableItem[] getZFItems() { @@ -254,7 +254,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp @Override public IZUGFeRDAllowanceCharge[] getItemAllowances() { - return null; + return null; } @Override @@ -326,7 +326,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp /** * Create the test case - * + * * @param testName * name of the test case */ @@ -349,7 +349,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp * The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20151008_504.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 */ @@ -364,6 +364,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp String iban = null; String holder = null; String ref = null; + String dueDate = null; if (zi.canParse()) { @@ -372,6 +373,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp bic = zi.getBIC(); iban = zi.getIBAN(); holder = zi.getHolder(); + dueDate = zi.getDueDate(); ref = zi.getForeignReference(); } @@ -379,6 +381,8 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp assertEquals(bic, getOwnBIC()); assertEquals(iban, getOwnIBAN()); assertEquals(holder, getOwnOrganisationName()); + + assertEquals(dueDate, "20141029"); assertEquals(ref, getNumber()); } diff --git a/mustang/src/test/resources/MustangGnuaccountingBeispielRE-20151008_504.pdf b/mustang/src/test/resources/MustangGnuaccountingBeispielRE-20151008_504.pdf index 236ea091..1771974d 100644 Binary files a/mustang/src/test/resources/MustangGnuaccountingBeispielRE-20151008_504.pdf and b/mustang/src/test/resources/MustangGnuaccountingBeispielRE-20151008_504.pdf differ