From 9931623c40499e9ec657df9f38ebb66ff5b01ba6 Mon Sep 17 00:00:00 2001 From: Mihai Fekete Date: Mon, 10 Jan 2022 16:49:29 +0200 Subject: [PATCH] [14.0] [FIX] Fix base comment template rendering. --- base_comment_template/__init__.py | 2 +- base_comment_template/__manifest__.py | 1 + base_comment_template/models/__init__.py | 5 +- .../models/comment_template.py | 14 ++++ base_comment_template/readme/USAGE.rst | 27 ++++-- .../security/ir.model.access.csv | 1 + .../tests/test_base_comment_template.py | 60 ++++++++++++++ .../views/base_comment_template_view.xml | 8 ++ base_comment_template/wizard/__init__.py | 1 + .../wizard/base_comment_template_preview.py | 83 +++++++++++++++++++ .../base_comment_template_preview_views.xml | 80 ++++++++++++++++++ 11 files changed, 270 insertions(+), 12 deletions(-) create mode 100644 base_comment_template/wizard/__init__.py create mode 100644 base_comment_template/wizard/base_comment_template_preview.py create mode 100644 base_comment_template/wizard/base_comment_template_preview_views.xml diff --git a/base_comment_template/__init__.py b/base_comment_template/__init__.py index 83e553ac4..ba0a966ff 100644 --- a/base_comment_template/__init__.py +++ b/base_comment_template/__init__.py @@ -1,3 +1,3 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from . import models +from . import models, wizard diff --git a/base_comment_template/__manifest__.py b/base_comment_template/__manifest__.py index 495f53901..0e8a8df1e 100644 --- a/base_comment_template/__manifest__.py +++ b/base_comment_template/__manifest__.py @@ -15,6 +15,7 @@ "data": [ "security/ir.model.access.csv", "security/security.xml", + "wizard/base_comment_template_preview_views.xml", "views/base_comment_template_view.xml", "views/res_partner_view.xml", ], diff --git a/base_comment_template/models/__init__.py b/base_comment_template/models/__init__.py index d695c580a..9ac817697 100644 --- a/base_comment_template/models/__init__.py +++ b/base_comment_template/models/__init__.py @@ -1,4 +1 @@ -from . import base_comment_template -from . import comment_template -from . import res_partner -from . import ir_model +from . import base_comment_template, comment_template, ir_model, res_partner diff --git a/base_comment_template/models/comment_template.py b/base_comment_template/models/comment_template.py index 9131cca1b..befd11cd0 100644 --- a/base_comment_template/models/comment_template.py +++ b/base_comment_template/models/comment_template.py @@ -42,3 +42,17 @@ class CommentTemplate(models.AbstractModel): domain = safe_eval(template.domain) if not domain or record.filtered_domain(domain): record.comment_template_ids = [(4, template.id)] + + def render_comment( + self, comment, engine="jinja", add_context=None, post_process=False + ): + self.ensure_one() + comment_texts = self.env["mail.render.mixin"]._render_template( + comment.text, + self._name, + [self.id], + engine=engine, + add_context=add_context, + post_process=post_process, + ) + return comment_texts[self.id] or "" diff --git a/base_comment_template/readme/USAGE.rst b/base_comment_template/readme/USAGE.rst index 2be8054ac..5c7d46bc8 100644 --- a/base_comment_template/readme/USAGE.rst +++ b/base_comment_template/readme/USAGE.rst @@ -16,16 +16,29 @@ The template is a html field which will be rendered just like a mail template, s Change the report related to the model from configuration and add a statement like: -

+ +

- + -

-

+ +

- - -

