From c23b13eafe0d7a23a0c9f0d96b9ecb9b62879a70 Mon Sep 17 00:00:00 2001 From: Christophe Monniez Date: Wed, 3 Mar 2021 12:33:20 +0000 Subject: [PATCH] [FIX] models: call inverse method right after cache invalidation When a record is written on a computed field with an inverse method and an x2many field wit a delete command, the computed field is not properly handled by the inverse method, because of a whole cache invalidation that happens during the unlink. With this commit, we write in cache on the fields that have been invalidated before invoking the inverse method. opw #2439861 closes odoo/odoo#67525 X-original-commit: d39855bad5153654d443d1b7ede3907f8bae3e66 Signed-off-by: Christophe Monniez (moc) Signed-off-by: Raphael Collet (rco) Co-authored-by: Raphael Collet --- .../test_new_api/tests/test_new_fields.py | 27 +++++++++++++++++++ odoo/models.py | 5 ++++ 2 files changed, 32 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 3cb4c3b2d78..3e85a0aa314 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -631,6 +631,33 @@ class TestFields(TransactionCaseWithUserDemo): with self.assertRaises(AccessError): foo.with_user(user).display_name = 'Forbidden' + def test_13_inverse_with_unlink(self): + """ test x2many delete command combined with an inverse field """ + country1 = self.env['res.country'].create({'name': 'test country'}) + country2 = self.env['res.country'].create({'name': 'other country'}) + company = self.env['res.company'].create({ + 'name': 'test company', + 'child_ids': [ + (0, 0, {'name': 'Child Company 1'}), + (0, 0, {'name': 'Child Company 2'}), + ] + }) + child_company = company.child_ids[0] + + # check first that the field has an inverse and is not stored + field = type(company).country_id + self.assertFalse(field.store) + self.assertTrue(field.inverse) + + company.write({'country_id': country1.id}) + self.assertEqual(company.country_id, country1) + + company.write({ + 'country_id': country2.id, + 'child_ids': [(2, child_company.id)], + }) + self.assertEqual(company.country_id, country2) + def test_14_search(self): """ test search on computed fields """ discussion = self.env.ref('test_new_api.discussion_0') diff --git a/odoo/models.py b/odoo/models.py index 8a1ec0b86b9..b0121bb003c 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3683,6 +3683,11 @@ Fields: real_recs._validate_fields(vals, inverse_fields) for fields in determine_inverses.values(): + # write again on non-stored fields that have been invalidated from cache + for field in fields: + if not field.store and any(self.env.cache.get_missing_ids(real_recs, field)): + field.write(real_recs, vals[field.name]) + # inverse records that are not being computed try: fields[0].determine_inverse(real_recs)