diff --git a/mail_restrict_follower_selection/models/mail_thread.py b/mail_restrict_follower_selection/models/mail_thread.py index c12f19b1b..2d3a08d88 100644 --- a/mail_restrict_follower_selection/models/mail_thread.py +++ b/mail_restrict_follower_selection/models/mail_thread.py @@ -27,7 +27,7 @@ def _message_add_suggested_recipient( return result domain = self.env[ "mail.wizard.invite" - ]._mail_restrict_follower_selection_get_domain() + ]._mail_restrict_follower_selection_get_domain(res_model=self._name) eval_domain = safe_eval( str(domain), locals_dict={"ref": lambda str_id: _id_get(self.env, str_id)} ) diff --git a/mail_restrict_follower_selection/models/mail_wizard_invite.py b/mail_restrict_follower_selection/models/mail_wizard_invite.py index 24cadd3e1..fd139a0e4 100644 --- a/mail_restrict_follower_selection/models/mail_wizard_invite.py +++ b/mail_restrict_follower_selection/models/mail_wizard_invite.py @@ -5,7 +5,7 @@ from lxml import etree -from odoo import api, models +from odoo import api, fields, models from odoo.osv import expression from odoo.tools.safe_eval import safe_eval @@ -15,6 +15,22 @@ class MailWizardInvite(models.TransientModel): _inherit = "mail.wizard.invite" + partner_ids_domain = fields.Binary(compute="_compute_partner_ids_domain") + + @api.depends("res_model") + @api.depends_context("default_res_model") + def _compute_partner_ids_domain(self): + for wizard in self: + domain = wizard._mail_restrict_follower_selection_get_domain( + res_model=wizard.res_model + ) + wizard.partner_ids_domain = safe_eval( + str(domain), + locals_dict={ + "ref": lambda str_id, env=wizard.env: _id_get(env, str_id) + }, + ) + @api.model def _mail_restrict_follower_selection_get_domain(self, res_model=None): if not res_model: @@ -38,12 +54,16 @@ def _mail_restrict_follower_selection_get_domain(self, res_model=None): @api.model def get_view(self, view_id=None, view_type="form", **options): result = super().get_view(view_id=view_id, view_type=view_type, **options) + if view_type != "form": + return result arch = etree.fromstring(result["arch"]) - domain = self._mail_restrict_follower_selection_get_domain() - eval_domain = safe_eval( - str(domain), locals_dict={"ref": lambda str_id: _id_get(self.env, str_id)} - ) - for field in arch.xpath('//field[@name="partner_ids"]'): - field.attrib["domain"] = str(eval_domain) + partner_ids_fields = arch.xpath('//field[@name="partner_ids"]') + if partner_ids_fields and not arch.xpath('//field[@name="partner_ids_domain"]'): + domain_field = etree.Element("field") + domain_field.attrib["name"] = "partner_ids_domain" + domain_field.attrib["invisible"] = "1" + partner_ids_fields[0].addprevious(domain_field) + for field in partner_ids_fields: + field.attrib["domain"] = "partner_ids_domain" result["arch"] = etree.tostring(arch) return result diff --git a/mail_restrict_follower_selection/tests/test_mail_restrict_follower_selection.py b/mail_restrict_follower_selection/tests/test_mail_restrict_follower_selection.py index e01f50e9d..00dbbc399 100644 --- a/mail_restrict_follower_selection/tests/test_mail_restrict_follower_selection.py +++ b/mail_restrict_follower_selection/tests/test_mail_restrict_follower_selection.py @@ -27,18 +27,38 @@ def setUp(self): ) self.switzerland = self.env.ref("base.ch") - def _use_ref_in_domain(self): - """Change the general domain to test the safe_eval.""" - param = self.env.ref("mail_restrict_follower_selection.parameter_domain") + def _use_ref_in_domain(self, param=None): + """Change a domain to test the safe_eval.""" + if param is None: + param = self.env.ref("mail_restrict_follower_selection.parameter_domain") country_id = self.env.ref("base.ch").id param.value = f"[('country_id', '!=', {country_id})]" + def _use_restrictive_global_domain(self): + param = self.env.ref("mail_restrict_follower_selection.parameter_domain") + param.value = "[('category_id.name', '!=', 'Employees')]" + self.param.value = "[('category_id.name', '=', 'Employees')]" + def test_fields_view_get(self): result = self.env["mail.wizard.invite"].get_view(view_type="form") - for field in etree.fromstring(result["arch"]).xpath( - '//field[@name="partner_ids"]' - ): - self.assertTrue(field.get("domain")) + arch = etree.fromstring(result["arch"]) + self.assertTrue(arch.xpath('//field[@name="partner_ids_domain"]')) + for field in arch.xpath('//field[@name="partner_ids"]'): + self.assertEqual(field.get("domain"), "partner_ids_domain") + + def test_get_view_non_form(self): + view = self.env["ir.ui.view"].create( + { + "name": "mail.wizard.invite.test.list", + "model": "mail.wizard.invite", + "type": "list", + "arch": "", + } + ) + result = self.env["mail.wizard.invite"].get_view( + view_id=view.id, view_type="list" + ) + self.assertNotIn("partner_ids_domain", result["arch"]) def send_action(self): compose = ( @@ -87,20 +107,40 @@ def test_message_add_suggested_recipient(self): )._message_add_suggested_recipient([]) self.assertFalse(new_res[0].get("partner_id")) - def test_get_view_eval(self): - """Check using safe_eval in field_view_get.""" + def test_message_add_suggested_recipient_specific_domain(self): + self._use_restrictive_global_domain() + res = self.partner.with_context( + test_restrict_follower=True + )._message_add_suggested_recipient([], partner=self.partner) + self.assertEqual(res[0]["partner_id"], self.partner.id) + + def test_partner_ids_domain_specific_domain(self): + self._use_restrictive_global_domain() + wizard = self.env["mail.wizard.invite"].new({"res_model": "res.partner"}) + self.assertIn(("category_id.name", "=", "Employees"), wizard.partner_ids_domain) + self.assertNotIn( + ("category_id.name", "!=", "Employees"), wizard.partner_ids_domain + ) + + def test_partner_ids_domain_eval(self): + """Check using safe_eval in the dynamic partner domain.""" + self._use_ref_in_domain(self.param) + wizard = self.env["mail.wizard.invite"].new({"res_model": "res.partner"}) + domain = str(wizard.partner_ids_domain) + self.assertTrue(domain.find("country_id") > 0) + self.assertTrue(domain.find(str(self.switzerland.id)) > 0) + + def test_partner_ids_domain_eval_global_domain(self): + """Check using safe_eval in the dynamic global domain.""" self._use_ref_in_domain() - result = self.env["mail.wizard.invite"].get_view(view_type="form") - for field in etree.fromstring(result["arch"]).xpath( - '//field[@name="partner_ids"]' - ): - domain = field.get("domain") - self.assertTrue(domain.find("country_id") > 0) - self.assertTrue(domain.find(str(self.switzerland.id)) > 0) + wizard = self.env["mail.wizard.invite"].new({}) + domain = str(wizard.partner_ids_domain) + self.assertTrue(domain.find("country_id") > 0) + self.assertTrue(domain.find(str(self.switzerland.id)) > 0) def test_message_add_suggested_recipient_eval(self): """Check using safe_eval when adding recipients.""" - self._use_ref_in_domain() + self._use_ref_in_domain(self.param) partner = self.partner.with_context(test_restrict_follower=True) res = partner._message_add_suggested_recipient([], partner=self.partner) self.assertEqual(res[0]["partner_id"], self.partner.id)