+ You should always use t-if since the method returns False if no template is found. + +If you want to use Qweb templates, or different context, you can specify it just like in +mail.render.mixin with parameters: + +- engine: "jinja" or "qweb", +- add_context: dict with your own context, +- post_process: perform a post processing on rendered result + +so you could use it : + + +
+ + diff --git a/base_comment_template/security/ir.model.access.csv b/base_comment_template/security/ir.model.access.csv index d2db39e34..af72e1c8f 100644 --- a/base_comment_template/security/ir.model.access.csv +++ b/base_comment_template/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_base_comment_template_user,access_base_comment_template_user,model_base_comment_template,,1,0,0,0 access_base_comment_template,access_base_comment_template no one,model_base_comment_template,base.group_no_one,1,1,1,1 +access_base_comment_template_preview,access.base.comment.template.preview,model_base_comment_template_preview,base.group_user,1,1,1,0 diff --git a/base_comment_template/tests/test_base_comment_template.py b/base_comment_template/tests/test_base_comment_template.py index 30ae71a52..58ff8209b 100644 --- a/base_comment_template/tests/test_base_comment_template.py +++ b/base_comment_template/tests/test_base_comment_template.py @@ -2,6 +2,7 @@ # Copyright 2021 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo.tests import common +from odoo.tools.misc import mute_logger from .fake_models import ResUsers, setup_test_model, teardown_test_model @@ -16,6 +17,7 @@ class TestCommentTemplate(common.SavepointCase): cls.user2 = cls.env.ref("base.demo_user0") cls.partner_id = cls.env.ref("base.res_partner_12") cls.partner2_id = cls.env.ref("base.res_partner_10") + cls.ResPartnerTitle = cls.env["res.partner.title"] cls.main_company = cls.env.ref("base.main_company") cls.company = cls.env["res.company"].create({"name": "Test company"}) cls.before_template_id = cls.env["base.comment.template"].create( @@ -87,3 +89,61 @@ class TestCommentTemplate(common.SavepointCase): self.assertTrue( self.before_template_id not in self.partner_id.base_comment_template_ids ) + + def test_render_comment_text(self): + expected_text = "Test comment render %s" % self.user.name + self.before_template_id.text = "Test comment render ${object.name}" + with self.with_user(self.user.login): + self.assertEqual( + self.user.render_comment(self.before_template_id), expected_text + ) + + def test_render_comment_text_(self): + with mute_logger("odoo.addons.base.models.ir_translation"): + self.env["base.language.install"].create( + {"lang": "ro_RO", "overwrite": True} + ).lang_install() + with mute_logger("odoo.tools.translate"): + self.env["base.update.translations"].create({"lang": "ro_RO"}).act_update() + partner_title = self.ResPartnerTitle.create( + {"name": "Ambassador", "shortcut": "Amb."} + ) + # Adding translated terms + ctx = dict(lang="ro_RO") + partner_title.with_context(ctx).write({"name": "Ambasador", "shortcut": "Amb."}) + self.user.partner_id.title = partner_title + self.before_template_id.text = "Test comment render ${object.title.name}" + + expected_en_text = "Test comment render Ambassador" + expected_ro_text = "Test comment render Ambasador" + with self.with_user(self.user.login): + self.assertEqual( + self.user.render_comment(self.before_template_id), expected_en_text + ) + self.assertEqual( + self.user.with_context(ctx).render_comment(self.before_template_id), + expected_ro_text, + ) + + def test_partner_template_wizaard(self): + partner_preview = ( + self.env["base.comment.template.preview"] + .with_context(default_base_comment_template_id=self.before_template_id.id) + .create({}) + ) + self.assertTrue(partner_preview) + default = ( + self.env["base.comment.template.preview"] + .with_context(default_base_comment_template_id=self.before_template_id.id) + .default_get(partner_preview._fields) + ) + self.assertTrue(default.get("base_comment_template_id")) + resource_ref = partner_preview._selection_target_model() + self.assertTrue(len(resource_ref) >= 2) + partner_preview._compute_no_record() + self.assertTrue(partner_preview.no_record) + + def test_partner_commercial_fields(self): + self.assertTrue( + "base_comment_template_ids" in self.env["res.partner"]._commercial_fields() + ) diff --git a/base_comment_template/views/base_comment_template_view.xml b/base_comment_template/views/base_comment_template_view.xml index 79b4979a5..bcacdeb44 100644 --- a/base_comment_template/views/base_comment_template_view.xml +++ b/base_comment_template/views/base_comment_template_view.xml @@ -44,6 +44,14 @@ bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}" /> +

