Skip to content

Commit f3aa04d

Browse files
committed
Merge PR #4395 into 16.0
Signed-off-by rvalyi
2 parents 234bcd9 + a022609 commit f3aa04d

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

l10n_br_fiscal/models/document_mixin.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,18 @@ def _distribute_amount_to_lines(self, amount_field_name, line_field_name):
259259
if lines:
260260
lines[0][line_field_name] = amount_to_distribute
261261

262+
# Force recompute of document-level fiscal amounts. When called from an
263+
# inverse method (e.g. _inverse_amount_freight), the ORM protects all
264+
# co-computed _compute_fiscal_amount fields — including fiscal_amount_untaxed.
265+
# The line value changes above should trigger recomputation via the trigger
266+
# tree, but the ORM protection mechanism blocks it (all co-computed fields are
267+
# protected during the write that fires the inverse). We bypass this by
268+
# explicitly adding the fields to the recompute queue.
269+
for fname in self._get_amount_fields():
270+
field = self._fields.get(fname)
271+
if field and field.store and field.compute == "_compute_fiscal_amount":
272+
self.env.add_to_compute(field, self)
273+
262274
def _inverse_amount_freight(self):
263275
self._distribute_amount_to_lines("amount_freight_value", "freight_value")
264276

l10n_br_fiscal/tests/test_document_edition.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,67 @@ def test_landed_costs_by_line_and_by_total(self):
285285
doc_after_total_update.fiscal_amount_total, 2776.48, places=2
286286
)
287287

288+
def test_fiscal_amount_recompute_on_delivery_cost_write(self):
289+
"""Verify fiscal_amount_untaxed recomputes after direct delivery cost write.
290+
291+
When amount_freight_value (or insurance/other) is written on the document,
292+
the ORM protects all co-computed _compute_fiscal_amount fields during the
293+
inverse call. This means the trigger tree propagation from line field
294+
changes back to fiscal_amount_untaxed is blocked by the protection
295+
mechanism. Without an explicit env.add_to_compute in
296+
_distribute_amount_to_lines, fiscal_amount_untaxed remains stale —
297+
especially when the trigger tree has extra hops due to addon-added computed
298+
fields on the lines.
299+
"""
300+
self.env.user.groups_id |= self.env.ref("l10n_br_fiscal.group_user")
301+
product1 = self.env.ref("product.product_product_6")
302+
product2 = self.env.ref("product.product_product_7")
303+
304+
self.company.delivery_costs = "total"
305+
doc_form = Form(self.env["l10n_br_fiscal.document"])
306+
doc_form.company_id = self.company
307+
doc_form.partner_id = self.env.ref("l10n_br_base.res_partner_cliente1_sp")
308+
doc_form.fiscal_operation_id = self.env.ref("l10n_br_fiscal.fo_venda")
309+
310+
with doc_form.fiscal_line_ids.new() as line_form:
311+
line_form.product_id = product1
312+
line_form.fiscal_operation_line_id = self.env.ref(
313+
"l10n_br_fiscal.fo_venda_venda"
314+
)
315+
line_form.price_unit = 1000.0
316+
line_form.quantity = 2.0 # price_gross = 2000
317+
318+
with doc_form.fiscal_line_ids.new() as line_form:
319+
line_form.product_id = product2
320+
line_form.fiscal_operation_line_id = self.env.ref(
321+
"l10n_br_fiscal.fo_venda_venda"
322+
)
323+
line_form.price_unit = 500.0
324+
line_form.quantity = 1.0 # price_gross = 500
325+
326+
doc = doc_form.save()
327+
self.assertAlmostEqual(doc.fiscal_amount_untaxed, 2500.0)
328+
329+
# Write delivery costs directly via write() — triggers inverse methods
330+
# inside the ORM's protecting() context. Unlike Form.save(), write()
331+
# does not automatically flush pending computations, exposing the
332+
# staleness when add_to_compute is missing.
333+
doc.write({"amount_freight_value": 50.0})
334+
335+
# Freight distributed proportionally (80%/20%): line1=40, line2=10
336+
# fiscal_amount_untaxed = (2000+40) + (500+10) = 2550
337+
self.assertAlmostEqual(doc.fiscal_amount_untaxed, 2550.0)
338+
339+
doc.write({"amount_insurance_value": 25.0})
340+
# Insurance distributed: line1=20, line2=5
341+
# fiscal_amount_untaxed = (2000+40+20) + (500+10+5) = 2575
342+
self.assertAlmostEqual(doc.fiscal_amount_untaxed, 2575.0)
343+
344+
doc.write({"amount_other_value": 10.0})
345+
# Other distributed: line1=8, line2=2
346+
# fiscal_amount_untaxed = (2000+40+20+8) + (500+10+5+2) = 2585
347+
self.assertAlmostEqual(doc.fiscal_amount_untaxed, 2585.0)
348+
288349
def test_difal_calculation(self):
289350
partner = self.env.ref("l10n_br_base.res_partner_cliente5_pe")
290351
partner.ind_ie_dest = "9"

0 commit comments

Comments
 (0)