From 4b1bfb8502085938833c45bd3c99de750f9216d5 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Thu, 25 Jun 2020 08:27:08 +0100 Subject: [PATCH] [FIX] contract: do not die if modified partner has contracts in several companies In a multicompany scenario where a contact belongs to a company and has contracts in several companies, if the user goes to the contact to edit anything, when saving, it will trigger the recomputation of the `commercial_partner_id` field, which gets populated to all the related contracts, and will undeniably fail with an `AccessError`. A simple test is provided that, without the fix, fails like this: ``` 2020-06-25 07:21:24,859 33 ERROR devel odoo.addons.contract.tests.test_contract: ERROR: test_multicompany_partner_edited (odoo.addons.contract.tests.test_contract.TestContract) 2020-06-25 07:21:24,859 33 ERROR devel odoo.addons.contract.tests.test_contract: ` Editing a partner with contracts in several companies works. 2020-06-25 07:21:24,859 33 ERROR devel odoo.addons.contract.tests.test_contract: Traceback (most recent call last): 2020-06-25 07:21:24,859 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/auto/addons/contract/tests/test_contract.py", line 2513, in test_multicompany_partner_edited 2020-06-25 07:21:24,859 33 ERROR devel odoo.addons.contract.tests.test_contract: ` 'parent_id': parent_partner.id, 2020-06-25 07:21:24,859 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/auto/addons/partner_autocomplete/models/res_partner.py", line 183, in write 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` res = super(ResPartner, self).write(values) 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/res_partner.py", line 570, in write 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` result = result and super(Partner, self).write(vals) 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/auto/addons/mail/models/mail_thread.py", line 321, in write 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` result = super(MailThread, self).write(values) 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/auto/addons/mail/models/mail_activity.py", line 613, in write 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` return super(MailActivityMixin, self).write(vals) 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3381, in write 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` self.recompute() 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/custom/src/odoo/odoo/models.py", line 5308, in recompute 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` target._write(dict(vals)) 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3433, in _write 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` self.check_access_rule('write') 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3081, in check_access_rule 2020-06-25 07:21:24,860 33 ERROR devel odoo.addons.contract.tests.test_contract: ` + ' - ({} {}, {} {})'.format(_('Records:'), invalid.ids[:6], _('User:'), self._uid) 2020-06-25 07:21:24,861 33 ERROR devel odoo.addons.contract.tests.test_contract: ` odoo.exceptions.AccessError: ('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: Contract, Operation: write) - (Records: [101], User: 12)', None) ``` @Tecnativa TT24482 --- contract/models/contract.py | 1 + contract/tests/test_contract.py | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/contract/models/contract.py b/contract/models/contract.py index 12ef80668..3a2a3e581 100644 --- a/contract/models/contract.py +++ b/contract/models/contract.py @@ -87,6 +87,7 @@ class ContractContract(models.Model): commercial_partner_id = fields.Many2one( 'res.partner', + compute_sudo=True, related='partner_id.commercial_partner_id', store=True, string='Commercial Entity', diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index c31c2cbc5..87039a25a 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -2361,6 +2361,31 @@ class TestContract(TestContractBase): ).fields_view_get(view_type='form') self.assertEqual(view['view_id'], purchase_form_view.id) + def test_multicompany_partner_edited(self): + """Editing a partner with contracts in several companies works.""" + company2 = self.env['res.company'].create({ + "name": "Company 2", + }) + unprivileged_user = self.env["res.users"].create({ + "name": "unprivileged test user", + "login": "test", + "company_id": company2.id, + "company_ids": [(4, company2.id, False)], + }) + parent_partner = self.env["res.partner"].create({ + "name": "parent partner", + "is_company": True, + }) + # Assume contract 2 is for company 2 + self.contract2.company_id = company2 + # Update the partner attached to both contracts + self.partner.sudo(unprivileged_user).with_context( + company_id=company2.id, force_company=company2.id + ).write({ + "is_company": False, + "parent_id": parent_partner.id, + }) + def test_sale_fields_view_get(self): sale_form_view = self.env.ref( 'contract.contract_line_customer_form_view'