diff --git a/web_field_required_invisible_manager/models/custom_field_restriction.py b/web_field_required_invisible_manager/models/custom_field_restriction.py
index 573557060a23..b1d1f7496aad 100644
--- a/web_field_required_invisible_manager/models/custom_field_restriction.py
+++ b/web_field_required_invisible_manager/models/custom_field_restriction.py
@@ -56,13 +56,30 @@ class CustomFieldRestriction(models.Model):
@api.onchange("field_id")
def onchange_field_id(self):
- self.update(
- {
- "required": self.field_id.required,
- "field_invisible": False,
- "field_readonly": self.field_id.readonly,
- }
- )
+ vals = {
+ "required": self.field_id.required,
+ "field_invisible": False,
+ "field_readonly": self.field_id.readonly,
+ }
+ if self.env.context.get("default_readonly_model_id"):
+ vals["readonly_model_id"] = (
+ self.env["ir.model"]
+ ._get(self.env.context.get("default_readonly_model_id"))
+ .id
+ )
+ elif self.env.context.get("default_required_model_id"):
+ vals["required_model_id"] = (
+ self.env["ir.model"]
+ ._get(self.env.context.get("default_required_model_id"))
+ .id
+ )
+ elif self.env.context.get("default_invisible_model_id"):
+ vals["invisible_model_id"] = (
+ self.env["ir.model"]
+ ._get(self.env.context.get("default_invisible_model_id"))
+ .id
+ )
+ self.update(vals)
@api.depends("required_model_id", "invisible_model_id", "readonly_model_id")
def _compute_model_name(self):
diff --git a/web_field_required_invisible_manager/models/models.py b/web_field_required_invisible_manager/models/models.py
index a21dfb3a04ae..fa101ac0e44b 100644
--- a/web_field_required_invisible_manager/models/models.py
+++ b/web_field_required_invisible_manager/models/models.py
@@ -7,6 +7,8 @@
from odoo import api, fields, models
from odoo.tools.safe_eval import safe_eval
+from odoo.addons.base.models.ir_ui_view import NameManager
+
class IrModel(models.Model):
_inherit = "ir.model"
@@ -45,7 +47,62 @@ def fields_view_get(
]
)
if restrictions:
- return self.create_restrictions_fields(restrictions, view_type, arch)
+ arch = self.create_restrictions_fields(restrictions, view_type, arch)
+ arch = self.process_child_fields(arch, view_type)
+ return arch
+
+ def process_child_fields(self, arch, view_type):
+ """Collect all relational fields and update its views"""
+ related_fields = [
+ (k, v.comodel_name) for k, v in self._fields.items() if v.comodel_name
+ ]
+ related_models_names = [r[1] for r in related_fields]
+ restrictions = self.env["custom.field.restriction"].search(
+ [
+ ("model_name", "in", related_models_names),
+ ("group_ids", "in", self.env.user.groups_id.ids),
+ ]
+ )
+ if restrictions and view_type == "form":
+ for restr in restrictions:
+ todo_fields = list(
+ filter(lambda x: x[1] == restr.model_name, related_fields)
+ )
+ for todo_field in todo_fields:
+ if not arch["fields"].get(todo_field[0]):
+ continue
+ for sub_view_type, sub_view in arch["fields"][todo_field[0]][
+ "views"
+ ].items():
+ if sub_view_type not in ["form", "tree"]:
+ continue
+ z_arch = sub_view
+ z_arch = self.create_restrictions_fields(
+ restr, view_type, z_arch
+ )
+ z_arch["arch"] = z_arch["arch"].decode("utf-8")
+ name_manager = NameManager(False, self.env[restr.model_name])
+ if restr.readonly_field_id and restr.readonly_model_id:
+ model_field_infos = name_manager.fields_get.get(
+ restr.readonly_field_id.name
+ )
+ z_arch["fields"][
+ restr.readonly_field_id.name
+ ] = model_field_infos
+ if restr.visibility_field_id and restr.invisible_model_id:
+ model_field_infos = name_manager.fields_get.get(
+ restr.visibility_field_id.name
+ )
+ z_arch["fields"][
+ restr.visibility_field_id.name
+ ] = model_field_infos
+ if restr.required_field_id and restr.required_model_id:
+ model_field_infos = name_manager.fields_get.get(
+ restr.required_field_id.name
+ )
+ z_arch["fields"][
+ restr.required_field_id.name
+ ] = model_field_infos
return arch
def create_restrictions_fields(self, restrictions, view_type, arch):
diff --git a/web_field_required_invisible_manager/tests/test_web_field_required_invisible_manager.py b/web_field_required_invisible_manager/tests/test_web_field_required_invisible_manager.py
index a8679ce376cd..39a3685d734d 100644
--- a/web_field_required_invisible_manager/tests/test_web_field_required_invisible_manager.py
+++ b/web_field_required_invisible_manager/tests/test_web_field_required_invisible_manager.py
@@ -1,13 +1,14 @@
# Copyright 2023 ooops404
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo.tests import common
+from odoo.tests import Form, common
class TestFieldRequiredIvisibleManager(common.SavepointCase):
@classmethod
def setUpClass(cls):
super(TestFieldRequiredIvisibleManager, cls).setUpClass()
+ cls.view_model = cls.env["ir.ui.view"].sudo()
cls.partner_name_field_id = cls.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "name")]
)
@@ -21,6 +22,9 @@ def setUpClass(cls):
cls.partner_title_name_field_id = cls.env["ir.model.fields"].search(
[("model", "=", "res.partner.title"), ("name", "=", "name")]
)
+ cls.partner_name_field_id = cls.env["ir.model.fields"].search(
+ [("model", "=", "res.partner"), ("name", "=", "name")]
+ )
cls.partner_title_shortcut_field_id = cls.env["ir.model.fields"].search(
[("model", "=", "res.partner.title"), ("name", "=", "shortcut")]
)
@@ -65,9 +69,92 @@ def setUpClass(cls):
cls.partner_tree_view = cls.env.ref("base.view_partner_tree")
cls.view_partner_title_form = cls.env.ref("base.view_partner_title_form")
cls.view_partner_title_tree = cls.env.ref("base.view_partner_title_tree")
+ cls.users_model = cls.env["ir.model"]._get("res.users")
cls.view_users_form = cls.env.ref("base.view_users_form")
cls.view_users_tree = cls.env.ref("base.view_users_tree")
+ cls.company_model_id = cls.env["ir.model"]._get("res.company")
+ cls.company_name_field = cls.env["ir.model.fields"].search(
+ [("model", "=", "res.company"), ("name", "=", "name")]
+ )
+ cls.company_street_field = cls.env["ir.model.fields"].search(
+ [("model", "=", "res.company"), ("name", "=", "street")]
+ )
+ cls.company_city_field = cls.env["ir.model.fields"].search(
+ [("model", "=", "res.company"), ("name", "=", "city")]
+ )
+ cls.company_name_readonly = cls.env["custom.field.restriction"].create(
+ {
+ "readonly_model_id": cls.company_model_id.id,
+ "field_id": cls.company_name_field.id,
+ "group_ids": [(6, 0, cls.env.ref("base.group_user").ids)],
+ "field_readonly": True,
+ "condition_domain": "[('id', '>', 0)]",
+ }
+ )
+ cls.company_street_required = cls.env["custom.field.restriction"].create(
+ {
+ "required_model_id": cls.company_model_id.id,
+ "field_id": cls.company_street_field.id,
+ "group_ids": [(6, 0, cls.env.ref("base.group_user").ids)],
+ "required": True,
+ "condition_domain": "[('id', '>', 0)]",
+ }
+ )
+ cls.company_city_invisible = cls.env["custom.field.restriction"].create(
+ {
+ "invisible_model_id": cls.company_model_id.id,
+ "field_id": cls.company_city_field.id,
+ "group_ids": [(6, 0, cls.env.ref("base.group_user").ids)],
+ "field_invisible": True,
+ "condition_domain": "[('id', '>', 0)]",
+ }
+ )
+ cls.company_tree_view = cls.env["ir.ui.view"].create(
+ {
+ "name": "Test Tree",
+ "model": "res.company",
+ "type": "tree",
+ "mode": "primary",
+ "arch": ""
+ ""
+ "",
+ }
+ )
+ cls.view_users_form.arch = cls.view_users_form.arch.replace(
+ "",
+ ""
+ ""
+ "",
+ )
+
+ def test_model_form(self):
+ """onchange should set correct model"""
+
+ partner_form_view = self.view_model.default_view(
+ self.partner_model_id._name, "form"
+ )
+ with Form(self.partner_model_id, view=partner_form_view) as partner_form:
+ with partner_form.custom_required_restriction_ids.new() as new_line:
+ self.assertTrue(new_line.required_model_id)
+ new_line.field_id = self.partner_name_field_id
+ with partner_form.custom_readonly_restriction_ids.new() as new_line:
+ self.assertTrue(new_line.readonly_model_id)
+ new_line.field_id = self.partner_name_field_id
+ with partner_form.custom_invisible_restriction_ids.new() as new_line:
+ self.assertTrue(new_line.invisible_model_id)
+ new_line.field_id = self.partner_name_field_id
+
+ def test_relational_fields(self):
+ """res.users has company_ids field. It has restrictions.
+ Restrictions should be added into company tree view"""
+ user = self.env["res.users"].search([], limit=1)
+ arch = user.fields_view_get(view_id=self.view_users_form.id, view_type="form")
+ sub_arch = arch["fields"]["company_ids"]["views"]["tree"]["arch"]
+ self.assertIn("x_computed_res_company_name_readonly", sub_arch)
+ self.assertIn("x_computed_res_company_street_required", sub_arch)
+ self.assertIn("x_computed_res_company_city_visibility", sub_arch)
+
def test_all_web_field_required_invisible_manager(self):
# related fields are created
self.assertTrue(self.invisible_rec_id.visibility_field_id)