Merge branch 'master' of github.com:ZUGFeRD/mustangproject

# Conflicts:
#	src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java
This commit is contained in:
Jochen Stärk
2019-04-11 17:06:09 +02:00
15 changed files with 521 additions and 711 deletions

View File

@@ -40,7 +40,7 @@
<github.global.server>github</github.global.server> <github.global.server>github</github.global.server>
<additionalparam>-Xdoclint:none</additionalparam> <additionalparam>-Xdoclint:none</additionalparam>
<!-- Skip error check for javadoc --> <!-- Skip error check for javadoc -->
<maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
</properties> </properties>
@@ -134,8 +134,8 @@
<!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven <!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
mvn clean compile assembly:single --> mvn clean compile assembly:single -->
<!-- or whatever version you use --> <!-- or whatever version you use -->
<source>1.7</source> <source>1.8</source>
<target>1.7</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>

View File

@@ -15,16 +15,23 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
import java.math.BigDecimal; import java.math.BigDecimal;
/** /**
* @author AlexanderSchmidt * @author AlexanderSchmidt
*/ */
public interface IZUGFeRDAllowanceCharge { public interface IZUGFeRDAllowanceCharge {
BigDecimal getTotalAmount(); BigDecimal getTotalAmount();
String getReason(); String getReason();
BigDecimal getTaxPercent(); BigDecimal getTaxPercent();
default String getCategoryCode() {
return TaxCategoryCodeTypeConstants.STANDARDRATE;
}
} }

View File

@@ -19,9 +19,7 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
/** /**
* Mustangproject's ZUGFeRD implementation * Mustangproject's ZUGFeRD implementation Neccessary interface for ZUGFeRD exporter Licensed under the APLv2
* Neccessary interface for ZUGFeRD exporter
* Licensed under the APLv2
* *
* @author jstaerk * @author jstaerk
* @version 1.2.0 * @version 1.2.0
@@ -31,6 +29,16 @@ package org.mustangproject.ZUGFeRD;
public interface IZUGFeRDExportableContact { public interface IZUGFeRDExportableContact {
/**
* customer identification assigned by the seller
*
* @return customer identification
*/
default String getID() {
return null;
}
/** /**
* First and last name of the recipient * First and last name of the recipient
* *
@@ -38,6 +46,7 @@ public interface IZUGFeRDExportableContact {
*/ */
String getName(); String getName();
/** /**
* Postal code of the recipient * Postal code of the recipient
* *
@@ -45,6 +54,7 @@ public interface IZUGFeRDExportableContact {
*/ */
String getZIP(); String getZIP();
/** /**
* VAT ID (Umsatzsteueridentifikationsnummer) of the contact * VAT ID (Umsatzsteueridentifikationsnummer) of the contact
* *
@@ -52,6 +62,7 @@ public interface IZUGFeRDExportableContact {
*/ */
String getVATID(); String getVATID();
/** /**
* two-letter country code of the contact * two-letter country code of the contact
* *
@@ -59,6 +70,7 @@ public interface IZUGFeRDExportableContact {
*/ */
String getCountry(); String getCountry();
/** /**
* Returns the city of the contact * Returns the city of the contact
* *
@@ -66,6 +78,7 @@ public interface IZUGFeRDExportableContact {
*/ */
String getLocation(); String getLocation();
/** /**
* Returns the street address (street+number) of the contact * Returns the street address (street+number) of the contact
* *

View File

@@ -26,6 +26,8 @@ package org.mustangproject.ZUGFeRD;
* @author jstaerk * @author jstaerk
* */ * */
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
import java.math.BigDecimal; import java.math.BigDecimal;
public interface IZUGFeRDExportableItem { public interface IZUGFeRDExportableItem {
@@ -51,5 +53,8 @@ public interface IZUGFeRDExportableItem {
*/ */
BigDecimal getQuantity(); BigDecimal getQuantity();
default String getCategoryCode() {
return TaxCategoryCodeTypeConstants.STANDARDRATE;
}
} }

View File

@@ -27,55 +27,75 @@ package org.mustangproject.ZUGFeRD;
* */ * */
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
import java.util.Date; import java.util.Date;
public interface IZUGFeRDExportableTransaction { public interface IZUGFeRDExportableTransaction {
/**
*
*
* @return Code of Document
*/
default String getDocumentCode() {
return DocumentCodeTypeConstants.INVOICE;
}
/** /**
* Number, typically invoice number of the invoice * Number, typically invoice number of the invoice
* *
* @return invoice number * @return invoice number
*/ */
String getNumber(); default String getNumber() {
return null;
}
/** /**
* the date when the invoice was created * the date when the invoice was created
* *
* @return when the invoice was created * @return when the invoice was created
*/ */
Date getIssueDate(); default Date getIssueDate() {
return null;
}
/** /**
* this should be the full sender institution name, details, manager and tax registration. * this should be the full sender institution name, details, manager and tax registration. It is one of the few functions which may return null. e.g.
* It is one of the few functions which may return null.
* e.g.
* <p/> * <p/>
* Lieferant GmbH * Lieferant GmbH Lieferantenstraße 20 80333 München Deutschland Geschäftsführer: Hans Muster Handelsregisternummer: H A 123
* Lieferantenstraße 20
* 80333 München
* Deutschland
* Geschäftsführer: Hans Muster
* Handelsregisternummer: H A 123
* *
* @return null or full sender institution name, details, manager and tax registration * @return null or full sender institution name, details, manager and tax registration
*/ */
String getOwnOrganisationFullPlaintextInfo(); default String getOwnOrganisationFullPlaintextInfo() {
return null;
}
/** /**
* when the invoice is to be paid * when the invoice is to be paid
* *
* @return when the invoice is to be paid * @return when the invoice is to be paid
*/ */
Date getDueDate(); default Date getDueDate() {
return null;
}
IZUGFeRDAllowanceCharge[] getZFAllowances(); IZUGFeRDAllowanceCharge[] getZFAllowances();
IZUGFeRDAllowanceCharge[] getZFCharges(); IZUGFeRDAllowanceCharge[] getZFCharges();
IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges(); IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges();
IZUGFeRDExportableItem[] getZFItems(); IZUGFeRDExportableItem[] getZFItems();
/** /**
* the recipient * the recipient
* *
@@ -83,89 +103,136 @@ public interface IZUGFeRDExportableTransaction {
*/ */
IZUGFeRDExportableContact getRecipient(); IZUGFeRDExportableContact getRecipient();
/** /**
* BIC of the sender * BIC of the sender
* *
* @return the BIC code of the recipient sender's bank * @return the BIC code of the recipient sender's bank
*/ */
String getOwnBIC(); default String getOwnBIC() {
return null;
}
/** /**
* BLZ of the sender * BLZ of the sender
* *
* @return the BLZ code of the recipient sender's bank * @return the BLZ code of the recipient sender's bank
*/ */
String getOwnBLZ(); default String getOwnBLZ() {
return null;
}
/** /**
* Bank name of the sender * Bank name of the sender
* *
* @return the name of the sender's bank * @return the name of the sender's bank
*/ */
String getOwnBankName(); default String getOwnBankName() {
return null;
}
/** /**
* IBAN of the sender * IBAN of the sender
* *
* @return the IBAN of the invoice sender's bank account * @return the IBAN of the invoice sender's bank account
*/ */
String getOwnIBAN(); default String getOwnIBAN() {
return null;
}
/** /**
* IBAN of the sender * IBAN of the sender
* *
* @return the Account Number of the invoice sender's bank account * @return the Account Number of the invoice sender's bank account
*/ */
String getOwnKto(); default String getOwnKto() {
return null;
}
/** /**
* Tax ID (not VAT ID) of the sender * Tax ID (not VAT ID) of the sender
* *
* @return Tax ID (not VAT ID) of the sender * @return Tax ID (not VAT ID) of the sender
*/ */
String getOwnTaxID(); default String getOwnTaxID() {
return null;
}
/** /**
* VAT ID (Umsatzsteueridentifikationsnummer) of the sender * VAT ID (Umsatzsteueridentifikationsnummer) of the sender
* *
* @return VAT ID (Umsatzsteueridentifikationsnummer) of the sender * @return VAT ID (Umsatzsteueridentifikationsnummer) of the sender
*/ */
String getOwnVATID(); default String getOwnVATID() {
return null;
}
/**
* supplier identification assigned by the costumer
*
* @return the sender's identification
*/
default String getOwnForeignOrganisationID() {
return null;
}
/** /**
* own name * own name
* *
* @return the sender's organisation name * @return the sender's organisation name
*/ */
String getOwnOrganisationName(); default String getOwnOrganisationName() {
return null;
}
/** /**
* own street address * own street address
* *
* @return sender street address * @return sender street address
*/ */
String getOwnStreet(); default String getOwnStreet() {
return null;
}
/** /**
* own street postal code * own street postal code
* *
* @return sender postal code * @return sender postal code
*/ */
String getOwnZIP(); default String getOwnZIP() {
return null;
}
/** /**
* own city * own city
* *
* @return the invoice sender's city * @return the invoice sender's city
*/ */
String getOwnLocation(); default String getOwnLocation() {
return null;
}
/** /**
* own two digit country code * own two digit country code
* *
* @return the invoice senders two character country iso code * @return the invoice senders two character country iso code
*/ */
String getOwnCountry(); default String getOwnCountry() {
return null;
}
/** /**
* get delivery date * get delivery date
@@ -174,35 +241,44 @@ public interface IZUGFeRDExportableTransaction {
*/ */
Date getDeliveryDate(); Date getDeliveryDate();
/** /**
* get main invoice currency used on the invoice * get main invoice currency used on the invoice
* *
* @return three character currency of this invoice * @return three character currency of this invoice
*/ */
String getCurrency(); default String getCurrency() {
return null;
}
/** /**
* get payment information text. e.g. Bank transfer * get payment information text. e.g. Bank transfer
* *
* @return payment information text * @return payment information text
*/ */
String getOwnPaymentInfoText(); default String getOwnPaymentInfoText() {
return null;
}
/** /**
* get payment term descriptional text * get payment term descriptional text e.g. Bis zum 22.10.2015 ohne Abzug
* e.g. Bis zum 22.10.2015 ohne Abzug
* *
* @return get payment terms * @return get payment terms
*/ */
String getPaymentTermDescription(); default String getPaymentTermDescription() {
return null;
}
/** /**
* get reference document number * get reference document number typically used for Invoice Corrections Will be added as IncludedNote in comfort profile
* typically used for Invoice Corrections
* Will be added as IncludedNote in comfort profile
* *
* @return the ID of the document this document refers to * @return the ID of the document this document refers to
*/ */
String getReferenceNumber(); default String getReferenceNumber() {
return null;
}
} }

View File

@@ -31,14 +31,17 @@ import java.math.BigDecimal;
*/ */
public class VATAmount { public class VATAmount {
public VATAmount(BigDecimal basis, BigDecimal calculated) { public VATAmount(BigDecimal basis, BigDecimal calculated, String documentCode) {
super(); super();
this.basis = basis; this.basis = basis;
this.calculated = calculated; this.calculated = calculated;
this.documentCode = documentCode;
} }
BigDecimal basis, calculated; BigDecimal basis, calculated;
String documentCode;
public BigDecimal getBasis() { public BigDecimal getBasis() {
return basis; return basis;
} }
@@ -55,12 +58,20 @@ public class VATAmount {
this.calculated = calculated; this.calculated = calculated;
} }
public String getDocumentCode() {
return documentCode;
}
public void setDocumentCode(String documentCode) {
this.documentCode = documentCode;
}
public VATAmount add(VATAmount v) { public VATAmount add(VATAmount v) {
return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated())); return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.documentCode);
} }
public VATAmount subtract(VATAmount v) { public VATAmount subtract(VATAmount v) {
return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated())); return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated()), this.documentCode);
} }
} }

