From 5d72156bf0f6386cfd7fb3c84c7da4ef28ab16e1 Mon Sep 17 00:00:00 2001 From: Alexander Berndt Date: Wed, 20 May 2020 09:38:34 +0200 Subject: [PATCH] Implemented method "getSellerTradePartyAddress" to ZUGFeRDImporter.java which gets an instance of PostalTradeAddress. Removed method "getISODate" from last Commit due lack of implementation - will be implemented at a later time. Also Added Tests for "getSellerTradePartyAddress" to match ZF1 and ZF2 --- .../IZUGFeRDExportablePostalTradeAddress.java | 11 + .../ZUGFeRD/PostalTradeAddress.java | 75 +++ .../ZUGFeRD/ZUGFeRDImporter.java | 87 +++- .../ZUGFeRD/MustangReaderWriterTest.java | 7 + .../org/mustangproject/ZUGFeRD/ZF2Test.java | 436 +++++++++--------- 5 files changed, 387 insertions(+), 229 deletions(-) create mode 100644 libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java create mode 100644 libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java diff --git a/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java new file mode 100644 index 000000000..05e7b766b --- /dev/null +++ b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java @@ -0,0 +1,11 @@ +package org.mustangproject.ZUGFeRD; + +public interface IZUGFeRDExportablePostalTradeAddress { + default String getPostcodeCode(){return null;} + default String getLineOne() {return null;} + default String getLineTwo() {return null;} + default String getLineThree() {return null;} + default String getCityName() {return null;} + default String getCountryID() {return null;} + default String getCountrySubDivisionName() {return null;} +} diff --git a/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java new file mode 100644 index 000000000..e40cd074e --- /dev/null +++ b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java @@ -0,0 +1,75 @@ +package org.mustangproject.ZUGFeRD; + +public class PostalTradeAddress implements IZUGFeRDExportablePostalTradeAddress { + + private String postCodeCode; + private String lineOne; + private String lineTwo; + private String lineThree; + private String cityName; + private String countryID; + private String CountrySubDivisionName; + + public void setPostCodeCode(String postCodeCode) { + this.postCodeCode = postCodeCode; + } + + public void setLineOne(String lineOne) { + this.lineOne = lineOne; + } + + public void setLineTwo(String lineTwo) { + this.lineTwo = lineTwo; + } + + public void setLineThree(String lineThree) { + this.lineThree = lineThree; + } + + public void setCityName(String cityName) { + this.cityName = cityName; + } + + public void setCountryID(String countryID) { + this.countryID = countryID; + } + + public void setCountrySubDivisionName(String countrySubDivisionName) { + CountrySubDivisionName = countrySubDivisionName; + } + + @Override + public String getPostcodeCode() { + return this.postCodeCode; + } + + @Override + public String getLineOne() { + return this.lineOne; + } + + @Override + public String getLineTwo() { + return this.lineTwo; + } + + @Override + public String getLineThree() { + return this.lineThree; + } + + @Override + public String getCityName() { + return this.cityName; + } + + @Override + public String getCountryID() { + return this.countryID; + } + + @Override + public String getCountrySubDivisionName() { + return this.CountrySubDivisionName; + } +} diff --git a/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index d35bdc3db..fa5a4bfdc 100644 --- a/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/libraryBasic/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -30,9 +30,7 @@ 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 javax.xml.xpath.*; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; @@ -41,6 +39,8 @@ import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class ZUGFeRDImporter { @@ -235,7 +235,7 @@ protected String extractString(String xpathStr) { /** - * Wrapper for protected method + * Wrapper for protected method exracteString * @return the extracted String for the specific path in the document */ public String wExtractString(String xpathStr) { @@ -243,16 +243,6 @@ public String wExtractString(String xpathStr) { } - /** - * @return an ISO XXX coded datetime string - */ - public String getISOdate(String xpathString) { - String date = extractString(xpathString); - //do some conversion magic here - return date; - } - - /** * @return the reference (purpose) the sender specified for this invoice */ @@ -468,4 +458,73 @@ static String convertStreamToString(java.io.InputStream is) { return s.hasNext() ? s.next() : ""; } + public PostalTradeAddress getSellerTradePartyAddress() { + + NodeList nl = null; + PostalTradeAddress address = new PostalTradeAddress(); + + try { + if (getVersion() == 1) { + nl = getNodeListByPath("//CrossIndustryDocument//SpecifiedSupplyChainTradeTransaction//ApplicableSupplyChainTradeAgreement//SellerTradeParty//PostalTradeAddress"); + } else { + nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//SellerTradeParty//PostalTradeAddress"); + } + } catch (Exception e) { + e.printStackTrace(); + return address; + } + + if (nl != null) { + for (int i = 0; i < nl.getLength(); i++) { + Node n = nl.item(i); + NodeList nodes = n.getChildNodes(); + for (int j = 0; j < nodes.getLength(); j++) { + n = nodes.item(j); + short nodeType = n.getNodeType(); + if (nodeType==Node.ELEMENT_NODE){ + switch (n.getNodeName()) { + case "ram:PostcodeCode": + address.setPostCodeCode(n.getFirstChild().getNodeValue()); + break; + case "ram:LineOne": + address.setLineOne(n.getFirstChild().getNodeValue()); + break; + case "ram:LineTwo": + address.setLineTwo(n.getFirstChild().getNodeValue()); + break; + case "ram:LineThree": + address.setLineThree(n.getFirstChild().getNodeValue()); + break; + case "ram:CityName": + address.setCityName(n.getFirstChild().getNodeValue()); + break; + case "ram:CountryID": + address.setCountryID(n.getFirstChild().getNodeValue()); + break; + case "ram:CountrySubDivisionName": + address.setCountrySubDivisionName(n.getFirstChild().getNodeValue()); + break; + } + } + } + } + } + return address; + } + + public NodeList getNodeListByPath(String path) { + + XPathFactory xpathFact = XPathFactory.newInstance(); + XPath xPath = xpathFact.newXPath(); + String s = path; + + try { + XPathExpression xpr = xPath.compile(s); + return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + } diff --git a/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index 38f9a552d..0efc5a934 100644 --- a/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -203,6 +203,13 @@ public void testAImport() { assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getForeignReference(), "RE-20170509/505"); assertEquals(zi.getBankName(), "Commerzbank"); + assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen"); + assertEquals(zi.getSellerTradePartyAddress().getCountryID(), "DE"); + assertEquals(zi.getSellerTradePartyAddress().getCountrySubDivisionName(), null); + assertEquals(zi.getSellerTradePartyAddress().getLineOne(), "Ecke 12"); + assertEquals(zi.getSellerTradePartyAddress().getLineThree(), null); + assertEquals(zi.getSellerTradePartyAddress().getLineTwo(), null); + assertEquals(zi.getSellerTradePartyAddress().getPostcodeCode(), "12345"); } public void testForeignImport() { diff --git a/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2Test.java b/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2Test.java index f5441ad0b..2f2b85ee5 100644 --- a/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2Test.java +++ b/libraryBasic/src/test/java/org/mustangproject/ZUGFeRD/ZF2Test.java @@ -1,226 +1,232 @@ -/** ********************************************************************** - * - * 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 ZF2Test extends MustangReaderTestCase { - final String TARGET_PDF = "./target/testout-ZF2new.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 ZF2Test(String testName) { - super(testName); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(ZF2Test.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 testExport() { - - // 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).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).ignorePDFAErrors() +/** ********************************************************************** + * + * 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 ZF2Test extends MustangReaderTestCase { + final String TARGET_PDF = "./target/testout-ZF2new.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 ZF2Test(String testName) { + super(testName); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(ZF2Test.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 testExport() { + + // 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).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).ignorePDFAErrors() .load(SOURCE_PDF)) { - - ze.PDFattachZugferdFile(this); - String theXML = new String(ze.getProvider().getXML()); - assertTrue(theXML.contains("")); - - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getHolder(), getOwnOrganisationName()); + + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getAmount(), "571.04"); assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); assertEquals(zi.getIBAN(),getTradeSettlementPayment()[0].getOwnIBAN()); assertEquals(zi.getHolder(), getOwnOrganisationName()); assertEquals(zi.getForeignReference(), getNumber()); + assertEquals(zi.getSellerTradePartyAddress().getPostcodeCode(), "12345"); + assertEquals(zi.getSellerTradePartyAddress().getLineOne(), "Ecke 12"); + assertEquals(zi.getSellerTradePartyAddress().getLineTwo(), null); + assertEquals(zi.getSellerTradePartyAddress().getLineThree(), null); + assertEquals(zi.getSellerTradePartyAddress().getCountrySubDivisionName(), null); + assertEquals(zi.getSellerTradePartyAddress().getCountryID(), "DE"); + assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen"); + + try { + assertEquals(zi.getVersion(), 2); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } - - try { - assertEquals(zi.getVersion(), 2); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } -} + } +}