diff --git a/auditlog/models/rule.py b/auditlog/models/rule.py index 1cbabdfa3c8..0336ed3e551 100644 --- a/auditlog/models/rule.py +++ b/auditlog/models/rule.py @@ -2,9 +2,11 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import copy +from collections import defaultdict from odoo import Command, _, api, fields, models from odoo.exceptions import UserError +from odoo.tools.misc import OrderedSet FIELDS_BLACKLIST = [ "id", @@ -61,7 +63,7 @@ def __init__(self, env): self._transaction = env.transaction def __enter__(self): - """Replace the cache on all envs and on the transaction. + """Replace the cache + tocompute on all envs and on the transaction. It is not enough to replace the cache on the current env, because once a sudo is executed under the scope of this context manager, another new @@ -69,6 +71,12 @@ def __enter__(self): don't swap them all out here. """ self._original_cache = self._transaction.cache + # Copy the sets of records, which are popped on recompute but do not + # copy the keys because they do not match the original field object + # afterwards. + self._original_tocompute = defaultdict(OrderedSet) + for key, value in self._transaction.tocompute.items(): + self._original_tocompute[key] = OrderedSet(value) temporary_cache = api.Cache() for env in self._transaction.envs: env.cache = temporary_cache @@ -80,6 +88,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): for env in self._transaction.envs: env.cache = self._original_cache self._transaction.cache = self._original_cache + self._transaction.tocompute = self._original_tocompute class AuditlogRule(models.Model): diff --git a/test_auditlog/tests/test_account_move_reverse.py b/test_auditlog/tests/test_account_move_reverse.py index aa62f32778a..ff68ab7df0f 100644 --- a/test_auditlog/tests/test_account_move_reverse.py +++ b/test_auditlog/tests/test_account_move_reverse.py @@ -145,6 +145,20 @@ def setUp(self): ) self.rule.subscribe() + def test_in_invoice_stored_related_field(self): + """Stored related fields are computed properly""" + self.invoice.name = "TEST" + line = self.env["account.move.line"].create( + { + "display_type": "line_note", + "name": __name__, + "move_id": self.invoice.id, + } + ) + self.assertEqual(line.move_name, "TEST") + self.invoice.name = "TEST2" + self.assertEqual(line.move_name, "TEST2") + def test_in_invoice_create_refund(self): """Test creating a refund from a vendor bill.