Skip to content

EN 16931 Semantic JSON 0.9.4

Choose a tag to compare

@github-actions github-actions released this 07 Oct 08:15
· 109 commits to main since this release
Immutable release. Only release title and notes can be modified.

Added

  • Pack directories: esj validate and esj inspect take --packs <directory> (repeatable) and
    read the environment variable ESJ_PACKS (a path list); every <id>/<version>/<release>/pack.json
    found there joins the bundled packs and is chosen by the profile of the document. A pack with the
    identity of a bundled one, and a profile two packs recognize, are refused by name — except where
    those packs are releases of one pack (same id and version): then the newest release is taken,
    compared part by part (3.0.10 after 3.0.9), and --pack takes another. Every report
    names the origin of the pack beside its identity: syntax.pack.source is directory and the new
    syntax.pack.location the directory it was read from (null for a bundled pack), and
    esj --list-packs prints origin for every pack.
  • esj packs list and esj packs fetch <recipe> --into <directory> [--replace]. fetch follows a
    recipe this build carries for artefacts that may be used but not redistributed: it downloads the
    files over https, refuses any whose SHA-256 is not the one the recipe pins, compiles the
    Schematron to XSLT in process with the ISO Schematron XSLT 2 skeleton (MIT, now in
    esj-syntax), copies the schema modules out of the bundled pack and writes a pack whose
    manifest records the source URLs, the fetch date and the SHA-256 of every file. It is the only
    command that opens a network connection.
  • The recipes peppol-bis-billing-3.0.21 and peppol-bis-billing-3.0.20: the Peppol BIS
    Billing 3.0 validation artefacts, as published by OpenPeppol — the Peppol rules for UBL and CII
    and the EN 16931 Schematron that release ships (1.3.16 and 1.3.15). 3.0.21 is the May 2026
    release, mandatory from 2026-08-17; OpenPeppol tagged no 3.0.21, so its recipe fetches below
    the commit 806866bd2bd91d7e9623b68f08164e8fbe9e67a0, never by a branch name, and a recipe
    without a tag may fetch only below the commit it names. esj packs fetch peppol-bis-billing
    follows the newest recipe this build carries (3.0.21); esj packs list marks it. None of those
    files is in this repository or in any artefact; esj validate on a Peppol invoice without the
    pack names the command that makes it. With 3.0.21, OpenPeppol's 10 examples validate VALID
    and all 62 rules its own unit tests cover fire as those tests expect; with 3.0.20, 9 examples
    and 58 rules (conformance/peppol/README.md, run with -Desj.network=true and in the JDK 21
    job of the continuous integration).

Changed

  • A recipe's source.tag is optional, with a new optional source.branch; the manifest of a
    fetched pack records them as the recipe has them, and esj packs list names the revision a
    recipe fetches by (at tag v3.0.20, at commit … (branch 2026-Q2-QA2)).

  • A PDF written by 0.9.0 to 0.9.3 still carries invoice.esj.json. It is read as an attachment
    that is not the invoice, as a logo would be: esj inspect and esj extract --list list it
    (not XML, application/json, Supplement), esj extract --attachment invoice.esj.json
    hands out its bytes, and esj validate reports nothing about it. A PDF whose one attachment it
    is carries no invoice (exit code 2).

  • docs/java-api.md names Saxon-HE 13.0 as the minimum: with 12.x the XML Schema, Schematron
    and XSLT path still run, and every HTML page of esj-render, the HTML report included, fails
    with AbstractMethodError (UnparsedTextURIResolver). docs/install.md notes that the jar
    carries Saxon-HE 13.0 unrelocated.

Removed

  • The ESJ document inside the hybrid PDF. esj embed and esj render --embed cii write one
    embedded file, the invoice XML. Gone with the second file invoice.esj.json: the rule that it
    and the XML are two accounts of one invoice, the option --no-esj and the line saying the
    attachment went in, the container row ESJ document attached of esj validate (lines, the
    JSON member container.esj, the HTML and the PDF report), the findings PDF-ESJ-DISAGREES,
    PDF-ESJ-UNSOUND, PDF-ESJ-UNREADABLE, PDF-ESJ-UNCHECKED, PDF-EMBEDDED-SEVERAL-ESJ and
    PDF-EMBEDDED-ESJ-LABEL, and section 15 of SPEC.md (informative). A receiver of two
    representations of one invoice has to parse and compare both; the XML is the invoice, and the
    ESJ document derives from it at any time (docs/design-decisions.md).
  • The API of that feature, which breaks callers of it: in esj-pdf the classes EsjAgreement
    and EsjAttachment, EmbedOptions.withEsj and the esj component of EmbedOptions (its
    constructors take one argument fewer), EmbedResult.EsjOutcome, EmbedResult.esj(),
    esjAttached() and esjOmitted() (its constructor takes the file and the report),
    AttachmentKind.ESJ_DOCUMENT, ContainerFinding.Category.PDF_ESJ and the three-argument
    ContainerChecks.run; in esj-core the phrases Phrase.ROW_PDF_ESJ, ESJ_ATTACHMENT and
    ESJ_ATTACHMENT_PARTLY.

Fixed

  • UBL Credit Notes keep the sub lines of the XRechnung extension. The extension's source binds
    them for UBL Invoice only, so the streaming reader dropped every cac:SubCreditNoteLine
    without an observation, and the writer had no place for BG-DEX-01. ubl-creditnote.json now
    binds BG-DEX-01 to BG-DEX-08 and the 36 core terms a sub line reuses below
    cac:CreditNoteLine//cac:SubCreditNoteLine, quantity from cbc:CreditedQuantity (two
    corrections, model/bindings/README.md). BG-DEX-09 and BT-DEX-001 to BT-DEX-003 stay unbound:
    UBL 2.1 gives the credit note no cac:PrepaidPayment. Measured on
    conformance/creditnote/04.01a-CREDITNOTE_ubl.xml, the KoSIT extension instance 04.01a as a
    credit note: read, written, read again and accepted by the pack, with the values of the
    invoice. The XSLT path (--importer xslt) still gives every sub credit note line the values
    of the first credit note line, a defect of the vendored KoSIT stylesheet
    (conformance/creditnote/README.md).
  • esj-bom no longer hands on the versions the build of this project manages. The deployed POM
    is flattened: no parent, no properties, and only the modules of this project in
    dependencyManagement. Importing 0.9.0 to 0.9.3 also imported JUnit 6.1.3, Saxon-HE, PDFBox,
    Jackson and the PostgreSQL test binaries, and so decided the JUnit version of the importing
    build.

Full Changelog: v0.9.3...v0.9.4