Zum Inhalt springen

Changelog

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.


[Unreleased]


[1.31.0] - 2026-09-07

Added

  • models.py: TaxIdentifier.validate_in_gstin() — format-only validation of an Indian GSTIN (GST Identification Number), added ahead of the mcp-einvoicing-in country package’s own scaffolding, per its Step 0.5 core-reuse check. Confirmed directly against GSTN’s FORM GST INV-01 schema v1.1: total length (15) and the digits-first-two/alphanumeric shape. The full state-code + PAN + entity-code + check-character structural breakdown, and any check-digit algorithm, are not confirmed by any locally supplied NIC/GSTN document, so this validator does not assert either — see the method’s docstring and context-library/countries/in.md in the mcp-einvoicing monorepo.

Deferred

  • TaxIdentifier.validate_in_pan() was planned alongside validate_in_gstin() but is not added in this release: the only staged local document mentions PAN once, in passing, with no length, character-class, or check-digit fact confirmed. Tracked in gaps_registry.toml as core.tax_id.in_pan (unresolved).

[1.28.0] - 2026-08-31

Fixed

  • exceptions.py: PlatformError now accepts and stores an optional response_body: bytes | None (default None, fully backward-compatible — every existing call site uses keyword args). http_client.py’s _extract_platform_error() populates it from response.content. Previously the raw error body was discarded after _parse_error_body() extracted a summary message/error_code, so a country adapter’s own re-parse of a platform-specific error schema (e.g. mcp-ksef-pl’s _raise_ksef_error, which keys on exc.response_body) was unreachable dead code — PlatformError never set that attribute, so hasattr(exc, "response_body") was always False. Surfaced during the KSeF v2.7.1 delta review; see PL-ERR-1 in mcp-ksef-pl’s audit-history.md.

[1.27.0] - 2026-08-31

Added

  • xml_utils.py: sanitize_xml_text() and DiscouragedCharacterError — strip or reject W3C XML 1.0 Appendix C “discouraged” code points (C1 controls + DEL, U+007F-U+009F; noncharacters U+FDD0-U+FDEF and U+nFFFE/U+nFFFF in every plane) before a field value is embedded via xml_escape(). These code points pass the Char production and XSD validation, so xml_escape() alone does not filter them, but a receiving platform can enforce a stricter policy and reject an otherwise schema-valid document. Opt-in and additive; no effect on existing callers. Surfaced by the KSeF API v2.4.0 discouraged- Unicode rejection (PRD since 2026-07-16); see PL-DISC-1 in mcp-ksef-pl’s audit-history.md for the consuming change.

[1.25.0] - 2026-08-29

Added

  • en16931.py: EN16931Invoice.document_uuid — optional field emitted as <cbc:UUID>, a sibling immediately after <cbc:ID> in UBL 2.1 output. Several Peppol jurisdiction CIUS profiles mandate a document UUID (e.g. PINT AE BTAE-07, PINT-SG BT-SG-003); previously each country package had no core hook to emit it. None by default, so existing packages that never set it produce byte-identical output to before this change.
  • wire_formats.py: EN16931UBLSerializer._emit_item_price_extension (default False) — an opt-in flag for country subclasses that must emit cac:ItemPriceExtension per invoice line (line net amount + line VAT amount, and the line VAT amount, as a sibling of cac:Price). Not part of base EN 16931 or generic Peppol BIS 3.0 — confirmed absent from the BE, DE, IT, PL, ES, SG, FR specs vendored in this workspace; present only in PINT AE’s jurisdiction rules (ibr-104-ae/ibr-194-ae). Base behavior is unchanged for every package that doesn’t opt in.

Fixed

  • audit.py: _read_core_version_spec (CHECK 4) no longer matches a prose comment line that happens to contain the substring "mcp-einvoicing-core" when it precedes the real dependency-array entry — it now only matches lines that are themselves a TOML string literal starting with the package name. Both mcp-invoicenow-sg and mcp-einvoicing-ae carry an explanatory comment directly above their dependency line and were hitting this bug, rendering a garbled “declared range” in their audit reports.

[1.23.0] - 2026-08-27

Added

  • ubl_documents.py: new BaseUBLDocument model — a shared envelope (document_id, issue_date, customization_id, profile_id, sender/ receiver as PeppolParticipantId) for non-invoice UBL/Peppol document families (Peppol Ordering: Order, OrderResponse, OrderChange, OrderCancellation, OrderAgreement, Invoice Response, and jurisdiction extensions such as Singapore IMDA’s Order Balance). Explicitly outside the canonical invoice tree (InvoiceDocument/EN16931Invoice) per CLAUDE.md — never subclass one for the other. Resolves the mcp-invoicenow-sg (Singapore) roadmap item SG-INV-2. Additive, non-breaking.

[1.20.1] - 2026-08-25

Changed

  • en16931.py: verified the full EN 16931 semantic model (BT-1 through BT-161, BG-1 through BG-32) against NF EN 16931-1:2017+A1:2019 (AFNOR), Article 6.3, Tableau 2. No mislabeled BT number was found. Lifted the [Inference] disclaimer on the module docstring to [Verified against NF EN 16931-1:2017+A1:2019 §6.3] and added an explicit coverage statement of the optional BTs/BGs this module deliberately omits.

Added

  • tests/test_en16931_bt_mapping.py: regression test pinning each en16931.py field’s declared BT reference, so an edit to a Field(description=...) string cannot silently drift the field -> BT mapping.

[1.19.0] - 2026-08-22

Added

  • Initial changelog. Prior release history is recorded in the Git tags and GitHub Releases for this repository.