[FIX] base_comment_template: Add models text field to prevent error from ir.model model

TT40209
This commit is contained in:
Víctor Martínez
2022-11-02 08:52:09 +01:00
parent 8dfa82089f
commit d9d2ef5b27
8 changed files with 142 additions and 32 deletions

View File

@@ -1,9 +1,10 @@
# Copyright 2014 Guewen Baconnier (Camptocamp SA)
# Copyright 2013-2014 Nicolas Bessi (Camptocamp SA)
# Copyright 2020 NextERP Romania SRL
# Copyright 2021 Tecnativa - Víctor Martínez
# Copyright 2021-2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class BaseCommentTemplate(models.Model):
@@ -51,17 +52,15 @@ class BaseCommentTemplate(models.Model):
help="If set, the comment template will be available only for the selected "
"partner.",
)
models = fields.Text(required=True)
model_ids = fields.Many2many(
comodel_name="ir.model",
compute="_compute_model_ids",
compute_sudo=True,
string="IR Model",
ondelete="cascade",
domain=[
("is_comment_template", "=", True),
("model", "!=", "comment.template"),
],
required=True,
help="This comment template will be available on this models. "
"You can see here only models allowed to set the coment template.",
search="_search_model_ids",
)
domain = fields.Char(
string="Filter Domain",
@@ -74,6 +73,37 @@ class BaseCommentTemplate(models.Model):
required=True, default=10, help="The smaller number = The higher priority"
)
def _get_ir_model_items(self, models):
return (
self.env["ir.model"]
.sudo()
.search(
[
("is_comment_template", "=", True),
("model", "!=", "comment.template"),
("model", "in", models),
]
)
)
@api.depends("models")
def _compute_model_ids(self):
im_model = self.env["ir.model"]
for item in self:
models = im_model.browse()
if item.models:
models = self._get_ir_model_items(item.models.split(","))
item.model_ids = [(6, 0, models.ids)]
@api.constrains("models")
def check_models(self):
"""Avoid non-existing or not allowed models (is_comment_template=True)"""
for item in self.filtered("models"):
models = item.models.split(",")
res = self._get_ir_model_items(item.models.split(","))
if not res or len(res) != len(models):
raise ValidationError(_("Some model (%s) not found") % item.models)
def name_get(self):
"""Redefine the name_get method to show the template name with the position."""
res = []
@@ -85,3 +115,10 @@ class BaseCommentTemplate(models.Model):
name += " (%s)" % ", ".join(item.model_ids.mapped("name"))
res.append((item.id, name))
return res
def _search_model_ids(self, operator, value):
# We cannot use model_ids.model in search() method to avoid access errors
allowed_items = (
self.sudo().search([]).filtered(lambda x: x.model_ids.model == value)
)
return [("id", "in", allowed_items.ids)]

View File

@@ -1,9 +1,10 @@
# Copyright 2014 Guewen Baconnier (Camptocamp SA)
# Copyright 2013-2014 Nicolas Bessi (Camptocamp SA)
# Copyright 2020 NextERP Romania SRL
# Copyright 2021 Tecnativa - Víctor Martínez
# Copyright 2021-2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
from odoo.osv import expression
from odoo.tools.safe_eval import safe_eval
@@ -20,23 +21,28 @@ class CommentTemplate(models.AbstractModel):
comment_template_ids = fields.Many2many(
compute="_compute_comment_template_ids",
compute_sudo=True,
comodel_name="base.comment.template",
string="Comment Template",
domain=lambda self: [("model_ids.model", "=", self._name)],
domain=lambda self: [("model_ids", "=", self._name)],
store=True,
readonly=False,
)
@api.depends(_comment_template_partner_field_name)
def _compute_comment_template_ids(self):
template_model = self.env["base.comment.template"]
template_domain = template_model._search_model_ids("=", self._name)
for record in self:
partner = record[self._comment_template_partner_field_name]
record.comment_template_ids = [(5,)]
templates = self.env["base.comment.template"].search(
[
("id", "in", partner.base_comment_template_ids.ids),
("model_ids.model", "=", self._name),
]
templates = template_model.search(
expression.AND(
[
[("id", "in", partner.base_comment_template_ids.ids)],
template_domain,
]
)
)
for template in templates:
domain = safe_eval(template.domain)