Skip to content

Commit 311f494

Browse files
committed
[BUG] the invalidate recordset call is harming the abilitity to save updated records in sale.order, with this change seems to solve it and the extension seems working, needs review
1 parent 5abce08 commit 311f494

File tree

1 file changed

+36
-32
lines changed

1 file changed

+36
-32
lines changed

sale_triple_discount/models/sale_order_line.py

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
# Copyright 2018 Simone Rubino - Agile Business Group
55
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
66

7+
from contextlib import contextmanager
8+
79
from odoo import _, api, fields, models
810
from odoo.exceptions import ValidationError
911

@@ -66,9 +68,8 @@ def _discount_fields(self):
6668

6769
@api.depends("discount2", "discount3", "discounting_type")
6870
def _compute_amount(self):
69-
prev_values = self.triple_discount_preprocess()
70-
res = super()._compute_amount()
71-
self.triple_discount_postprocess(prev_values)
71+
with self._aggregated_discount() as lines:
72+
res = super(SaleOrderLine, lines)._compute_amount()
7273
return res
7374

7475
_sql_constraints = [
@@ -93,37 +94,40 @@ def _prepare_invoice_line(self, **kwargs):
9394
res.update({"discount2": self.discount2, "discount3": self.discount3})
9495
return res
9596

96-
def triple_discount_preprocess(self):
97-
"""Prepare data for post processing.
98-
99-
Save the values of the discounts in a dictionary,
100-
to be restored in postprocess.
101-
Resetting every discount except the main one to 0.0 avoids issues if
102-
this method is called multiple times.
103-
Updating the cache provides consistency through re-computations."""
104-
prev_values = dict()
105-
self.invalidate_recordset(self._discount_fields())
106-
for line in self:
107-
prev_values[line] = {
108-
fname: line[fname] for fname in self._discount_fields()
109-
}
110-
111-
vals = {fname: 0 for fname in self._discount_fields()}
112-
vals["discount"] = line._get_final_discount()
113-
114-
line._cache.update(vals)
115-
return prev_values
116-
117-
@api.model
118-
def triple_discount_postprocess(self, prev_values):
119-
"""Restore the discounts of the lines in the dictionary prev_values.
120-
Updating the cache provides consistency through re-computations."""
121-
self.invalidate_recordset(self._discount_fields())
122-
for line, prev_vals_dict in list(prev_values.items()):
123-
line.update(prev_vals_dict)
97+
@contextmanager
98+
def _aggregated_discount(self):
99+
"""A context manager to temporarily change the discount value on the
100+
records and restore it after the context is exited. It temporarily
101+
changes the discount value to the aggregated discount value so that
102+
methods that depend on the discount value will use the aggregated
103+
discount value instead of the original one.
104+
"""
105+
discount_field = self._fields["discount"]
106+
# Protect discount field from triggering recompute of totals. We don't want
107+
# to invalidate the cache to avoid to flush the records to the database.
108+
# This is safe because we are going to restore the original value at the end
109+
# of the method.
110+
with self.env.protecting([discount_field], self):
111+
old_values = {}
112+
for line in self:
113+
old_values[line.id] = line.discount
114+
aggregated_discount = line._get_final_discount()
115+
line.update({"discount": aggregated_discount})
116+
yield self.with_context(discount_is_aggregated=True)
117+
for line in self:
118+
if line.id not in old_values:
119+
continue
120+
line.with_context(
121+
restoring_triple_discount=True,
122+
).update({"discount": old_values[line.id]})
124123

125124
def _convert_to_tax_base_line_dict(self):
126125
self.ensure_one()
126+
discount = (
127+
self.discount
128+
if self.env.context.get("discount_is_aggregated")
129+
else self._get_final_discount()
130+
)
127131
return self.env["account.tax"]._convert_to_tax_base_line_dict(
128132
self,
129133
partner=self.order_id.partner_id,
@@ -132,6 +136,6 @@ def _convert_to_tax_base_line_dict(self):
132136
taxes=self.tax_id,
133137
price_unit=self.price_unit,
134138
quantity=self.product_uom_qty,
135-
discount=self._get_final_discount(),
139+
discount=discount,
136140
price_subtotal=self.price_subtotal,
137141
)

0 commit comments

Comments
 (0)