Upgrade of PDFBox to 2.0.5, Version upgrade to 1.4.0.0, add reference document to exporter interface (e.g. used for invoice corrections)

This commit is contained in:
Alexander Schmidt
2017-04-21 15:53:38 +02:00
26 changed files with 1661 additions and 1192 deletions

Binary file not shown.

View File

@@ -167,7 +167,7 @@ public class MustangWriter implements IZUGFeRDExportableTransaction {
@Override
public String getOwnBIC() {
return "COBADEFXXX";
return "COBADEFFXXX";
}
@Override

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3,24 +3,66 @@
<parent>
<groupId>com.github.rayman2200</groupId>
<artifactId>mustang-sample-project</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.3.0.1-SNAPSHOT</version>
</parent>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>mustang</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.3.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Mustang</name>
<description>The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs</description>
<url>http://www.mustangproject.org/</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<!--exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude-->
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>1.8.8</version>
</dependency>
</dependencies>
<mailingLists>
@@ -56,5 +98,4 @@
</roles>
</developer>
</developers>
</project>

View File

@@ -4,7 +4,7 @@ package org.mustangproject.ZUGFeRD;
* Neccessary interface for ZUGFeRD exporter
* Licensed under the APLv2
* @date 2014-05-10
* @version 1.0
* @version 1.2.0
* @author jstaerk
* */

View File

@@ -4,7 +4,7 @@ package org.mustangproject.ZUGFeRD;
* Neccessary interface for ZUGFeRD exporter
* Licensed under the APLv2
* @date 2014-05-10
* @version 1.0
* @version 1.2.0
* @author jstaerk
* */

View File

@@ -5,7 +5,7 @@ import java.math.BigDecimal;
* Necessary interface for ZUGFeRD exporter
* Licensed under the APLv2
* @date 2014-05-10
* @version 1.0
* @version 1.2.0
* @author jstaerk
* */

View File

@@ -4,7 +4,7 @@ package org.mustangproject.ZUGFeRD;
* Neccessary interface for ZUGFeRD exporter
* Licensed under the APLv2
* @date 2014-05-10 to 2014-06-25
* @version 1.0.2
* @version 1.2.0
* @author jstaerk
* */
@@ -127,7 +127,7 @@ public interface IZUGFeRDExportableTransaction {
* get main invoice currency used on the invoice
* @return
*/
String getInvoiceCurrency();
String getCurrency();
/**
* get payment information text. e.g. Bank transfer

View File

@@ -1,7 +1,14 @@
package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
/**
* Mustangproject's ZUGFeRD implementation
* ZUGFeRD exporter helper class
* Licensed under the APLv2
* @date 2015-10-29
* @version 1.2.0
* @author jstaerk
* */
public class VATAmount {
public VATAmount(BigDecimal basis, BigDecimal calculated) {

View File

@@ -4,7 +4,7 @@ package org.mustangproject.ZUGFeRD;
* ZUGFeRD exporter helper class
* Licensed under the APLv2
* @date 2014-05-10
* @version 1.0
* @version 1.2.0
* @author jstaerk
* */
import org.apache.jempbox.impl.XMLUtil;
@@ -112,6 +112,12 @@ import org.w3c.dom.Element;
Element propertyNode = schema.getOwnerDocument().createElement(
"pdfaSchema:property"); //$NON-NLS-1$
Element valueTypeNode = schema.getOwnerDocument().createElement(
"pdfaSchema:valueType"); //$NON-NLS-1$
Element seqListValueType = schema.getOwnerDocument().createElement(
"rdf:Seq"); //$NON-NLS-1$
Element sequenceNode = schema.getOwnerDocument().createElement(
"rdf:Seq"); //$NON-NLS-1$
@@ -150,6 +156,9 @@ import org.w3c.dom.Element;
bagListNode.appendChild(propertyNode);
valueTypeNode.appendChild(seqListValueType);
bagListNode.appendChild(valueTypeNode);
bagNode.appendChild(bagListNode);
schemasNode.appendChild(bagNode);

View File

@@ -4,7 +4,7 @@ package org.mustangproject.ZUGFeRD;
* ZUGFeRD exporter helper class
* Licensed under the APLv2
* @date 2014-05-10
* @version 1.0
* @version 1.2.0s
* @author jstaerk
* */
import org.apache.jempbox.impl.XMLUtil;
@@ -15,7 +15,7 @@ import org.w3c.dom.Element;
public class XMPSchemaZugferd extends XMPSchemaBasic
{
private String conformanceLevel = "COMFORT";
private String conformanceLevel = "EXTENDED";
/**
* This is what needs to be added to the RDF metadata - basically the name of the embedded

View File

@@ -15,6 +15,7 @@ import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.Map;
import javax.management.RuntimeErrorException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -34,12 +35,12 @@ import org.xml.sax.SAXException;
public class ZUGFeRDImporter {
/*
call extract(importFilename).
containsMeta() will return if ZUGFeRD data has been found,
call extract(importFilename).
containsMeta() will return if ZUGFeRD data has been found,
afterwards you can call getBIC(), getIBAN() etc.
*/
/**@var if metadata has been found */
private boolean containsMeta=false;
/**@var the reference (i.e. invoice number) of the sender */
@@ -48,16 +49,20 @@ public class ZUGFeRDImporter {
private String IBAN;
private String holder;
private String amount;
private String dueDate;
/** Raw XML form of the extracted data - may be directly obtained. */
private byte[] rawXML=null;
private String bankName;
private boolean amountFound;
private boolean extracted=false;
private boolean parsed=false;
/**
* Extracts a ZUGFeRD invoice from a PDF document represented by a file name.
* Errors are just logged to STDOUT.
*/
public void extract(String pdfFilename)
public void extract(String pdfFilename)
{
try
{
@@ -66,7 +71,7 @@ public class ZUGFeRDImporter {
{
ioe.printStackTrace();
}
}
}
/**
* Extracts a ZUGFeRD invoice from a PDF document represented by an input stream.
@@ -106,6 +111,7 @@ public class ZUGFeRDImporter {
// FileOutputStream fos = new FileOutputStream(file);
rawXML = embeddedFile.getByteArray();
setMeta(new String(rawXML));
extracted=true;
// fos.write(embeddedFile.getByteArray());
// fos.close();
}
@@ -123,12 +129,16 @@ public class ZUGFeRDImporter {
}
}
public void parse() {
DocumentBuilderFactory factory = null;
DocumentBuilder builder = null;
Document document = null;
if (!extracted) {
throw new RuntimeException("extract() or extractLowLevel() must be used before parsing.");
}
factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); //otherwise we can not act namespace independend, i.e. use document.getElementsByTagNameNS("*",...
try {
@@ -147,17 +157,17 @@ public class ZUGFeRDImporter {
ex2.printStackTrace();
}
NodeList ndList ;
// rootNode = document.getDocumentElement();
// ApplicableSupplyChainTradeSettlement
ndList = document.getDocumentElement()
.getElementsByTagNameNS("*","PaymentReference"); //$NON-NLS-1$
for (int bookingIndex = 0; bookingIndex < ndList
.getLength(); bookingIndex++) {
Node booking = ndList.item(bookingIndex);
// if there is a attribute in the tag number:value
setForeignReference(booking.getTextContent());
}
@@ -189,7 +199,7 @@ public class ZUGFeRDImporter {
<ram:BICID>DE5656565</ram:BICID>
<ram:Name>Commerzbank</ram:Name>
</ram:PayeeSpecifiedCreditorFinancialInstitution>
*/
ndList = document.getElementsByTagNameNS("*","PayeePartyCreditorFinancialAccount"); //$NON-NLS-1$
@@ -200,7 +210,7 @@ public class ZUGFeRDImporter {
// there are many "name" elements, so get the one below
// SellerTradeParty
NodeList bookingDetails = booking.getChildNodes();
for (int detailIndex = 0; detailIndex < bookingDetails
.getLength(); detailIndex++) {
@@ -208,7 +218,7 @@ public class ZUGFeRDImporter {
if ((detail.getLocalName()!=null)&&(detail.getLocalName().equals("IBANID"))) { //$NON-NLS-1$
setIBAN(detail.getTextContent());
}
}
}
}
@@ -266,7 +276,7 @@ public class ZUGFeRDImporter {
if (!amountFound) {
/* there is apparently no requirement to mention DuePayableAmount,,
/* there is apparently no requirement to mention DuePayableAmount,,
* if it's not there, check for GrandTotalAmount
*/
ndList = document.getElementsByTagNameNS("*","GrandTotalAmount"); //$NON-NLS-1$
@@ -278,10 +288,28 @@ public class ZUGFeRDImporter {
setAmount(booking.getTextContent());
}
}
}
ndList = document.getElementsByTagNameNS("*","SpecifiedTradePaymentTerms"); //$NON-NLS-1$
for (int bookingIndex = 0; bookingIndex < ndList
.getLength(); bookingIndex++) {
Node booking = ndList.item(bookingIndex);
// there are many "name" elements, so get the one below
// SellerTradeParty
NodeList bookingDetails = booking.getChildNodes();
for (int detailIndex = 0; detailIndex < bookingDetails
.getLength(); detailIndex++) {
Node detail = bookingDetails.item(detailIndex);
if ((detail.getLocalName()!=null)&&(detail.getLocalName().equals("DueDateDateTime"))) { //$NON-NLS-1$
setDueDate(detail.getTextContent().trim());
}
}
}
parsed=true;
}
@@ -290,18 +318,24 @@ public class ZUGFeRDImporter {
}
public String getForeignReference() {
if (!parsed) {
throw new RuntimeException("use parse() before requesting a value");
}
return foreignReference;
}
public void setForeignReference(String foreignReference) {
private void setForeignReference(String foreignReference) {
this.foreignReference = foreignReference;
}
public String getBIC() {
if (!parsed) {
throw new RuntimeException("use parse() before requesting a value");
}
return BIC;
}
@@ -312,6 +346,11 @@ public class ZUGFeRDImporter {
}
private void setDueDate(String dueDate) {
this.dueDate = dueDate;
}
private void setBankName(String bankname) {
this.bankName = bankname;
}
@@ -319,23 +358,32 @@ public class ZUGFeRDImporter {
public String getIBAN() {
if (!parsed) {
throw new RuntimeException("use parse() before requesting a value");
}
return IBAN;
}
public String getBankName() {
if (!parsed) {
throw new RuntimeException("use parse() before requesting a value");
}
return bankName;
}
public void setIBAN(String IBAN) {
private void setIBAN(String IBAN) {
this.IBAN = IBAN;
}
public String getHolder() {
if (rawXML==null) {
throw new RuntimeException("use parse() before requesting a value");
}
return holder;
}
@@ -348,9 +396,18 @@ public class ZUGFeRDImporter {
public String getAmount() {
if (rawXML==null) {
throw new RuntimeException("use parse() before requesting a value");
}
return amount;
}
public String getDueDate() {
if (rawXML==null) {
throw new RuntimeException("use parse() before requesting a value");
}
return dueDate;
}
private void setAmount(String amount) {
this.amount = amount;
@@ -362,7 +419,7 @@ public class ZUGFeRDImporter {
public String getMeta() {
if (rawXML==null){
return null;
return null;
} else {
return new String(rawXML);
}
@@ -372,7 +429,7 @@ public class ZUGFeRDImporter {
/**
* Returns the raw XML data as extracted from the ZUGFeRD PDF file.
*/
public byte[] getRawXML()
public byte[] getRawXML()
{
return rawXML;
}
@@ -381,8 +438,8 @@ public class ZUGFeRDImporter {
* will return true if the metadata (just extract-ed or set with setMeta) contains ZUGFeRD XML
* */
public boolean canParse() {
//SpecifiedExchangedDocumentContext is in the schema, so a relatively good indication if zugferd is present - better than just invoice
String meta=getMeta();
return (meta!=null)&&( meta.length()>0)&&( meta.contains("SpecifiedExchangedDocumentContext")); //$NON-NLS-1$

View File

@@ -49,7 +49,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
@Override
public String getOwnBIC()
{
return "COBADEFXXX";
return "COBADEFFXXX";
}
@Override
@@ -118,7 +118,13 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
{
return null;
}
@Override
public String getCurrency()
{
return "EUR";
}
@Override
public IZUGFeRDExportableItem[] getZFItems()
{
@@ -133,11 +139,6 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
return allItems;
}
@Override
public String getInvoiceCurrency() {
return "EUR";
}
@Override
public String getOwnPaymentInfoText() {
return "Überweisung";
@@ -258,7 +259,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
@Override
public IZUGFeRDAllowanceCharge[] getItemAllowances() {
return null;
return null;
}
@Override
@@ -330,7 +331,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
/**
* Create the test case
*
*
* @param testName
* name of the test case
*/
@@ -353,7 +354,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
* The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20151008_504.pdf to check the values.
* --> as only Name Ascending is supported for Test Unit sequence, I renamed the this test-A-Export to run before
* testZExport
*
*
* @throws IOException
*/
@@ -368,6 +369,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
String iban = null;
String holder = null;
String ref = null;
String dueDate = null;
if (zi.canParse())
{
@@ -376,6 +378,7 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
bic = zi.getBIC();
iban = zi.getIBAN();
holder = zi.getHolder();
dueDate = zi.getDueDate();
ref = zi.getForeignReference();
}
@@ -383,6 +386,8 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
assertEquals(bic, getOwnBIC());
assertEquals(iban, getOwnIBAN());
assertEquals(holder, getOwnOrganisationName());
assertEquals(dueDate, "20141029");
assertEquals(ref, getNumber());
}
@@ -401,16 +406,13 @@ public class MustangReaderWriterEdgeTest extends TestCase implements IZUGFeRDExp
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20151008_504newEdge.pdf";
// the writing part
PDDocument doc;
try
{
doc = PDDocument.load(SOURCE_PDF);
// automatically add Zugferd to all outgoing invoices
ZUGFeRDExporter ze = new ZUGFeRDExporter();
ze.PDFmakeA3compliant(doc, "My Application", System.getProperty("user.name"), true);
ze.PDFattachZugferdFile(doc, this);
doc.save(TARGET_PDF);
doc.close();
ze.PDFmakeA3compliant(SOURCE_PDF, "My Application", System.getProperty("user.name"), true);
ze.PDFattachZugferdFile(this);
ze.export(TARGET_PDF);
}
catch (IOException e)
{

View File

@@ -49,7 +49,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
@Override
public String getOwnBIC()
{
return "COBADEFXXX";
return "COBADEFFXXX";
}
@Override
@@ -118,6 +118,12 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
return null;
}
@Override
public String getCurrency()
{
return "EUR";
}
@Override
public IZUGFeRDExportableItem[] getZFItems()
{
@@ -132,11 +138,6 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
return allItems;
}
@Override
public String getInvoiceCurrency() {
return "EUR";
}
@Override
public String getOwnPaymentInfoText() {
return "Überweisung";
@@ -257,16 +258,16 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
{
this.product = product;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemAllowances() {
return null;
return null;
}
@Override
public IZUGFeRDAllowanceCharge[] getItemCharges() {
return null;
}
}
}
@@ -332,7 +333,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
/**
* Create the test case
*
*
* @param testName
* name of the test case
*/
@@ -355,7 +356,7 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
* The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20151008_504.pdf to check the values.
* --> as only Name Ascending is supported for Test Unit sequence, I renamed the this test-A-Export to run before
* testZExport
*
*
* @throws IOException
*/
@@ -403,16 +404,13 @@ public class MustangReaderWriterTest extends TestCase implements IZUGFeRDExporta
final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20151008_504new.pdf";
// the writing part
PDDocument doc;
try
{
doc = PDDocument.load(SOURCE_PDF);
// automatically add Zugferd to all outgoing invoices
ZUGFeRDExporter ze = new ZUGFeRDExporter();
ze.PDFmakeA3compliant(doc, "My Application", System.getProperty("user.name"), true);
ze.PDFattachZugferdFile(doc, this);
doc.save(TARGET_PDF);
doc.close();
ze.PDFmakeA3compliant(SOURCE_PDF, "My Application", System.getProperty("user.name"), true);
ze.PDFattachZugferdFile(this);
ze.export(TARGET_PDF);
}
catch (IOException e)
{

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>toecount</artifactId>
<version>0.0.6-SNAPSHOT</version>
<version>0.0.8-SNAPSHOT</version>
<name>ZUGFeRD PDF checker</name>
<description>Shows statistics on how many PDFs in a directory are ZUGFeRD-Compliant</description>
<repositories>
@@ -27,7 +27,7 @@
<dependency>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>mustang</artifactId>
<version>1.2.1-SNAPSHOT</version>
<version>1.3.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>

View File

@@ -30,11 +30,34 @@ public class FileChecker {
return false;
}
ZUGFeRDImporter zi=new ZUGFeRDImporter();
zi.extract(filename);
if (zi.canParse()) {
thisRun.incZUGFeRDCount();
return true;
} else {
try {
zi.extract(filename);
if (zi.canParse()) {
thisRun.incZUGFeRDCount();
return true;
} else {
return false;
}
} catch (NullPointerException e) {
// something really rare happened -- corrupted ZF?
/***
* e.g. Exception in thread "main" java.lang.NullPointerException
at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extractLowLevel(ZUGFeRDImporter.java:90)
at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extract(ZUGFeRDImporter.java:64)
at toecount.FileChecker.checkForZUGFeRD(FileChecker.java:33)
at toecount.Toecount.main(Toecount.java:111)
*
*/
// Ignore nevertheless, most likely we're batch processing
return false;
} catch (Exception e2) {
/**
* probably thrown up from
AM org.apache.pdfbox.pdfparser.PDFParser parse, most likely
INFORMATION: Document is encrypted
but also other internal PDF errors possible like
..Okt 23, 2015 11:17:53 AM org.apache.pdfbox.pdfparser.XrefTrailerResolver setStartxref
*/
return false;
}
}

View File

@@ -22,7 +22,7 @@ public class Toecount {
}
private static void printHelp() {
System.out
.println("Mustangproject.org's Toecount 0.0.6 \r\n"
.println("Mustangproject.org's Toecount 0.0.7 \r\n"
+ "A Apache Public License command line tool for statistics on PDF invoices with\r\n"
+ "ZUGFeRD Metadata (http://www.zugferd.de)\r\n"
+ "\r\n"