View File

@@ -134,8 +134,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
res = res.add(amount.getCalculated()); res = res.add(amount.getCalculated());
} }
return res; return res;
} }
@@ -162,16 +160,14 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent(); BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalc lc = new LineCalc(currentItem); LineCalc lc = new LineCalc(currentItem);
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount()); VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), trans.getDocumentCode());
VATAmount current = hm.get(percent); VATAmount current = hm.get(percent);
if (current == null) { if (current == null) {
hm.put(percent, itemVATAmount); hm.put(percent, itemVATAmount);
} else { } else {
hm.put(percent, current.add(itemVATAmount)); hm.put(percent, current.add(itemVATAmount));
} }
} }
return hm; return hm;
} }

View File

@@ -33,27 +33,21 @@ import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.*; import java.io.*;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
//root.setNamespace(Namespace.getNamespace("http://www.energystar.gov/manageBldgs/req"));
public class ZUGFeRDImporter { public class ZUGFeRDImporter {
/*
* 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 * @var if metadata has been found
@@ -62,57 +56,31 @@ public class ZUGFeRDImporter {
/** /**
* @var the reference (i.e. invoice number) of the sender * @var the reference (i.e. invoice number) of the sender
*/ */
private String foreignReference; private HashMap<String, byte[]> additionalXMLs = new HashMap<>();
private String BLZ;
private String BIC;
private String IBAN;
private String KTO;
private String holder;
private String amount;
private String dueDate;
private HashMap<String, byte[]> additionalXMLs = new HashMap<String, byte[]>();
/** /**
* Raw XML form of the extracted data - may be directly obtained. * Raw XML form of the extracted data - may be directly obtained.
*/ */
private byte[] rawXML = null; private byte[] rawXML = null;
private String bankName;
private boolean amountFound;
private boolean extractAttempt = false;
private boolean parsed = false;
private String xmpString = null; // XMP metadata private String xmpString = null; // XMP metadata
private static final Logger LOG = Logger.getLogger(ZUGFeRDImporter.class.getName());
/** public ZUGFeRDImporter(String pdfFilename) {
* Extracts a ZUGFeRD invoice from a PDF document represented by a file name.
* Errors are just logged to STDOUT.
*
* @param pdfFilename the filename of the pdf
*/
public void extract(String pdfFilename) {
try { try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFilename)); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFilename));
extractLowLevel(bis); extractLowLevel(bis);
bis.close(); bis.close();
} catch (IOException ioe) { } catch (IOException e) {
ioe.printStackTrace(); e.printStackTrace();
throw new ZUGFeRDExportException(e);
} }
} }
static String convertStreamToString(java.io.InputStream is) { public ZUGFeRDImporter(InputStream pdfStream) {
// source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to try {
// https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks extractLowLevel(pdfStream);
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); } catch (IOException e) {
return s.hasNext() ? s.next() : ""; e.printStackTrace();
throw new ZUGFeRDExportException(e);
} }
/**
* get xmp metadata of the PDF, null if not available
*
* @return string
*/
public String getXMP() {
return xmpString;
} }
/** /**
@@ -121,9 +89,7 @@ public class ZUGFeRDImporter {
* *
* @param pdfStream a inputstream of a pdf file * @param pdfStream a inputstream of a pdf file
*/ */
public void extractLowLevel(InputStream pdfStream) throws IOException { private void extractLowLevel(InputStream pdfStream) throws IOException {
PDEmbeddedFilesNameTreeNode etn;
extractAttempt = true;
try (PDDocument doc = PDDocument.load(pdfStream)) { try (PDDocument doc = PDDocument.load(pdfStream)) {
// PDDocumentInformation info = doc.getDocumentInformation(); // PDDocumentInformation info = doc.getDocumentInformation();
PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
@@ -131,7 +97,8 @@ public class ZUGFeRDImporter {
InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata();
xmpString = convertStreamToString(XMP); xmpString = convertStreamToString(XMP);
etn = names.getEmbeddedFiles();
PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles();
if (etn == null) { if (etn == null) {
return; return;
} }
@@ -188,352 +155,136 @@ public class ZUGFeRDImporter {
} }
} }
public HashMap<String, byte[]> getAdditionalData() { private void prettyPrint(Document document) throws TransformerException {
return additionalXMLs; TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = null;
try {
transformer = tf.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));
String output = writer.getBuffer().toString();//.replaceAll("\n|\r", "");
System.err.println(output);
} }
/** private Document getDocument() throws ParserConfigurationException, IOException, SAXException, TransformerException {
* needs to be called to be able to call the getters DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
*/ xmlFact.setNamespaceAware(false);
public void parse() { DocumentBuilder builder = xmlFact.newDocumentBuilder();
DocumentBuilderFactory factory = null; Document doc = builder.parse(new ByteArrayInputStream(rawXML));
DocumentBuilder builder = null; //prettyPrint(doc);
Document document = null; return doc;
if (!extractAttempt) {
throw new RuntimeException("extract() or extractLowLevel() must be used before parsing.");
} }
private String extractString(String xpathStr) {
if (!containsMeta) { if (!containsMeta) {
throw new RuntimeException("No suitable data/ZUGFeRD file could be found."); throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found.");
} }
String result;
factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use
// document.getElementsByTagNameNS("*",...
try { try {
builder = factory.newDocumentBuilder(); Document document = getDocument();
} catch (ParserConfigurationException ex3) { XPathFactory xpathFact = XPathFactory.newInstance();
// TODO Auto-generated catch block XPath xpath = xpathFact.newXPath();
ex3.printStackTrace(); result = xpath.evaluate(xpathStr, document);
} catch (ParserConfigurationException e) {
e.printStackTrace();
throw new ZUGFeRDExportException(e);
} catch (IOException | SAXException | TransformerException | XPathExpressionException e) {
e.printStackTrace();
throw new ZUGFeRDExportException(e);
} }
return result;
try {
InputStream bais = new ByteArrayInputStream(rawXML);
document = builder.parse(bais);
} catch (SAXException ex1) {
ex1.printStackTrace();
} catch (IOException ex2) {
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());
}
/*
* ndList = document .getElementsByTagName("GermanBankleitzahlID");
* //$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 setBIC(booking.getTextContent());
*
* }
*
* ndList = document.getElementsByTagName("ProprietaryID"); //$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 setIBAN(booking.getTextContent());
*
* } <ram:PayeePartyCreditorFinancialAccount> <ram:IBANID>DE1234</ram:IBANID>
* </ram:PayeePartyCreditorFinancialAccount>
* <ram:PayeeSpecifiedCreditorFinancialInstitution>
* <ram:BICID>DE5656565</ram:BICID> <ram:Name>Commerzbank</ram:Name>
* </ram:PayeeSpecifiedCreditorFinancialInstitution>
*
*/
/***
* we should switch to xpath like this // Create XPathFactory object
* XPathFactory xpathFactory = XPathFactory.newInstance();
*
* // Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression
* expr =
* xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]");
* //evaluate expression result on XML document ndList = (NodeList)
* expr.evaluate(doc, XPathConstants.NODESET);
*
*/
ndList = document.getElementsByTagNameNS("*", "PayeePartyCreditorFinancialAccount"); //$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("IBANID"))) { //$NON-NLS-1$
setIBAN(detail.getTextContent());
}
if ((detail.getLocalName() != null) && (detail.getLocalName().equals("ProprietaryID"))) { //$NON-NLS-1$
setKTO(detail.getTextContent());
}
}
}
ndList = document.getElementsByTagNameNS("*", "PayeeSpecifiedCreditorFinancialInstitution");// ZF1 //$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("BICID"))) { //$NON-NLS-1$
setBIC(detail.getTextContent());
}
if ((detail.getLocalName() != null) && (detail.getLocalName().equals("GermanBankleitzahlID"))) { //$NON-NLS-1$
setBLZ(detail.getTextContent());
}
if ((detail.getLocalName() != null) && (detail.getLocalName().equals("Name"))) { //$NON-NLS-1$
setBankName(detail.getTextContent());
}
}
}
ndList = document.getElementsByTagNameNS("*", "SellerTradeParty"); //$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("Name"))) { //$NON-NLS-1$
setHolder(detail.getTextContent());
}
}
}
ndList = document.getElementsByTagNameNS("*", "DuePayableAmount"); //$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
amountFound = true;
setAmount(booking.getTextContent());
}
if (!amountFound) {
/*
* there is apparently no requirement to mention DuePayableAmount,, if it's not
* there, check for GrandTotalAmount
*/
ndList = document.getElementsByTagNameNS("*", "GrandTotalAmount"); //$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
amountFound = true;
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;
}
/**
* @return if export found parseable ZUGFeRD data
*/
public boolean containsMeta() {
return containsMeta;
} }
/** /**
* @return the reference (purpose) the sender specified for this invoice * @return the reference (purpose) the sender specified for this invoice
*/ */
public String getForeignReference() { public String getForeignReference() {
if (!parsed) { String result = extractString("//ApplicableHeaderTradeSettlement/PaymentReference");
throw new RuntimeException("use extract() before requesting a value"); if(result == null || result.isEmpty())
} result = extractString("//ApplicableSupplyChainTradeSettlement/PaymentReference");
if (foreignReference == null) { return result;
parse();
}
return foreignReference;
} }
private void setForeignReference(String foreignReference) { /**
this.foreignReference = foreignReference; * @return the document code
*/
public String getDocumentCode() {
return extractString("//HeaderExchangedDocument/TypeCode");
} }
/** /**
* @return the sender's bank's BLZ code * @return the sender's bank's BLZ code
*/ */
public String getBLZ() { public String getBLZ() {
if (!parsed) { return extractString("//PayeeSpecifiedCreditorFinancialInstitution/GermanBankleitzahlID");
throw new RuntimeException("use extract() before requesting a value");
}
if (BLZ == null) {
parse();
}
return BLZ;
}
private void setBLZ(String blz) {
this.BLZ = blz;
} }
/** /**
* @return the sender's bank's BIC code * @return the sender's bank's BIC code
*/ */
public String getBIC() { public String getBIC() {
if (!parsed) { return extractString("//PayeeSpecifiedCreditorFinancialInstitution/BICID");
throw new RuntimeException("use extract() before requesting a value");
}
if (BIC == null) {
parse();
}
return BIC;
}
private void setBIC(String bic) {
this.BIC = bic;
}
private void setDueDate(String dueDate) {
this.dueDate = dueDate;
}
private void setBankName(String bankname) {
this.bankName = bankname;
}
/**
* @return the sender's IBAN
*/
public String getIBAN() {
if (!parsed) {
throw new RuntimeException("use extract() before requesting a value");
}
if (IBAN == null) {
parse();
}
return IBAN;
}
/**
* @return the sender's KTO
*/
public String getKTO() {
if (!parsed) {
throw new RuntimeException("use extract() before requesting a value");
}
if (KTO == null) {
parse();
}
return KTO;
} }
/** /**
* @return the sender's bankname * @return the sender's bankname
*/ */
public String getBankName() { public String getBankName() {
if (!parsed) { return extractString("/CrossIndustryInvoice/SupplyChainTradeTransaction/ApplicableHeaderTradeSettlement/SpecifiedTradeSettlementPaymentMeans/PayeeSpecifiedCreditorFinancialInstitution/Name");
throw new RuntimeException("use extract() before requesting a value");
}
if (bankName == null) {
parse();
}
return bankName;
} }
private void setIBAN(String IBAN) { public String getIBAN() {
this.IBAN = IBAN; return extractString("//PayeePartyCreditorFinancialAccount/IBANID");
} }
private void setKTO(String KTO) { public String getKTO() {
this.KTO = KTO; return extractString("//PayeePartyCreditorFinancialAccount/ProprietaryID");
} }
/**
* @return the name of the owner of the sender's bank account
*/
public String getHolder() { public String getHolder() {
if (rawXML == null) { return extractString("//SellerTradeParty/Name");
throw new RuntimeException("use extract() before requesting a value");
}
if (holder == null) {
parse();
}
return holder;
}
private void setHolder(String holder) {
this.holder = holder;
} }
/** /**
* @return the total payable amount * @return the total payable amount
*/ */
public String getAmount() { public String getAmount() {
if (rawXML == null) { String result = extractString("//SpecifiedTradeSettlementHeaderMonetarySummation/DuePayableAmount");
throw new RuntimeException("use extract() before requesting a value"); if(result == null || result.isEmpty())
} result = extractString("//SpecifiedTradeSettlementMonetarySummation/GrandTotalAmount");
if (amount == null) { return result;
parse();
}
return amount;
} }
/** /**
* @return when the payment is due * @return when the payment is due
*/ */
public String getDueDate() { public String getDueDate() {
if (rawXML == null) { return extractString("//SpecifiedTradePaymentTerms/DueDateDateTime/DateTimeString");
throw new RuntimeException("use extract() before requesting a value");
}
if (dueDate == null) {
parse();
}
return dueDate;
} }
private void setAmount(String amount) { public HashMap<String, byte[]> getAdditionalData() {
this.amount = amount; 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;
} }
/** /**
@@ -604,4 +355,12 @@ public class ZUGFeRDImporter {
return (meta != null) && (meta.length() > 0) && ((meta.contains("SpecifiedExchangedDocumentContext") //$NON-NLS-1$ return (meta != null) && (meta.length() > 0) && ((meta.contains("SpecifiedExchangedDocumentContext") //$NON-NLS-1$
/* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */)); /* 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).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
} }

View File

@@ -0,0 +1,23 @@
/** **********************************************************************
*
* Copyright 2019 ak on 09.04.19.
*
* 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;
public class ZUGFeRDImporterException extends RuntimeException {
}

View File

@@ -18,14 +18,65 @@
*********************************************************************** */ *********************************************************************** */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.ZUGFeRD.model.*;
import javax.xml.bind.JAXBElement;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.mustangproject.ZUGFeRD.model.AmountType;
import org.mustangproject.ZUGFeRD.model.CodeType;
import org.mustangproject.ZUGFeRD.model.CountryIDType;
import org.mustangproject.ZUGFeRD.model.CreditorFinancialAccountType;
import org.mustangproject.ZUGFeRD.model.CreditorFinancialInstitutionType;
import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType;
import org.mustangproject.ZUGFeRD.model.DateTimeType;
import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants;
import org.mustangproject.ZUGFeRD.model.DocumentCodeType;
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
import org.mustangproject.ZUGFeRD.model.DocumentContextParameterType;
import org.mustangproject.ZUGFeRD.model.DocumentContextParameterTypeConstants;
import org.mustangproject.ZUGFeRD.model.DocumentLineDocumentType;
import org.mustangproject.ZUGFeRD.model.ExchangedDocumentContextType;
import org.mustangproject.ZUGFeRD.model.ExchangedDocumentType;
import org.mustangproject.ZUGFeRD.model.IDType;
import org.mustangproject.ZUGFeRD.model.IndicatorType;
import org.mustangproject.ZUGFeRD.model.LogisticsServiceChargeType;
import org.mustangproject.ZUGFeRD.model.NoteType;
import org.mustangproject.ZUGFeRD.model.NoteTypeConstants;
import org.mustangproject.ZUGFeRD.model.ObjectFactory;
import org.mustangproject.ZUGFeRD.model.PaymentMeansCodeType;
import org.mustangproject.ZUGFeRD.model.PaymentMeansCodeTypeConstants;
import org.mustangproject.ZUGFeRD.model.PercentType;
import org.mustangproject.ZUGFeRD.model.QuantityType;
import org.mustangproject.ZUGFeRD.model.SupplyChainEventType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeAgreementType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeDeliveryType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeLineItemType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeSettlementType;
import org.mustangproject.ZUGFeRD.model.SupplyChainTradeTransactionType;
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeType;
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
import org.mustangproject.ZUGFeRD.model.TaxRegistrationType;
import org.mustangproject.ZUGFeRD.model.TaxRegistrationTypeConstants;
import org.mustangproject.ZUGFeRD.model.TaxTypeCodeType;
import org.mustangproject.ZUGFeRD.model.TaxTypeCodeTypeConstants;
import org.mustangproject.ZUGFeRD.model.TextType;
import org.mustangproject.ZUGFeRD.model.TradeAddressType;
import org.mustangproject.ZUGFeRD.model.TradeAllowanceChargeType;
import org.mustangproject.ZUGFeRD.model.TradePartyType;
import org.mustangproject.ZUGFeRD.model.TradePaymentTermsType;
import org.mustangproject.ZUGFeRD.model.TradePriceType;
import org.mustangproject.ZUGFeRD.model.TradeProductType;
import org.mustangproject.ZUGFeRD.model.TradeSettlementMonetarySummationType;
import org.mustangproject.ZUGFeRD.model.TradeSettlementPaymentMeansType;
import org.mustangproject.ZUGFeRD.model.TradeTaxType;
class ZUGFeRDTransactionModelConverter { class ZUGFeRDTransactionModelConverter {
private static final SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); private static final SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd");
@@ -36,10 +87,11 @@ class ZUGFeRDTransactionModelConverter {
private boolean isTest; private boolean isTest;
private String currency = "EUR"; private String currency = "EUR";
ZUGFeRDTransactionModelConverter(IZUGFeRDExportableTransaction trans) { ZUGFeRDTransactionModelConverter(IZUGFeRDExportableTransaction trans) {
this.trans = trans; this.trans = trans;
totals = new Totals(); totals = new Totals();
this.currency = trans.getCurrency() != null ? trans.getCurrency() : currency; currency = trans.getCurrency() != null ? trans.getCurrency() : currency;
} }
@@ -47,15 +99,15 @@ class ZUGFeRDTransactionModelConverter {
CrossIndustryDocumentType invoice = xmlFactory CrossIndustryDocumentType invoice = xmlFactory
.createCrossIndustryDocumentType(); .createCrossIndustryDocumentType();
invoice.setSpecifiedExchangedDocumentContext(this.getDocumentContext()); invoice.setSpecifiedExchangedDocumentContext(getDocumentContext());
invoice.setHeaderExchangedDocument(this.getDocument()); invoice.setHeaderExchangedDocument(getDocument());
invoice.setSpecifiedSupplyChainTradeTransaction(this invoice.setSpecifiedSupplyChainTradeTransaction(getTradeTransaction());
.getTradeTransaction());
return xmlFactory return xmlFactory
.createCrossIndustryDocument(invoice); .createCrossIndustryDocument(invoice);
} }
private ExchangedDocumentContextType getDocumentContext() { private ExchangedDocumentContextType getDocumentContext() {
ExchangedDocumentContextType context = xmlFactory ExchangedDocumentContextType context = xmlFactory
@@ -75,6 +127,7 @@ class ZUGFeRDTransactionModelConverter {
return context; return context;
} }
private ExchangedDocumentType getDocument() { private ExchangedDocumentType getDocument() {
ExchangedDocumentType document = xmlFactory ExchangedDocumentType document = xmlFactory
@@ -94,7 +147,7 @@ class ZUGFeRDTransactionModelConverter {
document.setIssueDateTime(issueDateTime); document.setIssueDateTime(issueDateTime);
DocumentCodeType documentCodeType = xmlFactory.createDocumentCodeType(); DocumentCodeType documentCodeType = xmlFactory.createDocumentCodeType();
documentCodeType.setValue(DocumentCodeTypeConstants.INVOICE); documentCodeType.setValue(trans.getDocumentCode());
document.setTypeCode(documentCodeType); document.setTypeCode(documentCodeType);
TextType name = xmlFactory.createTextType(); TextType name = xmlFactory.createTextType();
@@ -113,7 +166,7 @@ class ZUGFeRDTransactionModelConverter {
document.getIncludedNote().add(regularInfo); document.getIncludedNote().add(regularInfo);
} }
if (trans.getReferenceNumber() != null && !new String().equals(trans.getReferenceNumber())) { if (trans.getReferenceNumber() != null && !"".equals(trans.getReferenceNumber())) {
NoteType referenceInfo = xmlFactory.createNoteType(); NoteType referenceInfo = xmlFactory.createNoteType();
TextType referenceInfoContent = xmlFactory.createTextType(); TextType referenceInfoContent = xmlFactory.createTextType();
referenceInfoContent.setValue("Ursprungsbeleg: " + trans.getReferenceNumber()); referenceInfoContent.setValue("Ursprungsbeleg: " + trans.getReferenceNumber());
@@ -124,36 +177,44 @@ class ZUGFeRDTransactionModelConverter {
return document; return document;
} }
private SupplyChainTradeTransactionType getTradeTransaction() { private SupplyChainTradeTransactionType getTradeTransaction() {
SupplyChainTradeTransactionType transaction = xmlFactory SupplyChainTradeTransactionType transaction = xmlFactory
.createSupplyChainTradeTransactionType(); .createSupplyChainTradeTransactionType();
transaction.getApplicableSupplyChainTradeAgreement().add( transaction.getApplicableSupplyChainTradeAgreement().add(
this.getTradeAgreement()); getTradeAgreement());
transaction.setApplicableSupplyChainTradeDelivery(this transaction.setApplicableSupplyChainTradeDelivery(getTradeDelivery());
.getTradeDelivery()); transaction.setApplicableSupplyChainTradeSettlement(getTradeSettlement());
transaction.setApplicableSupplyChainTradeSettlement(this
.getTradeSettlement());
transaction.getIncludedSupplyChainTradeLineItem().addAll( transaction.getIncludedSupplyChainTradeLineItem().addAll(
this.getLineItems()); getLineItems());
return transaction; return transaction;
} }
private SupplyChainTradeAgreementType getTradeAgreement() { private SupplyChainTradeAgreementType getTradeAgreement() {
SupplyChainTradeAgreementType tradeAgreement = xmlFactory SupplyChainTradeAgreementType tradeAgreement = xmlFactory
.createSupplyChainTradeAgreementType(); .createSupplyChainTradeAgreementType();
tradeAgreement.setBuyerTradeParty(this.getBuyer()); tradeAgreement.setBuyerTradeParty(getBuyer());
tradeAgreement.setSellerTradeParty(this.getSeller()); tradeAgreement.setSellerTradeParty(getSeller());
return tradeAgreement; return tradeAgreement;
} }
private TradePartyType getBuyer() { private TradePartyType getBuyer() {
TradePartyType buyerTradeParty = xmlFactory.createTradePartyType(); TradePartyType buyerTradeParty = xmlFactory.createTradePartyType();
if (trans.getRecipient().getID() != null) {
IDType buyerID = xmlFactory.createIDType();
buyerID.setValue(trans.getRecipient().getID());
buyerTradeParty.getID().add(buyerID);
}
TextType buyerName = xmlFactory.createTextType(); TextType buyerName = xmlFactory.createTextType();
buyerName.setValue(trans.getRecipient().getName()); buyerName.setValue(trans.getRecipient().getName());
buyerTradeParty.setName(buyerName); buyerTradeParty.setName(buyerName);
@@ -189,9 +250,17 @@ class ZUGFeRDTransactionModelConverter {
return buyerTradeParty; return buyerTradeParty;
} }
private TradePartyType getSeller() { private TradePartyType getSeller() {
TradePartyType sellerTradeParty = xmlFactory.createTradePartyType(); TradePartyType sellerTradeParty = xmlFactory.createTradePartyType();
if (trans.getOwnForeignOrganisationID() != null) {
IDType sellerID = xmlFactory.createIDType();
sellerID.setValue(trans.getOwnForeignOrganisationID());
sellerTradeParty.getID().add(sellerID);
}
TextType sellerName = xmlFactory.createTextType(); TextType sellerName = xmlFactory.createTextType();
sellerName.setValue(trans.getOwnOrganisationName()); sellerName.setValue(trans.getOwnOrganisationName());
sellerTradeParty.setName(sellerName); sellerTradeParty.setName(sellerName);
@@ -238,6 +307,7 @@ class ZUGFeRDTransactionModelConverter {
return sellerTradeParty; return sellerTradeParty;
} }
private SupplyChainTradeDeliveryType getTradeDelivery() { private SupplyChainTradeDeliveryType getTradeDelivery() {
SupplyChainTradeDeliveryType tradeDelivery = xmlFactory SupplyChainTradeDeliveryType tradeDelivery = xmlFactory
@@ -257,6 +327,7 @@ class ZUGFeRDTransactionModelConverter {
return tradeDelivery; return tradeDelivery;
} }
private SupplyChainTradeSettlementType getTradeSettlement() { private SupplyChainTradeSettlementType getTradeSettlement() {
SupplyChainTradeSettlementType tradeSettlement = xmlFactory SupplyChainTradeSettlementType tradeSettlement = xmlFactory
.createSupplyChainTradeSettlementType(); .createSupplyChainTradeSettlementType();
@@ -270,29 +341,29 @@ class ZUGFeRDTransactionModelConverter {
tradeSettlement.setInvoiceCurrencyCode(currencyCode); tradeSettlement.setInvoiceCurrencyCode(currencyCode);
tradeSettlement.getSpecifiedTradeSettlementPaymentMeans().add( tradeSettlement.getSpecifiedTradeSettlementPaymentMeans().add(
this.getPaymentData()); getPaymentData());
tradeSettlement.getApplicableTradeTax().addAll(this.getTradeTax()); tradeSettlement.getApplicableTradeTax().addAll(getTradeTax());
tradeSettlement.getSpecifiedTradePaymentTerms().addAll( tradeSettlement.getSpecifiedTradePaymentTerms().addAll(
this.getPaymentTerms()); getPaymentTerms());
if (trans.getZFAllowances() != null) { if (trans.getZFAllowances() != null) {
tradeSettlement.getSpecifiedTradeAllowanceCharge().addAll( tradeSettlement.getSpecifiedTradeAllowanceCharge().addAll(
this.getHeaderAllowances()); getHeaderAllowances());
} }
if (trans.getZFLogisticsServiceCharges() != null) { if (trans.getZFLogisticsServiceCharges() != null) {
tradeSettlement.getSpecifiedLogisticsServiceCharge().addAll( tradeSettlement.getSpecifiedLogisticsServiceCharge().addAll(
this.getHeaderLogisticsServiceCharges()); getHeaderLogisticsServiceCharges());
} }
if (trans.getZFCharges() != null) { if (trans.getZFCharges() != null) {
tradeSettlement.getSpecifiedTradeAllowanceCharge().addAll( tradeSettlement.getSpecifiedTradeAllowanceCharge().addAll(
this.getHeaderCharges()); getHeaderCharges());
} }
tradeSettlement.setSpecifiedTradeSettlementMonetarySummation(this tradeSettlement.setSpecifiedTradeSettlementMonetarySummation(getMonetarySummation());
.getMonetarySummation());
return tradeSettlement; return tradeSettlement;
} }
private TradeSettlementPaymentMeansType getPaymentData() { private TradeSettlementPaymentMeansType getPaymentData() {
TradeSettlementPaymentMeansType paymentData = xmlFactory TradeSettlementPaymentMeansType paymentData = xmlFactory
.createTradeSettlementPaymentMeansType(); .createTradeSettlementPaymentMeansType();
@@ -335,11 +406,11 @@ class ZUGFeRDTransactionModelConverter {
return paymentData; return paymentData;
} }
private Collection<TradeTaxType> getTradeTax() {
List<TradeTaxType> tradeTaxTypes = new ArrayList<TradeTaxType>();
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = this private Collection<TradeTaxType> getTradeTax() {
.getVATPercentAmountMap(); List<TradeTaxType> tradeTaxTypes = new ArrayList<>();
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = this.getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); TradeTaxType tradeTax = xmlFactory.createTradeTaxType();
@@ -347,9 +418,9 @@ class ZUGFeRDTransactionModelConverter {
taxTypeCode.setValue(TaxTypeCodeTypeConstants.SALESTAX); taxTypeCode.setValue(TaxTypeCodeTypeConstants.SALESTAX);
tradeTax.setTypeCode(taxTypeCode); tradeTax.setTypeCode(taxTypeCode);
TaxCategoryCodeType taxCategoryCode = xmlFactory TaxCategoryCodeType taxCategoryCode = xmlFactory.createTaxCategoryCodeType();
.createTaxCategoryCodeType(); VATAmount vatAmount = VATPercentAmountMap.get(currentTaxPercent);
taxCategoryCode.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE); taxCategoryCode.setValue(vatAmount.getDocumentCode());
tradeTax.setCategoryCode(taxCategoryCode); tradeTax.setCategoryCode(taxCategoryCode);
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
@@ -360,8 +431,7 @@ class ZUGFeRDTransactionModelConverter {
AmountType calculatedTaxAmount = xmlFactory.createAmountType(); AmountType calculatedTaxAmount = xmlFactory.createAmountType();
calculatedTaxAmount.setCurrencyID(currency); calculatedTaxAmount.setCurrencyID(currency);
calculatedTaxAmount calculatedTaxAmount.setValue(currencyFormat(amount.getCalculated()));
.setValue(currencyFormat(amount.getCalculated()));
tradeTax.getCalculatedAmount().add(calculatedTaxAmount); tradeTax.getCalculatedAmount().add(calculatedTaxAmount);
AmountType basisTaxAmount = xmlFactory.createAmountType(); AmountType basisTaxAmount = xmlFactory.createAmountType();
@@ -375,14 +445,13 @@ class ZUGFeRDTransactionModelConverter {
return tradeTaxTypes; return tradeTaxTypes;
} }
private Collection<TradeAllowanceChargeType> getHeaderAllowances() { private Collection<TradeAllowanceChargeType> getHeaderAllowances() {
List<TradeAllowanceChargeType> headerAllowances = new ArrayList<TradeAllowanceChargeType>(); List<TradeAllowanceChargeType> headerAllowances = new ArrayList<>();
for (IZUGFeRDAllowanceCharge iAllowance : trans.getZFAllowances()) { for (IZUGFeRDAllowanceCharge iAllowance : trans.getZFAllowances()) {
TradeAllowanceChargeType allowance = xmlFactory TradeAllowanceChargeType allowance = xmlFactory.createTradeAllowanceChargeType();
.createTradeAllowanceChargeType();
IndicatorType chargeIndicator = xmlFactory.createIndicatorType(); IndicatorType chargeIndicator = xmlFactory.createIndicatorType();
chargeIndicator.setIndicator(false); chargeIndicator.setIndicator(false);
allowance.setChargeIndicator(chargeIndicator); allowance.setChargeIndicator(chargeIndicator);
@@ -397,7 +466,6 @@ class ZUGFeRDTransactionModelConverter {
allowance.setReason(reason); allowance.setReason(reason);
TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); TradeTaxType tradeTax = xmlFactory.createTradeTaxType();
PercentType vatPercent = xmlFactory.createPercentType(); PercentType vatPercent = xmlFactory.createPercentType();
vatPercent.setValue(currencyFormat(iAllowance.getTaxPercent())); vatPercent.setValue(currencyFormat(iAllowance.getTaxPercent()));
tradeTax.setApplicablePercent(vatPercent); tradeTax.setApplicablePercent(vatPercent);
@@ -409,9 +477,8 @@ class ZUGFeRDTransactionModelConverter {
* basisAmount.setValue(amount.getBasis()); * basisAmount.setValue(amount.getBasis());
* allowance.setBasisAmount(basisAmount); * allowance.setBasisAmount(basisAmount);
*/ */
TaxCategoryCodeType taxType = xmlFactory TaxCategoryCodeType taxType = xmlFactory.createTaxCategoryCodeType();
.createTaxCategoryCodeType(); taxType.setValue(iAllowance.getCategoryCode());
taxType.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE);
tradeTax.setCategoryCode(taxType); tradeTax.setCategoryCode(taxType);
TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType();
@@ -420,20 +487,18 @@ class ZUGFeRDTransactionModelConverter {
allowance.getCategoryTradeTax().add(tradeTax); allowance.getCategoryTradeTax().add(tradeTax);
headerAllowances.add(allowance); headerAllowances.add(allowance);
} }
return headerAllowances; return headerAllowances;
} }
private Collection<TradeAllowanceChargeType> getHeaderCharges() { private Collection<TradeAllowanceChargeType> getHeaderCharges() {
List<TradeAllowanceChargeType> headerCharges = new ArrayList<TradeAllowanceChargeType>(); List<TradeAllowanceChargeType> headerCharges = new ArrayList<>();
for (IZUGFeRDAllowanceCharge iCharge : trans.getZFCharges()) { for (IZUGFeRDAllowanceCharge iCharge : trans.getZFCharges()) {
TradeAllowanceChargeType charge = xmlFactory TradeAllowanceChargeType charge = xmlFactory.createTradeAllowanceChargeType();
.createTradeAllowanceChargeType();
IndicatorType chargeIndicator = xmlFactory.createIndicatorType(); IndicatorType chargeIndicator = xmlFactory.createIndicatorType();
chargeIndicator.setIndicator(true); chargeIndicator.setIndicator(true);
charge.setChargeIndicator(chargeIndicator); charge.setChargeIndicator(chargeIndicator);
@@ -448,7 +513,6 @@ class ZUGFeRDTransactionModelConverter {
charge.setReason(reason); charge.setReason(reason);
TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); TradeTaxType tradeTax = xmlFactory.createTradeTaxType();
PercentType vatPercent = xmlFactory.createPercentType(); PercentType vatPercent = xmlFactory.createPercentType();
vatPercent.setValue(currencyFormat(iCharge.getTaxPercent())); vatPercent.setValue(currencyFormat(iCharge.getTaxPercent()));
tradeTax.setApplicablePercent(vatPercent); tradeTax.setApplicablePercent(vatPercent);
@@ -460,9 +524,8 @@ class ZUGFeRDTransactionModelConverter {
* basisAmount.setValue(amount.getBasis()); * basisAmount.setValue(amount.getBasis());
* allowance.setBasisAmount(basisAmount); * allowance.setBasisAmount(basisAmount);
*/ */
TaxCategoryCodeType taxType = xmlFactory TaxCategoryCodeType taxType = xmlFactory.createTaxCategoryCodeType();
.createTaxCategoryCodeType(); taxType.setValue(iCharge.getCategoryCode());
taxType.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE);
tradeTax.setCategoryCode(taxType); tradeTax.setCategoryCode(taxType);
TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType();
@@ -477,19 +540,17 @@ class ZUGFeRDTransactionModelConverter {
return headerCharges; return headerCharges;
} }
private Collection<LogisticsServiceChargeType> getHeaderLogisticsServiceCharges() { private Collection<LogisticsServiceChargeType> getHeaderLogisticsServiceCharges() {
List<LogisticsServiceChargeType> headerServiceCharge = new ArrayList<LogisticsServiceChargeType>(); List<LogisticsServiceChargeType> headerServiceCharge = new ArrayList<>();
for (IZUGFeRDAllowanceCharge iServiceCharge : trans for (IZUGFeRDAllowanceCharge iServiceCharge : trans.getZFLogisticsServiceCharges()) {
.getZFLogisticsServiceCharges()) {
LogisticsServiceChargeType serviceCharge = xmlFactory LogisticsServiceChargeType serviceCharge = xmlFactory.createLogisticsServiceChargeType();
.createLogisticsServiceChargeType();
AmountType actualAmount = xmlFactory.createAmountType(); AmountType actualAmount = xmlFactory.createAmountType();
actualAmount.setCurrencyID(currency); actualAmount.setCurrencyID(currency);
actualAmount.setValue(currencyFormat(iServiceCharge actualAmount.setValue(currencyFormat(iServiceCharge.getTotalAmount()));
.getTotalAmount()));
serviceCharge.getAppliedAmount().add(actualAmount); serviceCharge.getAppliedAmount().add(actualAmount);
TextType reason = xmlFactory.createTextType(); TextType reason = xmlFactory.createTextType();
@@ -509,9 +570,8 @@ class ZUGFeRDTransactionModelConverter {
* basisAmount.setValue(amount.getBasis()); * basisAmount.setValue(amount.getBasis());
* allowance.setBasisAmount(basisAmount); * allowance.setBasisAmount(basisAmount);
*/ */
TaxCategoryCodeType taxType = xmlFactory TaxCategoryCodeType taxType = xmlFactory.createTaxCategoryCodeType();
.createTaxCategoryCodeType(); taxType.setValue(iServiceCharge.getCategoryCode());
taxType.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE);
tradeTax.setCategoryCode(taxType); tradeTax.setCategoryCode(taxType);
TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType();
@@ -526,8 +586,9 @@ class ZUGFeRDTransactionModelConverter {
return headerServiceCharge; return headerServiceCharge;
} }
private Collection<TradePaymentTermsType> getPaymentTerms() { private Collection<TradePaymentTermsType> getPaymentTerms() {
List<TradePaymentTermsType> paymentTerms = new ArrayList<TradePaymentTermsType>(); List<TradePaymentTermsType> paymentTerms = new ArrayList<>();
TradePaymentTermsType paymentTerm = xmlFactory TradePaymentTermsType paymentTerm = xmlFactory
.createTradePaymentTermsType(); .createTradePaymentTermsType();
@@ -553,6 +614,7 @@ class ZUGFeRDTransactionModelConverter {
return paymentTerms; return paymentTerms;
} }
private TradeSettlementMonetarySummationType getMonetarySummation() { private TradeSettlementMonetarySummationType getMonetarySummation() {
TradeSettlementMonetarySummationType monetarySummation = xmlFactory TradeSettlementMonetarySummationType monetarySummation = xmlFactory
.createTradeSettlementMonetarySummationType(); .createTradeSettlementMonetarySummationType();
@@ -630,9 +692,10 @@ class ZUGFeRDTransactionModelConverter {
return monetarySummation; return monetarySummation;
} }
private Collection<SupplyChainTradeLineItemType> getLineItems() { private Collection<SupplyChainTradeLineItemType> getLineItems() {
ArrayList<SupplyChainTradeLineItemType> lineItems = new ArrayList<SupplyChainTradeLineItemType>(); ArrayList<SupplyChainTradeLineItemType> lineItems = new ArrayList<>();
int lineID = 0; int lineID = 0;
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
lineID++; lineID++;
@@ -734,9 +797,8 @@ class ZUGFeRDTransactionModelConverter {
.createSupplyChainTradeSettlementType(); .createSupplyChainTradeSettlementType();
TradeTaxType tradeTax = xmlFactory.createTradeTaxType(); TradeTaxType tradeTax = xmlFactory.createTradeTaxType();
TaxCategoryCodeType taxCategoryCode = xmlFactory TaxCategoryCodeType taxCategoryCode = xmlFactory.createTaxCategoryCodeType();
.createTaxCategoryCodeType(); taxCategoryCode.setValue(currentItem.getCategoryCode());
taxCategoryCode.setValue(TaxCategoryCodeTypeConstants.STANDARDRATE);
tradeTax.setCategoryCode(taxCategoryCode); tradeTax.setCategoryCode(taxCategoryCode);
TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType(); TaxTypeCodeType taxCode = xmlFactory.createTaxTypeCodeType();
@@ -777,22 +839,27 @@ class ZUGFeRDTransactionModelConverter {
return lineItems; return lineItems;
} }
private BigDecimal vatFormat(BigDecimal value) { private BigDecimal vatFormat(BigDecimal value) {
return nDigitFormat(value, 2); return nDigitFormat(value, 2);
} }
private BigDecimal currencyFormat(BigDecimal value) { private BigDecimal currencyFormat(BigDecimal value) {
return nDigitFormat(value, 2); return nDigitFormat(value, 2);
} }
private BigDecimal priceFormat(BigDecimal value) { private BigDecimal priceFormat(BigDecimal value) {
return nDigitFormat(value, 4); return nDigitFormat(value, 4);
} }
private BigDecimal quantityFormat(BigDecimal value) { private BigDecimal quantityFormat(BigDecimal value) {
return nDigitFormat(value, 4); return nDigitFormat(value, 4);
} }
private BigDecimal nDigitFormat(BigDecimal value, int scale) { private BigDecimal nDigitFormat(BigDecimal value, int scale) {
/* /*
* I needed 123,45, locale independent.I tried * I needed 123,45, locale independent.I tried
@@ -837,11 +904,10 @@ class ZUGFeRDTransactionModelConverter {
} }
/** /**
* which taxes have been used with which amounts in this transaction, empty * which taxes have been used with which amounts in this transaction, empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable to 19% VAT
* for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable to * (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) 190 Eur
* 19% VAT (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT)
* 190 Eur
* *
* @return HashMap<BigDecimal, VATAmount> which taxes have been used with which amounts * @return HashMap<BigDecimal, VATAmount> which taxes have been used with which amounts
*/ */
@@ -849,15 +915,14 @@ class ZUGFeRDTransactionModelConverter {
return getVATPercentAmountMap(false); return getVATPercentAmountMap(false);
} }
private HashMap<BigDecimal, VATAmount> getVATPercentAmountMap(
Boolean itemOnly) { private HashMap<BigDecimal, VATAmount> getVATPercentAmountMap(Boolean itemOnly) {
HashMap<BigDecimal, VATAmount> hm = new HashMap<BigDecimal, VATAmount>(); HashMap<BigDecimal, VATAmount> hm = new HashMap<>();
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent(); BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalc lc = new LineCalc(currentItem); LineCalc lc = new LineCalc(currentItem);
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), trans.getDocumentCode());
lc.getItemTotalVATAmount());
VATAmount current = hm.get(percent); VATAmount current = hm.get(percent);
if (current == null) { if (current == null) {
hm.put(percent, itemVATAmount); hm.put(percent, itemVATAmount);
@@ -869,13 +934,12 @@ class ZUGFeRDTransactionModelConverter {
return hm; return hm;
} }
if (trans.getZFAllowances() != null) { if (trans.getZFAllowances() != null) {
for (IZUGFeRDAllowanceCharge headerAllowance : trans for (IZUGFeRDAllowanceCharge headerAllowance : trans.getZFAllowances()) {
.getZFAllowances()) {
BigDecimal percent = headerAllowance.getTaxPercent(); BigDecimal percent = headerAllowance.getTaxPercent();
VATAmount itemVATAmount = new VATAmount( VATAmount itemVATAmount = new VATAmount(
headerAllowance.getTotalAmount(), headerAllowance headerAllowance.getTotalAmount(), headerAllowance
.getTotalAmount().multiply(percent) .getTotalAmount().multiply(percent)
.divide(new BigDecimal(100))); .divide(new BigDecimal(100)), trans.getDocumentCode());
VATAmount current = hm.get(percent); VATAmount current = hm.get(percent);
if (current == null) { if (current == null) {
hm.put(percent, itemVATAmount); hm.put(percent, itemVATAmount);
@@ -892,7 +956,7 @@ class ZUGFeRDTransactionModelConverter {
VATAmount itemVATAmount = new VATAmount( VATAmount itemVATAmount = new VATAmount(
logisticsServiceCharge.getTotalAmount(), logisticsServiceCharge.getTotalAmount(),
logisticsServiceCharge.getTotalAmount() logisticsServiceCharge.getTotalAmount()
.multiply(percent).divide(new BigDecimal(100))); .multiply(percent).divide(new BigDecimal(100)), trans.getDocumentCode());
VATAmount current = hm.get(percent); VATAmount current = hm.get(percent);
if (current == null) { if (current == null) {
hm.put(percent, itemVATAmount); hm.put(percent, itemVATAmount);
@@ -907,7 +971,7 @@ class ZUGFeRDTransactionModelConverter {
BigDecimal percent = charge.getTaxPercent(); BigDecimal percent = charge.getTaxPercent();
VATAmount itemVATAmount = new VATAmount( VATAmount itemVATAmount = new VATAmount(
charge.getTotalAmount(), charge.getTotalAmount() charge.getTotalAmount(), charge.getTotalAmount()
.multiply(percent).divide(new BigDecimal(100))); .multiply(percent).divide(new BigDecimal(100)), trans.getDocumentCode());
VATAmount current = hm.get(percent); VATAmount current = hm.get(percent);
if (current == null) { if (current == null) {
hm.put(percent, itemVATAmount); hm.put(percent, itemVATAmount);
@@ -920,6 +984,7 @@ class ZUGFeRDTransactionModelConverter {
return hm; return hm;
} }
ZUGFeRDTransactionModelConverter withTest(boolean isTest) { ZUGFeRDTransactionModelConverter withTest(boolean isTest) {
this.isTest = isTest; this.isTest = isTest;
return this; return this;
@@ -932,6 +997,7 @@ class ZUGFeRDTransactionModelConverter {
private BigDecimal itemTotalVATAmount; private BigDecimal itemTotalVATAmount;
private BigDecimal itemNetAmount; private BigDecimal itemNetAmount;
public LineCalc(IZUGFeRDExportableItem currentItem) { public LineCalc(IZUGFeRDExportableItem currentItem) {
BigDecimal totalAllowance = BigDecimal.ZERO; BigDecimal totalAllowance = BigDecimal.ZERO;
BigDecimal totalCharge = BigDecimal.ZERO; BigDecimal totalCharge = BigDecimal.ZERO;
@@ -974,14 +1040,17 @@ class ZUGFeRDTransactionModelConverter {
BigDecimal.ROUND_HALF_UP); BigDecimal.ROUND_HALF_UP);
} }
public BigDecimal getItemTotalNetAmount() { public BigDecimal getItemTotalNetAmount() {
return itemTotalNetAmount; return itemTotalNetAmount;
} }
public BigDecimal getItemTotalVATAmount() { public BigDecimal getItemTotalVATAmount() {
return itemTotalVATAmount; return itemTotalVATAmount;
} }
public BigDecimal getItemNetAmount() { public BigDecimal getItemNetAmount() {
return itemNetAmount; return itemNetAmount;
} }
@@ -994,6 +1063,7 @@ class ZUGFeRDTransactionModelConverter {
private BigDecimal lineTotalAmount; private BigDecimal lineTotalAmount;
private BigDecimal totalTaxAmount; private BigDecimal totalTaxAmount;
public Totals() { public Totals() {
BigDecimal res = BigDecimal.ZERO; BigDecimal res = BigDecimal.ZERO;
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
@@ -1001,7 +1071,7 @@ class ZUGFeRDTransactionModelConverter {
res = res.add(lc.getItemTotalNetAmount()); res = res.add(lc.getItemTotalNetAmount());
} }
// Set line total // Set line total
this.lineTotalAmount = res; lineTotalAmount = res;
if (trans.getZFAllowances() != null) { if (trans.getZFAllowances() != null) {
for (IZUGFeRDAllowanceCharge headerAllowance : trans for (IZUGFeRDAllowanceCharge headerAllowance : trans
@@ -1024,33 +1094,36 @@ class ZUGFeRDTransactionModelConverter {
} }
// Set total net amount // Set total net amount
this.totalNetAmount = res; totalNetAmount = res;
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = getVATPercentAmountMap(); HashMap<BigDecimal, VATAmount> vatAmountHashMap = getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { for (VATAmount amount : vatAmountHashMap.values()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
res = res.add(amount.getCalculated()); res = res.add(amount.getCalculated());
} }
// Set total gross amount // Set total gross amount
this.totalGrossAmount = res; totalGrossAmount = res;
this.totalTaxAmount = this.totalGrossAmount totalTaxAmount = totalGrossAmount
.subtract(this.totalNetAmount); .subtract(totalNetAmount);
} }
public BigDecimal getTotalNet() { public BigDecimal getTotalNet() {
return totalNetAmount; return totalNetAmount;
} }
public BigDecimal getTotalGross() { public BigDecimal getTotalGross() {
return totalGrossAmount; return totalGrossAmount;
} }
public BigDecimal getLineTotal() { public BigDecimal getLineTotal() {
return lineTotalAmount; return lineTotalAmount;
} }
public BigDecimal getTaxTotal() { public BigDecimal getTaxTotal() {
return totalTaxAmount; return totalTaxAmount;
} }

View File

@@ -49,9 +49,8 @@ public class FileChecker {
if ((!isPDF) && (!thisRun.shallIgnoreFileExt())) { if ((!isPDF) && (!thisRun.shallIgnoreFileExt())) {
return false; return false;
} }
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(filename);
try { try {
zi.extract(filename);
if (zi.canParse()) { if (zi.canParse()) {
thisRun.incZUGFeRDCount(); thisRun.incZUGFeRDCount();
return true; return true;

View File

@@ -406,8 +406,7 @@ public class Toecount {
ensureFileNotExists(xmlName); ensureFileNotExists(xmlName);
// All params are good! continue... // All params are good! continue...
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(pdfName);
zi.extract(pdfName);
byte[] XMLContent = zi.getRawXML(); byte[] XMLContent = zi.getRawXML();
if (XMLContent == null) { if (XMLContent == null) {
System.err.println("No ZUGFeRD XML found in PDF file"); System.err.println("No ZUGFeRD XML found in PDF file");

View File

@@ -55,14 +55,12 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
// the writing part // the writing part
try { try {
InputStream SOURCE_PDF = this.getClass() InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931) ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931)
.load(SOURCE_PDF); .load(SOURCE_PDF);
final byte[] UTF8ByteOrderMark = new byte[]{(byte) 0xef, (byte) 0xbb, final byte[] UTF8ByteOrderMark = new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf};
(byte) 0xbf};
/* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */ /* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */
String ownZUGFeRDXML = new String(UTF8ByteOrderMark) + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + String ownZUGFeRDXML = new String(UTF8ByteOrderMark) + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<rsm:CrossIndustryInvoice xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:rsm=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100\" xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100\" xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100\">\n" + "<rsm:CrossIndustryInvoice xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:rsm=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100\" xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100\" xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100\">\n" +
@@ -267,41 +265,20 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1); assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
// now check the contents (like MustangReaderTest) // now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
zi.extract(TARGET_PDF);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBLZ(), "41441604");
String bic = null; assertEquals(zi.getBIC(), "COBADEFFXXX");
String blz = null; assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00");
String iban = null; assertEquals(zi.getKTO(), "44421800");
String kto = null; assertEquals(zi.getHolder(), "Bei Spiel GmbH");
String holder = null; assertEquals(zi.getForeignReference(), "RE-20171118/506");
String ref = null;
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
blz = zi.getBLZ();
bic = zi.getBIC();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
ref = zi.getForeignReference();
}
assertEquals(amount, "571.04");
assertEquals(blz, "41441604");
assertEquals(bic, "COBADEFFXXX");
assertEquals(iban, "DE88 2008 0000 0970 3757 00");
assertEquals(kto, "44421800");
assertEquals(holder, "Bei Spiel GmbH");
assertEquals(ref, "RE-20171118/506");
} }
/** /**
@@ -318,8 +295,7 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
// the writing part // the writing part
try { try {
InputStream SOURCE_PDF = this.getClass() InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.BASIC) ZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1Factory().setProducer("My Application").setCreator("Test").setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.BASIC)
.load(SOURCE_PDF); .load(SOURCE_PDF);
@@ -469,41 +445,20 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>BASIC</zf:ConformanceLevel>") == -1); assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>BASIC</zf:ConformanceLevel>") == -1);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
// now check the contents (like MustangReaderTest) // now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
zi.extract(TARGET_PDF);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBIC(), "COBADEFFXXX");
String bic = null; assertEquals(zi.getBLZ(), "41441604");
String blz = null; assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00");
String iban = null; assertEquals(zi.getKTO(), "44421800");
String kto = null; assertEquals(zi.getHolder(), "Bei Spiel GmbH");
String holder = null; assertEquals(zi.getForeignReference(), "RE-20170509/505");
String ref = null;
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
bic = zi.getBIC();
blz = zi.getBLZ();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
ref = zi.getForeignReference();
}
assertEquals(amount, "571.04");
assertEquals(bic, "COBADEFFXXX");
assertEquals(blz, "41441604");
assertEquals(iban, "DE88 2008 0000 0970 3757 00");
assertEquals(kto, "44421800");
assertEquals(holder, "Bei Spiel GmbH");
assertEquals(ref, "RE-20170509/505");
} }
} }

View File

@@ -336,40 +336,19 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
*/ */
public void testAImport() throws IOException { public void testAImport() throws IOException {
ZUGFeRDImporter zi = new ZUGFeRDImporter(); InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf");
zi.extractLowLevel(this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf")); ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBIC(), getOwnBIC());
String bic = null; assertEquals(zi.getBLZ(), getOwnBLZ());
String blz = null; assertEquals(zi.getIBAN(), getOwnIBAN());
String iban = null; assertEquals(zi.getKTO(), getOwnKto());
String kto = null; assertEquals(zi.getHolder(), getOwnOrganisationName());
String holder = null; assertEquals(zi.getDueDate(), "20170530");
String ref = null; assertEquals(zi.getForeignReference(), getNumber());
String dueDate = null; assertEquals(zi.getDocumentCode(), "380");
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
bic = zi.getBIC();
blz = zi.getBLZ();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
dueDate = zi.getDueDate();
ref = zi.getForeignReference();
}
assertEquals(amount, "571.04");
assertEquals(bic, getOwnBIC());
assertEquals(blz, getOwnBLZ());
assertEquals(iban, getOwnIBAN());
assertEquals(kto, getOwnKto());
assertEquals(holder, getOwnOrganisationName());
assertEquals(dueDate, "20170530");
assertEquals(ref, getNumber());
} }
@@ -401,37 +380,16 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
} }
// now check the contents (like MustangReaderTest) // now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
zi.extract(TARGET_PDF);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBIC(), getOwnBIC());
String bic = null; assertEquals(zi.getBLZ(), getOwnBLZ());
String blz = null; assertEquals(zi.getIBAN(), getOwnIBAN());
String iban = null; assertEquals(zi.getKTO(), getOwnKto());
String kto = null; assertEquals(zi.getHolder(), getOwnOrganisationName());
String holder = null; assertEquals(zi.getForeignReference(), getNumber());
String ref = null;
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
bic = zi.getBIC();
blz = zi.getBLZ();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
ref = zi.getForeignReference();
}
assertEquals(amount, "571.04");
assertEquals(bic, getOwnBIC());
assertEquals(blz, getOwnBLZ());
assertEquals(iban, getOwnIBAN());
assertEquals(kto, getOwnKto());
assertEquals(holder, getOwnOrganisationName());
assertEquals(ref, getNumber());
} }
} }

View File

@@ -346,52 +346,24 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
*/ */
public void testAImport() throws IOException { public void testAImport() throws IOException {
ZUGFeRDImporter zi = new ZUGFeRDImporter(); InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf");
try (InputStream inputStream = this.getClass() ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf")) {
zi.extractLowLevel(inputStream);
}
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBLZ(), getOwnBLZ());
String blz = null; assertEquals(zi.getBIC(), getOwnBIC());
String bic = null; assertEquals(zi.getIBAN(), getOwnIBAN());
String iban = null; assertEquals(zi.getKTO(), getOwnKto());
String kto = null; assertEquals(zi.getHolder(), getOwnOrganisationName());
String holder = null; assertEquals(zi.getForeignReference(), "RE-20170509/505");
String ref = null;
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
blz = zi.getBLZ();
bic = zi.getBIC();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
ref = zi.getForeignReference();
}
// this resembles the data written in MustangReaderWriterCustomXMLTest
assertEquals(amount, "571.04");
assertEquals(blz, "41441604");
assertEquals(bic, "COBADEFFXXX");
assertEquals(iban, "DE88 2008 0000 0970 3757 00");
assertEquals(kto, "44421800");
assertEquals(holder, "Bei Spiel GmbH");
assertEquals(ref, "RE-20170509/505");
} }
public void testForeignImport() throws IOException { public void testForeignImport() throws IOException {
ZUGFeRDImporter zi = new ZUGFeRDImporter(); InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf");
ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
try (InputStream inputStream = this.getClass()
.getResourceAsStream("/zugferd_invoice.pdf")) {
zi.extractLowLevel(inputStream);
}
// Reading ZUGFeRD // Reading ZUGFeRD
String amount = zi.getAmount(); String amount = zi.getAmount();
assertEquals("<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n" + assertEquals("<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n" +
@@ -523,33 +495,15 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
} }
// now check the contents (like MustangReaderTest) // now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
zi.extract(TARGET_PDF);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBIC(), getOwnBIC());
String bic = null; assertEquals(zi.getIBAN(), getOwnIBAN());
String iban = null; assertEquals(zi.getKTO(), getOwnKto());
String kto = null; assertEquals(zi.getHolder(), getOwnOrganisationName());
String holder = null; assertEquals(zi.getForeignReference(), getNumber());
String ref = null;
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
bic = zi.getBIC();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
ref = zi.getForeignReference();
}
assertEquals(amount, "571.04");
assertEquals(bic, getOwnBIC());
assertEquals(iban, getOwnIBAN());
assertEquals(kto, getOwnKto());
assertEquals(holder, getOwnOrganisationName());
assertEquals(ref, getNumber());
} }
public void testFXExport() throws Exception { public void testFXExport() throws Exception {
@@ -578,33 +532,15 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
} }
// now check the contents (like MustangReaderTest) // now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(); ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF);
zi.extract(TARGET_PDF);
// Reading ZUGFeRD // Reading ZUGFeRD
assertEquals(zi.getAmount(), "571.04");
String amount = null; assertEquals(zi.getBIC(), getOwnBIC());
String bic = null; assertEquals(zi.getIBAN(), getOwnIBAN());
String iban = null; assertEquals(zi.getKTO(), getOwnKto());
String kto = null; assertEquals(zi.getHolder(), getOwnOrganisationName());
String holder = null; assertEquals(zi.getForeignReference(), getNumber());
String ref = null;
if (zi.canParse()) {
zi.parse();
amount = zi.getAmount();
bic = zi.getBIC();
iban = zi.getIBAN();
kto = zi.getKTO();
holder = zi.getHolder();
ref = zi.getForeignReference();
}
assertEquals(amount, "571.04");
assertEquals(bic, getOwnBIC());
assertEquals(iban, getOwnIBAN());
assertEquals(kto, getOwnKto());
assertEquals(holder, getOwnOrganisationName());
assertEquals(ref, getNumber());
} }
/** /**