From e3177646b6629bc29fe77f962ec7cf7bfe7035c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Voet=20=28ryv=29?= Date: Tue, 9 Jan 2024 14:37:52 +0100 Subject: [PATCH] [FIX] core: fix Field._update() method to take in account archived record In e0297bd, we fixed the inverse field values of the new record during the onchange. But we actually filter out inactive records by doing record[self.name] in _update(). And since the XtoMany field cache values should always contain inactive records, we need to add with_context(active_test=False) on records. Also remove the useless 'if value', value is always truly because it is always a record. Note that this solves a performance issue in our production, because in order to filter out inactive records, we need to fetch the active field next to every prefechable field. closes odoo/odoo#148675 Signed-off-by: Raphael Collet --- .../test_new_api/models/test_new_api.py | 2 +- .../test_new_api/tests/test_onchange.py | 19 +++++++++++++++++++ odoo/fields.py | 11 +++++------ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/odoo/addons/test_new_api/models/test_new_api.py b/odoo/addons/test_new_api/models/test_new_api.py index 13485aa9aee..9104a5662da 100644 --- a/odoo/addons/test_new_api/models/test_new_api.py +++ b/odoo/addons/test_new_api/models/test_new_api.py @@ -159,7 +159,7 @@ class Message(models.Model): @api.depends('discussion.messages.important') def _compute_has_important_sibling(self): for record in self: - siblings = record.discussion.messages - record + siblings = record.discussion.with_context(active_test=False).messages - record record.has_important_sibling = any(siblings.mapped('important')) @api.constrains('author', 'discussion') diff --git a/odoo/addons/test_new_api/tests/test_onchange.py b/odoo/addons/test_new_api/tests/test_onchange.py index 2fdd9ba7c43..5343cbcafe9 100644 --- a/odoo/addons/test_new_api/tests/test_onchange.py +++ b/odoo/addons/test_new_api/tests/test_onchange.py @@ -1252,3 +1252,22 @@ class TestComputeOnchange2(common.TransactionCase): self.assertEqual(message_form.has_important_sibling, True) message_form.body = 'Required Body' self.assertEqual(len(discussion_form.messages), 2) + + # Test the same flow but when the important message is archived. + # The _compute_has_important_sibling should take in account archived siblings. + discussion = self.env['test_new_api.discussion'].create({ + 'messages': [ + Command.create({'body': 'Archived Important sibling', 'important': True, 'active': False}), + ], + 'name': 'Required field', + 'participants': [Command.set(self.env.user.ids)], + }) + + with Form(discussion, 'test_new_api.discussion_form_2') as discussion_form: + self.assertEqual(len(discussion_form.messages), 0) + with discussion_form.messages.new() as message_form: + # this actually checks that during the onchange, the new message + # has access to its archived sibling messages through the discussion + self.assertEqual(message_form.has_important_sibling, True) + message_form.body = 'Required Body' + self.assertEqual(len(discussion_form.messages), 1) diff --git a/odoo/fields.py b/odoo/fields.py index 3a6463ab011..69695c69a35 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -4159,12 +4159,11 @@ class _RelationalMulti(_Relational): def _update(self, records, value): """ Update the cached value of ``self`` for ``records`` with ``value``. """ - if value: - cache = records.env.cache - for record in records: - val = self.convert_to_cache(record[self.name] | value, record, validate=False) - cache.set(record, self, val) - records.modified([self.name]) + cache = records.env.cache + for record in records.with_context(active_test=False): + val = self.convert_to_cache(record[self.name] | value, record, validate=False) + cache.set(record, self, val) + records.modified([self.name]) def convert_to_cache(self, value, record, validate=True): # cache format: tuple(ids)