UBL 2.1 pour la facturation
Comment est assemblée une facture OASIS Universal Business Language : les espaces de noms qui l’identifient, les structures qui portent les parties, les lignes et la TVA, et les points où les implémentations se trompent le plus souvent.
Ce qu’est UBL
UBL est une norme de l’OASIS qui définit des documents XML pour les processus commerciaux : commandes, avis d’expédition, factures et bien d’autres. La version 2.1 est celle sur laquelle repose la facturation électronique européenne : c’est la syntaxe de Peppol BIS Billing 3.0 et l’une des deux syntaxes dans lesquelles EN 16931 peut être exprimée, l’autre étant UN/CEFACT CII.
Une facture UBL est un arbre d’éléments typés. Le schéma ne laisse aucune latitude pour inventer ses propres champs : ce que l’on peut exprimer est ce que la norme définit, et des profils comme Peppol restreignent encore davantage.
Espaces de noms
Quatre URI d’espaces de noms comptent pour la facturation. Ce sont ces URI — et non les préfixes qu’on leur associe par convention — qui identifient un élément.
urn:oasis:names:specification:ubl:schema:xsd:Invoice-2— la racine du document Invoice.urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2— la racine du document CreditNote.urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2— les structures, conventionnellementcac.urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2— les valeurs terminales, conventionnellementcbc.
Le mot conventionnellement a ici un sens précis. Un préfixe est un alias local au document. Une facture qui déclare xmlns:foo="…CommonBasicComponents-2" et écrit <foo:ID> est exactement aussi valide qu’une facture écrivant <cbc:ID>, tout comme celle qui fait de cet espace de noms l’espace par défaut et écrit <ID>. Tout outil qui recherche la chaîne cbc: échouera sur des documents conformes. C’est de loin le défaut le plus répandu dans les analyseurs UBL faits maison.
Squelette du document
Une facture UBL conforme à EN 16931 présente cet ordre au premier niveau :
cbc:CustomizationID,cbc:ProfileID— la spécification et le processus que le document déclare suivre.cbc:ID,cbc:IssueDate,cbc:DueDate,cbc:InvoiceTypeCode,cbc:DocumentCurrencyCode,cbc:BuyerReference— l’en-tête.cac:AccountingSupplierParty,cac:AccountingCustomerParty, et le cas échéantcac:PayeePartyetcac:TaxRepresentativeParty.cac:Delivery,cac:PaymentMeans,cac:PaymentTerms.cac:AllowanceCharge— remises et majorations au niveau du document.cac:TaxTotal— la ventilation de TVA.cac:LegalMonetaryTotal— les totaux.cac:InvoiceLine— une par ligne, en dernier.
Notez que les totaux viennent avant les lignes. C’est déroutant lorsqu’on lit un document brut pour la première fois.
Les parties
Un cac:Party répartit l’identité entre plusieurs enfants, qui n’ont pas le même sens :
cac:PartyName/cbc:Name— le nom commercial.cac:PartyLegalEntity/cbc:RegistrationName— la raison sociale enregistrée, aveccbc:CompanyIDpour le numéro d’immatriculation etcbc:CompanyLegalFormpour les mentions légales complémentaires.cac:PartyTaxScheme/cbc:CompanyIDavec uncac:TaxScheme/cbc:IDimbriqué valantVAT— le numéro de TVA.cbc:EndpointIDavec unschemeID— l’adresse électronique utilisée pour l’acheminement, par exemple un identifiant de participant Peppol.cac:PartyIdentification/cbc:ID— tout autre identifiant, avec son schéma.cac:PostalAddressetcac:Contact.
Réduire tout cela à un seul « nom » et un seul « numéro fiscal » fait perdre de l’information. Le visualiseur UBL les distingue.
Les lignes
Chaque cac:InvoiceLine porte un cbc:InvoicedQuantity avec un attribut unitCode (recommandation 20 de l’UN/ECE), un cbc:LineExtensionAmount pour le montant net de la ligne, un cac:Item décrivant ce qui a été fourni, et un cac:Price donnant le prix unitaire et sa quantité de base.
Le taux de TVA d’une ligne ne figure pas sur la ligne elle-même mais dans cac:Item/cac:ClassifiedTaxCategory, qui porte le code de catégorie, le pourcentage et le régime de taxe. Un prix brut s’exprime indirectement : UBL n’a pas d’élément de prix brut, de sorte qu’un prix remisé apparaît comme un cac:Price/cac:AllowanceCharge dont le cbc:BaseAmount est le prix avant remise.
TVA et totaux
cac:TaxTotal porte le montant total de taxe et un cac:TaxSubtotal par combinaison de catégorie et de taux de TVA, chacun avec sa base taxable, son montant de taxe, son code de catégorie, son pourcentage et — lorsque la catégorie l’exige — un motif d’exonération. Un document peut porter un second cac:TaxTotal exprimant la même taxe dans la devise comptable.
cac:LegalMonetaryTotal donne ensuite l’arithmétique du document :
cbc:LineExtensionAmount— la somme des montants nets de lignes.cbc:AllowanceTotalAmount,cbc:ChargeTotalAmount.cbc:TaxExclusiveAmount— la base taxable.cbc:TaxInclusiveAmount— la base plus la TVA.cbc:PrepaidAmount,cbc:PayableRoundingAmount.cbc:PayableAmount— le montant réellement dû.
Les relations entre ces montants sont précisément ce que vérifient les règles BR-CO-* d’EN 16931. Un document peut être conforme au schéma et les enfreindre.
Là où les implémentations se trompent
- Filtrer sur les préfixes. Le point est traité plus haut, et mérite d’être répété : c’est la panne qui produit le fameux « ça marche avec nos fichiers, pas avec les leurs ».
- Chercher dans les descendants plutôt que dans les enfants. Une recherche non restreinte de
Namedepuis la racine trouvera la première partie apparaissant dans le fichier, qui n’est pas nécessairement le fournisseur. - Supposer que la devise figure sur chaque montant. En UBL, la plupart des montants portent bien
currencyID, mais un code qui l’exige échouera sur les documents qui s’appuient surcbc:DocumentCurrencyCode. - Analyser les montants avec un analyseur numérique localisé. Les décimaux XSD utilisent le point et aucun séparateur de milliers. Un analyseur qui accepte
1.234,56produira un nombre qui ne figure pas dans le document.
Essayer
Ouvrez un document dans le visualiseur UBL pour voir ces structures résolues, avec le XML brut et le modèle analysé côte à côte. Pour le modèle sémantique que mettent en œuvre UBL et CII, voyez EN 16931 ; pour l’autre syntaxe, voyez UN/CEFACT CII.
Questions fréquentes
Quelle est la différence entre cac et cbc ?
Ce sont deux espaces de noms, et non deux niveaux d’importance. Les Common Basic Components (cbc) portent des valeurs terminales : un identifiant, une date, un montant. Les Common Aggregate Components (cac) portent des structures qui contiennent d’autres éléments, comme une Party ou une InvoiceLine. Les préfixes cac et cbc sont des conventions ; seules les URI des espaces de noms sont normatives.
Une Invoice et une CreditNote sont-elles le même document en UBL ?
Non. Ce sont deux types de documents distincts, avec des espaces de noms racines distincts (…:xsd:Invoice-2 et …:xsd:CreditNote-2) et des éléments de ligne différents : cac:InvoiceLine avec cbc:InvoicedQuantity d’un côté, cac:CreditNoteLine avec cbc:CreditedQuantity de l’autre. Certains profils expriment plutôt un avoir sous forme d’Invoice portant le code de type 381 et des montants négatifs : les deux usages existent en pratique.
Que signifie CustomizationID ?
C’est l’identifiant de la spécification que le document déclare suivre — par exemple une URN Peppol BIS Billing 3.0 ou une URN EN 16931 simple. Il s’agit d’une déclaration de l’émetteur, non d’une preuve de conformité. Valider un document consiste à exécuter le jeu de règles que cet identifiant désigne, ce qui est une étape distincte.