Skip to content

Add FR CTC Flow 10 and Flow 6 addons#820

Open
alvarolivie wants to merge 13 commits intomainfrom
fr-ctc-reporting-status
Open

Add FR CTC Flow 10 and Flow 6 addons#820
alvarolivie wants to merge 13 commits intomainfrom
fr-ctc-reporting-status

Conversation

@alvarolivie
Copy link
Copy Markdown
Contributor

@alvarolivie alvarolivie commented Apr 24, 2026

  • Add fr-ctc-flow10-v1 addon: French e-reporting for B2B/B2C invoices and payments (billing mode, document types, G1.24 rate whitelist, exempt-VAT rules, B2C transaction category, payment receipt validation)
  • Add fr-ctc-flow6-v1 addon: French CDV lifecycle statuses on bill.Status with CDAR code tables (ProcessConditionCode, ReasonCode, RequestedAction), role / reason-code extensions, and a Characteristic complement carrying the MEN on paid lines; enforces exactly one status line per document
  • Move Flow 2 into addons/fr/ctc/flow2/; rename package to flow2 and shorten Flow2Key/Flow2V1 to Key/V1 (breaking change for external consumers like gobl.ubl)
  • Default the flow2 billing mode (M2 if paid, M1 otherwise), auto-fill the three BR-FR-05 regulatory mentions (PMT/PMD/AAB) with minimal placeholders, and the BR-FR-CO-14 TXD note for STC suppliers
  • Tighten flow2 rule descriptions (03/04 corrective preceding, 09 factoring, 24/25 contract reference) so each message states what it actually checks
  • Add five GOBL examples covering the new addons (flow10 B2B/B2C invoices and B2B payment, flow6 accepted and paid statuses)
  • Reorganise tests: one _test.go per source file in internal package, individual named tests with helpers (no table-driven loops); regenerate data/ artefacts via go generate

Pre-Review Checklist

  • Opened this PR as a draft
  • Read the CONTRIBUTING.md guide.
  • Performed a self-review of my code.
  • Added thorough tests with at least 90% code coverage.
  • Modified or created example GOBL documents to show my changes in use, if appropriate.
  • Added links to the source of the changes in tax regimes or addons, either structured or in the comments.
  • Run go generate . to ensure that the Schemas and Regime data are up to date.
  • Reviewed and fixed all linter warnings.
  • Been obsessive with pointer nil checks to avoid panics.
  • Updated the CHANGELOG.md with an overview of my changes.
  • Marked this PR as ready for review.

And if you are part of the org:

  • Requested a review from Copilot and fixed or dismissed (with a reason) all the feedback raised.
  • Requested a review from @samlown.

Introduce two new French CTC addons — reporting (Flow 10, on bill.Invoice
and bill.Payment) and lifecycle status (Flow 6, on bill.Status) — and
reorganise Flow 2 under addons/fr/ctc/flow2/ so the three variants sit
side by side.

Flow 10 (e-reporting) covers B2B and B2C invoices plus B2B and B2C
payments, gated by a b2c tag. Validates billing mode (G1.02), allowed
UNTDID document types, final-after-advance invariant (G1.60), currency
convertibility to EUR, address country, supplier/customer legal scheme
(G2.19), VAT ID when scheme is SIREN/EU-VAT (G2.33), exempt categories,
G1.24 rate whitelist on invoices and payments, B2C transaction category
(G1.68), and payment receipt/lines/document refs. Normalizes SIREN and
EU VAT identities from TaxID, defaults billing mode (M1/M2) and the B2C
category (TNT1), and maps rate keys to UNTDID 5305 categories.

Flow 6 (CDV lifecycle) is standalone — does not require Flow 2. Carries
the authoritative tables gobl.cii reads for the CDAR round-trip:
ProcessConditionCode 200–213 (extends bill.StatusEvents with 8
France-specific keys), 45 ReasonCodes with bucket + default-for-key
flag, 7 RequestedActionCodes. Three extensions (fr-ctc-role,
fr-ctc-reason-code) plus a Characteristic complement covering MDT-207
and the MEN for paid lines. Validations for the rules surfaced in
BR-FR-CDV (supplier SIREN, doc code/issue-date, reason required on
rejection-like statuses, TypeCode whitelist, characteristic ReasonCode
link to sibling Reason); the Type-dependent role and recipient routing
rules are intentionally left to PPF-side business logic.

