Skip to content

[17.0][IMP] account_invoice_facturx: comply with Factur-X 4.x schematron#1340

Open
odoo-service wants to merge 5 commits into
OCA:17.0from
odoo-service:17.0
Open

[17.0][IMP] account_invoice_facturx: comply with Factur-X 4.x schematron#1340
odoo-service wants to merge 5 commits into
OCA:17.0from
odoo-service:17.0

Conversation

@odoo-service
Copy link
Copy Markdown

@odoo-service odoo-service commented May 13, 2026

Bumps the module to 17.0.1.3.0. The produced XML now validates cleanly against the bundled factur-x 4.x schematrons for all five profiles (MINIMUM, BASICWL, BASIC, EN16931, EXTENDED), and two new extension hooks on account.move let downstream modules plug in their own delivery date and line period source without patching the generator.

Fully includes #1320 and resolves four additional schematron items surfaced by the new meta-test suite.

Details:

tendil and others added 5 commits April 8, 2026 08:23
Prevent Factur-X invoices from failing schematron validation with
factur-x 4.x.

The generated XML must stay compliant with newer validation rules,
otherwise valid Odoo invoices cannot be exported as Factur-X documents.
This change removes the invalid email URI attribute, exports a
proprietary account identifier when IBAN is not available, and updates
tests to cover the new compliant output and the missing-account error.

Task: 5347
Some invoices already have a delivery/service date on the Odoo side, but
this date was not exported to the generated Factur-X XML.

As a result, the XML could fail validation because neither a header
delivery date nor a billing period was present.

This patch adds the delivery date to the header trade delivery block by
exporting `ActualDeliverySupplyChainEvent/OccurrenceDateTime`, using the
invoice date as the default delivery/service date.

The XML node order is also kept XSD-compliant.

Task: 5347
…iles + BG-26 line period

This change brings the Factur-X / ZUGFeRD generator to a state where
the produced XML validates cleanly against the bundled factur-x
schematrons for all five profiles (MINIMUM, BASICWL, BASIC, EN16931,
EXTENDED), and adds a generic extension hook for the EN 16931 invoice
line period (BG-26) so subscription / recurring billing modules can
plug in their own date fields without patching the line generator.
Schematron fixes
----------------
* MINIMUM: do not emit BuyerTradeParty/PostalTradeAddress and
  BuyerTradeParty/SpecifiedTaxRegistration. Both are marked as
  "not used" by the MINIMUM schematron. The corresponding
  SellerTradeParty children are kept because MINIMUM does require
  BT-31 (Seller VAT identifier).
* BASIC: emit a non-empty ApplicableHeaderTradeDelivery block with
  ActualDeliverySupplyChainEvent/OccurrenceDateTime (BT-72), fixing
  both PEPPOL-EN16931-R008 ("document MUST not contain empty
  elements") and BR-FX-EN-04 ("Each invoice must contain a delivery
  date or invoicing period"). The delivery date is read through the
  existing _cii_get_delivery_date() hook so the source field is not
  re-decided here.
* EN16931: do not emit CalculationPercent and BasisAmount inside
  GrossPriceProductTradePrice/AppliedTradeAllowanceCharge. Both are
  marked as "not used" in EN16931. The EXTENDED profile keeps them.
BG-26 line period
-----------------
* Add _cii_get_line_period(iline) hook on account.move that returns
  a (start_date, end_date) tuple. Default implementation reads, in
  order of precedence:
  - account.move.line.deferred_start_date / deferred_end_date
    (Odoo Enterprise account_accountant module, detected at runtime
    via _fields so this OCA module gains no hard dependency on
    Enterprise code), or
  - account.move.line.start_date / end_date (OCA module
    account_invoice_start_end_dates).
* The line generator emits BillingSpecifiedPeriod with StartDateTime
  and EndDateTime children whenever the hook returns at least one
  date, gated to the EN16931 and EXTENDED profiles per the BG-26
  schematron.
Tests
-----
* Add a schematron-based test suite that exercises all five Factur-X
  profiles for two scenarios (default invoice, invoice with
  line-level discount), plus a third subscription scenario covering
  BG-26. The subscription test guards itself with
  account.move.line._fields so it skips gracefully on Community
  installations without account_accountant.
Documentation
-------------
* Add readme/DEVELOP.md describing both extension hooks
  (_cii_get_delivery_date and _cii_get_line_period) with EN 16931
  business term mapping (BT-72, BG-26), the corresponding XPath
  locations and a worked example for downstream subscription
  modules.
* Add readme/HISTORY.md with an "Unreleased" section listing the
  schematron fixes and the BG-26 hook.
Co-authored-by: tendil <tendil@users.noreply.github.com>

Signed-off-by: Pawel Kazakow <github@kazacom.net>
_cii_get_delivery_date() returned self.invoice_date
unconditionally, so a value set in the standard Odoo
account.move.delivery_date field (manually, or via upstream
modules like subscription engines or
account_invoice_delivery_date_from_period) was silently dropped
from ActualDeliverySupplyChainEvent/OccurrenceDateTime (BT-72)
across all five Factur-X profiles. The hook now reads
self.delivery_date and falls back to invoice_date only when it
is unset.

Add an integration test that posts a draft with two subscription
lines and asserts that the auto-derived delivery_date lands in BT-72.
Bumps version to 17.0.1.3.0.
@OCA-git-bot
Copy link
Copy Markdown
Contributor

Hi @alexis-via,
some modules you are maintaining are being modified, check this out!

@OCA-git-bot OCA-git-bot added series:17.0 mod:account_invoice_facturx Module account_invoice_facturx labels May 13, 2026
@odoo-service odoo-service marked this pull request as ready for review May 13, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:account_invoice_facturx Module account_invoice_facturx series:17.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants