forked from Techsystech/web
commit
ed1ac14353
|
@ -56,13 +56,30 @@ class CustomFieldRestriction(models.Model):
|
||||||
|
|
||||||
@api.onchange("field_id")
|
@api.onchange("field_id")
|
||||||
def onchange_field_id(self):
|
def onchange_field_id(self):
|
||||||
self.update(
|
vals = {
|
||||||
{
|
"required": self.field_id.required,
|
||||||
"required": self.field_id.required,
|
"field_invisible": False,
|
||||||
"field_invisible": False,
|
"field_readonly": self.field_id.readonly,
|
||||||
"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")
|
@api.depends("required_model_id", "invisible_model_id", "readonly_model_id")
|
||||||
def _compute_model_name(self):
|
def _compute_model_name(self):
|
||||||
|
|
|
@ -7,6 +7,8 @@ from lxml import etree
|
||||||
from odoo import api, fields, models
|
from odoo import api, fields, models
|
||||||
from odoo.tools.safe_eval import safe_eval
|
from odoo.tools.safe_eval import safe_eval
|
||||||
|
|
||||||
|
from odoo.addons.base.models.ir_ui_view import NameManager
|
||||||
|
|
||||||
|
|
||||||
class IrModel(models.Model):
|
class IrModel(models.Model):
|
||||||
_inherit = "ir.model"
|
_inherit = "ir.model"
|
||||||
|
@ -45,7 +47,62 @@ class Base(models.AbstractModel):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
if restrictions:
|
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
|
return arch
|
||||||
|
|
||||||
def create_restrictions_fields(self, restrictions, view_type, arch):
|
def create_restrictions_fields(self, restrictions, view_type, arch):
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
# Copyright 2023 ooops404
|
# Copyright 2023 ooops404
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# 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):
|
class TestFieldRequiredIvisibleManager(common.SavepointCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(TestFieldRequiredIvisibleManager, cls).setUpClass()
|
super(TestFieldRequiredIvisibleManager, cls).setUpClass()
|
||||||
|
cls.view_model = cls.env["ir.ui.view"].sudo()
|
||||||
cls.partner_name_field_id = cls.env["ir.model.fields"].search(
|
cls.partner_name_field_id = cls.env["ir.model.fields"].search(
|
||||||
[("model", "=", "res.partner"), ("name", "=", "name")]
|
[("model", "=", "res.partner"), ("name", "=", "name")]
|
||||||
)
|
)
|
||||||
|
@ -21,6 +22,9 @@ class TestFieldRequiredIvisibleManager(common.SavepointCase):
|
||||||
cls.partner_title_name_field_id = cls.env["ir.model.fields"].search(
|
cls.partner_title_name_field_id = cls.env["ir.model.fields"].search(
|
||||||
[("model", "=", "res.partner.title"), ("name", "=", "name")]
|
[("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(
|
cls.partner_title_shortcut_field_id = cls.env["ir.model.fields"].search(
|
||||||
[("model", "=", "res.partner.title"), ("name", "=", "shortcut")]
|
[("model", "=", "res.partner.title"), ("name", "=", "shortcut")]
|
||||||
)
|
)
|
||||||
|
@ -65,9 +69,92 @@ class TestFieldRequiredIvisibleManager(common.SavepointCase):
|
||||||
cls.partner_tree_view = cls.env.ref("base.view_partner_tree")
|
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_form = cls.env.ref("base.view_partner_title_form")
|
||||||
cls.view_partner_title_tree = cls.env.ref("base.view_partner_title_tree")
|
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_form = cls.env.ref("base.view_users_form")
|
||||||
cls.view_users_tree = cls.env.ref("base.view_users_tree")
|
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": "<tree><field name='city'/>"
|
||||||
|
"<field name='street'/>"
|
||||||
|
"<field name='name'/></tree>",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cls.view_users_form.arch = cls.view_users_form.arch.replace(
|
||||||
|
"</notebook>",
|
||||||
|
"</notebook><field name='company_ids'><tree><field name='city'/>"
|
||||||
|
"<field name='street'/>"
|
||||||
|
"<field name='name'/></tree></field>",
|
||||||
|
)
|
||||||
|
|
||||||
|
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):
|
def test_all_web_field_required_invisible_manager(self):
|
||||||
# related fields are created
|
# related fields are created
|
||||||
self.assertTrue(self.invisible_rec_id.visibility_field_id)
|
self.assertTrue(self.invisible_rec_id.visibility_field_id)
|
||||||
|
|
Loading…
Reference in New Issue