The Flow 2 move (addons/fr/ctc/ → addons/fr/ctc/flow2/) renames the
package to flow2 and shortens Flow2Key/Flow2V1 to Key/V1. addons.go
blank-imports all three flows.

Tests are one _test.go per source file in each package (internal
package so unexported helpers are reachable), with individual named
tests wired to tiny per-axis helpers instead of table-driven loops.
Coverage: flow2 93.0%, flow10 90.1%, flow6 96.4%.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 94.15011% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.54%. Comparing base (0982364) to head (8975a72).

Files with missing lines Patch % Lines
addons/fr/ctc/flow10/bill_invoice.go 90.76% 12 Missing and 11 partials ⚠️
addons/fr/ctc/flow6/bill_status.go 93.88% 7 Missing and 7 partials ⚠️
addons/fr/ctc/flow10/party.go 86.44% 6 Missing and 2 partials ⚠️
addons/fr/ctc/flow10/bill_payment.go 94.02% 2 Missing and 2 partials ⚠️
addons/fr/ctc/flow2/bill_invoice.go 96.26% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #820      +/-   ##
==========================================
+ Coverage   93.38%   93.54%   +0.16%     
==========================================
  Files         369      377       +8     
  Lines       20048    20868     +820     
==========================================
+ Hits        18721    19521     +800     
- Misses        888      900      +12     
- Partials      439      447       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

alvarolivie and others added 9 commits April 27, 2026 08:14
- Five GOBL example documents covering the new addons:
  - Flow 10 B2B invoice, B2C invoice, B2B payment
  - Flow 6 accepted status, paid status with MEN complement
- Flow 6 now enforces exactly one StatusLine per bill.Status (CDAR
  carries a single status per CDV message)
- Tighten Flow 2 description copy

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Each source file now matches a single domain: bill_invoice.go owns
the invoice rules, normalizers, and shared VAT-key map; bill_payment.go
owns the payment rules and helpers. The catch-all bill.go file is
removed; tests follow the same split.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Merge bill.go (invoice helpers) and bill_invoices.go (invoice rules)
into a single bill_invoice.go matching the flow10 layout. Tests follow
the rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Tighten descriptions on rules 03/04 (corrective preceding), 09
  (factoring vs advance-payment doc type), 24/25 (consolidated credit
  note contracts) so each message says what it actually checks.
- Default the flow2 billing mode the same way flow10 does — M2 if
  Totals.Paid(), M1 otherwise; user-supplied values are preserved.
- Auto-fill the three BR-FR-05 regulatory mentions (PMT / PMD / AAB)
  with minimal, business-neutral text when missing.
- Auto-fill the BR-FR-CO-14 TXD / MEMBRE_ASSUJETTI_UNIQUE note when the
  supplier carries an STC-scheme (0231) identity.