diff --git a/base_comment_template/wizard/__init__.py b/base_comment_template/wizard/__init__.py new file mode 100644 index 000000000..9a0d64bbf --- /dev/null +++ b/base_comment_template/wizard/__init__.py @@ -0,0 +1 @@ +from . import base_comment_template_preview diff --git a/base_comment_template/wizard/base_comment_template_preview.py b/base_comment_template/wizard/base_comment_template_preview.py new file mode 100644 index 000000000..23dbe4eaf --- /dev/null +++ b/base_comment_template/wizard/base_comment_template_preview.py @@ -0,0 +1,83 @@ +from odoo import api, fields, models +from odoo.tools.safe_eval import safe_eval + + +class BaseCommentTemplatePreview(models.TransientModel): + _name = "base.comment.template.preview" + _description = "Base Comment Template Preview" + + @api.model + def _selection_target_model(self): + models = self.env["ir.model"].search([("is_comment_template", "=", True)]) + return [(model.model, model.name) for model in models] + + @api.model + def _selection_languages(self): + return self.env["res.lang"].get_installed() + + @api.model + def default_get(self, fields): + result = super(BaseCommentTemplatePreview, self).default_get(fields) + base_comment_template_id = self.env.context.get( + "default_base_comment_template_id" + ) + if not base_comment_template_id or "resource_ref" not in fields: + return result + base_comment_template = self.env["base.comment.template"].browse( + base_comment_template_id + ) + result["model_ids"] = base_comment_template.model_ids + domain = safe_eval(base_comment_template.domain) + model = ( + base_comment_template.model_ids[0] + if base_comment_template.model_ids + else False + ) + res = self.env[model.model].search(domain, limit=1) + if res: + result["resource_ref"] = "%s,%s" % (model.model, res.id) + return result + + base_comment_template_id = fields.Many2one( + "base.comment.template", required=True, ondelete="cascade" + ) + lang = fields.Selection(_selection_languages, string="Template Preview Language") + engine = fields.Selection( + [("jinja", "Jinja"), ("qweb", "QWeb")], + string="Template Preview Engine", + defult="jinja", + ) + model_ids = fields.Many2many( + "ir.model", related="base_comment_template_id.model_ids" + ) + model_id = fields.Many2one("ir.model") + body = fields.Char("Body", compute="_compute_base_comment_template_fields") + resource_ref = fields.Reference( + string="Record reference", selection="_selection_target_model" + ) + no_record = fields.Boolean("No Record", compute="_compute_no_record") + + @api.depends("model_id") + def _compute_no_record(self): + for preview in self: + domain = safe_eval(self.base_comment_template_id.domain) + preview.no_record = ( + (self.env[preview.model_id.model].search_count(domain) == 0) + if preview.model_id + else True + ) + + @api.depends("lang", "resource_ref", "engine") + def _compute_base_comment_template_fields(self): + for wizard in self: + if ( + wizard.model_id + and wizard.resource_ref + and wizard.lang + and wizard.engine + ): + wizard.body = wizard.resource_ref.with_context( + lang=wizard.lang + ).render_comment(self.base_comment_template_id, engine=wizard.engine) + else: + wizard.body = wizard.base_comment_template_id.text diff --git a/base_comment_template/wizard/base_comment_template_preview_views.xml b/base_comment_template/wizard/base_comment_template_preview_views.xml new file mode 100644 index 000000000..513bab63d --- /dev/null +++ b/base_comment_template/wizard/base_comment_template_preview_views.xml @@ -0,0 +1,80 @@ + + + + + + base.comment.template.preview.form + base.comment.template.preview + +
+

Preview of + +

+ + +
+ Choose an example + + record: + +
+ + No records + +
+
+

Choose a language: + +

+

Choose an engine: + +

+
+ + + Template Preview + base.comment.template.preview + ir.actions.act_window + form + + new + {'default_base_comment_template_id':active_id} + + + +
+