From 6ed63b9fee150af4272ff4a54b593038340d71b7 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 7 Oct 2022 10:18:44 +0000 Subject: [PATCH] [IMP] base: possibility to archive companies It is technically nearly impossible to delete a company when it actually dealed with customers (emitted invoices, received payments, ...). Hence, if you want to get rid of a company, for instance because you closed one of your subsidiaries, giving the possibility to archive your company, thanks to an active field, would be the best way to go. We are hesitating to do a related field to the `partner_id.active`, but we are a bit afraid some people archive the partner linked to their company for other valid reasons than get rid of their subsidiary (such as avoid changing the address of their company by mistake through the Contacts app), while still wanting the company itself to be active. So, we make it an independant column at the moment, so we have the actual stored column in case we need it, and will do a related stored to the partner later on if we change our mind. Manual forward-port of #102801 closes odoo/odoo#102586 Signed-off-by: Olivier Dony --- odoo/addons/base/models/res_company.py | 1 + odoo/addons/base/models/res_users.py | 6 ++++-- odoo/addons/base/tests/test_expression.py | 4 ++-- odoo/api.py | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/odoo/addons/base/models/res_company.py b/odoo/addons/base/models/res_company.py index 83b792c4edc..913db9016f5 100644 --- a/odoo/addons/base/models/res_company.py +++ b/odoo/addons/base/models/res_company.py @@ -57,6 +57,7 @@ class Company(models.Model): return base64.b64encode(stream.getvalue()) name = fields.Char(related='partner_id.name', string='Company Name', required=True, store=True, readonly=False) + active = fields.Boolean(default=True) sequence = fields.Integer(help='Used to order Companies in the company switcher', default=10) parent_id = fields.Many2one('res.company', string='Parent Company', index=True) child_ids = fields.One2many('res.company', 'parent_id', string='Child Companies') diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 678a17e4dd6..04dfdf9daa7 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -697,9 +697,11 @@ class Users(models.Model): return frozendict(context) - @tools.ormcache('self._uid') + @tools.ormcache('self.id') def _get_company_ids(self): - return frozenset(self.company_ids.ids) + # use search() instead of `self.company_ids` to avoid extra query for `active_test` + domain = [('active', '=', True), ('user_ids', 'in', self.id)] + return frozenset(self.env['res.company'].search(domain).ids) @api.model def action_get(self): diff --git a/odoo/addons/base/tests/test_expression.py b/odoo/addons/base/tests/test_expression.py index abb3c68311a..f0e64eb6cc8 100644 --- a/odoo/addons/base/tests/test_expression.py +++ b/odoo/addons/base/tests/test_expression.py @@ -1339,7 +1339,7 @@ class TestMany2one(TransactionCase): WHERE ("res_partner"."company_id" IN ( SELECT "res_company".id FROM "res_company" - WHERE ("res_company"."name"::text like %s) + WHERE (("res_company"."active" = %s) AND ("res_company"."name"::text like %s)) )) ORDER BY "res_partner"."display_name", "res_partner"."id" ''']): @@ -1353,7 +1353,7 @@ class TestMany2one(TransactionCase): WHERE ("res_partner"."company_id" IN ( SELECT "res_company".id FROM "res_company" - WHERE ("res_company"."name"::text like %s) + WHERE (("res_company"."active" = %s) AND ("res_company"."name"::text like %s)) ORDER BY "res_company"."id" LIMIT 1 )) diff --git a/odoo/api.py b/odoo/api.py index aa275dcf826..76442108e1a 100644 --- a/odoo/api.py +++ b/odoo/api.py @@ -658,9 +658,9 @@ class Environment(Mapping): the targeted company. """ company_ids = self.context.get('allowed_company_ids', []) + user_company_ids = self.user._get_company_ids() if company_ids: if not self.su: - user_company_ids = self.user._get_company_ids() if any(cid not in user_company_ids for cid in company_ids): raise AccessError(_("Access to unauthorized or invalid companies.")) return self['res.company'].browse(company_ids) @@ -674,7 +674,7 @@ class Environment(Mapping): # - when printing a report for several records from several companies # - when accessing to a record from the notification email template # - when loading an binary image on a template - return self.user.company_ids.with_env(self) + return self['res.company'].browse(user_company_ids) @property def lang(self):