Pular para o conteúdo

Changelog

Este conteúdo não está disponível em sua língua ainda.

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.