[IMP] base_comment_template: Refactor code and convert to Many2Many

This commit is contained in:
Víctor Martínez
2021-04-22 18:04:48 +02:00
parent 1d8e552b70
commit 19b7692ee8
10 changed files with 168 additions and 278 deletions

View File

@@ -1,3 +1,4 @@
from . import base_comment_template
from . import comment_template
from . import res_partner
from . import ir_model

View File

@@ -1,76 +1,9 @@
# 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
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from lxml import etree
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.safe_eval import safe_eval
class CommentTemplate(models.AbstractModel):
_name = "comment.template"
_description = (
"base.comment.template to put header and footer "
"in reports based on created comment templates"
)
def get_comment_template_records(
self, position="before_lines", company_id=False, partner_id=False
):
self.ensure_one()
if not company_id:
company_id = self.env.company.id
present_model_id = self.env["ir.model"].search([("model", "=", self._name)])
default_dom = [
("model_ids", "in", present_model_id.id),
("position", "=", position),
]
lang = False
if partner_id and "partner_id" in self._fields:
default_dom += [
"|",
("partner_ids", "=", False),
("partner_ids", "in", partner_id),
]
lang = self.env["res.partner"].browse(partner_id).lang
if company_id and "company_id" in self._fields:
if partner_id and "partner_id" in self._fields:
default_dom.insert(-3, "&")
default_dom += [
"|",
("company_id", "=", company_id),
("company_id", "=", False),
]
templates = self.env["base.comment.template"].search(
default_dom, order="priority"
)
if lang:
templates = templates.with_context({"lang": lang})
return templates
def get_comment_template(
self, position="before_lines", company_id=False, partner_id=False
):
""" Method that is called from report xml and is returning the
position template as a html if exists
"""
self.ensure_one()
templates = self.get_comment_template_records(
position=position, company_id=company_id, partner_id=partner_id
)
template = False
if templates:
for templ in templates:
if self in self.search(safe_eval(templ.domain or "[]")):
template = templ
break
if not template:
return ""
return self.env["mail.template"]._render_template(
template.text, self._name, self.id, post_process=True
)
from odoo import fields, models
class BaseCommentTemplate(models.Model):
@@ -78,11 +11,12 @@ class BaseCommentTemplate(models.Model):
_name = "base.comment.template"
_description = "Comments Template"
_order = "sequence,id"
active = fields.Boolean(default=True)
position = fields.Selection(
string="Position on document",
selection=[("before_lines", "Before lines"), ("after_lines", "After lines")],
selection=[("before_lines", "Top"), ("after_lines", "Bottom")],
required=True,
default="before_lines",
help="This field allows to select the position of the comment on reports.",
@@ -101,7 +35,7 @@ class BaseCommentTemplate(models.Model):
help="This is the text template that will be inserted into reports.",
)
company_id = fields.Many2one(
"res.company",
comodel_name="res.company",
string="Company",
ondelete="cascade",
index=True,
@@ -110,79 +44,46 @@ class BaseCommentTemplate(models.Model):
)
partner_ids = fields.Many2many(
comodel_name="res.partner",
relation="base_comment_template_res_partner_rel",
column1="res_partner_id",
column2="base_comment_template_id",
string="Partner",
ondelete="cascade",
readonly=True,
help="If set, the comment template will be available only for the selected "
"partner.",
)
model_ids = fields.Many2many(
comodel_name="ir.model",
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.",
)
domain = fields.Char(
"Filter Domain",
string="Filter Domain",
required=True,
default="[]",
help="This comment template will be available only for objects "
"that satisfy the condition",
)
priority = fields.Integer(
default=10, copy=False, help="the highest priority = the smallest number",
sequence = fields.Integer(
required=True, default=10, help="The smaller number = The higher priority"
)
@api.constrains("domain", "priority", "model_ids", "position")
def _check_partners_in_company_id(self):
templates = self.search([])
for record in self:
other_template_same_models_and_priority = templates.filtered(
lambda t: t.priority == record.priority
and set(record.model_ids).intersection(record.model_ids)
and t.domain == record.domain
and t.position == record.position
and t.id != record.id
def name_get(self):
"""Redefine the name_get method to show the template name with the position.
"""
res = []
for item in self:
name = "{} ({})".format(
item.name, dict(self._fields["position"].selection).get(item.position)
)
if other_template_same_models_and_priority:
raise ValidationError(
_(
"There are other records with same models, priority, "
"domain and position."
)
)
@api.model
def fields_view_get(
self, view_id=None, view_type="form", toolbar=False, submenu=False
):
# modify the form view of base_commnent_template
# Add domain on model_id to get only models that have a report set
# and those whom have inherited this model
res = super().fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
)
if view_type == "form":
doc = etree.XML(res["arch"])
for node in doc.xpath("//field[@name='model_ids']"):
report_models = self.env["ir.actions.report"].search([]).mapped("model")
model_ids = (
self.env["ir.model"]
.search(
[
("model", "in", report_models),
("is_comment_template", "=", True),
"!",
("name", "=like", "ir.%"),
]
)
.ids
)
model_filter = "[('id','in'," + str(model_ids) + ")]"
node.set("domain", model_filter)
res["arch"] = etree.tostring(doc, encoding="unicode")
if self.env.context.get("comment_template_model_display"):
name += " (%s)" % ", ".join(item.model_ids.mapped("name"))
res.append((item.id, name))
return res

View File

@@ -0,0 +1,45 @@
# 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
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
from odoo.tools.safe_eval import safe_eval
class CommentTemplate(models.AbstractModel):
_name = "comment.template"
_description = (
"base.comment.template to put header and footer "
"in reports based on created comment templates"
)
# This field allows to set any given field that determines the source partner for
# the comment templates downstream.
# E.g.: other models where the partner field is called customer_id.
_comment_template_partner_field_name = "partner_id"
comment_template_ids = fields.Many2many(
compute="_compute_comment_template_ids",
comodel_name="base.comment.template",
string="Comment Template",
domain=lambda self: [("model_ids.model", "=", self._name)],
store=True,
readonly=False,
)
@api.depends(_comment_template_partner_field_name)
def _compute_comment_template_ids(self):
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),
]
)
for template in templates:
if not template.domain or self in self.search(
safe_eval(template.domain)
):
record.comment_template_ids = [(4, template.id)]

View File

@@ -1,7 +1,8 @@
# Copyright 2020 NextERP Romania SRL
# Copyright 2021 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
class ResPartner(models.Model):
@@ -9,6 +10,14 @@ class ResPartner(models.Model):
base_comment_template_ids = fields.Many2many(
comodel_name="base.comment.template",
relation="base_comment_template_res_partner_rel",
column1="base_comment_template_id",
column2="res_partner_id",
string="Comment Templates",
help="Specific partner comments that can be included in reports",
)
@api.model
def _commercial_fields(self):
"""Add comment templates to commercial fields"""
return super()._commercial_fields() + ["base_comment_template_ids"]