From 2a1dfc54ef29ee2fc83cd3b1e63a20bf4a341364 Mon Sep 17 00:00:00 2001 From: jstaerk Date: Fri, 8 Aug 2014 19:34:20 +0200 Subject: [PATCH] Patches courtesy by Ivan Vaklinov (with one little modification), direct XML access --- mustang/pom.xml | 2 +- .../ZUGFeRD/ZUGFeRDExporter.java | 1023 +++++++++-------- .../ZUGFeRD/ZUGFeRDImporter.java | 748 ++++++------ .../ZUGFeRD/ZUGFeRDExporter.class | Bin 15979 -> 16104 bytes .../ZUGFeRD/ZUGFeRDImporter.class | Bin 7426 -> 7828 bytes mustang/target/maven-archiver/pom.properties | 4 +- mustang/target/mustang-1.0.1.jar | Bin 17296 -> 0 bytes mustang/target/mustang-1.0.2.jar | Bin 16971 -> 0 bytes mustang/target/mustang-1.0.jar | Bin 17026 -> 0 bytes mustang/target/mustang-1.1.0.alpha.jar | Bin 17231 -> 0 bytes mustang/target/mustang-1.1.0.jar | Bin 17276 -> 0 bytes ...EST-org.mustangproject.ZUGFeRD.AppTest.xml | 60 - .../org.mustangproject.ZUGFeRD.AppTest.txt | 4 - 13 files changed, 915 insertions(+), 926 deletions(-) delete mode 100644 mustang/target/mustang-1.0.1.jar delete mode 100644 mustang/target/mustang-1.0.2.jar delete mode 100644 mustang/target/mustang-1.0.jar delete mode 100644 mustang/target/mustang-1.1.0.alpha.jar delete mode 100644 mustang/target/mustang-1.1.0.jar delete mode 100644 mustang/target/surefire-reports/TEST-org.mustangproject.ZUGFeRD.AppTest.xml delete mode 100644 mustang/target/surefire-reports/org.mustangproject.ZUGFeRD.AppTest.txt diff --git a/mustang/pom.xml b/mustang/pom.xml index f88270c9..c44e810c 100644 --- a/mustang/pom.xml +++ b/mustang/pom.xml @@ -4,7 +4,7 @@ org.mustangproject.ZUGFeRD mustang - 1.1.0 + 1.1.1alpha diff --git a/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java b/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java index 588797d6..c8fa3d20 100644 --- a/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java +++ b/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java @@ -1,501 +1,522 @@ -package org.mustangproject.ZUGFeRD; -/** - * Mustangproject's ZUGFeRD implementation - * ZUGFeRD exporter - * Licensed under the APLv2 - * @date 2014-07-12 - * @version 1.1 - * @author jstaerk - * */ - - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.GregorianCalendar; -import java.util.HashMap; - -import javax.xml.transform.TransformerException; - -import org.apache.jempbox.xmp.XMPMetadata; -import org.apache.jempbox.xmp.XMPSchemaBasic; -import org.apache.jempbox.xmp.XMPSchemaDublinCore; -import org.apache.jempbox.xmp.XMPSchemaPDF; -import org.apache.jempbox.xmp.pdfa.XMPSchemaPDFAId; -import org.apache.pdfbox.cos.COSArray; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentCatalog; -import org.apache.pdfbox.pdmodel.PDDocumentInformation; -import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.apache.pdfbox.pdmodel.common.PDMetadata; -import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; -import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; - - -public class ZUGFeRDExporter { - /*** - * You will need Apache PDFBox. To use the ZUGFeRD exporter, - implement IZUGFeRDExportableTransaction in yourTransaction - (which will require you to implement Product, Item and Contact) - then call - doc = PDDocument.load(PDFfilename); - // automatically add Zugferd to all outgoing invoices - ZUGFeRDExporter ze = new ZUGFeRDExporter(); - ze.PDFmakeA3compliant(doc, "Your application name", - System.getProperty("user.name"), true); - ze.PDFattachZugferdFile(doc, yourTransaction); - - doc.save(PDFfilename); - - * @author jstaerk - * - */ - - - - - - //// MAIN CLASS - - private String conformanceLevel="U"; - private String versionStr="1.0"; - - private String currencyFormat(BigDecimal value, char decimalDelimiter) { - /* - * I needed 123,45, locale independent.I tried - * NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is - * locale specific.I also tried DecimalFormat df = new DecimalFormat( - * "0,00" ); df.setDecimalSeparatorAlwaysShown(true); - * df.setGroupingUsed(false); DecimalFormatSymbols symbols = new - * DecimalFormatSymbols(); symbols.setDecimalSeparator(','); - * symbols.setGroupingSeparator(' '); - * df.setDecimalFormatSymbols(symbols); - * - * but that would not switch off grouping. Although I liked very much - * the (incomplete) "BNF diagram" in - * http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html - * in the end I decided to calculate myself and take eur+sparator+cents - * - * This function will cut off, i.e. floor() subcent values Tests: - * System.err.println(utils.currencyFormat(new BigDecimal(0), - * ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"), - * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.1"), - * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.01"), - * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"), - * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"), - * ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ",")); - * - * results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00 - */ - value=value.setScale( 2, BigDecimal.ROUND_HALF_UP ); // first, round so that e.g. 1.189999999999999946709294817992486059665679931640625 becomes 1.19 - long totalCent = value.multiply(new BigDecimal(100)).intValue(); //now get the cents - long eurOnly = value.longValue(); - long centOnly = Math.abs(totalCent % 100); - StringBuffer res = new StringBuffer(); - res.append(eurOnly); - res.append(decimalDelimiter); - if (centOnly < 10) { - res.append('0'); - } - res.append(centOnly); - return res.toString(); - } - - /** - All files are PDF/A-3, setConformance refers to the level conformance. - - PDF/A-3 has three coformance levels, called "A", "U" and "B". - - PDF/A-3-B where B means only visually - preservable, U -standard for Mustang- means visually and unicode - preservable and A means full compliance, i.e. visually, - unicode and structurally preservable and tagged PDF, i.e. useful metainformation for blind people. - - Feel free to pass "A" as new level if you know what you are doing :-) - - - */ - public void setConformanceLevel(String newLevel) { - conformanceLevel=newLevel; - } - - - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on - * the metadata level, this will not e.g. convert graphics to JPG-2000) - * */ - public PDDocumentCatalog PDFmakeA3compliant(PDDocument doc, String producer, String creator, - boolean attachZugferdHeaders) throws IOException, - TransformerException { - String fullProducer=producer+"(via mustangproject.org "+versionStr+")"; - PDDocumentCatalog cat = doc.getDocumentCatalog(); - PDMetadata metadata = new PDMetadata(doc); - cat.setMetadata(metadata); - // we're using the jempbox org.apache.jempbox.xmp.XMPMetadata version, - // not the xmpbox one - XMPMetadata xmp = new XMPMetadata(); - - XMPSchemaPDFAId pdfaid = new XMPSchemaPDFAId(xmp); - pdfaid.setAbout(""); //$NON-NLS-1$ - xmp.addSchema(pdfaid); - - XMPSchemaDublinCore dc = xmp.addDublinCoreSchema(); - dc.addCreator(creator); - dc.setAbout(""); //$NON-NLS-1$ - - XMPSchemaBasic xsb = xmp.addBasicSchema(); - xsb.setAbout(""); //$NON-NLS-1$ - - xsb.setCreatorTool(creator); - xsb.setCreateDate(GregorianCalendar.getInstance()); - // PDDocumentInformation pdi=doc.getDocumentInformation(); - PDDocumentInformation pdi = new PDDocumentInformation(); - pdi.setProducer(fullProducer); - pdi.setAuthor(creator); - doc.setDocumentInformation(pdi); - - XMPSchemaPDF pdf = xmp.addPDFSchema(); - pdf.setProducer(fullProducer); - pdf.setAbout(""); //$NON-NLS-1$ - - /* - // Mandatory: PDF/A3-a is tagged PDF which has to be expressed using a - // MarkInfo dictionary (PDF A/3 Standard sec. 6.7.2.2) - PDMarkInfo markinfo = new PDMarkInfo(); - markinfo.setMarked(true); - doc.getDocumentCatalog().setMarkInfo(markinfo); -*/ -/* - * - To be on the safe side, we use level B without Markinfo because we can not - guarantee that the user correctly tagged the templates for the PDF. - - * */ - pdfaid.setConformance(conformanceLevel);//$NON-NLS-1$ //$NON-NLS-1$ - - pdfaid.setPart(3); - - if (attachZugferdHeaders) { - addZugferdXMP(xmp); /* - * this is the only line where we do something - * Zugferd-specific, i.e. add PDF metadata - * specifically for Zugferd, not generically for - * a embedded file - */ - } - - metadata.importXMPMetadata(xmp); - return cat; - } - - private String getZugferdXMLForTransaction(IZUGFeRDExportableTransaction trans) { - SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); //$NON-NLS-1$ - String xml= "\n" //$NON-NLS-1$ - - + "\n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " false\n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " urn:ferd:invoice:rc:comfort\n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " RECHNUNG\n" //$NON-NLS-1$ - + " 380\n" //$NON-NLS-1$ - + " "+zugferdDateFormat.format(trans.getIssueDate())+"\n" //date format was 20130605 //$NON-NLS-1$ //$NON-NLS-2$ -// + " \n" -// + " \n" -// + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n" -// + "\n" -// + " \n" -// + " \n" -// + " \n" -// + " \n" -// + "Es bestehen Rabatt- und Bonusvereinbarungen.\n" -// + " \n" -// + " AAK\n" -// + " \n" - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ -// + " AB-312\n" - + " \n" //$NON-NLS-1$ -// + " 4000001123452\n" - + " "+trans.getOwnOrganisationName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" - + " "+trans.getOwnZIP()+"\n" - + " "+trans.getOwnStreet()+"\n" - + " "+trans.getOwnLocation()+"\n" - + " "+trans.getOwnCountry()+"\n" - + " \n" - + " \n" //$NON-NLS-1$ - + " "+trans.getOwnTaxID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+trans.getOwnVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ -// + " GE2020211\n" -// + " 4000001987658\n" - + " "+trans.getRecipient().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ -// + " \n" -// + " xxx\n" -// + " \n" - + " \n" //$NON-NLS-1$ - + " "+trans.getRecipient().getZIP()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+trans.getRecipient().getStreet()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+trans.getRecipient().getLocation()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+trans.getRecipient().getCountry()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+trans.getRecipient().getVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ -// + " \n" -// + " 20130301\n" -// + " 2013-471331\n" -// + " \n" - + " \n" //$NON-NLS-1$ - + " \n" - + " \n" - + " "+zugferdDateFormat.format(trans.getDeliveryDate())+"\n" - + " \n" - /* - + " \n" - + " 20130603\n" - + " 2013-51112\n" - + " \n" */ - + " \n" - + " \n" //$NON-NLS-1$ - + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " EUR\n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " 42\n" //$NON-NLS-1$ - + " Überweisung\n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+trans.getOwnIBAN()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+trans.getOwnBIC()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+trans.getOwnBankName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n"; //$NON-NLS-1$ - - - /* - HashMap VATPercentAmountMap=trans.getVATPercentAmountMap(); - for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - BigDecimal amount = VATPercentAmountMap.get(currentTaxPercent); - if (amount != null) { - xml += " \n" //$NON-NLS-1$ - + " "+currencyFormat(amount, '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " VAT\n" //$NON-NLS-1$ -// + " 129.37\n" - + " S\n" //$NON-NLS-1$ - + " "+currentTaxPercent+"\n" //$NON-NLS-1$ - + " \n"; //$NON-NLS-1$ - - - - } - }*/ -/* xml+= " - + " \n" - + " false\n" - + " 10\n" - + " 1.00\n" - + " Sondernachlass\n" - + " \n" - + " VAT\n" - + " S\n" - + " 19\n" - + " \n" - + " \n" - + " \n" - + " false\n" - + " 137.30\n" - + " 13.73\n" - + " Sondernachlass\n" - + " \n" - + " VAT\n" - + " S\n" - + " 7\n" - + " \n" - + " \n" - + " \n" - + " Versandkosten\n" - + " 5.80\n" - + " \n" - + " VAT\n" - + " S\n" - + " 7\n" - + " \n" - + " \n"*/ - - xml=xml+ " \n" //$NON-NLS-1$ -// + " Zahlbar innerhalb 30 Tagen netto bis 04.07.2013, 3% Skonto innerhalb 10 Tagen bis 15.06.2013\n" - + " "+zugferdDateFormat.format(trans.getDueDate())+"\n"//20130704 //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+currencyFormat(trans.getTotal(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ -// + " 5.80\n" -// + " 14.73\n" - + " "+currencyFormat(trans.getTotal(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+currencyFormat(trans.getTotalGross().subtract(trans.getTotal()), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+currencyFormat(trans.getTotalGross(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ -// + " 0.00\n" - + " "+currencyFormat(trans.getTotalGross(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n"; //$NON-NLS-1$ -// + " \n" -// + " \n" -// + " \n" -// + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. 2013-51112 in Rechnung zu stellen:\n" -// + " \n" -// + " \n" -// + " \n"; - - - int lineID=0; - for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - lineID++; - xml=xml+ " \n"+ //$NON-NLS-1$ - " \n" //$NON-NLS-1$ - + " "+lineID+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+currencyFormat(currentItem.getPriceGross(),'.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " 1\n" //$NON-NLS-1$ //$NON-NLS-2$ -// + " \n" -// + " false\n" -// + " 0.6667\n" -// + " Rabatt\n" -// + " \n" - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+currencyFormat(currentItem.getPrice(),'.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " 1\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - - + " \n" //$NON-NLS-1$ - + " "+currentItem.getQuantity()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " VAT\n" //$NON-NLS-1$ - + " S\n" //$NON-NLS-1$ - + " "+currentItem.getProduct().getVATPercent()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " "+currencyFormat(currentItem.getTotalGross(),'.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ - + " \n" //$NON-NLS-1$ -// + " 4012345001235\n" -// + " KR3M\n" -// + " 55T01\n" - + " "+currentItem.getProduct().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " "+currentItem.getProduct().getDescription()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ - + " \n" //$NON-NLS-1$ - + " \n"; //$NON-NLS-1$ - - - - } - - - xml=xml + " \n" //$NON-NLS-1$ - + ""; //$NON-NLS-1$ - return xml; - } - - /** - * embed the Zugferd XML structure in a file named ZUGFeRD-invoice.xml - * */ - public void PDFattachZugferdFile(PDDocument doc, IZUGFeRDExportableTransaction trans) throws IOException { - - // embedded files are stored in a named tree - PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode(); - - String filename="ZUGFeRD-invoice.xml"; //$NON-NLS-1$ - // first create the file specification, which holds the embedded file - PDComplexFileSpecification fs = new PDComplexFileSpecification(); - fs.setFile(filename); - - COSDictionary dict = fs.getCOSDictionary(); - // Relation "Source" for linking with eg. catalog - dict.setName("AFRelationship", "Alternative"); // as defined in Zugferd standard //$NON-NLS-1$ //$NON-NLS-2$ - - dict.setString("UF", filename); //$NON-NLS-1$ - - // create a dummy file stream, this would probably normally be a - // FileInputStream - - byte[] zugferdRaw = getZugferdXMLForTransaction(trans).getBytes("UTF-8"); //$NON-NLS-1$ - - byte[] zugferdData; - - - - if ((zugferdRaw[0]==(byte)0xEF)&&(zugferdRaw[1]==(byte)0xBB)&&(zugferdRaw[2]==(byte)0xBF)) { - // I don't like BOMs, lets remove it - zugferdData=new byte[zugferdRaw.length-3]; - System.arraycopy(zugferdRaw,3,zugferdData,0,zugferdRaw.length-3); - } else { - zugferdData=zugferdRaw; - } - - ByteArrayInputStream fakeFile = new ByteArrayInputStream(zugferdData); - PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); - // now lets some of the optional parameters - ef.setSubtype("text/xml");// as defined in Zugferd standard //$NON-NLS-1$ - ef.setSize(zugferdData.length); - ef.setCreationDate(new GregorianCalendar()); - - ef.setModDate(GregorianCalendar.getInstance()); - - fs.setEmbeddedFile(ef); - - // now add the entry to the embedded file tree and set in the document. - efTree.setNames(Collections.singletonMap(filename, fs)); - PDDocumentNameDictionary names = new PDDocumentNameDictionary( - doc.getDocumentCatalog()); - names.setEmbeddedFiles(efTree); - doc.getDocumentCatalog().setNames(names); - // AF entry (Array) in catalog with the FileSpec - COSArray cosArray = new COSArray(); - cosArray.add(fs); - doc.getDocumentCatalog().getCOSDictionary().setItem("AF", cosArray); //$NON-NLS-1$ - - } - -/*** - * This will add both the RDF-indication which embedded file is Zugferd and the - * neccessary PDF/A schema extension description to be able to add this information to RDF - * @param metadata - */ - private void addZugferdXMP(XMPMetadata metadata) { - - XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata); - zf.setAbout(""); //$NON-NLS-1$ - metadata.addSchema(zf); - - XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(metadata); - pdfaex.setAbout(""); //$NON-NLS-1$ - metadata.addSchema(pdfaex); - - } - -} +package org.mustangproject.ZUGFeRD; +/** + * Mustangproject's ZUGFeRD implementation + * ZUGFeRD exporter + * Licensed under the APLv2 + * @date 2014-07-12 + * @version 1.1 + * @author jstaerk + * */ + + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.HashMap; + +import javax.xml.transform.TransformerException; + +import org.apache.jempbox.xmp.XMPMetadata; +import org.apache.jempbox.xmp.XMPSchemaBasic; +import org.apache.jempbox.xmp.XMPSchemaDublinCore; +import org.apache.jempbox.xmp.XMPSchemaPDF; +import org.apache.jempbox.xmp.pdfa.XMPSchemaPDFAId; +import org.apache.pdfbox.cos.COSArray; +import org.apache.pdfbox.cos.COSDictionary; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentCatalog; +import org.apache.pdfbox.pdmodel.PDDocumentInformation; +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; +import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; +import org.apache.pdfbox.pdmodel.common.PDMetadata; +import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; +import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; + + +public class ZUGFeRDExporter { + /*** + * You will need Apache PDFBox. To use the ZUGFeRD exporter, + implement IZUGFeRDExportableTransaction in yourTransaction + (which will require you to implement Product, Item and Contact) + then call + doc = PDDocument.load(PDFfilename); + // automatically add Zugferd to all outgoing invoices + ZUGFeRDExporter ze = new ZUGFeRDExporter(); + ze.PDFmakeA3compliant(doc, "Your application name", + System.getProperty("user.name"), true); + ze.PDFattachZugferdFile(doc, yourTransaction); + + doc.save(PDFfilename); + + * @author jstaerk + * + */ + + + + + + //// MAIN CLASS + + private String conformanceLevel="U"; + private String versionStr="1.0"; + + /** + * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, in which case passing a + * IZUGFeRDExportableTransaction is not necessary. By default it is null meaning the caller needs to + * pass a IZUGFeRDExportableTransaction for the XML to be populated. + */ + byte[] zugferdData = null; + + private String currencyFormat(BigDecimal value, char decimalDelimiter) { + /* + * I needed 123,45, locale independent.I tried + * NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is + * locale specific.I also tried DecimalFormat df = new DecimalFormat( + * "0,00" ); df.setDecimalSeparatorAlwaysShown(true); + * df.setGroupingUsed(false); DecimalFormatSymbols symbols = new + * DecimalFormatSymbols(); symbols.setDecimalSeparator(','); + * symbols.setGroupingSeparator(' '); + * df.setDecimalFormatSymbols(symbols); + * + * but that would not switch off grouping. Although I liked very much + * the (incomplete) "BNF diagram" in + * http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html + * in the end I decided to calculate myself and take eur+sparator+cents + * + * This function will cut off, i.e. floor() subcent values Tests: + * System.err.println(utils.currencyFormat(new BigDecimal(0), + * ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.1"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.01"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ",")); + * + * results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00 + */ + value=value.setScale( 2, BigDecimal.ROUND_HALF_UP ); // first, round so that e.g. 1.189999999999999946709294817992486059665679931640625 becomes 1.19 + long totalCent = value.multiply(new BigDecimal(100)).intValue(); //now get the cents + long eurOnly = value.longValue(); + long centOnly = Math.abs(totalCent % 100); + StringBuffer res = new StringBuffer(); + res.append(eurOnly); + res.append(decimalDelimiter); + if (centOnly < 10) { + res.append('0'); + } + res.append(centOnly); + return res.toString(); + } + + /** + All files are PDF/A-3, setConformance refers to the level conformance. + + PDF/A-3 has three coformance levels, called "A", "U" and "B". + + PDF/A-3-B where B means only visually + preservable, U -standard for Mustang- means visually and unicode + preservable and A means full compliance, i.e. visually, + unicode and structurally preservable and tagged PDF, i.e. useful metainformation for blind people. + + Feel free to pass "A" as new level if you know what you are doing :-) + + + */ + public void setConformanceLevel(String newLevel) { + conformanceLevel=newLevel; + } + + + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on + * the metadata level, this will not e.g. convert graphics to JPG-2000) + * */ + public PDDocumentCatalog PDFmakeA3compliant(PDDocument doc, String producer, String creator, + boolean attachZugferdHeaders) throws IOException, + TransformerException { + String fullProducer=producer + " (via mustangproject.org " + versionStr + ")"; + PDDocumentCatalog cat = doc.getDocumentCatalog(); + PDMetadata metadata = new PDMetadata(doc); + cat.setMetadata(metadata); + // we're using the jempbox org.apache.jempbox.xmp.XMPMetadata version, + // not the xmpbox one + XMPMetadata xmp = new XMPMetadata(); + + XMPSchemaPDFAId pdfaid = new XMPSchemaPDFAId(xmp); + pdfaid.setAbout(""); //$NON-NLS-1$ + xmp.addSchema(pdfaid); + + XMPSchemaDublinCore dc = xmp.addDublinCoreSchema(); + dc.addCreator(creator); + dc.setAbout(""); //$NON-NLS-1$ + + XMPSchemaBasic xsb = xmp.addBasicSchema(); + xsb.setAbout(""); //$NON-NLS-1$ + + xsb.setCreatorTool(creator); + xsb.setCreateDate(GregorianCalendar.getInstance()); + // PDDocumentInformation pdi=doc.getDocumentInformation(); + PDDocumentInformation pdi = new PDDocumentInformation(); + pdi.setProducer(fullProducer); + pdi.setAuthor(creator); + doc.setDocumentInformation(pdi); + + XMPSchemaPDF pdf = xmp.addPDFSchema(); + pdf.setProducer(fullProducer); + pdf.setAbout(""); //$NON-NLS-1$ + + /* + // Mandatory: PDF/A3-a is tagged PDF which has to be expressed using a + // MarkInfo dictionary (PDF A/3 Standard sec. 6.7.2.2) + PDMarkInfo markinfo = new PDMarkInfo(); + markinfo.setMarked(true); + doc.getDocumentCatalog().setMarkInfo(markinfo); +*/ +/* + * + To be on the safe side, we use level B without Markinfo because we can not + guarantee that the user correctly tagged the templates for the PDF. + + * */ + pdfaid.setConformance(conformanceLevel);//$NON-NLS-1$ //$NON-NLS-1$ + + pdfaid.setPart(3); + + if (attachZugferdHeaders) { + addZugferdXMP(xmp); /* + * this is the only line where we do something + * Zugferd-specific, i.e. add PDF metadata + * specifically for Zugferd, not generically for + * a embedded file + */ + } + + metadata.importXMPMetadata(xmp); + return cat; + } + + private String getZugferdXMLForTransaction(IZUGFeRDExportableTransaction trans) { + SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); //$NON-NLS-1$ + String xml= "\n" //$NON-NLS-1$ + + + "\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " false\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " urn:ferd:invoice:rc:comfort\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " RECHNUNG\n" //$NON-NLS-1$ + + " 380\n" //$NON-NLS-1$ + + " "+zugferdDateFormat.format(trans.getIssueDate())+"\n" //date format was 20130605 //$NON-NLS-1$ //$NON-NLS-2$ +// + " \n" +// + " \n" +// + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n" +// + "\n" +// + " \n" +// + " \n" +// + " \n" +// + " \n" +// + "Es bestehen Rabatt- und Bonusvereinbarungen.\n" +// + " \n" +// + " AAK\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " AB-312\n" + + " \n" //$NON-NLS-1$ +// + " 4000001123452\n" + + " "+trans.getOwnOrganisationName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" + + " "+trans.getOwnZIP()+"\n" + + " "+trans.getOwnStreet()+"\n" + + " "+trans.getOwnLocation()+"\n" + + " "+trans.getOwnCountry()+"\n" + + " \n" + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnTaxID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " GE2020211\n" +// + " 4000001987658\n" + + " "+trans.getRecipient().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " \n" +// + " xxx\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " "+trans.getRecipient().getZIP()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getRecipient().getStreet()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getRecipient().getLocation()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getRecipient().getCountry()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getRecipient().getVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " \n" +// + " 20130301\n" +// + " 2013-471331\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " \n" + + " \n" + + " "+zugferdDateFormat.format(trans.getDeliveryDate())+"\n" + + " \n" + /* + + " \n" + + " 20130603\n" + + " 2013-51112\n" + + " \n" */ + + " \n" + + " \n" //$NON-NLS-1$ + + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " EUR\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " 42\n" //$NON-NLS-1$ + + " Überweisung\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnIBAN()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnBIC()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getOwnBankName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ + + + /* + HashMap VATPercentAmountMap=trans.getVATPercentAmountMap(); + for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + BigDecimal amount = VATPercentAmountMap.get(currentTaxPercent); + if (amount != null) { + xml += " \n" //$NON-NLS-1$ + + " "+currencyFormat(amount, '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " VAT\n" //$NON-NLS-1$ +// + " 129.37\n" + + " S\n" //$NON-NLS-1$ + + " "+currentTaxPercent+"\n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ + + + + } + }*/ +/* xml+= " + + " \n" + + " false\n" + + " 10\n" + + " 1.00\n" + + " Sondernachlass\n" + + " \n" + + " VAT\n" + + " S\n" + + " 19\n" + + " \n" + + " \n" + + " \n" + + " false\n" + + " 137.30\n" + + " 13.73\n" + + " Sondernachlass\n" + + " \n" + + " VAT\n" + + " S\n" + + " 7\n" + + " \n" + + " \n" + + " \n" + + " Versandkosten\n" + + " 5.80\n" + + " \n" + + " VAT\n" + + " S\n" + + " 7\n" + + " \n" + + " \n"*/ + + xml=xml+ " \n" //$NON-NLS-1$ +// + " Zahlbar innerhalb 30 Tagen netto bis 04.07.2013, 3% Skonto innerhalb 10 Tagen bis 15.06.2013\n" + + " "+zugferdDateFormat.format(trans.getDueDate())+"\n"//20130704 //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+currencyFormat(trans.getTotal(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " 5.80\n" +// + " 14.73\n" + + " "+currencyFormat(trans.getTotal(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+currencyFormat(trans.getTotalGross().subtract(trans.getTotal()), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+currencyFormat(trans.getTotalGross(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " 0.00\n" + + " "+currencyFormat(trans.getTotalGross(), '.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ +// + " \n" +// + " \n" +// + " \n" +// + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. 2013-51112 in Rechnung zu stellen:\n" +// + " \n" +// + " \n" +// + " \n"; + + + int lineID=0; + for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + lineID++; + xml=xml+ " \n"+ //$NON-NLS-1$ + " \n" //$NON-NLS-1$ + + " "+lineID+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+currencyFormat(currentItem.getPriceGross(),'.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " 1\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " \n" +// + " false\n" +// + " 0.6667\n" +// + " Rabatt\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+currencyFormat(currentItem.getPrice(),'.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " 1\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + + " \n" //$NON-NLS-1$ + + " "+currentItem.getQuantity()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " VAT\n" //$NON-NLS-1$ + + " S\n" //$NON-NLS-1$ + + " "+currentItem.getProduct().getVATPercent()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+currencyFormat(currentItem.getTotalGross(),'.')+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " 4012345001235\n" +// + " KR3M\n" +// + " 55T01\n" + + " "+currentItem.getProduct().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+currentItem.getProduct().getDescription()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ + + + + } + + + xml=xml + " \n" //$NON-NLS-1$ + + ""; //$NON-NLS-1$ + return xml; + } + + /** + * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. + * + * @param doc PDDocument to attach an XML invoice to + * @param trans a IZUGFeRDExportableTransaction that provides the data-model to populate the XML. + * This parameter may be null, if so the XML data should hav ebeen set via setZUGFeRDXMLData(byte[] zugferdData) + */ + public void PDFattachZugferdFile(PDDocument doc, IZUGFeRDExportableTransaction trans) throws IOException { + + // embedded files are stored in a named tree + PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode(); + + String filename="ZUGFeRD-invoice.xml"; //$NON-NLS-1$ + // first create the file specification, which holds the embedded file + PDComplexFileSpecification fs = new PDComplexFileSpecification(); + fs.setFile(filename); + + COSDictionary dict = fs.getCOSDictionary(); + // Relation "Source" for linking with eg. catalog + dict.setName("AFRelationship", "Alternative"); // as defined in Zugferd standard //$NON-NLS-1$ //$NON-NLS-2$ + + dict.setString("UF", filename); //$NON-NLS-1$ + + if (zugferdData == null) // XML ZUGFeRD data not set externally, needs to be built + { + // create a dummy file stream, this would probably normally be a + // FileInputStream + + byte[] zugferdRaw = getZugferdXMLForTransaction(trans).getBytes("UTF-8"); //$NON-NLS-1$ + + if ((zugferdRaw[0]==(byte)0xEF)&&(zugferdRaw[1]==(byte)0xBB)&&(zugferdRaw[2]==(byte)0xBF)) { + // I don't like BOMs, lets remove it + zugferdData=new byte[zugferdRaw.length-3]; + System.arraycopy(zugferdRaw,3,zugferdData,0,zugferdRaw.length-3); + } else { + zugferdData=zugferdRaw; + } + } + + ByteArrayInputStream fakeFile = new ByteArrayInputStream(zugferdData); + PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); + // now lets some of the optional parameters + ef.setSubtype("text/xml");// as defined in Zugferd standard //$NON-NLS-1$ + ef.setSize(zugferdData.length); + ef.setCreationDate(new GregorianCalendar()); + + ef.setModDate(GregorianCalendar.getInstance()); + + fs.setEmbeddedFile(ef); + + // now add the entry to the embedded file tree and set in the document. + efTree.setNames(Collections.singletonMap(filename, fs)); + PDDocumentNameDictionary names = new PDDocumentNameDictionary( + doc.getDocumentCatalog()); + names.setEmbeddedFiles(efTree); + doc.getDocumentCatalog().setNames(names); + // AF entry (Array) in catalog with the FileSpec + COSArray cosArray = new COSArray(); + cosArray.add(fs); + doc.getDocumentCatalog().getCOSDictionary().setItem("AF", cosArray); //$NON-NLS-1$ + + } + + /** + * Sets the ZUGFeRD XML data to be attached as a single byte array. This is useful for + * use-cases where the XML has already been produced by some external API or component. + * + * @param zugferdData XML data to be set as a byte array (XML file in raw form). + */ + public void setZUGFeRDXMLData(byte[] zugferdData) + { + this.zugferdData = zugferdData; + } + +/*** + * This will add both the RDF-indication which embedded file is Zugferd and the + * neccessary PDF/A schema extension description to be able to add this information to RDF + * @param metadata + */ + private void addZugferdXMP(XMPMetadata metadata) { + + XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata); + zf.setAbout(""); //$NON-NLS-1$ + metadata.addSchema(zf); + + XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(metadata); + pdfaex.setAbout(""); //$NON-NLS-1$ + metadata.addSchema(pdfaex); + + } + +} diff --git a/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 1c8f7dc6..10c32cc1 100644 --- a/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/mustang/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -1,358 +1,390 @@ -package org.mustangproject.ZUGFeRD; -/** - * Mustangproject's ZUGFeRD implementation - * ZUGFeRD importer - * Licensed under the APLv2 - * @date 2014-07-07 - * @version 1.1.0 - * @author jstaerk - * */ - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.apache.pdfbox.pdmodel.common.COSObjectable; -import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; -import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -//root.setNamespace(Namespace.getNamespace("http://www.energystar.gov/manageBldgs/req")); - -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 */ - private boolean containsMeta=false; - /**@var the reference (i.e. invoice number) of the sender */ - private String foreignReference; - private String BIC; - private String IBAN; - private String holder; - private String amount; - private String meta; - private String bankName; - private boolean amountFound; - - - - - public void extract(String pdfFilename) { - PDDocument doc = null; - try { - doc = PDDocument.load(pdfFilename); -// PDDocumentInformation info = doc.getDocumentInformation(); - PDDocumentNameDictionary names = new PDDocumentNameDictionary( - doc.getDocumentCatalog()); - PDEmbeddedFilesNameTreeNode etn; - etn = names.getEmbeddedFiles(); - if (etn==null) { - doc.close(); - return; - } - Map efMap = etn.getNames(); - // String filePath = "/tmp/"; - for (String filename : efMap.keySet()) { - /** - * currently (in the release candidate of version 1) only one - * attached file with the name ZUGFeRD-invoice.xml is allowed - * */ - if (filename.equals("ZUGFeRD-invoice.xml")) { //$NON-NLS-1$ - containsMeta = true; - - PDComplexFileSpecification fileSpec = (PDComplexFileSpecification) efMap - .get(filename); - PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); - // String embeddedFilename = filePath + filename; - // File file = new File(filePath + filename); - // System.out.println("Writing " + embeddedFilename); - // ByteArrayOutputStream fileBytes=new - // ByteArrayOutputStream(); - // FileOutputStream fos = new FileOutputStream(file); - - setMeta(new String(embeddedFile.getByteArray())); - // fos.write(embeddedFile.getByteArray()); - // fos.close(); - } - } - - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - finally { - try { - if(doc!=null) { - doc.close(); - } - } catch (IOException e) {} - } - - } - - public void parse() { - DocumentBuilderFactory factory = null; - DocumentBuilder builder = null; - Document document = null; - - factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); //otherwise we can not act namespace independend, i.e. use document.getElementsByTagNameNS("*",... - try { - builder = factory.newDocumentBuilder(); - } catch (ParserConfigurationException ex3) { - // TODO Auto-generated catch block - ex3.printStackTrace(); - } - - try { - InputStream bais = new ByteArrayInputStream(meta.getBytes()); - 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()); - - } - - DE1234 - - - DE5656565 - Commerzbank - - -*/ - 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()); - - } - } - - } - - ndList = document.getElementsByTagNameNS("*","PayeeSpecifiedCreditorFinancialInstitution"); //$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("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()); - - } - - } - - - } - - - public boolean containsMeta() { - return containsMeta; - } - - public String getForeignReference() { - return foreignReference; - } - - - - public void setForeignReference(String foreignReference) { - this.foreignReference = foreignReference; - } - - - - public String getBIC() { - return BIC; - } - - - - private void setBIC(String bic) { - this.BIC = bic; - } - - - private void setBankName(String bankname) { - this.bankName = bankname; - } - - - - public String getIBAN() { - return IBAN; - } - - - public String getBankName() { - return bankName; - } - - - - public void setIBAN(String IBAN) { - this.IBAN = IBAN; - } - - - - public String getHolder() { - return holder; - } - - - - private void setHolder(String holder) { - this.holder = holder; - } - - - - public String getAmount() { - return amount; - } - - - private void setAmount(String amount) { - this.amount = amount; - } - - public void setMeta(String meta) { - this.meta=meta; - } - - public String getMeta() { - return meta; - } - - /** - * 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 - return (meta!=null)&&( meta.length()>0)&&( meta.contains("SpecifiedExchangedDocumentContext")); //$NON-NLS-1$ - } -} +package org.mustangproject.ZUGFeRD; +/** + * Mustangproject's ZUGFeRD implementation + * ZUGFeRD importer + * Licensed under the APLv2 + * @date 2014-07-07 + * @version 1.1.0 + * @author jstaerk + * */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; +import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; +import org.apache.pdfbox.pdmodel.common.COSObjectable; +import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; +import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +//root.setNamespace(Namespace.getNamespace("http://www.energystar.gov/manageBldgs/req")); + +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 */ + private boolean containsMeta=false; + /**@var the reference (i.e. invoice number) of the sender */ + private String foreignReference; + private String BIC; + private String IBAN; + private String holder; + private String amount; + /** Raw XML form of the extracted data - may be directly obtained. */ + private byte[] rawXML=null; + private String bankName; + private boolean amountFound; + + /** + * Extracts a ZUGFeRD invoice from a PDF document represented by a file name. + * Errors are just logged to STDOUT. + */ + public void extract(String pdfFilename) + { + try + { + extractLowLevel(new BufferedInputStream(new FileInputStream(pdfFilename))); + } catch (IOException ioe) + { + ioe.printStackTrace(); + } + } + + /** + * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. + * Errors are reported via exception handling. + */ + public void extractLowLevel(InputStream pdfStream) throws IOException { + PDDocument doc = null; + try { + doc = PDDocument.load(pdfStream); +// PDDocumentInformation info = doc.getDocumentInformation(); + PDDocumentNameDictionary names = new PDDocumentNameDictionary( + doc.getDocumentCatalog()); + PDEmbeddedFilesNameTreeNode etn; + etn = names.getEmbeddedFiles(); + if (etn==null) { + doc.close(); + return; + } + Map efMap = etn.getNames(); + // String filePath = "/tmp/"; + for (String filename : efMap.keySet()) { + /** + * currently (in the release candidate of version 1) only one + * attached file with the name ZUGFeRD-invoice.xml is allowed + * */ + if (filename.equals("ZUGFeRD-invoice.xml")) { //$NON-NLS-1$ + containsMeta = true; + + PDComplexFileSpecification fileSpec = (PDComplexFileSpecification) efMap + .get(filename); + PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); + // String embeddedFilename = filePath + filename; + // File file = new File(filePath + filename); + // System.out.println("Writing " + embeddedFilename); + // ByteArrayOutputStream fileBytes=new + // ByteArrayOutputStream(); + // FileOutputStream fos = new FileOutputStream(file); + rawXML = embeddedFile.getByteArray(); + setMeta(new String(rawXML)); + // fos.write(embeddedFile.getByteArray()); + // fos.close(); + } + } + + } catch (IOException e1) { + throw e1; + } + finally { + try { + if(doc!=null) { + doc.close(); + } + } catch (IOException e) {} + } + + } + + public void parse() { + DocumentBuilderFactory factory = null; + DocumentBuilder builder = null; + Document document = null; + + factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); //otherwise we can not act namespace independend, i.e. use document.getElementsByTagNameNS("*",... + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex3) { + // TODO Auto-generated catch block + ex3.printStackTrace(); + } + + 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()); + + } + + DE1234 + + + DE5656565 + Commerzbank + + +*/ + 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()); + + } + } + + } + + ndList = document.getElementsByTagNameNS("*","PayeeSpecifiedCreditorFinancialInstitution"); //$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("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()); + + } + + } + + + } + + + public boolean containsMeta() { + return containsMeta; + } + + public String getForeignReference() { + return foreignReference; + } + + + + public void setForeignReference(String foreignReference) { + this.foreignReference = foreignReference; + } + + + + public String getBIC() { + return BIC; + } + + + + private void setBIC(String bic) { + this.BIC = bic; + } + + + private void setBankName(String bankname) { + this.bankName = bankname; + } + + + + public String getIBAN() { + return IBAN; + } + + + public String getBankName() { + return bankName; + } + + + + public void setIBAN(String IBAN) { + this.IBAN = IBAN; + } + + + + public String getHolder() { + return holder; + } + + + + private void setHolder(String holder) { + this.holder = holder; + } + + + + public String getAmount() { + return amount; + } + + + private void setAmount(String amount) { + this.amount = amount; + } + + public void setMeta(String meta) { + this.rawXML=meta.getBytes(); + } + + public String getMeta() { + if (rawXML==null){ + return null; + } else { + return new String(rawXML); + } + } + + + /** + * Returns the raw XML data as extracted from the ZUGFeRD PDF file. + */ + public byte[] getRawXML() + { + return rawXML; + } + + /** + * will return true if the metadata (just extract-ed or set with setMeta) contains ZUGFeRD XML + * */ + public boolean canParse() { + + + //SpecifiedExchangedDocumentContext is in the schema, so a relatively good indication if zugferd is present - better than just invoice + String meta=getMeta(); + return (meta!=null)&&( meta.length()>0)&&( meta.contains("SpecifiedExchangedDocumentContext")); //$NON-NLS-1$ + } +} diff --git a/mustang/target/classes/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.class b/mustang/target/classes/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.class index b5c652b23d996d3d040d99bdd27474654dd16eb9..54f41f99d72c5741e7c4d4ec10b4fdb90cdd78c3 100644 GIT binary patch delta 5076 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 delta 5003 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 Tn}~0>;xJ1bLA*^|AsqgHhDJ^j diff --git a/mustang/target/classes/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.class b/mustang/target/classes/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.class index f2e6764233ddac9e64538f17be6c55f4d486610c..e4f918d310ed18608efc0d4661016f5c29919c2a 100644 GIT binary patch literal 7828 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 diff --git a/mustang/target/mustang-1.0.2.jar b/mustang/target/mustang-1.0.2.jar deleted file mode 100644 index 85a027b7f07181ae4a9fd9b5e6bae721b59b1039..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16971 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 E1EEk9_y7O^ diff --git a/mustang/target/mustang-1.0.jar b/mustang/target/mustang-1.0.jar deleted file mode 100644 index 4c1c0e6863b8eef6145f993aed54e968501ab623..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17026 zcmbVz1$10VlC3OR%#4;SW@ct)W@aogGn2*4%*@QPn360we_j0J4f6d{T3CsnT3kkiR_-6&Ab?2TyOqD- z7Xse@9r*r2`S0DN`DMgKgcX%&q(yF}$H$~3scB|lC8;SU$EWHQ=;j%>59}!>#>r=# z${G}gDQLu{s7He#3Xk0jjRF!{K) zYkG;To5?G~cqQS}T(7_%^CRa31f)W_$HzKS-ENCs-fo{jw}Cjp>eLqHMTkRCLCV$U zYO3@D@I8pQF>x6Su-ZQb-<6(12X|0&+hMk9Bd*_62};eVa9=pOe%|vGDC#F=Hz--5 zz)-Vcf@)>G0%1n!oOW;F1caqCo(+6YpFgobp;y9+eu&|97|WF@{{%LR%@p6sg%P7* zE|S`7R!(*tmK5o7C}zuR!;p(#tUot^Rt9qzWQ(KRuIe{eZMn=MFPNG8+|3-^=eVQH zO7k;!l{R0l<<3P(DClN6Q)!V|9eN~Zn+B6=A_tR+cM^xAeLcmA`E+=?eP9bm%@bBQ zlOZAo(d2=rM<>3HpFTYX>ySKc53CPV;8Vn~Y%n}B{q826s#GT-H!2+j{~kM5diXJ! zURcZ~+X>Yh@ITkf?+Y5dtt)=WNQ%EGR;0DDJ$11n=efQ_TRq2uq7 zbBgMf=;uQS{#nW_u9=9-<*^tcnae60rvVwLp>ZFx#zKWpyg_{?bhp6u2*jgw@)3>8 z3GQ~H$CL5aFZD4ZYvIQ0tEMCf>Y$lY4E@!KY2Zzl#g&6 z;p_?P{l^f0o-M&BBIeEaSrh77qV5g#W3QTalI&X#;K_j$!jszzc_M`K(bqetVQZ!*eY)E&|5BNV%89i!z z%*y*z5&vHnn4CSp$m!Ptqn8BXM+n*)U@WFbgodWHwAT8_Sw4)3C=@_XK5Mjw<;J|hJG>>G65Yl27%eOM+(oW@i zl+5O2-e3=HdVO7`UTkFTOs%WHST3}^Vsg=b9i%94WQt6k`NVoqY}FG51+e<*P|IBj zNRBS;NdU>KnpXD$K1nBq8&~3@%>^}g9V7p5UFvt8!9XG#J-K%`2zNOz^~*( zolb8MI%CGZ*_b$s5_bD^bbaW-wK~uv1W$*#!Ds!#bYVM@qqNEH(?fbkkdV8?pfP+E z)5|39PbA(N9n7ePQKLXeFf|#SGmI zTXPJYm}sBMQgZVeOSqR2rfg&85_+;WtOG+3L(?QM{>E87x&^@MBhsVphIFBI`+@h; zJibJ14x+>Z>oVRz>wcT03}vlEVQUX=K%wqamcG5L;aM@UKp4paQ5EbS4y>%_<6R01 zng&JTnG@p7=y|t#1M_HL-{+}zXUM^)YAT;&%yF;o3X>ryQVcqb4=<=g7?FJ#Ks#(w zMkxU!Ft>2fHawtnn3H_;{p!W(4s4gUy*qjRas9+Rb5O_2p7*f;q~RJ!`KetA|V~3N?yLl>Y)Uia<2XFtLAEExzrD zeG~^3F1>%pmfc3IacIZkBaU(u))2=K*pPG-I-Ab^Bh8Q`4lOBJq$(Q=d)JU%#GZ20 zr9%hW(3#!3iC9`tpYfDk5c;}N%VxGyhl0BoS2hh>;+>SbQsAeIv8q&NMs1dJ1$X=_ zs`fh{3$P>%0!0~qx^Gh&O)1qXDuKz2s-p!n^)j1Ow5eIdOHRf_YK@-3_4;awWq2{H zOAd=dJYu@q9j^RZsWP-v+B(D4;o)v>&wcyjBA>0c?5%#{fY54s)8S>gm@N$)1FcmA zhVUX(aJ?2udT;^2^7dVovW@s3-KOk8IDA=%R9cT_mBKXowWz;0^Cgfx1R87h#={gV zHA*iPT+LbL?N+g2pL_|YR7^wmQ>O!Aq|z8?<_=HZ8R-8^Cc{e=S`8OjokC1ZEIw+p zWRzW())*0`KxEb3x_soGXJ*ZWnx=Uq?sXD@t*n0}>_D!aZLS;DNISHaYmBL=%0lv|iiF0GE2yl`cOfJQUqYVqp8ZT2_T^(H!9X(tX`6Vh!fp)Yh+k_1P z3iHI66ErxUnryC)0$*me0FnsH*&OzArx+%h$*aVl?#?R-WMPuWzyWzV<9vt*dew~D zZx6f3!>&nT_KJr`@0iGWVXPrjtVo8I;Q?xJ+^t>+B~f9;;5Z5RdZAi1MHkU~SqBzR zB7}Rw^VGW}?Ot7GB&oP*N}PF?XWc(m`@tM&U^h`6EdO*RHSY>azX@}!id{v=sKZnD zMLc{Q<`XSSDZ4fH7vP{)s!(jDM{`o$MD#$TeNR_@A^Uk;2@#f&`U!^q)b%p45j_PN zdej)IV+KkTA$+GsjX1=@q@%i0cfL{rx7p)bI+1;VtLlB&)FiETT4ox)xwvaM=}^IC zng;Vas|1l~hCqhB8C_?%I7kXAGyex^3AwIPnZ!bG)+y~FER?gw?%-1FoG}6c*_SgMF|oFEe$r%)$(|0eLwt~JlbmoRo8nr z?gqL#NXiQR(eV0gZPC~oeG&p8EY zr)V^eg0?}g=H8I3BdV7ugvfyHn-pS&K7j^@Y1_Lm4*{Y{DP*J@o;dI2eh_I`!h#N+ zEEu5NR0r@3SkpypGoddajs>WjS|8i?juESy|-%+MBTW;Rnu<&6#In$*=DX!Fbi_sQ#c5He0iq3127 z2WWDS$sVIfwE+=@tP-p67U{ezYUl(6MOk8hZ%lu*`5LvaR&JE9h^mlO>=dT3It~T0 zkW@T;HdWd43j+O3YX6dW_}nEMiFn=;>z&+32qj zZAC5secg}u2i|Y7i^kDa%{1^yD96P z+sZ3K3q}i}`+Ow;p@EP~(?0Z?^-?r>JUCYNs!fNtRw~!@Gwq`0*8JUq<{MuDB;ibC z!ank|;j{SLJog$HCPB*&=FcYxOa*+axH&fY?V$6O z@F6*fprXx@#m@G$(zHVhdFQYp+&R= z8!ro8NpnRs+kSGX_18sQ;U%%(8lw0C0qxU!`-p=2no0E&Gmc zm=#?5H}-V{OV>o}ZD!|)AF;0RfEwLh=?BY>iHjY$7vxQSpTYKTfV+o#c=yyNR-PQl zr;>bV-m~N0DbA>E^c}Sg`Hz4|RB^@@zPs+P7mEAH38@p_g4eRsYSwk_Da7Rd?N-RL zu_%LH&ako}hWF%Sa!E`oRA1o?Wuj2ejOEA2YV#g{hDj0;likSLrWO=LVr~(M=bJgS z2q>^-b|5S=e%Jl;@mTni6$$@67up5|0;2z49*-JMrY6SrM*m2GlvWgw`BAt(`D5zK zL6lR5euk7J3CI2*3=uJdK$SnUTbb(ECs)5vAedLp^K?P`xF4^agn{=8#5;O3$tPDK z7bLzgzP@&p<&b>wxq-^{=0{+*EtHLBFGplZ%n3sMa9#20-94WT?|w3C<1)QJuLOe`(j+LR_t?S+_2( zTA)_-=)ATP6w}#{n;L?K*=bNjfjO!VrnXnM)O4kNY!c5hTbyZC-_F`u3z@80r>B5n z{LrpkDQ1(bJ+*?`Hs7RERULLj*(H#rMBSxKogAo|QQV<*0jbFlnMpzoCLG>24jOh3 zj@YQKP05keWC0Zs3Nah&QkF%t2*X?X!-pBU-7~rzqYo4{0>ikaj<7I&wn3vZsbqr0 zb5e7}D6T=eJulYaD%M@ophfQfTY_wyeFSk9!#D1sY2neiYSAmPL8K&10;h{A(~7!q zCKZg;l8>n6YWX5v)P*WIou|c5yI&{?)KsrAFvCaoq0&?DEI!IAaS5vog4x4#`hY$z z?6(M`-s3tu9Ln+VKgrJoQbSZ5u(1dpyFGvAIA10ns&A=`s8~i0wA9rZH8pcO<^4K9 z=Y3-Z7cnB6Beq;AzfUmnp`T^_uP(w_wa;K1L*PxGdN(rD#Jm?Hd$ zp2>!T|fWV%c zsRFPawHITv;q{gChF*~59T5pNgdKB3&MXPt;fZ<{%?q{&O)=k1I{=+4Y2mq5?Jyv< z2&nebWzHgU^^>uEmHW!ZCAIy@z%`nUM-K{*K0r3`M>vtN-!#7@*|WuTo!2f#ZZLJ8 zOh~n5YQDD5D?wp@3%ia5HPm?eY;h1g1h1@%rMFtZ)Gkv zQE4)SSjQX`8Jw-3XBhj18}F;t)fxrBeyF}wne9Wh8%%;BM{tMWzBBmj7dSn(A`%Ff z8@vfg4GKYxA4EhHle*EFHz&^V^7H;F-Q&e%v%_s}^P9&RX?NEV4^Rs2kKI5(jix~~ zNSBDRX+n{Es+#C+1qOxxkKYh0y8Vf@EGH?-AJ&pLF&IBCe5a zv`-6&b-(&+Rc)gpRXYlN(jmS+C0Gwz66;Xebwcu?xHet4<2D4uJUWDR$GGMX=t^{m z?@mOv3-4AU0peXbc{lK{Wx`zSZf(Ns!rEI}+abPhb0dKhZH`Uoig(EFzO8%m?FJy> z?H=|c;l)0ZvEs!)T82eC+(L%QN_a}_&LL&TK4OPWNqEZa-XiJhZPH43itmmg>Bc@% zxO9+QJB0ykZ>7Tk;;+=KTh6sWIf|3}$b~vWOc!B|1bSAZMA&Rns67r`XqTyKN zhhp@}wnotMV@x*WhvM|Q;h+js2?ntQXq-Fj;jpzrh?1FC1Re_!2ABZ=@ts(MR>k=+ zRE7E5Oa1~jyBZW&nHjRQj6C%UC7}r9P1JG}yHMm!^h$+_!z}=#T7D>t^O}vfnQ2WD zX0=1O;Glb&sv}w69AtJFEDVc6U}!&zT?=y8Hok7C^tzyd)nRM2+(4|%BWc$7wvw>t z5Tx#Pzv`=P0zs4r*+a0ucCIZSwEI2tGs{M_T-_mtb^76hWv`8kD3jI4_GCh~=98UJ zL?{Jt0sTxwro4Lyw?t)Z#G7;ho=^JgScE0bL%^E%w#7{g)r`e4s<(joJ}}<3%%>S# zLVr3_X|nZmxB&wBv|?5q4w3I78|kbS7Bfq%q~59z_rZPg+)}sE_h0+;xsT5Q`uh10 z%!x@Uchh?|Ol|2-)rixtW9emeVY)Taw?k$(b>9NS;CaedDqg<$@;eadA^Q_zgxoa>SFui%(->pyMNeC`zoVmzkG3!JPJZavPX|{7 zF*=#6uSgy$S1Yso8NQuc65!7-L}*?PR^?j|EJ1y30LK=i$3$}AhT7$vT)zkCx&VLz2>z>$HWeCcqfh5tfk5J4bz65oDb zV!htKwkX%*9NefUbjyG!;Bg=pyTw6vH_;G_)xl+Hg>K;|7YSn6kw}=AsjFA&+!|9fY9;sCzg_d%s*5Ciq7v zxD)xHi89TW-B(T4$RJUDlJ`w)czg0}BeyQlhCb#h$&ATJZYyCF^BSm&km_{4+aDk# z=qyO0>9_n!Dm^ox>9;w==va`yob4IRnugfUVhAAHwb59cu}UeQ?|Z{(e_&X$TvO** zHKQWN(@PzMXvKcXcNb)$n|_wPDc^q7P)~Wul%+$nI&<{#>TrvuSkh|?= zk6Djh1l~E}$gM|2*Mh z^88Wq@-m=~!=gnR^0m43#us(r0jHTxJ7PU^SnFsE9q#O3AVj#lVo_1KXUwXH&NsWf zJkB42tXRMMyWJkfe_d3=Dz7m&zY7mnV>=GJ=G`bqzB|=UkmR-kf=}Nn4)V$>`kM3= zHk~Viax}gkBVU$r34#Hts0ab5dN3di(%-ma8 zD=%C!=;^_9R1jYVLuUB?OqJ!+Y*((Aa^{*R(Y(Dh3o)jFGE|XXp3dS?|q6 zVjkRepM$6N6N%(NItqs%MB`5kfqKJ z`H?V?!zq`X-P;ffFzX5gio=B*KpqsuEBZC&^yF9lARTFdsb1|Go*qn6fQKK;ErpqB1z;s%Dqz zA;&5o-B|L}pl2NeS#8>v$KjF}V)j*?Nm`^~Yw;LXs$j7-URy}nO3|(t>w>gcX>cml z3MQ8LCDg`8(rqPBb&%FI&|LXD!l%zlc0N&6^2~YYPRBDPyyERWOo^zc(hoDir8$Y% zi%YHb?_Z4X^+>VCoiZ1vc&$0ySdeAu(KBJ%g`vTQwsFSP71|Zv`ceS(<7Vt2Nuqq0V>$X0;;_3+}AUet=acD^E5UT8Ua&nXy{i6Iw2dQ&qxw;9JFH zEKkTvXKKA5JgcmdMw(IKS6PHjFRvO&TuCPR!dmelcMZqlR*@U`W8Uj)ztC~{JqPf;iMSMh2Vt66j9r1RM?sdaLw=7k8B)1UyW00a?OTgFbA)f%{#;j`)0@NV3g76f*6Run|Je2TT$1f290xg^LpM~>2D#Hki!)_> zoFIwRY8#6iwy=4U$5X@9CCjBsi7A)C~)kO%|uC&@9 z4FGK`R4XDkyw4F=E5n$yD-vZset8JX*=R+xg+u*@jH$j^))UfOq?T4Z%YY4cnw_B} zvCF}xj-cv+E9}4`)=sD!gykspK2+)6o*Ur=;~nsdBb>o>4KqsqAO}FH%--KW?HyXT0OZPCvOt&xa9u8x-$ECW{Xo+Dl)!wpRSM^ zqjRu8g9l2iZo{f+CxkI%HdDM20qYH@j6ueehA2QFapicNvI7D=I1C;V$0|XsAp~6w zO}tfal^nb;Z#{$JttrD)L0ms!2I({{GoY=a{Pu)BW~EHRi%XzTgaSe{Kq)H~Pc>z$ zx#HYlp|L2WRGPn@yaIt5$2gAaV@KSzh;RM39Owk&7x!2R3DR_pEs)r_<*u**EeVhS zm~k&p?L}i<)A5pVAronN;{k{BhwW9{W;7;(BL3BhwFLrbeq&Ny#Wh)_n;T^4x~w|8 zYW>4}f!#;k(a*(HgTPG;CxH?JJLm@+8J+ z?lr1A4T}S$7K^s-W>(e&fZ8>UD>chF2FvN`vA0=%5;5(|XuMhRINb8@E;WvO;IMf# zQ6v1HI{H_#)r`K{trnvb3wnq%a%&W1o)SCYtxI9+OnYK<@T+_9__Rz<#7~srgpWz^ zxS;fnzeO^yXV|JPc0B#){hroub8d*FbcjuJ`LVWA$*pE4b?p$XYQ5A)+<2kOi-y72 z*2*-T%ct5+gCV_otZ97mLTGh8dAmmR!pWA%bbou94=|fFD&1QVBi6yIiBycUdh^)8 zN<}%Nu6j6#!+o;F1v4^9=!rwm4bEW6Ksjw_k}^O3Gkfx&71&aAgI|98(-+ zsOm7iMI2?GHxv|e26AnsCxFP(!@b)1zV;%5ACZ4ywjhdY7efD5{(D0u$lOvJcz(wbfzx~4Bg5P zgg<~{849`w8uyAH)8Wfy{6Q)evlFrm=(N^Cn)~umKfK2^&*IiqGc8^ry#Eeda z?}T$TnOZHpU+{Gv0cmbjJDYgE3<^^P>~_o51Hw7aG-TTkKR)i#ttj$6XY7*W_?D(y zIQM?Q9aKIhVE)7gbiibjCJM(lNRqq`I;Y-G%(zQ8N30%HuVoasf?GVs&I*@ELz-XK zQoX9UPqAB!rHYt)*b?px^0o-)o6a_QTSBuSOfc?JI^Ul2weYJxezfL3<{nmm%3u{e zmuJ`*f8XJte(9Ke3wF}rj%MLgvVVSB;dKiNZvDD)N}Ul#5dv3Y#&@Qh<~efsccs@gdOpVQ7Mpw-wkRX#yB`p!&4LE6eprwP2U}nQa-h zpj~>M=zv^$2Lv!P1pAsu0bU{t<2SNbQ zWN+(!D|(Mcg)pn|{6r1L(T*oZ0Q54c7%8+JV((zfz)iLPP{s17k1^0GOJc<`=)HB5 zO9GD2rd&NZoQU3*ncnnpP8dIxFge+%3Bg~@u zTS(EhZnluK+VG^*J{TDG+%j%(4LF?aUT0YEA=5r0+Km|4miQU(=qYbnZ&HKz#Oc;( zPx|6z{j(F8cB+3G%0}w!105X(PXD$Vm^au5Fn%z6uuio2y^3pnFhnqUFnZ|L2>~0^ zX;Y{BVrmcYfW1l}8`5>i2GN7|o4ucn!glu`vo5D_L^lbIf24pd`j0kB&YNqX4h{Wy41I83k#0L&w zs)qer;(C=~s+yK!n+tr+oZ~K_w1d7=%ikmoE2x)gMI5z5Nge=4@9hIi=^it~R2kcT z@>7t|;H7@TpLBWo-J*FE`3XM@7oCsZjDF^+|}oR5Dc!2n44HB z2cFSwda!Ppk9KiOd*&CfLL9r|(AOvd#h6@%>BmN4te&65So;7NT$cGqH#{+>7a(8c zq^=N0ouYRc**@tOWjqs4qPVe1ie*r%>;caNXSxv|Pf-r?Z3@5~QuoUJ*uWUZ>nXq0 z?Xw*3@MefabZdyFE$r0prOgFNmM=%x0^#+B=9c3llW%gow+y^VYCY9li(G5;(q#dLyBV^gX{B!ocI|6)e zE$Fhvf+UL#v+c>fwU*)eZC(Py8^-G82xm6oAlH`8jX$XmkWRsaWCl1JWyg5>Ddo2n z;_9Rhw2-CJYcRsiimZC*O^PRLoXx|?nC6Uf5oH4;;nq3whfz zK(0QB-|OS>*t1WBZ_5&8F~Z?Z6%HuXVDp6a7lT}_kkE)Z_a12pBg|w!%_yUUbi?$Z zGySLzd)@&=hW2ks{^&&=NG`P}hlm%)XZ0UQ=Nr__K>-AjyK+hmaq7cuO0Vs6E5&gG ziS7#K?DZ#D;RStqWXtfE?QwfV(ejs7Byk0^=`-D-@yud5O5UdT#MBv3-Es2#!g9sB zZRm;I)ze&Z=+3DQe5^Fxq|cd-O|Nfbu`&qMxP0Y*^|PW`?9xSiWv6rSGu zW&Xh)M^|i4JCM{yKVTceYehZq3=;>QAp19cS2k3TBYs+&zKQ*PS_OKykGSH4JwtNA zTfO;a3tGT6`BX%iIA1is0pG%;F=l(0gKcMPoxhb^!=Y>ZtjayLT?FzR^!jO@J?8bZ z5`SY#g8Uw+%Jmw=b~}U)j@LizkzQ(0R;)BzfY{rHB6rmwt0JI`?80Pj_LE!`mQ7)y zEb&aoF(EyIQ@qR4&p&E;f3M9%Is#2dh6Vz{c(1zs-~AFJZv9(n<{!VrsJZE(EMWfZ zT#+`Z#}rfRtNok@%n}#~${%B!Nc1sJoDWI9p-IM>bY%EKW_^P%ud(Ug>|CGQ9U|PN zP@^#qAHkej`AploQX_g%BiaI>xw^E~AN==$!p_2M=3vf2Fd_~YdQ z{JrQDE)Pu=Jr_*Ve>vPzNsIExn*Y%*6Q>G(7i?WEGTqjJ-lmr|!j7_OY)6yA273G9 zv&hbx{R~a4EjRU)Lx-ivdNCMi1>@xdO?G?Z$t2CG#!b zzc~T&raH?0comu9gVj@iQ*yLFbo=2|%Ddxp2>QWQ9F9&>|J1=1G~{t2kT>~}s`9JE zpe3-zyo8A(W2y}ULz^#~c22{_dwrCseddf!L8Q?<0t9nbC194&j(Y{se57F9XvpA$ zuC!pKZ+EVVa6O-XF={j>In7<*Lgu(Fp}r+d!^y~(33q>u@XShgIC=&e`gju)%=?5X zE!hVRN|CHM5k_++7t+;8rSeU*=BcJUchAl&hJ$9wJ5!E{20r8b#M4lswmD3KGYNH5 z>=~*3J4KZR?6cE42f@5C3FAl<#Bvc?l0s2P8?C2aG;tI^XGWU_M@)G?<|dm?$!KS+ z*eW%T^o4$M{)B6>c?qHlBO!+35v!(jd2YkFx~8f{3CF=N?-im`+i1~CFlnd}nDnjW zaxcAbYN`1~wGnLQFRJv#&XxH)X|3W< zz-}M8d49%VomQB+^of}i*k)oThTbbxqp+@~-_c-h{>&xx;|!-y-mx7nLN!;buOqc^ zY{jKKguD-UcrrkHzafPp$hp2w51gEjlE{w9AxOf>1oev+IZKbFv83849PAp;4$yEX zCXs!~aszg-D&&sM65=ud6wJmpK4@7IuT4Zu=qS?H-5u1wkk&Xtz7VM;x;cfB{8%mc7FXl*l7HC=L=w4Ir6$J z&F*82maJ5 zE)*7Q#)VYX7ZXXr7HR>FSf@1#gJ)QqJ?X$hoj=nnc9vWvPu(^90au!+-E&tSul$2} z%&(A_C6D#N-Fn&K-4>77H1k(39b@3cTMKs$&~>9yHg)4A^yz*}SMaZj{oPjpzasd? z2a8AeO~qQ>{tt(|ix9ax6d4j2xW=N$P>W@K#gN@((?Yp&peEhjV^p?6Dt6LVkwS<^(-v;RLXDh$ty+>y1S(i>I9oC;{Z9;Re!X1_=}*mU%)676y?Jr3Muw zqqeodk_E;?a>H~G40D?43czMO>>QE754ReDGjOsARmXuQJ+qztteq)7} zJ~U@-vjI4T=@==~aj9mIYF||W32z;VXX7rjM}Mv4CX8#g?CS(v2Vb+6^`a%G+jdnn z8PaZMCd0yD%JT_ja&An^Muxx>o5eYGHR=!&cBbJSA@&TSPB!@jC>-w4MDH`BJj_}v zU`7Ev|AH>gSvyM;6aAzUt2-04uuY&#W03 z-K2_RjauD)lxk+)m1GFyE;fexBz5rRe12|Xob)T3xvXF|5~=Jyqfy3O*p(TKNix!lde895%zzj?#eg&7C_q)cz!-Xy=OYhzm#bFCuk>bLK9hR*~l8L?1I+B@g{ZxxkN4x9F z&@J;>+ZImcn}5mGd0<`tp*E>`hF|GbJ`S~(IUK2m9h9lxJ=?+z!RjzF(RqEnbN^BU z_z&2`H?rlRJ`11aE%?UPGCaRif7@Q5@Q+|U&E0KuT5P@se$*w&l+t>%BFg3Z%uH=~ z#F}!-JEUp0{A!>0O8X}07yN8<@N!S{!nrXT@wMioYun`(qwUtd@~Byc|mUAgP-;_Kv5I#Zc-oFph|T~FV(rY1L3L)0Z~LQDD(zw*}7oN zj|I(IvZKo2jSwE)$RuyxO=kd6dqS6wyDKG6csX2el@;h;^2C`gzYcs=e}iDP7M;F+ z+~;O95ERBMy4xFmuMs@2PMFV6YtA3nXETX$5>Pf<1uCK}d3ZrXiKK*h0jCq(CXs@D z8KT!4vM;U?2tFnRek1EH;j`ksvR5`MDxNN77f>kjk5%!42Hpc^h+-N0R>MKFU4s%7 z0Y(==Ts{l;bPV-mji=}&?>oe0j_2&4Y}Rz7e}wa+W&t-uI2gAH+M$lq;npRpUVq)N zzomhK>9W7!DX0GszVXR*s=w$+B#70BpM|NtW;)3;OJBDJRkB=w)RPaC^V>HH{U0&{ z7!GvN%3_m}ZpGh5KZ~p}mwwTeKXiyx-;xQF866-u&Wpsv4h~A~V0W07hCSMLEs&eI zS151;VXQFWt`Iv~ZLUN{k8#Jn++1iu&|E>)jj(RPZQcd@Ms(QOf+@R)))9z(O;NQ2 zU$=G*chU12v|aUaPbPt1rvW1_Lh?4g9VjlM z=538VUKaYxwf}B^#Hblpal#I&F@uhx$+nX* z&!$q+9(5rcfYS0R*dEH~W1UFoN=LbIM=>PPNqlMrBwFS7xeH*8>|G0XRde@IS&xVl zKbz-sqs2w(jrnO_!kV}>43oUoC1KP}b97qk$tyqM;(xIdr z)=5XA<9HQS13XjFJX(+7(?N zX&+np@MMG51B!MM9nJ$v_t1JU&XcleHatJLHm|pFmokel=@2A!2QzJ~(~oKboFRgb zBIJX89`rtx?B}r?zw!Hz_Jyo5#!q}`2*Z8)z8U+#t)rSt37*;u^Np?;+Fz=ws@<`e ziML9Ov-E$gZf^kWIj7AP9`&W{+L8{I^eeQ2cvhoPHFKVu`!C1JVGNw2PR#?#x@{c1 z_PYOBZuPIiL-_Y{t3QN?*80xIHnjh9XNrIA{I1NS`Li;Q=C8`UelH>ez7S` zMX}M`T{9WAwnlPU_`Lg)&J%)!;p083M}_%14q3<|Wv~CeEeVtm`OBk} zorwVP&s@_DgN#O9U$`5H`KIKtmf9QPJA4ILC|nlp)joIaebCa;IMuBHYobZ}eEw9h zr&TW5!IykVN;tTh`9RLEu=B)Qg|IN}Lkfm5<+zso$G-Ofv_OU{I4Y-;LaK8yw1_dC z3WTZI;dVrS$y*b4_)X*wHi2JTfqSc0O!W7WE9(*>NJkR0%WW1FO<`Dm>~8CvO-l=bj9d=Xyi!F8@ygOok<`I zdi-*ZY8Dn>tb-S|>rc>sEZ{L3d z@az8ZPfz~6w)Y>dypLY#?}7eM`u=k5-z!mnAwItAhyTX4|Bo*9uRMR%aQ@;Uc@M&W z#Pdth`B##^svdulsK1x7|3@T$(m?)|=dWVHUp(ROin9NR=U=3Qf93kCPVE<$2gKiU z{jF;4uPlEp_y5I`_I^D6&4~VB`BU-#U*Z2+-TVt4>U~4~4g9~Yb^a^*U!U0hLQkOj z-=P2b`Q0z{e?7H-OBH@^2tYr7y1nZL|G4A)GjaImhW%IL-%^KP#zp^X{5}u=b0YCS zA{84CP(-ZPEA4Ek^U{wMxF5{+MT`|l67Uo@ng|5ut{ Z$DEub==*jA0z!WOb9ldcddCC;`hQ8i7JC2y diff --git a/mustang/target/mustang-1.1.0.alpha.jar b/mustang/target/mustang-1.1.0.alpha.jar deleted file mode 100644 index 410917b367e32ad2b1ad787611dddd2e20cf8537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17231 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 Pp}oAEU#Hpol6UX@-d+ED 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 p``Rxxq - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mustang/target/surefire-reports/org.mustangproject.ZUGFeRD.AppTest.txt b/mustang/target/surefire-reports/org.mustangproject.ZUGFeRD.AppTest.txt deleted file mode 100644 index e5dc4367..00000000 --- a/mustang/target/surefire-reports/org.mustangproject.ZUGFeRD.AppTest.txt +++ /dev/null @@ -1,4 +0,0 @@ -------------------------------------------------------------------------------- -Test set: org.mustangproject.ZUGFeRD.AppTest -------------------------------------------------------------------------------- -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.223 sec