From 070f1173dac28127d97aa681dec5331c5420971f Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 8 Mar 2018 14:15:21 +0100 Subject: [PATCH] [FIX] odoo: onchange load the related field data Configurations uses an onchange to populate the fields visible to the user. However, the related fields are by default called sudo, when it is an onchange, there may be a missmatch in the cache, the cache used being empty, there is no value to return (cache fix is not currently possible). Before this fix we must use 'related_sudo=False' to use the good cache but it's an inconsistent fix because in some case we must use sudo to avoid access error. opw-1823363 --- odoo/addons/test_new_api/models.py | 4 +++ .../test_new_api/tests/test_onchange.py | 29 +++++++++++++++++++ odoo/models.py | 19 ++++++------ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/odoo/addons/test_new_api/models.py b/odoo/addons/test_new_api/models.py index ab8ebdb1ac4..2d973c04ef4 100644 --- a/odoo/addons/test_new_api/models.py +++ b/odoo/addons/test_new_api/models.py @@ -320,6 +320,10 @@ class Related(models.Model): related_name = fields.Char(related='name') related_related_name = fields.Char(related='related_name') + message = fields.Many2one('test_new_api.message') + message_name = fields.Text(related="message.body", related_sudo=False, string='Message Body') + message_currency = fields.Many2one(related="message.author", string='Message Author') + class ComputeInverse(models.Model): _name = 'test_new_api.compute.inverse' diff --git a/odoo/addons/test_new_api/tests/test_onchange.py b/odoo/addons/test_new_api/tests/test_onchange.py index a87006c76cb..7caf433a467 100644 --- a/odoo/addons/test_new_api/tests/test_onchange.py +++ b/odoo/addons/test_new_api/tests/test_onchange.py @@ -425,3 +425,32 @@ class TestOnChange(common.TransactionCase): 'size': email.size, })] ) + + def test_onchange_related(self): + value = { + 'message': 1, + 'message_name': False, + 'message_currency': 2, + } + field_onchange = { + 'message': '1', + 'message_name': None, + 'message_currency': None, + } + + onchange_result = { + 'message_name': 'Hey dude!', + 'message_currency': (1, 'Administrator') + } + + self.env.cache.invalidate() + Message = self.env['test_new_api.related'] + result = Message.onchange(value, ['message', 'message_name', 'message_currency'], field_onchange) + + self.assertEqual(result['value'], onchange_result) + + self.env.cache.invalidate() + Message = self.env(user=self.env.ref('base.user_demo').id)['test_new_api.related'] + result = Message.onchange(value, ['message', 'message_name', 'message_currency'], field_onchange) + + self.assertEqual(result['value'], onchange_result) diff --git a/odoo/models.py b/odoo/models.py index 68efa22c314..335098311af 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -4985,15 +4985,16 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): done = set() # dummy assignment: trigger invalidations on the record - for name in todo: - if name == 'id': - continue - value = record[name] - field = self._fields[name] - if field.type == 'many2one' and field.delegate and not value: - # do not nullify all fields of parent record for new records - continue - record[name] = value + with env.do_in_onchange(): + for name in todo: + if name == 'id': + continue + value = record[name] + field = self._fields[name] + if field.type == 'many2one' and field.delegate and not value: + # do not nullify all fields of parent record for new records + continue + record[name] = value result = {} dirty = set()