Newer
Older
##############################################################################
#
# Redner Odoo module
# Copyright © 2016 XCG Consulting <https://xcg-consulting.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import logging
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from ..redner import Redner
LANGUAGE_MJML_MUSTACHE = "text/mjml|mustache"
DEFAULT_LANGUAGE = LANGUAGE_MJML_MUSTACHE
class RednerTemplate(models.Model):
_name = "redner.template"
damien.habets
committed
_description = "Redner Template"
name = fields.Char(
string="Name",
required=True,
help="This is a name of template mjml redner",
)
body = fields.Text(
string="Template remote Id",
translate=True,
help="Code for the mjml redner template must be added here",
)
slug = fields.Char(string="Slug")
active = fields.Boolean(
string="Active",
default=True,
help=(
"If unchecked, it will allow you to hide the "
"template without removing it."
),
)
is_mjml = fields.Boolean(
string="Is MJML",
default=True,
help="set to false if your template doesn't contain MJML",
)
detected_keywords = fields.Text(
string="Variables", readonly=True, compute="_compute_keywords"
selection=[
("text/html|mustache", "HTML + mustache"),
(LANGUAGE_MJML_MUSTACHE, "MJML + mustache"),
(
"application/vnd.oasis.opendocument.text|od+mustache",
"OpenDocument + mustache",
),
],
default=DEFAULT_LANGUAGE,
required=True,
help="templating language",
)
redner_id = fields.Char(string="Redner ID", readonly=True)
locale_id = fields.Many2one(
comodel_name="res.lang",
string="Locale",
help="Optional translation language (ISO code).",
)
template_data = fields.Binary("Libreoffice Template")
@property
def redner(self):
"""Try to avoid Redner instance to be over created"""
# Bypass security rules when reading these configuration params. By
# default, only some administrators have access to that model.
config_model = self.env["ir.config_parameter"].sudo()
config_model.get_param("redner.api_key"),
config_model.get_param("redner.server_url"),
config_model.get_param("redner.account"),
int(config_model.get_param("redner.timeout", default="20")),
@api.model_create_multi
def create(self, vals_list):
"""Overwrite create to create redner template"""
for vals in vals_list:
# Prepare template params according to the selected language.
# Use template data field if the selected language is "od";
# otherwise the body field is used.
produces, language = vals.get("language", DEFAULT_LANGUAGE).split("|")
body, body_format = (
(vals.get("template_data", ""), "base64")
if language == "od+mustache"
else (vals.get("body"), "text")
)
# We depend on the API for consistency here
# So raised error should not result with a created template
vals["redner_id"] = self.redner.templates.account_template_add(
language=language,
body=body,
name=vals.get("name"),
produces=produces,
body_format=body_format,
version=fields.Datetime.to_string(fields.Datetime.now()),
)
def write(self, vals):
"""Overwrite write to update redner template"""
# Similar to the "send_to_rednerd_server" method; not worth factoring
# out.
# We depend on the API for consistency here
# So raised error should not result with an updated template
if "name" in vals:
self.ensure_one()
redner_id = self.redner_id
vals["redner_id"] = vals["name"]
produces, language = record.language.split("|")
(record.template_data.decode(), "base64")
if language == "od+mustache"
if "name" not in vals:
redner_id = record.redner_id
record.redner.templates.account_template_update(
template_id=redner_id,
language=language,
body=body,
body_format=body_format,
version=fields.Datetime.to_string(record.write_date),
_("Failed to update render template, %s") % e
) from e
def unlink(self):
"""Overwrite unlink to delete redner template"""
# We do NOT depend on the API for consistency here
# So raised error should not result block template deletion
try:
self.redner.templates.account_template_delete(self.redner_id)
except Exception:
pass
def copy(self, default=None):
self.ensure_one()
default = dict(default or {}, name=_("%s (copy)") % self.name)
record.detected_keywords = "\n".join(record.template_varlist_fetch())
varlist = self.template_varlist_fetch()
for name in varlist:
while "." in name:
name = name[: name.rfind(".")]
if name not in varlist:
varlist.append(name)
varlist.sort()
return varlist
@api.model
def template_varlist_fetch(self):
"""Retrieve the list of variables present in the template."""
try:
if not self.redner_id:
return []
return self.redner.templates.account_template_varlist(self.redner_id)
logger.warning("Failed to fetch account template varlist: %s", e)
def send_to_rednerd_server(self):
"""Send templates to the rednerd server. Useful when you have
existing templates you want to register onto a new rednerd server (or
with a new user).
"""
for record in self:
# Similar to the "write" method override; not worth factoring out.
templates = record.redner.templates
produces, language = record.language.split("|")
(record.template_data.decode(), "base64")
if language == "od+mustache"
template_id=record.redner_id,
language=language,
body=body,
name=record.name,
version=fields.Datetime.to_string(record.write_date),
)
except ValidationError:
record.redner_id = templates.account_template_add(
language=language,
body=body,
name=record.name,
version=fields.Datetime.to_string(fields.Datetime.now()),