- Regenerate data/ artefacts via go generate.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The flow2 test files were external (package flow2_test) so the
defensive nil / wrong-type paths in unexported helpers were
unreachable, dragging coverage below the rest of the suite. Switching
to package flow2 lets the same one-test-per-source layout reach the
helpers; adding a focused set of nil/wrong-type tests pushes coverage
to 97.5%.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Lint flagged "TXD", "MEMBRE_ASSUJETTI_UNIQUE", and "peppol" as repeated
literals. Lift the first two into noteSubjectTXD / stcMembreAssujettiUnique
constants in flow2/bill_invoice.go, and switch all "peppol" references
to the existing org.InboxKeyPeppol constant.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Pull "BAR" / "B2B" out of bill_invoice.go into noteSubjectBAR and
barTreatmentB2B so the goconst lint stops complaining and the
isB2BTransaction / notesValidBARText helpers read clearly. No
behaviour change: the BAR note is intentionally not auto-defaulted —
its value (B2B / B2BINT / B2C / OUTOFSCOPE / ARCHIVEONLY) is
transaction-specific and must come from the caller.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Per BR-FR-22 ("règle à exécuter si la facture fait l'objet d'un
traitement B2B ou si elle contient une note (BG-1) avec un code sujet
(BT-21) = BAR et un contenu (BT-22) = B2B"), the B2B-specific rules
should fire whenever flow2 is in scope — flow2 *is* the B2B addon —
unless the caller explicitly opts the invoice out via a BAR note with
a non-B2B treatment (B2BINT / B2C / OUTOFSCOPE / ARCHIVEONLY).

Previously isB2BTransaction returned true only when an explicit BAR=B2B
note was present, which silently let invoices skip the customer-SIREN,
supplier-SIREN-inbox and self-billed-customer-inbox checks. Flip the
default so absence of a BAR note keeps the B2B path active.

The international b2bint example is updated to carry an explicit
BAR=B2BINT note to opt out, with no Key on the note so the en16931
normalizer doesn't rewrite the subject code based on note.Key.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the France CTC support by introducing two new addons (Flow 10 e-reporting and Flow 6 lifecycle statuses), while reorganizing and tightening the existing Flow 2 addon implementation and updating rules, schemas, and examples accordingly.

Changes:

  • Add fr-ctc-flow10-v1 (Flow 10) addon with scenarios/tags, validation + normalization for invoices and payments, and new examples.
  • Add fr-ctc-flow6-v1 (Flow 6) addon for bill.Status lifecycle messages, including a Characteristic complement schema, code tables, validation/normalization, and new examples.
  • Move/rename Flow 2 into addons/fr/ctc/flow2 (package rename + API rename), add normalization defaults (billing mode + required mentions), and refine rule descriptions.

Reviewed changes

Copilot reviewed 48 out of 54 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/ops/bulk_test.go Updates schema list fixture to include the new Flow 6 characteristic schema.
examples_test.go Skips an additional path during examples scanning.
examples/fr/status-fr-fr-ctc-flow6-paid.yaml New Flow 6 “paid” status example (includes characteristic/MEN).
examples/fr/status-fr-fr-ctc-flow6-accepted.yaml New Flow 6 “accepted” status example.
examples/fr/payment-fr-fr-ctc-flow10-b2b.yaml New Flow 10 B2B payment receipt example.
examples/fr/out/status-fr-fr-ctc-flow6-paid.json Generated output for the Flow 6 “paid” status example.
examples/fr/out/status-fr-fr-ctc-flow6-accepted.json Generated output for the Flow 6 “accepted” status example.
examples/fr/out/payment-fr-fr-ctc-flow10-b2b.json Generated output for the Flow 10 B2B payment example.
examples/fr/out/invoice-fr-fr-ctc-flow10-b2c.json Generated output for the Flow 10 B2C invoice example.
examples/fr/out/invoice-fr-fr-ctc-flow10-b2b.json Generated output for the Flow 10 B2B invoice example.
examples/fr/out/invoice-fr-de-ctc-b2bint.json Updates generated output (adds BAR note + digest changes).
examples/fr/invoice-fr-fr-ctc-flow10-b2c.yaml New Flow 10 B2C invoice input example.
examples/fr/invoice-fr-fr-ctc-flow10-b2b.yaml New Flow 10 B2B invoice input example.
examples/fr/invoice-fr-de-ctc-b2bint.yaml Updates input example to include BAR note.
data/schemas/tax/addon-list.json Registers Flow 6 and Flow 10 addon keys in the addon list schema.
data/schemas/addons/fr/ctc/flow6/characteristic.json New JSON Schema for the Flow 6 characteristic complement.
data/rules/fr-ctc-flow6.json New rule definitions for Flow 6 validations.
data/rules/fr-ctc-flow2.json Updates Flow 2 rule descriptions for clarity/accuracy.
data/rules/fr-ctc-flow10.json New rule definitions for Flow 10 validations.
data/addons/fr-ctc-flow6-v1.json New addon definition for Flow 6 (extensions + sources).
data/addons/fr-ctc-flow2-v1.json Updates Flow 2 addon definition text (removes currency conversion note).
data/addons/fr-ctc-flow10-v1.json New addon definition for Flow 10 (extensions, tags, scenarios).
addons/fr/ctc/item_test.go Removes old CTC-level item meta validation tests (moved under Flow 2 tests).
addons/fr/ctc/flow6/org_party_test.go Adds Flow 6 party extension/scheme validation tests.
addons/fr/ctc/flow6/org_party.go Adds Flow 6 org.Party validation for role code + allowed identity schemes.
addons/fr/ctc/flow6/flow6.go Registers Flow 6 addon, schema objects, rules, and normalizer.
addons/fr/ctc/flow6/extensions_test.go Tests helper for unwrapping extensions passed by pointer/value.
addons/fr/ctc/flow6/extensions.go Defines Flow 6 extensions + builds reason-code value list from table.
addons/fr/ctc/flow6/complements.go Defines Flow 6 Characteristic type + MDT-207 type-code whitelist.
addons/fr/ctc/flow6/codes_test.go Tests Process/Reason/Action code-table mappings and round-trips.
addons/fr/ctc/flow6/codes.go Implements ProcessCondition/Reason/Action code tables and lookups.
addons/fr/ctc/flow6/bill_status_test.go Adds Flow 6 status validation + normalization tests.
addons/fr/ctc/flow6/bill_status.go Implements Flow 6 bill.Status/bill.Reason/bill.Action validation + normalization.
addons/fr/ctc/flow2/tags.go Renames package from ctc to flow2.
addons/fr/ctc/flow2/org_test.go Updates Flow 2 tests for package/API rename; adds/moves item meta tests here.
addons/fr/ctc/flow2/org_party.go Renames package to flow2.
addons/fr/ctc/flow2/org.go Renames package; switches inbox peppol key handling to constants.
addons/fr/ctc/flow2/flow2.go Renames Flow 2 package and exports (Key/V1); updates registration/guard.
addons/fr/ctc/flow2/extensions.go Renames package to flow2.
addons/fr/ctc/flow2/bill_invoice.go Adds Flow 2 normalization defaults (billing mode + required mentions + TXD note) and BAR logic; updates rule descriptions.
addons/fr/ctc/flow10/tags.go Adds Flow 10 B2C tag definition for invoices/payments.
addons/fr/ctc/flow10/scenarios.go Adds Flow 10 scenarios mapping invoice types/tags → UNTDID document types.
addons/fr/ctc/flow10/party_test.go Adds unit tests for Flow 10 party normalization/helpers.
addons/fr/ctc/flow10/party.go Adds Flow 10 party normalization + legal scheme selection helpers.
addons/fr/ctc/flow10/flow10.go Registers Flow 10 addon, rules, scenarios, tags, and normalizer.
addons/fr/ctc/flow10/extensions.go Defines Flow 10 extensions and billing mode / B2C category values.
addons/fr/ctc/flow10/bill_payment_test.go Adds Flow 10 payment validation tests.
addons/fr/ctc/flow10/bill_payment.go Adds Flow 10 payment validation (receipt-only, value date, VAT whitelist, supplier SIREN, B2B doc refs).
addons/fr/ctc/flow10/bill_invoice_test.go Adds Flow 10 invoice validation + normalization tests (B2B/B2C).
addons/fr/ctc/flow10/bill_invoice.go Adds Flow 10 invoice validation + normalization (billing mode default, VAT whitelist, exempt rules, party scheme rules).
addons/fr/ctc/bill.go Removes old shared CTC bill helpers (now Flow 2–scoped).
addons/addons.go Registers new Flow 2/6/10 addon packages instead of the old monolithic CTC package.
CHANGELOG.md Documents addition of Flow 6 and Flow 10 addons.
Comments suppressed due to low confidence (1)

addons/fr/ctc/flow2/bill_invoice.go:838

  • notesValidBARText currently allows a BAR note with an empty Text value to pass validation, but the corresponding rule message states the BAR text must be one of the allowed treatment values. If a BAR note is present, its Text should be non-empty and within allowedBARTreatments; otherwise return false so invalid/blank BAR notes don’t silently disable B2B processing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread addons/fr/ctc/flow10/bill_invoice.go Outdated
Comment thread addons/fr/ctc/flow10/bill_payment.go
Comment thread addons/fr/ctc/flow10/extensions.go Outdated
alvarolivie and others added 3 commits April 27, 2026 11:22
The b2c distinction is naturally captured by Customer presence — a
B2C sale is to an unidentified consumer, so the Customer slot is left
unset. Drop the addon-specific TagB2C tag, the tags.go file, and the
Tags wiring on the addon definition; flip invoiceIsB2C / paymentIsB2C
to read Customer == nil. The b2c example loses its $tags and customer
block accordingly.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The supplier-SIREN rule fires on both B2B and B2C, so the addon must
also derive a SIREN-scheme identity from a French TaxID for B2C
suppliers that ship without an Identities entry. Move normalizeParty
calls before the B2C early return — Customer is nil for B2C so its
call is a harmless no-op — and keep the B2C-specific bits (default
TNT1 category) after.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The per-code Go comments said "Deposit of an already paid X invoice"
(and similar) which contradicted the documented suffix semantics — the
2-suffix means "already paid", not "deposit". Rewrite each comment to
state the actual meaning (B/S/M = goods / services / mixed; suffix =
payment context), and add a header summarising the convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants