mirror of https://github.com/OCA/web.git
135 lines
4.6 KiB
Python
135 lines
4.6 KiB
Python
# Copyright 2023 ooops404
|
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class CustomFieldRestriction(models.Model):
|
|
_name = "custom.field.restriction"
|
|
_description = "Make field invisible or required"
|
|
|
|
field_id = fields.Many2one(
|
|
"ir.model.fields",
|
|
ondelete="cascade",
|
|
required=True,
|
|
string="Field",
|
|
)
|
|
field_name = fields.Char(
|
|
related="field_id.name",
|
|
store=True,
|
|
string="Field Name",
|
|
)
|
|
required_model_id = fields.Many2one(
|
|
"ir.model",
|
|
ondelete="cascade",
|
|
string="required_model_id",
|
|
index=True,
|
|
)
|
|
invisible_model_id = fields.Many2one(
|
|
"ir.model",
|
|
ondelete="cascade",
|
|
string="invisible_model_id",
|
|
index=True,
|
|
)
|
|
readonly_model_id = fields.Many2one(
|
|
"ir.model",
|
|
ondelete="cascade",
|
|
string="readonly_model_id",
|
|
index=True,
|
|
)
|
|
model_name = fields.Char(
|
|
compute="_compute_model_name",
|
|
store=True,
|
|
string="Model Name",
|
|
index=True,
|
|
)
|
|
condition_domain = fields.Char()
|
|
group_ids = fields.Many2many("res.groups", required=True)
|
|
default_required = fields.Boolean(related="field_id.required")
|
|
required = fields.Boolean()
|
|
field_invisible = fields.Boolean()
|
|
field_readonly = fields.Boolean()
|
|
# generated technical fields used in form attrs:
|
|
visibility_field_id = fields.Many2one("ir.model.fields")
|
|
readonly_field_id = fields.Many2one("ir.model.fields")
|
|
required_field_id = fields.Many2one("ir.model.fields")
|
|
|
|
@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,
|
|
}
|
|
)
|
|
|
|
@api.depends("required_model_id", "invisible_model_id", "readonly_model_id")
|
|
def _compute_model_name(self):
|
|
for rec in self:
|
|
if rec.required_model_id:
|
|
rec.model_name = rec.required_model_id.model
|
|
elif rec.invisible_model_id:
|
|
rec.model_name = rec.invisible_model_id.model
|
|
elif rec.readonly_model_id:
|
|
rec.model_name = rec.readonly_model_id.model
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
rec = super().create(vals)
|
|
if rec.invisible_model_id and rec.field_invisible:
|
|
rec.create_restriction_field("visibility")
|
|
elif rec.readonly_model_id and rec.field_readonly:
|
|
rec.create_restriction_field("readonly")
|
|
elif rec.required_model_id and rec.required:
|
|
rec.create_restriction_field("required")
|
|
return rec
|
|
|
|
def write(self, vals):
|
|
res = super().write(vals)
|
|
if vals.get("field_id"):
|
|
if self.visibility_field_id:
|
|
self.visibility_field_id.unlink()
|
|
self.create_restriction_field("visibility")
|
|
elif self.readonly_field_id:
|
|
self.readonly_field_id.unlink()
|
|
self.create_restriction_field("readonly")
|
|
elif self.required_field_id:
|
|
self.required_field_id.unlink()
|
|
self.create_restriction_field("required")
|
|
return res
|
|
|
|
def create_restriction_field(self, f_type):
|
|
field_name = self.get_field_name(f_type)
|
|
field_id = self.env["ir.model.fields"].search([("name", "=", field_name)])
|
|
if f_type == "required":
|
|
rec_model_id = self.required_model_id.id
|
|
rec_field_name = "required_field_id"
|
|
elif f_type == "readonly":
|
|
rec_model_id = self.readonly_model_id.id
|
|
rec_field_name = "readonly_field_id"
|
|
elif f_type == "visibility":
|
|
rec_model_id = self.invisible_model_id.id
|
|
rec_field_name = "visibility_field_id"
|
|
if not field_id:
|
|
field_id = self.env["ir.model.fields"].create(
|
|
{
|
|
"name": field_name,
|
|
"model_id": rec_model_id,
|
|
"state": "manual",
|
|
"field_description": "%s %s field" % (self.field_id.name, f_type),
|
|
"store": False,
|
|
"ttype": "boolean",
|
|
"compute": "for r in self: r._compute_restrictions_fields()",
|
|
}
|
|
)
|
|
self[rec_field_name] = field_id
|
|
|
|
def get_field_name(self, f_type):
|
|
# e.g. x_computed_res_partner_name_readonly
|
|
res = "x_computed_%s_%s_%s" % (
|
|
self.field_id.model.replace(".", "_"),
|
|
self.field_id.name,
|
|
f_type,
|
|
)
|
|
return res
|