mirror of
https://github.com/OCA/reporting-engine.git
synced 2025-02-16 16:30:38 +02:00
@@ -1,3 +1,3 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
from . import models
|
from . import models, wizard
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"data": [
|
"data": [
|
||||||
"security/ir.model.access.csv",
|
"security/ir.model.access.csv",
|
||||||
"security/security.xml",
|
"security/security.xml",
|
||||||
|
"wizard/base_comment_template_preview_views.xml",
|
||||||
"views/base_comment_template_view.xml",
|
"views/base_comment_template_view.xml",
|
||||||
"views/res_partner_view.xml",
|
"views/res_partner_view.xml",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,4 +1 @@
|
|||||||
from . import base_comment_template
|
from . import base_comment_template, comment_template, ir_model, res_partner
|
||||||
from . import comment_template
|
|
||||||
from . import res_partner
|
|
||||||
from . import ir_model
|
|
||||||
|
|||||||
@@ -42,3 +42,17 @@ class CommentTemplate(models.AbstractModel):
|
|||||||
domain = safe_eval(template.domain)
|
domain = safe_eval(template.domain)
|
||||||
if not domain or record.filtered_domain(domain):
|
if not domain or record.filtered_domain(domain):
|
||||||
record.comment_template_ids = [(4, template.id)]
|
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 ""
|
||||||
|
|||||||
@@ -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:
|
Change the report related to the model from configuration and add a statement like:
|
||||||
|
|
||||||
<p t-if="o.get_comment_template('before_lines', o.company_id.id, o.partner_id and o.partner_id.id or False)">
|
<t t-foreach="o.comment_template_ids.filtered(lambda x: x.position == 'before_lines')" t-as="comment_template_top">
|
||||||
|
<div t-raw="o.render_comment(comment_template_top)" />
|
||||||
|
|
||||||
<span t-raw="o.get_comment_template('before_lines', o.company_id.id, o.partner_id and o.partner_id.id or False)"/>
|
</t>
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p t-if="o.get_comment_template('after_lines', o.company_id.id, o.partner_id and o.partner_id.id or False)">
|
<t t-foreach="o.comment_template_ids.filtered(lambda x: x.position == 'after_lines')" t-as="comment_template_bottom">
|
||||||
|
<div t-raw="o.render_comment(comment_template_bottom)" />
|
||||||
|
|
||||||
<span t-raw="o.get_comment_template('after_lines', o.company_id.id, o.partner_id and o.partner_id.id or False)"/>
|
</t>
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
You should always use t-if since the method returns False if no template is found.
|
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 :
|
||||||
|
|
||||||
|
<t t-foreach="o.comment_template_ids.filtered(lambda x: x.position == 'before_lines')" t-as="comment_template_top">
|
||||||
|
<div t-raw="o.render_comment(comment_template_top, engine='qweb', add_context={my dict}, postprocess=True)" />
|
||||||
|
|
||||||
|
</t>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
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_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,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
|
||||||
|
|||||||
|
@@ -2,6 +2,7 @@
|
|||||||
# Copyright 2021 Tecnativa - Víctor Martínez
|
# Copyright 2021 Tecnativa - Víctor Martínez
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
from odoo.tests import common
|
from odoo.tests import common
|
||||||
|
from odoo.tools.misc import mute_logger
|
||||||
|
|
||||||
from .fake_models import ResUsers, setup_test_model, teardown_test_model
|
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.user2 = cls.env.ref("base.demo_user0")
|
||||||
cls.partner_id = cls.env.ref("base.res_partner_12")
|
cls.partner_id = cls.env.ref("base.res_partner_12")
|
||||||
cls.partner2_id = cls.env.ref("base.res_partner_10")
|
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.main_company = cls.env.ref("base.main_company")
|
||||||
cls.company = cls.env["res.company"].create({"name": "Test company"})
|
cls.company = cls.env["res.company"].create({"name": "Test company"})
|
||||||
cls.before_template_id = cls.env["base.comment.template"].create(
|
cls.before_template_id = cls.env["base.comment.template"].create(
|
||||||
@@ -87,3 +89,61 @@ class TestCommentTemplate(common.SavepointCase):
|
|||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.before_template_id not in self.partner_id.base_comment_template_ids
|
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()
|
||||||
|
)
|
||||||
|
|||||||
@@ -44,6 +44,14 @@
|
|||||||
bg_color="bg-danger"
|
bg_color="bg-danger"
|
||||||
attrs="{'invisible': [('active', '=', True)]}"
|
attrs="{'invisible': [('active', '=', True)]}"
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
class="oe_stat_button"
|
||||||
|
name="%(base_comment_template_preview_action)d"
|
||||||
|
icon="fa-search-plus"
|
||||||
|
string="Preview"
|
||||||
|
type="action"
|
||||||
|
target="new"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<h1>
|
<h1>
|
||||||
|
|||||||
1
base_comment_template/wizard/__init__.py
Normal file
1
base_comment_template/wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import base_comment_template_preview
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- SMS Template Preview -->
|
||||||
|
<record model="ir.ui.view" id="base_comment_template_preview_form">
|
||||||
|
<field name="name">base.comment.template.preview.form</field>
|
||||||
|
<field name="model">base.comment.template.preview</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Base Comment Preview">
|
||||||
|
<h3>Preview of
|
||||||
|
<field
|
||||||
|
name="base_comment_template_id"
|
||||||
|
readonly="1"
|
||||||
|
nolabel="1"
|
||||||
|
class="oe_inline"
|
||||||
|
/>
|
||||||
|
</h3>
|
||||||
|
<field name="no_record" invisible="1" />
|
||||||
|
<field name="model_ids" />
|
||||||
|
<div class="o_row">
|
||||||
|
<span>Choose an example
|
||||||
|
<field
|
||||||
|
name="model_id"
|
||||||
|
domain="[('id', 'in', model_ids or False)]"
|
||||||
|
/>
|
||||||
|
record:
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<field
|
||||||
|
name="resource_ref"
|
||||||
|
class="oe_inline"
|
||||||
|
options="{'hide_model': True, 'no_create': True, 'no_edit': True, 'no_open': True}"
|
||||||
|
attrs="{'invisible': [('no_record', '=', True)]}"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="text-warning"
|
||||||
|
attrs="{'invisible': [('no_record', '=', False)]}"
|
||||||
|
>No records
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>Choose a language:
|
||||||
|
<field name="lang" class="oe_inline ml8" />
|
||||||
|
</p>
|
||||||
|
<p>Choose an engine:
|
||||||
|
<field name="engine" class="oe_inline ml8" />
|
||||||
|
</p>
|
||||||
|
<label for="body" string="Base Comment content" />
|
||||||
|
<hr />
|
||||||
|
<field
|
||||||
|
name="body"
|
||||||
|
readonly="1"
|
||||||
|
nolabel="1"
|
||||||
|
options='{"safe": True}'
|
||||||
|
/>
|
||||||
|
<hr />
|
||||||
|
<footer>
|
||||||
|
<button
|
||||||
|
string="Discard"
|
||||||
|
class="btn-secondary"
|
||||||
|
special="cancel"
|
||||||
|
/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="base_comment_template_preview_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Template Preview</field>
|
||||||
|
<field name="res_model">base.comment.template.preview</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="base_comment_template_preview_form" />
|
||||||
|
<field name="target">new</field>
|
||||||
|
<field name="context">{'default_base_comment_template_id':active_id}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user