diff --git a/odoo/addons/base/models/ir_config_parameter.py b/odoo/addons/base/models/ir_config_parameter.py index 3dd77cc1304..9063b1f2337 100644 --- a/odoo/addons/base/models/ir_config_parameter.py +++ b/odoo/addons/base/models/ir_config_parameter.py @@ -45,6 +45,9 @@ class IrConfigParameter(models.Model): Initializes the parameters listed in _default_parameters. It overrides existing parameters if force is ``True``. """ + # avoid prefetching during module installation, as the res_users table + # may not have all prescribed columns + self = self.with_context(prefetch_fields=False) for key, func in _default_parameters.items(): # force=True skips search and always performs the 'if' body (because ids=False) params = self.sudo().search([('key', '=', key)]) diff --git a/odoo/addons/base/models/ir_default.py b/odoo/addons/base/models/ir_default.py index 042279de073..3c0b3140220 100644 --- a/odoo/addons/base/models/ir_default.py +++ b/odoo/addons/base/models/ir_default.py @@ -117,7 +117,7 @@ class IrDefault(models.Model): return json.loads(default.json_value) if default else None @api.model - @tools.ormcache('self.env.uid', 'model_name', 'condition') + @tools.ormcache('self.env.uid', 'self.env.company.id', 'model_name', 'condition') # Note about ormcache invalidation: it is not needed when deleting a field, # a user, or a company, as the corresponding defaults will no longer be # requested. It must only be done when a user's company is modified. @@ -126,16 +126,16 @@ class IrDefault(models.Model): current user), as a dict mapping field names to values. """ cr = self.env.cr - query = """ SELECT f.name, d.json_value FROM ir_default d + query = """ SELECT f.name, d.json_value + FROM ir_default d JOIN ir_model_fields f ON d.field_id=f.id - JOIN res_users u ON u.id=%s WHERE f.model=%s - AND (d.user_id IS NULL OR d.user_id=u.id) - AND (d.company_id IS NULL OR d.company_id=u.company_id) + AND (d.user_id IS NULL OR d.user_id=%s) + AND (d.company_id IS NULL OR d.company_id=%s) AND {} ORDER BY d.user_id, d.company_id, d.id """ - params = [self.env.uid, model_name] + params = [model_name, self.env.uid, self.env.company.id] if condition: query = query.format("d.condition=%s") params.append(condition) diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 06df0a5a732..0eefb630525 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -503,8 +503,6 @@ class Users(models.Model): # if partner is global we keep it that way if user.partner_id.company_id and user.partner_id.company_id.id != values['company_id']: user.partner_id.write({'company_id': user.company_id.id}) - # clear default ir values when company changes - self.env['ir.default'].clear_caches() if 'company_id' in values or 'company_ids' in values: # Reset lazy properties `company` & `companies` on all envs diff --git a/odoo/addons/base/tests/test_ir_default.py b/odoo/addons/base/tests/test_ir_default.py index 57855de9b33..667e8d7c845 100644 --- a/odoo/addons/base/tests/test_ir_default.py +++ b/odoo/addons/base/tests/test_ir_default.py @@ -106,3 +106,40 @@ class TestIrDefault(TransactionCase): # delete the record, and check the presence of the default value title.unlink() self.assertEqual(IrDefault.get_model_defaults('res.partner'), {}) + + def test_multi_company_defaults(self): + """Check defaults in multi-company environment.""" + company_a = self.env["res.company"].create({"name": "C_A"}) + company_b = self.env["res.company"].create({"name": "C_B"}) + company_a_b = (company_a + company_b) + company_b_a = (company_b + company_a) + multi_company_user = self.env['res.users'].create({ + 'name': 'u2', 'login': 'u2', + 'company_id': company_a.id, + 'company_ids': company_a_b.ids, + }) + IrDefault = self.env["ir.default"].with_user(multi_company_user) + IrDefault.with_context(allowed_company_ids=company_a.ids).set( + 'res.partner', 'ref', 'CADefault', user_id=True, company_id=True) + IrDefault.with_context(allowed_company_ids=company_b.ids).set( + 'res.partner', 'ref', 'CBDefault', user_id=True, company_id=True) + self.assertEqual( + IrDefault.get_model_defaults('res.partner')['ref'], + 'CADefault', + ) + self.assertEqual( + IrDefault.with_context(allowed_company_ids=company_a.ids).get_model_defaults('res.partner')['ref'], + 'CADefault', + ) + self.assertEqual( + IrDefault.with_context(allowed_company_ids=company_b.ids).get_model_defaults('res.partner')['ref'], + 'CBDefault', + ) + self.assertEqual( + IrDefault.with_context(allowed_company_ids=company_a_b.ids).get_model_defaults('res.partner')['ref'], + 'CADefault', + ) + self.assertEqual( + IrDefault.with_context(allowed_company_ids=company_b_a.ids).get_model_defaults('res.partner')['ref'], + 'CBDefault', + )