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 48444cbdadb..ec96fbf351c 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -621,6 +621,33 @@ class TestFields(TransactionCaseWithUserDemo): self.assertEqual(record.bar3, 'C') self.assertCountEqual(log, ['compute']) + # corner case: write on a field that is marked to compute + log.clear() + # writing on 'foo' marks 'bar1', 'bar2', 'bar3' to compute + record.write({'foo': '1/2/3'}) + self.assertCountEqual(log, []) + # writing on 'bar3' must force the computation before updating + record.write({'bar3': 'X'}) + self.assertCountEqual(log, ['compute', 'inverse23']) + self.assertEqual(record.foo, '1/2/X') + self.assertEqual(record.bar1, '1') + self.assertEqual(record.bar2, '2') + self.assertEqual(record.bar3, 'X') + self.assertCountEqual(log, ['compute', 'inverse23']) + + log.clear() + # writing on 'foo' marks 'bar1', 'bar2', 'bar3' to compute + record.write({'foo': 'A/B/C'}) + self.assertCountEqual(log, []) + # writing on 'bar1', 'bar2', 'bar3' discards the computation + record.write({'bar1': 'X', 'bar2': 'Y', 'bar3': 'Z'}) + self.assertCountEqual(log, ['inverse1', 'inverse23']) + self.assertEqual(record.foo, 'X/Y/Z') + self.assertEqual(record.bar1, 'X') + self.assertEqual(record.bar2, 'Y') + self.assertEqual(record.bar3, 'Z') + self.assertCountEqual(log, ['inverse1', 'inverse23']) + def test_13_inverse_access(self): """ test access rights on inverse fields """ foo = self.env['test_new_api.category'].create({'name': 'Foo'}) diff --git a/odoo/models.py b/odoo/models.py index 31a6cacd9cd..944db478f18 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3855,6 +3855,14 @@ Fields: if fname == 'company_id' or (field.relational and field.check_company): check_company = True + # force the computation of fields that are computed with some assigned + # fields, but are not assigned themselves + to_compute = [field.name + for field in protected + if field.compute and field.name not in vals] + if to_compute: + self.recompute(to_compute, self) + # protect fields being written against recomputation with env.protecting(protected, self): # Determine records depending on values. When modifying a relational