[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) <moc@odoo.com>
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
Christophe Monniez
2021-03-09 11:24:09 +00:00
committed by Raphael Collet
co-authored by Raphael Collet
parent 819221086c
commit c23b13eafe
2 changed files with 32 additions and 0 deletions
@@ -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')
+5
View File
@@ -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)