Internes Format

Die interne verwendete Datenstruktur ist fast identisch zu der von Peppol UBL-Rechnungen. Aus ihm können alle unterstützten Ausgabeformate erzeugt werden.

Weshalb ein internes Format?

Daten im internen Format sind Ausgangspunkt für die Generierung von E-Rechnungen in allen unterstützten Ausgabeformaten. Dadurch brauchen sich Benutzerinnen und Benutzer der Software nicht mit allen Details anderer Formate beschäftigen und können sich dadurch auf lediglich eins fokussieren.

Weshalb UBL?

Tatsächlich gibt es gerade einmal zwei mögliche Syntaxen für E-Rechnungen, die dem Europäischen Standard EN16931 entsprechen, nämlich UBL und CII. UBL wurde gewählt, weil die Syntax gut dokumentiert und im Vergleich zu CII weniger komplex ist.

Nachteil der Sache ist, dass es zur Zeit nicht möglich ist, Informationen zu übermitteln, die in CII aber nicht in UBL vorgesehen sind. Das kann sich möglicherweise in der Zukunft noch ändern.

UBL vs. Peppol UBL

Mit der Universal Business Language UBL kann eine Vielzahl von Geschäftsdokumenten ausgedrückt werden. Eine dieser Dokumenttypen sind UBL-Rechnungen. Der UBL-Standard wird von der Organisation OASIS Open gepflegt.

Peppol (Pan-European Public Procurement OnLine) ist eine Initiative der Europäischen Union, die die Standardisierung grenzüberschreitender Beschaffungsprozesse zum Zeil hat. Peppol gibt die Business Interoperability Specifications (BIS), aktuell in der Version 3.0 heraus. Eine dieser Spezifikationen ist die für UBL-Rechnungen.

Die Spezifikation basiert auf der obengenannten UBL-Spezifikation von OASIS Open ist aber nicht identisch. Diese Dokumente bezeichnet daher die Peppol-BIS UBL-Rechnungen als Peppol UBL.

Struktur der Peppol-UBL-Dokumentation

Die Dokumentation der UBL-Rechnung steht sowohl als einzelne HTML-Seite als auch als mehrseitiger, klilckbarer Baum zur Verfügung.

Die Einzelseite eignet sich gut zum Suchen, während die mehrseitige Version leichter zu benutzen und zu verstehen ist.

Document Object Model (DOM)

Da es sich bei UBL um ein XML-Format handelt, ist das zugrundeliegende Denkmodell das Document Object Model (DOM). Die Software E-Invoice-EU setzt allerdings stattdessen auf JSON. Der wichtigste strukturelle Unterschied zu XML - jedenfalls im Kontext von Peppol UBL - ist die Verfügbarkeit von Arrays (Listen) in JSON.

Knoten und Blätter

Die Struktur von Peppol UBL besteht aus Knoten, also Elementen, die Unterelemente haben und Blättern, also Elementen, die keine Unterelemente haben.

Nodes have a namespace prefix of cac, for example the element cac:AccountingSupplierParty which describes the issuer of an invoice. Inside that definition we find the postal address of the supplier and the city part cbc:CityName is a leaf because it does not contain sub-elements. As all other leafs, it has a namespace prefix of cbc.

Kardinalität

The Peppol UBL documentation specifies a cardinality of each element. The cardinality describes how many occurences of a certain element are allowed at a certain location. The cardinality is specified as two integers separated by two dots, for example 0..2. The first number specifies the minimum number of occurences and the higher number specifies the maximum number of occurrences. If the higher number is the letter n, as for example in 0..n, there can be an arbitrary number of occurences.

Die folgende Tabelle listet typische Kardinalitäten auf.

Cardinality Meaning
1..1 A mandatory element, for example the amount due of an invoice.
0..1 An optional element, for example an advance payment.
1..n A mandatory list with an unlimited number of elements, for example the line items resp. invoice positions
0..n An optional list with an unlimited number of elements, for example the charges and allowances on document level
1..2 A mandatory list with a maximum of 2 elements, for example the tax total
0..2 An optional list with a maximum of 2 elements, for example the party tax scheme

Daumenregeln: Ist die erste Zahl 0 handelt es sich um ein optionales Element, ansonsten ist es obligatorisch, also ein Pflichtelement. Ist die zweite Zahl größer oder gleich 2 oder ist sie n, haben wir es mit einer Liste zu tun.

Attribute

XML-Elemente können Attribute besitzen, welche den Wert des Elements weiter beschreiben. Zum Beispiel hat die fällige Summe einer Rechnung das obligatorische Attribut @currencyID, das die abgekürzte Währungsbezeichnung der Summe angbit. In der Spalte „Use“ des Abschnitts „attributes“ in der Dokumentation gibt der Buchstabe M an, dass es sich um ein obligatorisches Attribut handelt, es also angegeben werden muss.

The company id has an optional attribute schemeID. This is indicated by the letter O in the column "Use".

Code-Listen

Many fields cannot have arbitrary values but there a restricted to a choice from a list. These lists are called code lists. The amount due of an invoice for example needs a currency id and the corresponding attribute @currencyID is restricted to the code list ISO 4217 Currency codes. You can get the relevant information by clicking on the element's or attribute's name, and then on the code list name in the section "Code lists". The code list page itself lists the possible values in the section "Codes". You often have to scroll down a little bit to get to the list of values.

Transformierung von XML zu JSON

Weil E-Invoice-EU JSON und nicht XML benutzt, muss das Peppol UBL in JSON transformiert werden.

