← Back to the report

How the EN 16931 code lists are compared

Unofficial showcase. The authoritative code lists and validation artefacts are those the European Commission publishes in its Registry of supporting artefacts to implement EN16931; where the report differs, the Registry prevails.

An invoice following EN 16931 may only use the codes of the published code lists: currencies, countries, units, identifier schemes and so on. Two parties are involved:

Declared: what the European Commission publishes
Every release of the "EN16931 code lists values" comes in three parts that must agree: the spreadsheet, one sheet per code list; the Genericode files, the same lists as XML; and the Index sheet, which states for each list whether and how it changed since the previous release.
Implemented: what the validator checks
The CEN validation artefacts (eInvoicing-EN16931) copy each list into a BR-CL rule. An invoice using a code the rule lacks is rejected, even when the code is declared.

The report lists every date on which either side changed, newest first, and compares each with what was in force on both sides that day. UBL and CII only.

Spreadsheet ⇄ Genericode

For each list published both ways, the codes of the sheet and of the Genericode file of the same release are compared one by one, and so are their names. A sheet that lists a code several times, as the Currency sheet does once per country, counts it once. Some lists are defined by EN 16931 itself and never published as Genericode: VAT ID, FISCAL ID, VAT CAT and Time. Before 2021 there was no Genericode at all.

Index change notes ⇄ actual changes

The Index sheet has a "Changes" column (Yes, No, Fixed) and a "Remark on updates" column, such as Added XCG, Removed ANG, BGN. Each remark is read for the codes it calls added, removed, renamed or deprecated, and set against what actually changed since the previous release:

A row is wrong when it states a change that did not happen, leaves out one that did, or names a code the list does not contain, before or after. A remark that counts instead of naming ("adding 49 codes") is accepted when the count is right. Every revision of a release is checked, so a correction such as 17 r02 shows what r01 got wrong. The Index's own effective date is checked against the date the release is filed under.

Business terms ⇄ EN 16931-1:2017

The Index column "EN business terms where the code list is used." is compared with the business terms whose description or usage note in Table 2 of EN 16931-1:2017 names the list, as recorded in business-terms-2017.csv, and with the previous release. Neither the sheets nor the Genericode files name business terms, so the Index is the only source.

Validator ⇄ declared codes

Each BR-CL rule is compared code by code with the codes declared, on the date, for the list it enforces (rule-catalog.csv). The Genericode file and the spreadsheet declare the same codes for every list published both ways, so one comparison speaks for both; the Time list, which BR-CL-06 checks, has no Genericode file and is compared with the spreadsheet. Should the two ever declare different codes for a list, its rule is shown against each. rules.csv keeps both comparisons for every rule. Where a rule states several lists, as UBL's BR-CL-01 for invoices and credit notes, their union is compared.

"7 of 22 rules wrong"
22 rules of the syntax could be compared with the declared codes; 7 of them implement other codes, so they accept an invoice they should reject or reject one they should accept.
"11 codes differ"
Counted once per rule: a code wrong in both BR-CL-03 and BR-CL-04 counts twice, because both checks fail an invoice.
implemented, not published
The validator accepts a code the published list does not contain. The link goes to the line listing it in the validator release in force, on GitHub.
published, not implemented
An invoice using a declared code fails validation. The link goes to the rule's list, where the code would have to be added.

A code's name comes from the compared release, or for a code it no longer lists, from the nearest release that did. "Listed by no EU release" means no release in this comparison ever contained it.

Renames

A removed code next to an added one is shown as one change, STD → STN, when the second replaced the first:

Pairing only changes how a difference is shown; it is still counted and checked as a removal and an addition.

Where the links go

Every finding links to where it is written, or to the file that lacks it:

A code of the EU code lists
Its line in the extracted text of the release: the Genericode file byte for byte as the archive holds it, or the sheet as CSV. GitHub cannot show a line of the original XLSX or ZIP, so the link goes to the text the EU-Codelist-Normalizer repository extracts and versions, release by release, in src/test/resources/<release>/rNN/extracted/. The link's title names the original, and for a sheet the cell, such as Currency sheet, cell C12. A code a file does not list links to that file.
A code that came, changed or went
Under What actually changed, its line in the commit of the code-history branch for that date. The commit is dated by the effective date, the date from which the change is in force, and its diff shows the line before and after: a new or renamed code on the new side, a removed one on the old.
A remark, a change flag or the business terms of the Index
The tab's row of the Index sheet, with the cell in the link's title.
The originals
Each release links its workbook and Genericode archive, as the European Commission published them, in the EU-Codelist-Downloader repository, which downloads and keeps them.
A validator rule
The line of its Schematron file at the commit the release tag names, in ConnectingEurope/eInvoicing-EN16931: exactly the lines that were in force, even if the tag were ever moved.

Dates

The validator's effective dates come from validator-releases.csv, those of the code lists from the release they are filed under. The two are not always the same day: validator 1.3.8 applies from 2022-05-15, the code lists from 2022-05-16. Every date of either side is listed, so a disagreement shows for as long as it lasted.

Files

All CSV files are UTF-8 with every field quoted; codes within a field are separated by spaces in code order. Every file is listed with its size and SHA-256 in manifest.json, so a copy of this folder can be checked for completeness.