From b15c2803699610179945ba690e1e5bc922a6e2b2 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Wed, 29 Apr 2020 14:23:27 +0000 Subject: [PATCH] [FIX] core: update on new records should only recompute new records The following situation can occur: a computed field depends on one2many lines, and during an onchange, a line is modified. Both the main record and the line are new records. If the many2one field is not in cache on the line, its value is fetched from the line's origin, and the field will be triggered for recomputation on the main record's origin instead of the record itself. The fix enforces the following property: if new records are modified, only new records can be triggered for recomputation. X-original-commit: f038b6c40b7045b6fe569c009d29ea092b614ed6 --- .../test_new_api/tests/test_new_fields.py | 23 +++++++++++++++++++ odoo/models.py | 3 +++ 2 files changed, 26 insertions(+) diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 44a1fe695bf..fa2f8007bb4 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -1450,6 +1450,29 @@ class TestFields(TransactionCaseWithUserDemo): self.assertNotEqual(new_disc.participants, disc.participants) self.assertEqual(new_disc.participants._origin, disc.participants) + def test_41_new_compute(self): + """ Check recomputation of fields on new records. """ + move = self.env['test_new_api.move'].create({ + 'line_ids': [(0, 0, {'quantity': 1}), (0, 0, {'quantity': 1})], + }) + move.flush() + line = move.line_ids[0] + + new_move = move.new(origin=move) + new_line = line.new(origin=line) + + # move_id is fetched from origin + self.assertEqual(new_line.move_id, move) + self.assertEqual(new_move.quantity, 2) + self.assertEqual(move.quantity, 2) + + # modifying new_line must trigger recomputation on new_move, even if + # new_line.move_id is not new_move! + new_line.quantity = 2 + self.assertEqual(new_line.move_id, move) + self.assertEqual(new_move.quantity, 3) + self.assertEqual(move.quantity, 2) + @mute_logger('odoo.addons.base.models.ir_model') def test_41_new_related(self): """ test the behavior of related fields starting on new records. """ diff --git a/odoo/models.py b/odoo/models.py index ba910ee4783..397d13f2691 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -5696,6 +5696,9 @@ Record ids: %(records)s # TODO: find a better fix if key.model_name == records._name: + if not any(self._ids): + # if self are new, records should be new as well + records = records.browse(it and NewId(it) for it in records._ids) break else: new_records = self.filtered(lambda r: not r.id)