E-invoicing concepts
A short map of the standards this library implements and the words the rest of the documentation uses: business terms, UBL, CIUS and customization ids, and the rule families.
EN 16931: business terms and rules
EN 16931-1 is the European standard for the content of an electronic invoice. It names each piece of information a business term with an id: BT-1 is the invoice number, BT-131 the net amount of a line. Related terms form business groups: BG-4 is the seller, BG-25 an invoice line. The standard also defines business rules an invoice must satisfy, such as BR-CO-10: the sum of the line net amounts (BT-106) equals the sum of the lines' BT-131.
UBL: the syntax
EN 16931 is bound to two XML syntaxes, and Peppol uses UBL 2.1. A UBL invoice is an Invoice (or CreditNote) element holding cbc: basic elements and cac: aggregates. The model of this library follows the syntax: cac:AccountingSupplierParty is accountingSupplierParty, cbc:ID is id, and an element that may repeat is an array. Business terms maps every BT and BG id to its property, and the documentation of each property names its id.
CIUS, Peppol and the customization id
A CIUS (core invoice usage specification) narrows EN 16931 for a community of users. Peppol BIS Billing 3.0 is the CIUS of the Peppol network: it adds rules and code lists of its own.
A document states the specification it follows in cbc:CustomizationID (BT-24). A CIUS built on another keeps the id it builds on and appends its own, so an extension of Peppol starts with the Peppol id. cbc:ProfileID (BT-23) names the business process. Peppol knows two, billing (01) and billing with response (02); any other profile id, the French ones included, is unknown to the Peppol rules and fails PEPPOL-EN16931-R007.
const profiles = Object.keys(PROFILE_IDS);
// ['urn:fdc:peppol.eu:2017:poacc:billing:01:1.0', 'urn:peppol:bis:billing_with_response']Rule families
| Ids | What they check | Ruleset |
|---|---|---|
BR-*, BR-CO-*, BR-CL-*, BR-DEC-* | EN 16931 business rules: presence, calculations, codes, decimals | en16931Ruleset |
BR-S-*, BR-Z-*, BR-E-*, BR-AE-*, ... | EN 16931 rules per VAT category | en16931Ruleset |
UBL-CR-*, UBL-SR-*, UBL-DT-* | The UBL syntax binding: unused elements, repetitions, attributes | the parser, and en16931Ruleset where the model shows it |
PEPPOL-EN16931-*, PEPPOL-COMMON-* | Peppol rules, code lists and identifier checks | peppolRuleset |
DK-R-* | Danish national rules | dkRuleset |
EINV-* | This library's own diagnostics: XML it cannot read, XSD lexical errors, a rule that crashed | always |
Every rule of the specification, with its message, is in the rule index.
Which rules run by default
When you do not pass a ruleset, validate() picks one from the document's customization id. A Peppol id, or an id that starts with it, gets EN 16931 and Peppol; any other id, or none, gets EN 16931 alone, so a plain EN 16931 invoice gets no Peppol noise and a document without BT-24 still gets its BR-01:
const ids = (customizationId: string) =>
resolveDocumentRuleset({ kind: 'Invoice', customizationId }).map((ruleset) => ruleset.id);
const peppol = ids(PEPPOL_BIS_BILLING_3_CUSTOMIZATION_ID); // ['en16931', 'peppol']
const suffixed = ids(`${PEPPOL_BIS_BILLING_3_CUSTOMIZATION_ID}#conformant#urn:example:cius`); // ['en16931', 'peppol']
const plain = ids('urn:cen.eu:en16931:2017'); // ['en16931']National rules are opt-in
The official Peppol validator applies national rules by the supplier's country. This library never adds them on its own: without dkRuleset in the list, validate() can accept an invoice from a Danish supplier that the Peppol network rejects. Version 0.1.0 implements the Danish rules only. The German, Greek, Icelandic, Italian, Dutch, Norwegian and Swedish rules are not implemented yet.
Spain has no national rule pack in Peppol: a Spanish invoice is validated with EN 16931, and with Peppol when it declares the Peppol id. Rulesets and extensions shows how to choose the rules yourself.