mustangproject

repository·master·Indexed 19 days ago

https://github.com/zugferd/mustangproject

An open-source Java library for reading and writing electronic invoice metadata in the ZUGFeRD format embedded within PDF documents. It includes ZUV (ZUgferd+[VeraPDF]), an e-invoice validator for ZUGFeRD and Factur-X standards that checks PDF/A-3 compliance and XML correctness against official schematron files.

Tokens
7.5K
Snippets
28
Records
34
Agent score
66%

What's inside mustangproject

  1. What is ZUV?

    master

    ZUV (ZUgferd+[VeraPDF]) is an open-source e-invoice validator for the ZUGFeRD and Factur-X standards. It performs two main types of checks:

    1. PDF/A-3 Compliance: Uses VeraPDF to ensure the PDF container meets requirements.
    2. XML Correctness: Validates ZUGFeRD version 1 and version 2/2.1 XMLs against official ZUGFeRD schematron files and the EN16931 UN/CEFACT SCRDM v16B uncoupled schematron from CEN.
  2. Understand ZUV validation output format

    master

    ZUV outputs its results in an XML format. The structure contains <pdf>, <xml>, and a top-level <summary> tag.

    • Valid files: The <summary status="..."> tags for pdf, xml, and the root element will all be valid.
    • Invalid files: The <summary> tags will indicate invalid, and the <xml> section will contain a <messages> block detailing the specific errors. Each error includes a type, location (XPath), and a criterion explaining why the rule failed.
  3. Read ZUGFeRD data from a PDF

    master

    To extract ZUGFeRD metadata from a PDF file, use the ZUGFeRDImporter class.

    1. Instantiate ZUGFeRDImporter.
    2. Call extract(String filename) to load the file.
    3. Use canParse() to verify if the PDF contains ZUGFeRD data.
    4. Call parse() to process the data.
    5. Access metadata using getter methods like getAmount(), getBIC(), getIBAN(), getHolder(), and getForeignReference().
    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());
            }
        }
    }
  4. Read Factur-X/ZUGFeRD data from a PDF

    master

    Use ZUGFeRDInvoiceImporter to extract invoice metadata from a PDF file into a CalculatedInvoice object. This allows you to programmatically access invoice details such as the amount due payable.

    Note that extractInto may throw XPathExpressionException or ParseException.

    ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("path/to/invoice.pdf");
    CalculatedInvoice ci = new CalculatedInvoice();
    try {
        zii.extractInto(ci);
        System.out.println("Pay: " + ci.getDuePayable());
    } catch (XPathExpressionException | ParseException e) {
        throw new RuntimeException(e);
    }
  5. Install a local JAR for testing in other projects

    master

    If you have added new functionality and want to test it in a separate project before a formal release, you can install a specific JAR (e.g., a shaded validator JAR) into your local Maven cache.

    For Maven projects:

    cd validator/target
    ./mvnw install:install-file -Dfile="validator-2.17.0-SNAPSHOT-shaded.jar" -Dclassifier=shaded -DgroupId="org.mustangproject" -DartifactId=validator -Dversion="2.17.0" -Dpackaging=jar -DgeneratePom=true

    For Gradle projects: Use the files dependency syntax:

    implementation files('libs/validator-2.17.0-shaded.jar')
    cd validator/target
    ./mvnw install:install-file -Dfile="validator-2.17.0-SNAPSHOT-shaded.jar" -Dclassifier=shaded -DgroupId="org.mustangproject" -DartifactId=validator -Dversion="2.17.0" -Dpackaging=jar -DgeneratePom=true
  6. Install Mustangproject via Maven

    master

    To use Mustangproject in a Maven project, add the following repository and dependency to your pom.xml. It is also recommended to include commons-logging and jaxb-impl for full compatibility.

    <repositories>
      <repository>
        <id>mustang-mvn-repo</id>
        <url>https://raw.github.com/ZUGFeRD/mustangproject/mvn-repo/</url>
      </repository>
    </repositories>
    
    <dependencies>
      <dependency>
        <groupId>org.mustangproject.ZUGFeRD</groupId>
        <artifactId>mustang</artifactId>
        <version>1.5.1</version>
      </dependency>
      <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>
    </dependencies>
  7. Run ZUV to validate ZUGFeRD files

    master

    To check a file for ZUGFeRD conformance, use the java -jar command with the --action validate flag.

    You can provide either:

    • A complete PDF file: The validator will check both the XML content and the PDF/A compliance.
    • An XML file: The validator will only check the XML correctness.
    java -jar ZUV-0.9.0.jar --action validate -f <filename of ZUGFeRD PDF.pdf>
  8. Write ZUGFeRD data to a PDF

    master

    To write ZUGFeRD data into a PDF, you must implement the IZUGFeRDExportableTransaction interface. This requires providing structured data through several sub-interfaces: IZUGFeRDExportableContact, IZUGFeRDExportableItem, and IZUGFeRDExportableProduct.

    Workflow:

    1. Create a class implementing IZUGFeRDExportableTransaction.
    2. Implement the required methods for contact info, items, and products.
    3. Use ZUGFeRDExporterFromA1Factory to create an exporter.
    4. Configure the exporter with setProducer(String) and setCreator(String).
    5. Load the base PDF/A-1 file using load(String filename).
    6. Attach your data using PDFattachZugferdFile(IZUGFeRDExportableTransaction).
    7. Export the final file using export(String filename).
    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); // 'this' must implement IZUGFeRDExportableTransaction
    
        System.out.println("Schreibe ZUGFeRD-PDF");
        ze.export("./MustangGnuaccountingBeispielRE-20171118_506new.pdf");
        System.out.println("Fertig.");
    } catch (IOException e) {
        e.printStackTrace();
    }
  9. Embed ZUV in your application

    master

    You can integrate ZUV into your software by either embedding it as a Java library or by executing the JAR via a system call and parsing the XML output.

    When using exec to run the JAR, it is recommended to:

    1. Use -Dfile.encoding=UTF-8 to ensure XML files with BOM are handled correctly.
    2. Redirect stderr to /dev/null to prevent logging messages from corrupting the XML output.
    3. Escape filenames to handle spaces and security concerns.
    exec('java -Dfile.encoding=UTF-8 -jar /path/to/ZUV-0.9.0.jar --action validate -f '.escapeshellarg($uploadfile).' 2>/dev/null', $output);
  10. Add Mustangproject to a Maven project

    master

    To use Mustangproject in your Java application, add the validator artifact to your pom.xml. It is recommended to use the shaded classifier to ensure all necessary dependencies are bundled within the artifact.

    Note: Ensure you check the latest version available, as the example below uses 2.25.0.

    <dependency>
        <groupId>org.mustangproject</groupId>
        <artifactId>validator</artifactId>
        <version>2.25.0</version>
        <classifier>shaded</classifier>
    </dependency>
  11. Write a ZUGFeRD-compliant PDF

    master

    To create a ZUGFeRD PDF, you must start with an existing PDF/A file. The process involves:

    1. Initializing a ZUGFeRDExporterFromPDFA and loading your source PDF.
    2. Constructing an Invoice object with details like TradeParty (sender/recipient), BankDetails, TaxID, and line Items.
    3. Setting the invoice as the transaction in the exporter.
    4. Calling export("filename.pdf") to generate the new file.

    It is recommended to use BigDecimal for all monetary values to avoid rounding errors.

    // 1. Setup Exporter
    IZUGFeRDExporter ze = new ZUGFeRDExporterFromPDFA()
        .load(sourcePDF)
        .setProducer("My Application")
        .setCreator(System.getProperty("user.name"));
    
    // 2. Build Invoice
    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)));
    
    // 3. Export
    ze.setTransaction(i);
    ze.export("factur-x.pdf");