diff --git a/README.md b/README.md
index 43ea3671..6c4ecb6c 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ If you set up a Maven project, you can reference the mustang artifact like this:
org.mustangproject
validator
- 2.15.0
+ 2.17.0
shaded
```
diff --git a/doc/MustangWriter.java b/doc/MustangWriter.java
deleted file mode 100644
index 6cf8670b..00000000
--- a/doc/MustangWriter.java
+++ /dev/null
@@ -1,277 +0,0 @@
-package mustangtest;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-import org.mustangproject.ZUGFeRD.IExportableTransaction;
-import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
-import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
-import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct;
-import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty;
-import org.mustangproject.ZUGFeRD.IZUGFeRDExporter;
-import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA1;
-
-class Contact implements IZUGFeRDExportableTradeParty {
-
- public String getCountry() {
- return "DE";
- }
-
- public String getLocation() {
- return "Spielkreis";
- }
-
- public String getName() {
- return "Theodor Est";
- }
-
- public String getStreet() {
- return "Bahnstr. 42";
- }
-
- public String getVATID() {
- return "DE999999999";
- }
-
- public String getZIP() {
- return "88802";
- }
-}
-
-class Item implements IZUGFeRDExportableItem {
- public Item(BigDecimal price, BigDecimal quantity, Product product) {
- super();
- this.price = price;
- this.quantity = quantity;
- this.product = product;
- }
-
- private BigDecimal price, quantity;
- private Product product;
-
- public BigDecimal getPrice() {
- return price;
- }
-
- public void setPrice(BigDecimal price) {
- this.price = price;
- }
-
- public BigDecimal getQuantity() {
- return quantity;
- }
-
- public void setQuantity(BigDecimal quantity) {
- this.quantity = quantity;
- }
-
- public Product getProduct() {
- return product;
- }
-
- public void setProduct(Product product) {
- this.product = product;
- }
-
- public IZUGFeRDAllowanceCharge[] getItemAllowances() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public IZUGFeRDAllowanceCharge[] getItemCharges() {
- // TODO Auto-generated method stub
- return null;
- }
-}
-
-class Product implements IZUGFeRDExportableProduct {
- public Product(String description, String name, String unit, BigDecimal vATPercent) {
- super();
- this.description = description;
- this.name = name;
- this.unit = unit;
- VATPercent = vATPercent;
- }
-
- private String description, name, unit;
- private BigDecimal VATPercent;
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getUnit() {
- return unit;
- }
-
- public void setUnit(String unit) {
- this.unit = unit;
- }
-
- public BigDecimal getVATPercent() {
- return VATPercent;
- }
-
- public void setVATPercent(BigDecimal vATPercent) {
- VATPercent = vATPercent;
- }
-}
-
-public class MustangWriter implements IExportableTransaction {
-
- private void apply() {
- try {
- System.out.println("Reading Blanko-PDF");
- IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setProducer("My Application")
- .setCreator(System.getProperty("user.name"))
- .load("./MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
- System.out.println("Generating and attaching ZUGFeRD-Data");
- ze.setTransaction(this);
- System.out.println("Writing ZUGFeRD-PDF");
- ze.export("./MustangGnuaccountingBeispielRE-20170509_505new.pdf");
- System.out.println("Done.");
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
-
- public static void main(String[] args) {
- MustangWriter mw=new MustangWriter();
- mw.apply();
- }
-
- public String getCurrency() {
- return "EUR";
- }
-
- public Date getDeliveryDate() {
- return new GregorianCalendar(2017, Calendar.NOVEMBER, 17).getTime();
- }
-
- public Date getDueDate() {
- return new GregorianCalendar(2017, Calendar.DECEMBER, 9).getTime();
- }
-
- public Date getIssueDate() {
- return new GregorianCalendar(2017, Calendar.NOVEMBER, 18).getTime();
- }
-
- public String getNumber() {
- // TODO Auto-generated method stub
- return "RE-20171118/506";
- }
-
- public String getOwnBIC() {
- // TODO Auto-generated method stub
- return "COBADEFFXXX";
- }
-
- public String getOwnBankName() {
- // TODO Auto-generated method stub
- return "Commerzbank";
- }
-
- public String getOwnCountry() {
- // TODO Auto-generated method stub
- return "DE";
- }
-
- public String getOwnIBAN() {
- // TODO Auto-generated method stub
- return "DE88 2008 0000 0970 3757 00";
- }
-
- public String getOwnLocation() {
- // TODO Auto-generated method stub
- return "Stadthausen";
- }
-
- public String getOwnOrganisationFullPlaintextInfo() {
- // TODO Auto-generated method stub
- return "Bei Spiel GmbH\n" + "Ecke 12\n" + "12345 Stadthausen\n" + "Geschäftsführer: Max Mustermann";
- }
-
- public String getOwnOrganisationName() {
- // TODO Auto-generated method stub
- return "Bei Spiel GmbH";
- }
-
- public String getOwnPaymentInfoText() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String getOwnStreet() {
- return "Ecke 12";
- }
-
- public String getOwnTaxID() {
- return "22/815/0815/4";
- }
-
- public String getOwnVATID() {
- return "DE136695976";
- }
-
- public String getOwnZIP() {
- return "12345";
- }
-
- public String getPaymentTermDescription() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public IZUGFeRDExportableTradeParty getRecipient() {
- return new Contact();
- }
-
- public String getReferenceNumber() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public IZUGFeRDAllowanceCharge[] getZFAllowances() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public IZUGFeRDAllowanceCharge[] getZFCharges() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public IZUGFeRDExportableItem[] getZFItems() {
- Item[] allItems = new Item[3];
- Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR",
- new BigDecimal("7.000000"));
- Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000"));
- Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000"));
- allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct);
- allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct);
- allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct);
- return allItems;
- }
-
- public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() {
- // TODO Auto-generated method stub
- return null;
- }
-
-}
diff --git a/doc/ZugferdDev.de.adoc b/doc/ZugferdDev.de.adoc
new file mode 100644
index 00000000..accca91c
--- /dev/null
+++ b/doc/ZugferdDev.de.adoc
@@ -0,0 +1,446 @@
+== [#anchor]####Mustang Project Nutzerdokumentation
+
+Jochen Stärk
+
+zu Mustangproject 1.5.1, 13.01.2018
+
+http://www.mustangproject.org/[http://www.mustangproject.org]
+
+== [#anchor-1]####Über Mustangproject
+
+Mustangproject ist eine Java-Bibliothek zur Unterstützung von
+erweiterten („ZUGFeRD“-)Metadaten in PDF-Rechnungsdateien. Sie verwendet
+als Eingabe PDF/A-Dateien, benötigt die Apache PDFBox-Bibliothek und
+unterliegt wie diese der APL-Lizenz. Sie ist daher, entsprechend den
+Richtlinien der Apache Public License, unter Einbettung einer
+entsprechenden „Notice“-Datei kostenlos einsetzbar in kommerziellen und
+nichtkommerziellen Projekten.
+
+== [#anchor-2]####Übersicht von ZUGFeRD-Lösungen
+
+[cols=",,,,,,,,,,,",]
+|===
+| |Plattform |Lizenz |ZF Versionen |Funktionsumfang |Geeignet für |Preis
+| | | | |
+
+|Lesen |XML erzeugen |PDF Schreiben |PDF/A-Umwandlung |Kommerz. Software
+|Freeware |Open Source | | | | |
+
+|intarsys |Java |proprietär |1 |Ja |Ja |Ja |Ja |Ja |Ja |Nein |a.A.
+
+|Konik |Java |AGPL |1 |Ja |Ja |Ja |Nein |Nein |Nein |Ja |0 €
+
+|Mustang |Java |APL |1 |Ja |Ja |Ja |Nein |Ja |Ja |Ja |0 €
+
+|https://github.com/akretion/factur-x |Python |BSD |1,2 |Nein |Nein |Ja
+|Nein |Ja |Ja |Ja |0€
+
+|https://github.com/stephanstapel/ZUGFeRD-csharp |C# |APL |1 |Ja |Ja
+|Nein |Nein |Ja |Ja |Ja |0 €
+|===
+
+== [#anchor-3]####Download/Projekteinrichtung
+
+=== [#anchor-4]####Source code
+
+Heimat der Mustangprojekt-Quelltexte ist
+https://github.com/ZUGFeRD/mustangproject/
+
+=== [#anchor-5]####Projekteinrichtung ohne Maven
+
+Mit installiertem OpenOffice.org oder LibreOffice und Eclipse for Java.
+
+[arabic]
+. Starten Sie Eclipse, Neues Java-Eclipse-Projekt erstellen,
+beispielsweise „MustangSample“.
+. Wechseln Sie in der Shell in den erstellten Ordner.
+. Download von
+[arabic]
+.. Mustang
+[arabic]
+... Downloaden Sie
+http://mustangproject.org/deploy/mustang-1.5.1.jarfootnote:[Falls Sie
+ohnehin PDFBox verwenden (pdfbox, fontbox, preflight, xmpbox sowie deren
+Abhängigkeiten apache-commons-io und apache-commons-logging) können Sie
+auch die wesentlich kleinere
+http://mustangproject.org/deploy/original-mustang-1.5.1.jar verwenden]
+... Downloaden Sie http://mustangproject.org/deploy/NOTICE
+.. Laden Sie
+[arabic]
+... Direkt eine PDF-A/1-Musterrechnung noch ohne
+ZUGFeRD-Mhttp://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-2017]etadaten
+von
+http://www.mustangproject.org/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[1118]http://www.mustangproject.org/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[_50]http://www.mustangproject.org/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[6]http://www.mustangproject.org/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[blanko.pdf]
+herunter.
+... oder erzeugen sich alternativ
+[arabic]
+.... ein eigenes Beispiel-PDF durch Download der Quelldatei im
+OpenOffice.org-Format
+http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20171118_506.odt[http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-]http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20171118_506.odt[20171118_506.odt]
+und
+[arabic]
+..... Öffnen Sie die Datei in OpenOffice.org
+..... Datei|Exportieren als PDF: Wichtig ist hier, dass Sie die Checkbox
+PDF/A-1a setzen
+..... Speichern Sie die PDF-Datei beispielsweise als
+„http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[MustangGnuaccountingBeispiel]http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf[RE-20171118_506blanko.pdf]“
+im MustangSample-Ordner
+. Wechseln Sie zurück zu Eclipse. Fügen Sie durch Rechtsklick auf das
+Projekt („Eigenschaften“) die heruntergeladene JAR-Dateien
+Projekteigenschaften als „externe Jars“ zum „Java Build Path“ Reiter
+„Bibliotheken“ hinzu.
+
+=== [#anchor-6]####Mit Maven
+
+Mit folgendem Repository
+
+
+
+
+
+mustang-mvn-repo
+
+https://raw.github.com/ZUGFeRD/mustangproject/mvn-repo/
+
+
+
+
+
+und folgender Dependency
+
+
+
+org.mustangproject.ZUGFeRD
+
+mustang
+
+1.5.1
+
+
+
+Bei der Gelegenheit kann man auch gleich Apache Commons Logging und JAXB
+importieren:
+
+
+
+commons-logging
+
+commons-logging
+
+1.1.1
+
+
+
+
+
+com.sun.xml.bind
+
+jaxb-impl
+
+2.2.5
+
+
+
+== [#anchor-7]####Lesen von ZUGFeRD-Daten
+
+[arabic]
+. Laden Sie sich eine PDF-Datei mit ZUGFeRD-Daten herunter,
+beispielsweise
+http://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20171118_506.pdf
+. Erstellen Sie eine neue Java-Klasse unterhalb von src, beispielsweise
+MustangReader. inklusive „Public static void main()“
+. Geben Sie innerhalb von Main „ZUGFeRDImporter zi=**new**
+ZUGFeRDImporter();“ ein und lassen Sie den Import durch STRG+SHIFT+O
+ergänzen
+. verwenden Sie zi.extract(PDF-Dateiname) und ggf. canParse() um
+festzustellen ob es sich um ZUGFeRD-Daten handelt.
+. Nach zi.parse() haben Sie Zugriff auf die getter wie getAmount()
+. Welche Daten enthalten sind, können Sie der XML-Datei entnehmen die im
+ZUGFeRD-Beispiel-PDF eingebettet ist
+
+=== [#anchor-8]####Komplettes Lesebeispiel
+
+[arabic, start=7]
+.
+
+*package* sample;
+
+*import* org.mustangproject.ZUGFeRD.ZUGFeRDImporter;
+
+*public* *class* Read \{
+
+*public* *static* *void* main(String[] args) \{
+
+ZUGFeRDImporter zi=**new** ZUGFeRDImporter();
+
+zi.extract("./MustangGnuaccountingBeispielRE-20171118_506.pdf");
+
+System._out_.println("Lese ZUGFeRD");
+
+*if* (zi.canParse()) \{
+
+zi.parse();
+
+System._out_.println("Fälliger Betrag:"+zi.getAmount());
+
+System._out_.println("BIC:"+zi.getBIC());
+
+System._out_.println("IBAN:"+zi.getIBAN());
+
+System._out_.println("Kontoinhaber:"+zi.getHolder());
+
+System._out_.println("Rechnungsnr:"+zi.getForeignReference());
+
+}
+
+}
+
+}
+
+== [#anchor-9]####Schreiben einer ZUGFeRD-PDF-Datei
+
+Ein Beispielprogramm zum Schreiben ist deshalb umfangreicher, weil
+erstens mehr Daten in einer differenzierteren Struktur geschrieben
+werden als derzeit beim Lesen benötigt und zweitens dem Exporter die
+Daten per Interface zur Verfügung gestellt werden müssen.
+
+[arabic]
+. Erstellen Sie eine neue Klasse unterhalb von src, beispielsweise
+MustangWriter inklusive des obligatorischen „Public static void main()“
+.
+. Ändern Sie __*public* *class* MustangWriter __in__ *public* *class*
+MustangWriter *implements* IZUGFeRDExportableTransaction__
+. Fügen Sie innerhalb der Klasse MustangWriter folgende Klassen hinzu
+[arabic]
+.. *class* _Contact_ *implements* IZUGFeRDExportableContact \{}
+.. *class* _Item_ *implements* IZUGFeRDExportableItem \{
+[arabic]
+... _*private* BigDecimal price, quantity;_
+
+*private* Product product;
+
+[arabic, start=4]
+. {blank}
+[arabic]
+.. }
+.. *class* Product *implements* IZUGFeRDExportableProduct \{
+[arabic]
+... *private* String description, name, unit;
+
+*private* BigDecimal VATPercent;
+
+}
+
+[arabic, start=5]
+. Generieren Sie die Imports durch Drücken von STRG+SHIFT+O
+. Markieren Sie den Klassennamen MustangWriter und drücken Sie
+ALT+SHIFT+S, wählen Sie Override/Implement Methods und drücken Return.
+. Klicken Sie auf Contact und Wiederholen Sie den letzten Schritt.
+. Klicken Sie auf Item, markieren Sie die Variablen und wählen Sie
+zuerst „_Generate Getters and Setters_“ nach drücken von ALT+SHIFT+S.
+Wählen Sie alle Member aus und drücken Sie Return.
+. Klicken Sie erneut auf Item, drücken von ALT+SHIFT+S und wählen
+„Generate Constructor using Fields“. Wählen Sie erneut alle Member aus
+und drücken Sie Return.
+. Auf Item muss der Quick Fix „add unimplemented methods“ ausgeführt
+werden, die zwei generierten Funktionen (getItemAllowances und
+getItemCharges) dürfen null zurück geben.
+. Wenden Sie die beiden letzten Schritte auch auf Product an: Klicken
+Sie auf Product, markieren Sie die Variablen und wählen Sie „Generate
+Getters and Setters“ nach drücken von ALT+SHIFT+S. Wählen Sie alle
+Member aus und drücken Sie Return.
+. Item benötigt neben den getter/setter auch noch andere Methode, wählen
+Sie Item aus, drücken Sie ALT+SHIFT+S, wählen Sie Override/Implement
+Methods
+. Klicken Sie erneut auf Product, drücken von ALT+SHIFT+S und wählen
+„Generate Constructor using Fields“. Wählen Sie erneut alle Member aus
+und drücken Sie Return.
+. Folgende Methoden von Contact sollten Folgendes zurückgeben:
+[arabic]
+.. getCountry(): "DE"
+.. getLocation(): "Spielkreis"
+.. getName(): "Theodor Est"
+.. getStreet(): "Bahnstr. 42"
+.. getVATID(): "DE999999999"
+.. getZIP(): "88802";
+. Folgende Methoden der Hauptklasse -MustangWriter- sollten folgendes
+zurückgeben:
+[arabic]
+.. getDeliveryDate(): *new*
+GregorianCalendar(2017,Calendar._NOVEMBER_,17).getTime()
+.. Zweimaliges CTRL+SHIFT+O importiert die dazu nötige GregorianCalendar
+und Calendar Klasse
+.. getDueDate(): *new*
+GregorianCalendar(2017,Calendar._DECEMBER_,9).getTime()
+.. getIssueDate(): *new*
+GregorianCalendar(2017,Calendar._NOVEMBER_,18).getTime()
+.. __getNumber(): "RE-2017__1118__/50__6__"__
+.. _getOwnBIC(): "COBADEFFXXX"_
+.. getOwnBankName(): "Commerzbank"
+.. getOwnCountry() "DE"
+.. getOwnIBAN(): "DE88 2008 0000 0970 3757 00"
+.. getOwnLocation() "Stadthausen"
+.. _getOwnOrganisationName(): "Bei Spiel GmbH"_
+.. getOwnStreet() "Ecke 12"
+.. getOwnTaxID(): "22/815/0815/4"
+.. getOwnVATID(): "DE136695976"
+.. getOwnZIP(): "12345"
+.. getOwnOrganisationFullPlaintextInfo(): "Bei Spiel GmbH\n"+
++
+"Ecke 12\n"+
++
+"12345 Stadthausen\n"+
++
+"Geschäftsführer: Max Mustermann"
+.. _getRecipient(): *new* Contact()_
++
+.. getZFItems() der Hauptklasse kann jetzt Produkte anlegen und diese
+als Array von Posten (Items) zurückliefern:
++
+Item[] allItems=**new** Item[3];
+
+Product designProduct=**new** Product("", "Künstlerische Gestaltung
+(Stunde): Einer Beispielrechnung", "HUR", *new* BigDecimal("7.000000"));
+
+Product balloonProduct=**new** Product("", "Luftballon: Bunt, ca.
+500ml", "C62", *new* BigDecimal("19.000000"));
+
+Product airProduct=**new** Product("", "Heiße Luft pro Liter", "LTR",
+*new* BigDecimal("19.000000"));
+
+allItems[0]=**new** Item(*new* BigDecimal("160"), *new* BigDecimal("1"),
+designProduct);
+
+allItems[1]=**new** Item(*new* BigDecimal("0.79"), *new*
+BigDecimal("400"), balloonProduct);
+
+allItems[2]=**new** Item(*new* BigDecimal("0.10"), *new*
+BigDecimal("200"), airProduct);
+
+*return* allItems;
+
+[arabic]
+.
+
+[arabic]
+. {blank}
+[arabic]
+.. Legen Sie eine neue Funktion, beispielsweise „apply“ an (private
+reicht).
+.. In der Main-Methode der Hauptklasse instantiiert man jetzt die Klasse
+und rufen Sie dort apply() auf.
+.. In der apply-Methode kann man jetzt
+[arabic]
+... eine ZUGFeRDExporterFactory instantiieren,
+... darauf Producer und Creator setzen (bspw. ZUGFeRDExporter ze=new
+ZUGFeRDExporterFromA1Factory().setProducer(_"string"_).setCreator(_"string"_))
+und über load die PDF-A/1-Datei angeben und über den Rückgabewert den
+ZUGFeRDExporter holen. Die ZUGFeRD-Version kann man in der
+setProducer.setCreator-Kette mit setZUGFeRDVersion(2) angeben.
+... Auf dem Exporter ruft man diePDFattachZugferdFile-Methode (mit this
+als IZUGFeRDExportableTransaction) auf und
+... benutzt schlussendlich die export-Funktion. Die apply-Methode sieht
+dann – mit entsprechenden try/catch-Blöcken- beispielsweise so aus:
+
+* try* \{
+
+System._out_.println("Lese Blanko-PDF");
+
+ZUGFeRDExporter ze = *new*
+ZUGFeRDExporterFromA1Factory().setProducer("My
+Application").setCreator(System._getProperty_("user.name")).load("./MustangGnuaccountingBeispielRE-20171118_506blanko.pdf");
+
+System._out_.println("Generiere ZUGFeRD-Daten");
+
+ze.PDFattachZugferdFile(*this*);
+
+System._out_.println("Schreibe ZUGFeRD-PDF");
+
+ze.export("./MustangGnuaccountingBeispielRE-20171118_506new.pdf");
+
+System._out_.println("Fertig.");
+
+} *catch* (IOException e) \{
+
+e.printStackTrace();
+
+}
+
+[arabic, start=2]
+. {blank}
+[arabic]
+.. Ein CTRL+SHIFT+O hilft wieder beim Hinzufügen der nötigen Imports
+.. „My Application“ und __System.getProperty("user.name") __werden in
+den Metadaten als „Producer“ (in etwa: erstellende Anwendung)
+beziehungsweise „Creator“ (in etwa: Autor) gespeichert. Bitte passen Sie
+die Werte entsprechend Ihrer Anwendung an.
+.. Starten Sie, es sollte eine valide ZUFeRD-Rechnung in
+_./MustangGnuaccountingBeispielRE-20171118_506new.pdf_
++
+erstellt werden.
+.. Passen Sie ggf. die NOTICE-Datei an und fügen Sie Ihrer Anwendung
+hinzu.
+.. Stellen Sie sicher, dass die XML-Daten in der dem PDF eingebetteten
+ZUGFeRD-invoice.xml immer den menschenlesbaren Daten im PDF entsprechen.
+
+Die erzeugte Datei beinhaltet ZUGFeRD-invoice.xml statt factur-x.xml im
+offiziellen Beispiel so lange die ZUGFeRD-Version in der Factory nicht
+auf 2 gesetzt wurde.
+
+[arabic]
+.
+
+=== [#anchor-10]####Komplettes Schreibbeispiel
+
+Siehe MustangWriter.java in diesem Verzeichnis.
+
+=== [#anchor-11]####Schreiben eigener XML-Daten
+
+Sollten Sie eine eigene Implementierung verwenden um ZUGFeRD-XML-Daten
+zu erzeugen können Sie diese mit setZUGFeRDXMLData schreiben:
+
+ZUGFeRDExporter ze;
+
+*try* \{
+
+System.*_out_*.println("Konvertiere zu PDF/A-3u");
+
+ze = new
+
+ZUGFeRDExporterFromA1Factory().setProducer("My
+
+Application").setCreator(System._getProperty_("user.name")).load("./MustangGnuaccountingBeispielRE-20171118_506blanko.pdf");
+
+System.*_out_*.println("Hänge ZUGFeRD-Datei an");
+
+String ownZUGFeRDXML =
+"";
+
+ze.setZUGFeRDXMLData(ownZUGFeRDXML.getBytes());
+
+System.*_out_*.println("Schreibe ZUGFeRD-PDF");
+
+ze.export("./Target.pdf");
+
+System.*_out_*.println("Fertig.");
+
+} *catch* (IOException e) \{
+
+e.printStackTrace();
+
+}
+
+Mustangproject prüft, die Eingabedatei auf einigermaßen korrektes PDF/A
+ist und dass die XML-Daten mindestens
+
+ org.mustangproject
+ validator
+ shaded
+ 2.17.0
+
+
+----
+
+Open the Maven Window and click Sync all Maven projects.
+
+== Reading Factur-X/ZUGFeRD data
+
+[arabic]
+. Download a factur-x sample with metadata like
+https://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20201121_508.pdf[https://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20201121_508.pdf]
+. Create a new Maven project. Add the jar in the pom.xml as described above. In
+----
+public class Main {
+public static void main(String[] args) {
+System.out.println("Hello, World!");
+}
+}
+----
+
+use
+
+----
+ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter("MustangGnuaccountingBeispielRE-20201121_508.pdf");
+ CalculatedInvoice ci=new CalculatedInvoice();
+ try {
+ zii.extractInto(ci);
+ System.out.println("Pay: "+ci.getDuePayable());
+ } catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+----
+
+To find out how much you have to pay.
+
+=== Complete sample source code for reading ZUGFeRD data
+
+
+----
+package de.usegroup;
+
+import org.mustangproject.CalculatedInvoice;
+import org.mustangproject.ZUGFeRD.ZUGFeRDInvoiceImporter;
+
+import javax.xml.xpath.XPathExpressionException;
+import java.text.ParseException;
+
+public class Main {
+ public static void main(String[] args) {
+ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter("MustangGnuaccountingBeispielRE-20201121_508.pdf");
+ CalculatedInvoice ci=new CalculatedInvoice();
+ try {
+ zii.extractInto(ci);
+ System.out.println("Pay: "+ci.getDuePayable());
+ } catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
+----
+
+NOTE: You can additionally validate the file with two additional lines
+----
+ ZUGFeRDValidator zv=new ZUGFeRDValidator();
+ System.out.println(zv.validate("MustangGnuaccountingBeispielRE-20201121_508.pdf"));
+----
+
+
+== Writing a ZUGFeRD-PDF file
+
+A sample for writing Factur-X/ZUGFeRD PDFs requires a PDF/A file to attach the XML to,
+saved
+e.g. as link:https://www.mustangproject.org/files/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf[blanko.pdf]
+
+The core is creating an exporter, an invoice and send the invoice through the exporter:
+----
+ IZUGFeRDExporter ze = new ZUGFeRDExporterFromPDFA().load(sourcePDF).setProducer("My Application").
+ setCreator(System.getProperty("user.name"));
+
+ Invoice i=new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
+ .setSender(new TradeParty("ACME co", "teststr", "55232", "teststadt", "DE")
+ .addBankDetails(new BankDetails("777666555", "DE4321"))).setOwnTaxID("4711").setOwnVATID("DE19990815")
+ .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")
+ .setContact(new Contact("nameRep", "phoneRep", "emailRep@test.com"))).setNumber("X12")
+ .addItem(new Item(new Product("Testproduct", "", "H87", new BigDecimal(19)),
+ new BigDecimal(2.5), new BigDecimal(1.0)));
+ ze.setTransaction(i);
+ ze.export("factur-x.pdf");
+----
+Additionally, you should confirm that Mustangs calculated total matches that of your PDF/A file, for which you can use
+the TransactionCalculator (which is also used internally in the exporter):
+
+----
+ TransactionCalculator tc=new TransactionCalculator(i);
+ System.out.println("Confirm "+tc.getDuePayable()+ " is also the final amount in your PDF");
+----
+
+NOTE: We're using BigDecimals to avoid rounding errors.
+
+So the complete write example looks like this:
+----
+package de.usegroup;
+
+import org.mustangproject.*;
+import org.mustangproject.ZUGFeRD.IZUGFeRDExporter;
+import org.mustangproject.ZUGFeRD.TransactionCalculator;
+import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromPDFA;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.Date;
+
+public class Main {
+ public static void main(String[] args) {
+
+ String sourcePDF="MustangGnuaccountingBeispielRE-20201121_508.pdf";
+ try {
+ IZUGFeRDExporter ze = new ZUGFeRDExporterFromPDFA().load(sourcePDF).setProducer("My Application").
+ setCreator(System.getProperty("user.name"));
+
+ Invoice i=new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
+ .setSender(new TradeParty("ACME co", "teststr", "55232", "teststadt", "DE")
+ .addBankDetails(new BankDetails("777666555", "DE4321"))).setOwnTaxID("4711").setOwnVATID("DE19990815")
+ .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")
+ .setContact(new Contact("nameRep", "phoneRep", "emailRep@test.com"))).setNumber("X12")
+ .addItem(new Item(new Product("Testproduct", "", "H87", new BigDecimal(19)),
+ new BigDecimal(2.5), new BigDecimal(1.0)));
+ ze.setTransaction(i);
+ ze.export("factur-x.pdf");
+ TransactionCalculator tc=new TransactionCalculator(i);
+ System.out.println("Confirm "+tc.getDuePayable()+ " is also the final amount in your PDF");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
+----
diff --git a/doc/ZugferdDev.en.pdf b/doc/ZugferdDev.en.pdf
index a16e3e9c..c8c206a5 100644
Binary files a/doc/ZugferdDev.en.pdf and b/doc/ZugferdDev.en.pdf differ