[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
This commit is contained in:
Raphael Collet
2020-06-11 14:40:32 +00:00
parent 574dd61351
commit b15c280369
2 changed files with 26 additions and 0 deletions
@@ -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. """
+3
View File
@@ -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)