Updated tutorial in EN

This commit is contained in:
jstaerk
2025-06-03 09:00:04 +02:00
parent 78861ef0b0
commit 046bc098bf
5 changed files with 629 additions and 278 deletions

View File

@@ -34,7 +34,7 @@ If you set up a Maven project, you can reference the mustang artifact like this:
<dependency>
<groupId>org.mustangproject</groupId>
<artifactId>validator</artifactId>
<version>2.15.0</version>
<version>2.17.0</version>
<classifier>shaded</classifier>
</dependency>
```

View File

@@ -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;
}
}

446
doc/ZugferdDev.de.adoc Normal file
View File

@@ -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
<repositories>
<repository>
<id>mustang-mvn-repo</id>
<url>https://raw.github.com/ZUGFeRD/mustangproject/mvn-repo/</url>
</repository>
</repositories>
und folgender Dependency
<dependency>
<groupId>org.mustangproject.ZUGFeRD</groupId>
<artifactId>mustang</artifactId>
<version>1.5.1</version>
</dependency>
Bei der Gelegenheit kann man auch gleich Apache Commons Logging und JAXB
importieren:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.5</version>
</dependency>
== [#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 =
"<rsm:CrossIndustryDocument></rsm:CrossIndustryDocument>";
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 <rsm:CrossIndustry enthalten was
auf ZF1- (CrossIndustryDocument) und ZF2-Daten (CrossIndustryInvoice)
zutrifft.
=== [#anchor-12]####Zusatzfunktionen
* ZUGFeRDExporter.setTest() setzt ein Attribut im ZUGFeRD-XML, das
benutzt wird um eine Testrechnung auszuzeichnen.
* ZUGFeRDExporter.ignoreA1Errors() überspringt die Überprüfung der
Eingangsdatei auf PDF/A-1-Fehler
* Ein erster Versuch bestehendes ZUGFeRD1-XML in 2 zu konvertieren kann
mit String facturx=new
ZUGFeRDMigrator().migrateFromV1ToV2(zugferdInvoice); begonnen werden.

182
doc/ZugferdDev.en.adoc Normal file
View File

@@ -0,0 +1,182 @@
== Mustang project user documentation
Jochen Stärk
For Mustangproject 2.17.0, 2025-05-28
http://www.mustangproject.org/[http://www.mustangproject.org]
== About Mustangproject
Mustangproject is a Java-Library for invoice („Factur-X/ZUGFeRD“-)metadata in
PDF-invoices as well as XRechnung (CII, or on the reading side also UBL).
It can read, write and validate those files uses PDF/A files as
input, underlies the Apache Public License and can
be used for free in commercial and noncommercial projects as long as
the license conditions are met.
On link:https://zugferd.org/[zugferd.org] we list other libraries also for other
languages
== Download/Project setup
=== Source code
Home of the Mustangproject source code is
https://github.com/ZUGFeRD/mustangproject/
=== With Maven
E.g. using link:https://www.jetbrains.com/idea/download/?section=windows[IntelliJ].
Add the following dependency to your project
----
<dependencies>
<dependency>
<groupId>org.mustangproject</groupId>
<artifactId>validator</artifactId>
<classifier>shaded</classifier>
<version>2.17.0</version>
</dependency>
</dependencies>
----
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();
}
}
}
----

Binary file not shown.