Daily updates from Odoo
Thursday, May 14, 2026
1 change
Resolved issues and error corrections
This update resolves a critical issue with Mexican electronic invoices (CFDI) caused by how discounts are handled when multiple product lines are present. The fix ensures accurate SAT validation by correctly reconciling document-level discount and subtotal totals with individual line values, preventing invoice rejection.
Original PR description
## Summary Fix SAT validation errors **CFDI40111** and **CFDI40108** that occur when invoices with many lines contain a small negative line, causing per-line discounts to be hidden due to currency…
## Summary Fix SAT validation errors **CFDI40111** and **CFDI40108** that occur when invoices with many lines contain a small negative line, causing per-line discounts to be hidden due to currency precision. ## Real Case Example Invoice has **48 positive product lines** and **1 negative line** (subtotal **-0.99**). CFDI does not allow negative concept lines, so Odoo distributes the `-0.99` as tiny discounts across all 48 lines. ### The Problem For each line, the discount is computed and rounded to 6 decimal places. When spread across 48 lines, each discount is roughly **0.02**. With MXN currency precision (2 decimals), many are below `0.01` and are **hidden** from the XML during cleanup. This causes two mismatches: 1. **CFDI40111** — `Descuento` mismatch: - Document-level `Descuento` is computed **before** cleanup: **0.99** - Sum of visible line `Descuento` after cleanup: only ~23 lines remain visible, summing to roughly **0.96** - SAT rejects because `0.99 ≠ 0.96` 2. **CFDI40108** — `SubTotal` mismatch: - Fixing the first error by adding the delta to the line's `Importe` also changes the document `SubTotal`, breaking the rule `SubTotal = Σ Importe` - SAT rejects because the rounded `SubTotal` no longer matches the sum of visible line `Importe` values ## Solution After the cleanup phase in `_add_base_lines_cfdi_values`, we independently reconcile both SAT requirements: 1. **SubTotal = Σ Importe** (CFDI40108): - Compute `delta = visible_importes - document_subtotal` - Add `delta` to the **largest line** by `Importe` - Update `SubTotal` and recalculate `ValorUnitario` 2. **Descuento = Σ Descuento** (CFDI40111): - Compute `delta = visible_descuento - document_descuento` - Add `delta` to the **largest line** by `Descuento` This ensures both SAT rules are satisfied simultaneously. ## Testing A unit test `test_invoice_negative_lines_many_lines` reproduces the exact scenario: - Creates an invoice with **10 positive lines** and **1 negative line (-0.99)** - Generates the CFDI - Asserts that `Descuento` total equals the sum of visible line `Descuento` values - Asserts that `SubTotal` equals the sum of visible line `Importe` values All existing rounding and negative-line tests pass (`0 failed, 0 errors`). Ticket: https://www.odoo.com/es_ES/my/tasks/6187014 @moduon MT-14784