Grundsätzliches Vorgehen

Die Transformation von XML nach JSON in E-Invoice-EU ist logisch und unkompliziert, und schwerer zu erklären als zu verstehen.

Die XML-Struktur wird durch die Befolgung einfacher Regeln vorgenommen:

  1. Elemente werden JSON-Schlüssel – Jedes XML-Element wird durch einen Schlüssel im JSON-Objekt repräsentiert.
  2. Die Verschachtelungstiefe wird bewahrt - Enthält ein Element Unterelemente, wird es ein Objekt mit diesen Elementen als Eigenschaften (properties).
  3. Textwerte werden Strings - Enthält ein Element nur Text, wird der Text zum Wert für den entsprechenden Schlüssel.

Die Angabe des Namens der Ausstellerin einer Rechnung im folgenden unvollständige Fragment einer UBL-Rechnung als XML-Dokument mag das verdeutlichen:

<ubl:Invoice>
    <cac:AccountingSupplierParty>
        <cac:Party>
            <cbc:PartyName>
                Acme Ltd.
            </cbc:PartyName>
        </cac:Party>
    </cac:AccountingSupplierParty>
</ubl:Invoice>

In JSON stellt sich der gleiche Sachverhalt so dar:

{
    "ubl:Invoice": {
        "cac:AccountingSupplierParty": {
            "cac:Party": {
                "cbc:PartyName": "Acme Ltd."
            }
        }
    }
}

Jedes XML-Element wird eine Eigenschaft des JSON-Objekts und die Hierarchie bleibt unverändert. Der Textinhalt von <cbc:PartyName wird zur Zeichenkette „Acme Ltd.“ in JSON.

Listen/Arrays

In XML fehlt das Konzept von Listen bzw. Arrays. Stattdessen werden Elemente einfach wiederholt. Das lässt sich an Rechnungspositionen zeigen:

<ubl:Invoice>
    <cac:InvoiceLine>
        <cbc:ID>1</cbc:ID>
        <cbc:AccountingCost>100:1</cbc:AccountingCost>
    </cac:InvoiceLine>
    <cac:InvoiceLine>
        <cbc:ID>2</cbc:ID>
        <cbc:AccountingCost>200:2</cbc:AccountingCost>
    </cac:InvoiceLine>
    <cac:InvoiceLine>
        <cbc:ID>3</cbc:ID>
        <cbc:AccountingCost>300:3</cbc:AccountingCost>
    </cac:InvoiceLine>
</ubl:Invoice>

Es gibt drei Element cac:InvoiceLine. Es handelt sich also um eine Liste.

Die Transformierung nach JSON ist logisch:

{
    "ubl:Invoice": {
        "cac:InvoiceLine": [
            {
                "cbc:ID": "1",
                "cbc:AccountingCost": "100:1",
            },
            {
                "cbc:ID": "2",
                "cbc:AccountingCost": "200:3",
            },
            {
                "cbc:ID": "3",
                "cbc:AccountingCost": "300:3",
            },
        ]
    }
}

Weil cac:InvoiceLine ein Array ist (es hat eine Kardinalität von 1..n), wird es auch in JSON als Array dargestellt. Und die Listenelemente sind einfach die Unterknoten von cac:InvoiceLine.

Attribute

Einige Elemente haben Attribute:

<ubl:Invoice>
    <cac:LegalMonetaryTotal>
        <cbc:PayableAmount currencyID="EUR">23.04</cbc:PayableAmount>
    </cac:LegalMonetaryTotal>
</ubl:Invoice>

JSON kennt keine Attribute. Stattdessen wird an den Namen des Elements ein Klammeraffer @ und der Name des Attributs angehangen:

{
    "ubl:Invoice": {
        "cac:LegalMonetaryTotal": {
            "cbc:PayableAmount": "23.04"
            "cbc:PayableAmount@currencyID": "EUR"
        }
    }
}

Nicht-String-Werte

Please note that strings must be used for all values, even if they are numbers. Check the above examples for that.

Validierung

Es ist nicht wichtig, sich exakt an alle Details zu erinnern. Der Service steigt mit einer Fehlermeldung aus, wenn die Struktur der Eingabedaten nicht dem Schema entsprechen.

JSON-Schema

Wer mit JSON Schema vertraut ist, kann auch auf die Schemadefinition zurückgreifen. Sie ist im GitHub-Repository E-Invoice-EU oder als REST-Endpunkt /api/schema/invoice verügbar.

Unterschiede zu Peppol UBL

Die einzigen Unterschiede zu Peppol UBL sind zur Zeit, dass die Felder cbc:CustomizationID und cbc:ProfileID optional sind. Der Grund dafür ist, dass sie aus dem Ausgabeformat geschlossen werden können. Sie müssen nur angegeben werden, wenn man die eingebauten Vorgabewerte für sie überschreiben will.

Diese Website verwendet Cookies und ähnliche Technologien, um gewisse Funktionalität zu ermöglichen, die Benutzbarkeit zu erhöhen und Inhalt entsprechend ihren Interessen zu liefern. Über die technisch notwendigen Cookies hinaus können abhängig von ihrem Zweck Analyse- und Marketing-Cookies zum Einsatz kommen. Sie können ihre Zustimmung zu den vorher erwähnten Cookies erklären, indem sie auf "Zustimmen und weiter" klicken. Hier können sie Detaileinstellungen vornehmen oder ihre Zustimmung - auch teilweise - mit Wirkung für die Zukunft zurücknehmen. Für weitere Informationen lesen sie bitte unsere Datenschutzerklärung.