forked from Techsystech/web
[IMP] web_field_required_invisible_manager: compatibility with tier validation
parent
880be42b9b
commit
0d3f420007
|
@ -1,2 +1,4 @@
|
|||
from . import custom_field_restriction
|
||||
from . import models
|
||||
from . import base
|
||||
from . import ir_ui_view
|
||||
from . import ir_model
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
# Copyright 2023 ooops404
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
|
||||
from odoo import models
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
class Base(models.AbstractModel):
|
||||
_inherit = "base"
|
||||
|
||||
def default_get(self, fields_list):
|
||||
res = super(Base, self).default_get(fields_list)
|
||||
if self.env.user.has_group("base.group_user"):
|
||||
vals = self._default_get_compute_restrictions_fields()
|
||||
if vals:
|
||||
res.update(vals)
|
||||
return res
|
||||
|
||||
def _default_get_compute_restrictions_fields(self):
|
||||
restrictions = self.env["custom.field.restriction"].search(
|
||||
[("model_name", "=", self._name)]
|
||||
)
|
||||
values = {}
|
||||
if not restrictions:
|
||||
return values
|
||||
for r in restrictions:
|
||||
if r.visibility_field_id:
|
||||
field_name = r.visibility_field_id.name
|
||||
values[field_name] = False
|
||||
if r.required_field_id:
|
||||
field_name = r.required_field_id.name
|
||||
values[field_name] = False
|
||||
if r.readonly_field_id:
|
||||
field_name = r.readonly_field_id.name
|
||||
values[field_name] = False
|
||||
if r.group_ids:
|
||||
if r.group_ids & self.env.user.groups_id:
|
||||
values[field_name] = True
|
||||
return values
|
||||
|
||||
def _compute_restrictions_fields(self):
|
||||
"""Common compute method for all restrictions types"""
|
||||
for record in self:
|
||||
restrictions = self.env["custom.field.restriction"].search(
|
||||
[("model_name", "=", self._name)]
|
||||
)
|
||||
if not restrictions:
|
||||
return
|
||||
for r in restrictions:
|
||||
if r.visibility_field_id:
|
||||
field_name = r.visibility_field_id.name
|
||||
record[field_name] = False
|
||||
if r.required_field_id:
|
||||
field_name = r.required_field_id.name
|
||||
record[field_name] = False
|
||||
if r.readonly_field_id:
|
||||
field_name = r.readonly_field_id.name
|
||||
record[field_name] = False
|
||||
if r.condition_domain:
|
||||
filtered_rec_id = record.filtered_domain(
|
||||
safe_eval(r.condition_domain)
|
||||
)
|
||||
if filtered_rec_id and r.group_ids & self.env.user.groups_id:
|
||||
record[field_name] = True
|
||||
elif r.group_ids:
|
||||
if r.group_ids & self.env.user.groups_id:
|
||||
record[field_name] = True
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright 2023 ooops404
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class IrModel(models.Model):
|
||||
_inherit = "ir.model"
|
||||
|
||||
custom_required_restriction_ids = fields.One2many(
|
||||
"custom.field.restriction",
|
||||
"required_model_id",
|
||||
)
|
||||
custom_invisible_restriction_ids = fields.One2many(
|
||||
"custom.field.restriction",
|
||||
"invisible_model_id",
|
||||
)
|
||||
custom_readonly_restriction_ids = fields.One2many(
|
||||
"custom.field.restriction",
|
||||
"readonly_model_id",
|
||||
)
|
|
@ -1,60 +1,40 @@
|
|||
# Copyright 2023 ooops404
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
|
||||
import json as simplejson
|
||||
import json
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
from odoo import models
|
||||
|
||||
from odoo.addons.base.models.ir_ui_view import NameManager
|
||||
|
||||
|
||||
class IrModel(models.Model):
|
||||
_inherit = "ir.model"
|
||||
class IrUiView(models.Model):
|
||||
_inherit = "ir.ui.view"
|
||||
|
||||
custom_required_restriction_ids = fields.One2many(
|
||||
"custom.field.restriction",
|
||||
"required_model_id",
|
||||
)
|
||||
custom_invisible_restriction_ids = fields.One2many(
|
||||
"custom.field.restriction",
|
||||
"invisible_model_id",
|
||||
)
|
||||
custom_readonly_restriction_ids = fields.One2many(
|
||||
"custom.field.restriction",
|
||||
"readonly_model_id",
|
||||
)
|
||||
|
||||
|
||||
class Base(models.AbstractModel):
|
||||
_inherit = "base"
|
||||
|
||||
@api.model
|
||||
def fields_view_get(
|
||||
self, view_id=None, view_type=False, toolbar=False, submenu=False
|
||||
):
|
||||
arch = super().fields_view_get(
|
||||
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
|
||||
)
|
||||
if view_type not in ["form", "tree"]:
|
||||
return arch
|
||||
# TODO speed up somehow
|
||||
def postprocess_and_fields(self, node, model=None, validate=False):
|
||||
arch, new_fields = super().postprocess_and_fields(node, model, validate)
|
||||
if self.type not in ["form", "tree"] and node.tag not in ["form", "tree"]:
|
||||
return arch, new_fields
|
||||
restrictions = self.env["custom.field.restriction"].search(
|
||||
[
|
||||
("model_name", "=", self._name),
|
||||
("model_name", "=", model or self.model),
|
||||
("group_ids", "in", self.env.user.groups_id.ids),
|
||||
]
|
||||
)
|
||||
view_type = node.tag or self.type
|
||||
if restrictions:
|
||||
arch = self.create_restrictions_fields(restrictions, view_type, arch)
|
||||
arch = self.process_child_fields(arch, view_type)
|
||||
return arch
|
||||
arch = self.process_child_fields(arch, new_fields, view_type)
|
||||
return arch, new_fields
|
||||
|
||||
def process_child_fields(self, arch, view_type):
|
||||
def process_child_fields(self, arch, new_fields, view_type):
|
||||
"""Collect all relational fields and update their views"""
|
||||
view_model = self.env["ir.model"]._get(self.model)
|
||||
related_fields = [
|
||||
(k, v.comodel_name) for k, v in self._fields.items() if v.comodel_name
|
||||
(k.name, k.relation)
|
||||
for k in view_model.field_id
|
||||
if k.ttype in ["many2many", "many2one", "one2many"]
|
||||
]
|
||||
related_models_names = [r[1] for r in related_fields]
|
||||
restrictions = self.env["custom.field.restriction"].search(
|
||||
|
@ -69,16 +49,16 @@ class Base(models.AbstractModel):
|
|||
filter(lambda x: x[1] == restr.model_name, related_fields)
|
||||
)
|
||||
for todo_field in todo_fields:
|
||||
if not arch["fields"].get(todo_field[0]):
|
||||
if not new_fields.get(todo_field[0]):
|
||||
continue
|
||||
for sub_view_type, sub_view in arch["fields"][todo_field[0]][
|
||||
for sub_view_type, sub_view in new_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"] = self.create_restrictions_fields(
|
||||
restr, view_type, z_arch["arch"]
|
||||
)
|
||||
if type(z_arch["arch"]) is bytes:
|
||||
z_arch["arch"] = z_arch["arch"].decode("utf-8")
|
||||
|
@ -107,7 +87,7 @@ class Base(models.AbstractModel):
|
|||
return arch
|
||||
|
||||
def create_restrictions_fields(self, restrictions, view_type, arch):
|
||||
doc = etree.XML(arch["arch"])
|
||||
doc = etree.XML(arch)
|
||||
for node in doc.xpath("//field"):
|
||||
name = node.attrib.get("name")
|
||||
restrictions_filtered = restrictions.filtered(
|
||||
|
@ -125,91 +105,33 @@ class Base(models.AbstractModel):
|
|||
"<field name='%s' column_invisible='1' optional='hide'/>"
|
||||
)
|
||||
if r.field_invisible and r.invisible_model_id:
|
||||
modifiers = simplejson.loads(node.get("modifiers"))
|
||||
modifiers = json.loads(node.get("modifiers"))
|
||||
visibility_field_name = r.get_field_name("visibility")
|
||||
modifiers["invisible"] = (
|
||||
"[('%s', '=', True)]" % visibility_field_name
|
||||
)
|
||||
node.set("modifiers", simplejson.dumps(modifiers))
|
||||
node.set("modifiers", json.dumps(modifiers))
|
||||
new_node = etree.fromstring(field_node_str % visibility_field_name)
|
||||
new_node.set("invisible", "1")
|
||||
new_node.set("modifiers", field_node_mod)
|
||||
node.getparent().append(new_node)
|
||||
if r.required_field_id and r.required_model_id:
|
||||
modifiers = simplejson.loads(node.get("modifiers"))
|
||||
modifiers = json.loads(node.get("modifiers"))
|
||||
required_field_name = r.get_field_name("required")
|
||||
modifiers["required"] = "[('%s', '=', True)]" % required_field_name
|
||||
node.set("modifiers", simplejson.dumps(modifiers))
|
||||
node.set("modifiers", json.dumps(modifiers))
|
||||
new_node = etree.fromstring(field_node_str % required_field_name)
|
||||
new_node.set("invisible", "1")
|
||||
new_node.set("modifiers", field_node_mod)
|
||||
node.getparent().append(new_node)
|
||||
if r.readonly_field_id and r.readonly_model_id:
|
||||
modifiers = simplejson.loads(node.get("modifiers"))
|
||||
modifiers = json.loads(node.get("modifiers"))
|
||||
readonly_field_name = r.get_field_name("readonly")
|
||||
modifiers["readonly"] = "[('%s', '=', True)]" % readonly_field_name
|
||||
node.set("modifiers", simplejson.dumps(modifiers))
|
||||
node.set("modifiers", json.dumps(modifiers))
|
||||
new_node = etree.fromstring(field_node_str % readonly_field_name)
|
||||
new_node.set("invisible", "1")
|
||||
new_node.set("modifiers", field_node_mod)
|
||||
node.getparent().append(new_node)
|
||||
arch["arch"] = etree.tostring(doc)
|
||||
arch = etree.tostring(doc)
|
||||
return arch
|
||||
|
||||
def _compute_restrictions_fields(self):
|
||||
"""Common compute method for all restrictions types"""
|
||||
for record in self:
|
||||
restrictions = self.env["custom.field.restriction"].search(
|
||||
[("model_name", "=", self._name)]
|
||||
)
|
||||
if not restrictions:
|
||||
return
|
||||
for r in restrictions:
|
||||
if r.visibility_field_id:
|
||||
field_name = r.visibility_field_id.name
|
||||
record[field_name] = False
|
||||
if r.required_field_id:
|
||||
field_name = r.required_field_id.name
|
||||
record[field_name] = False
|
||||
if r.readonly_field_id:
|
||||
field_name = r.readonly_field_id.name
|
||||
record[field_name] = False
|
||||
if r.condition_domain:
|
||||
filtered_rec_id = record.filtered_domain(
|
||||
safe_eval(r.condition_domain)
|
||||
)
|
||||
if filtered_rec_id and r.group_ids & self.env.user.groups_id:
|
||||
record[field_name] = True
|
||||
elif r.group_ids:
|
||||
if r.group_ids & self.env.user.groups_id:
|
||||
record[field_name] = True
|
||||
|
||||
def default_get(self, fields_list):
|
||||
res = super(Base, self).default_get(fields_list)
|
||||
if self.env.user.has_group("base.group_user"):
|
||||
vals = self._default_get_compute_restrictions_fields()
|
||||
if vals:
|
||||
res.update(vals)
|
||||
return res
|
||||
|
||||
def _default_get_compute_restrictions_fields(self):
|
||||
restrictions = self.env["custom.field.restriction"].search(
|
||||
[("model_name", "=", self._name)]
|
||||
)
|
||||
values = {}
|
||||
if not restrictions:
|
||||
return values
|
||||
for r in restrictions:
|
||||
if r.visibility_field_id:
|
||||
field_name = r.visibility_field_id.name
|
||||
values[field_name] = False
|
||||
if r.required_field_id:
|
||||
field_name = r.required_field_id.name
|
||||
values[field_name] = False
|
||||
if r.readonly_field_id:
|
||||
field_name = r.readonly_field_id.name
|
||||
values[field_name] = False
|
||||
if r.group_ids:
|
||||
if r.group_ids & self.env.user.groups_id:
|
||||
values[field_name] = True
|
||||
return values
|
|
@ -1,3 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
|
|
Loading…
Reference in New Issue