Skip to content

fix(billing): EN16931 critical compliance gaps in UBL XML builder (#177)#178

Open
b3lz3but wants to merge 1 commit intocaptainpragmatic:masterfrom
b3lz3but:fix/en16931-prexisting-gaps
Open

fix(billing): EN16931 critical compliance gaps in UBL XML builder (#177)#178
b3lz3but wants to merge 1 commit intocaptainpragmatic:masterfrom
b3lz3but:fix/en16931-prexisting-gaps

Conversation

@b3lz3but
Copy link
Copy Markdown
Contributor

Summary

Fixes three critical EN16931 compliance gaps in the e-Factura XML builder that caused ANAF Schematron rejection for any invoice with line discounts or partial payments.

  • BR-42: line-level AllowanceCharge now emits AllowanceChargeReasonCode=\"95\" and AllowanceChargeReason=\"Discount\" (BT-140). Previously missing — every invoice with a line discount was rejected.
  • BT-131: LineExtensionAmount is now net of line-level allowances. Previously gross (unit_price × quantity), which violated BR-CO-10 (line sum must equal Invoice.subtotal_cents, already net) and cascaded into wrong TaxExclusive/TaxInclusive totals.
  • BT-113/BT-115: LegalMonetaryTotal now subtracts prepaid payments. Emits PrepaidAmount when any collected payment exists and PayableAmount reflects the remaining balance. Fully-unpaid invoices still omit PrepaidAmount.

All three fixes are mirrored in UBLCreditNoteBuilder for symmetry.

Out of scope (tied to PR #160)

The meta-JSON validation, credit-note document-level allowances/charges parity, and dead PAYMENT_MEANS_CODES entries listed in #177 all touch code introduced by PR #160 and will be addressed there (or in a follow-up once it merges).

Test plan

  • New regression tests for BR-42 reason code, BT-131 net amount, BT-113 prepaid, and the unpaid-invoice PrepaidAmount omission
  • Full XML builder suite green (24/24 in test_xml_builder.py)
  • mypy clean

Closes #177

🤖 Generated with Claude Code

…ptainpragmatic#177)

- BR-42: emit AllowanceChargeReasonCode ("95") and AllowanceChargeReason on
  line-level AllowanceCharge; ANAF Schematron rejected any invoice with a
  line discount because BT-140 was missing
- BT-131: LineExtensionAmount is now net of line-level allowances so the line
  sum matches Invoice.subtotal_cents (already net); fixes BR-CO-10 violation
  that cascaded into wrong TaxExclusive/TaxInclusive totals
- BT-113/BT-115: LegalMonetaryTotal now subtracts prepaid payments. Emits
  PrepaidAmount when any collected payment exists and PayableAmount reflects
  the remaining balance; fully-unpaid invoices still omit PrepaidAmount
- Mirror all three fixes in UBLCreditNoteBuilder for symmetry

Addresses captainpragmatic#177. Dead payment_means entries, meta JSON sanitization, and the
credit-note document-level allowances/charges gap are tied to PR captainpragmatic#160's
additions and will be handled there.

Signed-off-by: Ciprian Radulescu <craps2003@gmail.com>
@b3lz3but
Copy link
Copy Markdown
Contributor Author

@mostlyvirtual PR ready — this addresses the CRITICAL+HIGH findings from #177 (BR-42, BT-131, BT-113/115) on master. The MEDIUM items (meta JSON validation, credit-note doc-level allowances, dead payment_means entries) are tied to PR #160's new code path and will be handled there. CI is green 🙏

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.

fix(billing): pre-existing EN16931 XML builder compliance gaps — BR-42, LineExtensionAmount, PayableAmount

1 participant