From cdaa89b07693dda6829c3af39b5898bcc6fb12d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Bernardi?= Date: Sat, 23 May 2020 11:19:07 -0300 Subject: [PATCH] lims_report_html: add template translation --- lims_diagnosis/results_report.py | 6 +- lims_report_html/__init__.py | 1 + lims_report_html/html_template.py | 75 +++++++++++- lims_report_html/html_template.xml | 13 ++ lims_report_html/locale/es.po | 28 +++++ lims_report_html/report/results_report.html | 4 +- .../report/translations/babel.cfg | 2 + .../translations/es/LC_MESSAGES/messages.po | 115 ++++++++++++++++++ .../report/translations/messages.pot | 113 +++++++++++++++++ lims_report_html/results_report.py | 106 +++++++++++++--- lims_report_html/view/template_form.xml | 3 + .../view/template_translation_form.xml | 12 ++ .../view/template_translation_list.xml | 6 + setup.py | 2 +- 14 files changed, 463 insertions(+), 23 deletions(-) create mode 100644 lims_report_html/report/translations/babel.cfg create mode 100644 lims_report_html/report/translations/es/LC_MESSAGES/messages.po create mode 100644 lims_report_html/report/translations/messages.pot create mode 100644 lims_report_html/view/template_translation_form.xml create mode 100644 lims_report_html/view/template_translation_list.xml diff --git a/lims_diagnosis/results_report.py b/lims_diagnosis/results_report.py index 31e4688..0e96222 100644 --- a/lims_diagnosis/results_report.py +++ b/lims_diagnosis/results_report.py @@ -102,13 +102,13 @@ class ResultReport(metaclass=PoolMeta): @classmethod def get_results_report_template(cls, action, detail_id): - content = super(ResultReport, cls).get_results_report_template( - action, detail_id) + content, template_id = super(ResultReport, + cls).get_results_report_template(action, detail_id) signature = 'show_diagnosis_content' diagnosis_content = ( '{%% macro %s(sample) %%}\n%s\n{%% endmacro %%}' % ( signature, '{{ sample.diagnosis }}')) - return '%s\n\n%s' % (diagnosis_content, content) + return '%s\n\n%s' % (diagnosis_content, content), template_id @classmethod def get_context(cls, records, data): diff --git a/lims_report_html/__init__.py b/lims_report_html/__init__.py index 1ce79e9..c1c5984 100644 --- a/lims_report_html/__init__.py +++ b/lims_report_html/__init__.py @@ -13,6 +13,7 @@ def register(): Pool.register( action.ActionReport, html_template.ReportTemplate, + html_template.ReportTemplateTranslation, sample.Sample, sample.CreateSampleStart, results_report.ResultsReportVersionDetail, diff --git a/lims_report_html/html_template.py b/lims_report_html/html_template.py index 4709bda..8c2fe40 100644 --- a/lims_report_html/html_template.py +++ b/lims_report_html/html_template.py @@ -3,8 +3,11 @@ # the full copyright notices and license terms. from trytond.model import ModelSQL, ModelView, fields +from trytond.pool import Pool +from trytond.transaction import Transaction +from trytond.cache import Cache -__all__ = ['ReportTemplate'] +__all__ = ['ReportTemplate', 'ReportTemplateTranslation'] class ReportTemplate(ModelSQL, ModelView): @@ -13,3 +16,73 @@ class ReportTemplate(ModelSQL, ModelView): name = fields.Char('Name', required=True) content = fields.Text('Content', required=True) + translations = fields.One2Many('lims.result_report.template.translation', + 'template', 'Translations') + _translation_cache = Cache('lims.result_report.template.translation', + size_limit=10240, context=False) + + @classmethod + def gettext(cls, *args, **variables): + ReportTemplateTranslation = Pool().get( + 'lims.result_report.template.translation') + template, src, lang = args + key = (template, src, lang) + text = cls._translation_cache.get(key) + if text is None: + translations = ReportTemplateTranslation.search([ + ('template', '=', template), + ('src', '=', src), + ('lang', '=', lang), + ], limit=1) + if translations: + text = translations[0].value + else: + text = src + cls._translation_cache.set(key, text) + return text if not variables else text % variables + + +class ReportTemplateTranslation(ModelSQL, ModelView): + 'Results Report Template Translation' + __name__ = 'lims.result_report.template.translation' + _order_name = 'src' + + template = fields.Many2One('lims.result_report.template', 'Template', + ondelete='CASCADE', select=True, required=True) + src = fields.Text('Source', required=True) + value = fields.Text('Translation Value', required=True) + lang = fields.Selection('get_language', string='Language', required=True) + _get_language_cache = Cache( + 'lims.result_report.template.translation.get_language') + + @staticmethod + def default_lang(): + return Transaction().language + + @classmethod + def get_language(cls): + result = cls._get_language_cache.get(None) + if result is not None: + return result + langs = Pool().get('ir.lang').search([('translatable', '=', True)]) + result = [(lang.code, lang.name) for lang in langs] + cls._get_language_cache.set(None, result) + return result + + @classmethod + def create(cls, vlist): + Template = Pool().get('lims.result_report.template') + Template._translation_cache.clear() + return super(ReportTemplateTranslation, cls).create(vlist) + + @classmethod + def write(cls, *args): + Template = Pool().get('lims.result_report.template') + Template._translation_cache.clear() + return super(ReportTemplateTranslation, cls).write(*args) + + @classmethod + def delete(cls, translations): + Template = Pool().get('lims.result_report.template') + Template._translation_cache.clear() + return super(ReportTemplateTranslation, cls).delete(translations) diff --git a/lims_report_html/html_template.xml b/lims_report_html/html_template.xml index d9acc65..a65aea3 100644 --- a/lims_report_html/html_template.xml +++ b/lims_report_html/html_template.xml @@ -34,5 +34,18 @@ id="menu_html_template_list" parent="lims.lims_config_report" sequence="10"/> + + + + lims.result_report.template.translation + form + template_translation_form + + + lims.result_report.template.translation + tree + template_translation_list + + diff --git a/lims_report_html/locale/es.po b/lims_report_html/locale/es.po index 4ac4e62..8f7bb05 100644 --- a/lims_report_html/locale/es.po +++ b/lims_report_html/locale/es.po @@ -18,6 +18,26 @@ msgctxt "field:lims.result_report.template,name:" msgid "Name" msgstr "Nombre" +msgctxt "field:lims.result_report.template,translations:" +msgid "Translations" +msgstr "Traducciones" + +msgctxt "field:lims.result_report.template.translation,lang:" +msgid "Language" +msgstr "Idioma" + +msgctxt "field:lims.result_report.template.translation,src:" +msgid "Source" +msgstr "Original" + +msgctxt "field:lims.result_report.template.translation,template:" +msgid "Template" +msgstr "Plantilla" + +msgctxt "field:lims.result_report.template.translation,value:" +msgid "Translation Value" +msgstr "Traducción" + msgctxt "field:lims.results_report.version.detail,template:" msgid "Report Template" msgstr "Plantilla de Informe" @@ -50,6 +70,14 @@ msgctxt "model:lims.result_report.template,name:" msgid "Results Report Template" msgstr "Plantilla de Informe de resultados" +msgctxt "model:lims.result_report.template.translation,name:" +msgid "Results Report Template Translation" +msgstr "Traducción de Plantilla de Informe de resultados" + msgctxt "view:lims.result_report.template:" msgid "Content" msgstr "Contenido" + +msgctxt "view:lims.result_report.template:" +msgid "Translations" +msgstr "Traducciones" diff --git a/lims_report_html/report/results_report.html b/lims_report_html/report/results_report.html index 7c7720e..a0c2516 100644 --- a/lims_report_html/report/results_report.html +++ b/lims_report_html/report/results_report.html @@ -981,7 +981,7 @@ {% if stp_polisample_project == 'True' and fraction.stp_variety %} -

{{ _('CUSTOMER VARIETY') }}: {{ fraction.stp_variety }}

+

{{ _('VARIETY') }}: {{ fraction.stp_variety }}

{% endif %} @@ -1216,7 +1216,7 @@
-

The results only refer to the analyzed samples. This report must not be partially reproduced without the written approval of {{ company.party.rec_name }}.

+

{{ _('The results only refer to the analyzed samples. This report must not be partially reproduced without the written approval of') }} {{ company.party.rec_name }}.

diff --git a/lims_report_html/report/translations/babel.cfg b/lims_report_html/report/translations/babel.cfg new file mode 100644 index 0000000..82319fb --- /dev/null +++ b/lims_report_html/report/translations/babel.cfg @@ -0,0 +1,2 @@ +[jinja2: **.html] +extensions=jinja2.ext.i18n,jinja2.ext.autoescape,jinja2.ext.with_ diff --git a/lims_report_html/report/translations/es/LC_MESSAGES/messages.po b/lims_report_html/report/translations/es/LC_MESSAGES/messages.po new file mode 100644 index 0000000..d571e42 --- /dev/null +++ b/lims_report_html/report/translations/es/LC_MESSAGES/messages.po @@ -0,0 +1,115 @@ +msgid "ACTIVE INGREDIENT" +msgstr "PRINCIPIO ACTIVO" + +msgid "ADDRESS" +msgstr "DIRECCIÓN" + +msgid "APPLICATION DATES" +msgstr "FECHA/S DE APLICACIÓN" + +msgid "Analysis" +msgstr "Análisis" + +msgid "BEGINNING OF THE ANALYSIS" +msgstr "FECHA INICIO DE ANÁLISIS" + +msgid "CODE OF THE SAMPLE" +msgstr "CÓDIGO DE LA MUESTRA" + +msgid "CONFIRMATION SAMPLE RECEPTION" +msgstr "CONFIRMACIÓN INGRESO DE LA MUESTRA" + +msgid "CONTAINER" +msgstr "ENVASE" + +msgid "CUSTOMER DESCRIPTION" +msgstr "DESCRIPCIÓN DEL CLIENTE" + +msgid "DAYS AFTER TREATMENT (DAT)" +msgstr "DÍAS DESPUÉS DE APLICADO" + +msgid "DOSE" +msgstr "DOSIS" + +msgid "Date" +msgstr "Fecha" + +msgid "Detection Limit" +msgstr "Límite de Detección" + +msgid "END OF ANALYSIS" +msgstr "FECHA FINALIZACIÓN DE ANÁLISIS" + +msgid "FORMULATION TYPES" +msgstr "TIPO DE FORMULACIÓN ARMONIZADA" + +msgid "For the SAT NRO" +msgstr "Correspondiente al SAT NRO" + +msgid "LABEL" +msgstr "RÓTULO" + +msgid "METHODS" +msgstr "MÉTODOS" + +msgid "Method" +msgstr "Método" + +msgid "OBSERVATIONS" +msgstr "OBSERVACIONES" + +msgid "PRODUCER COMPANY" +msgstr "EMPRESA PRODUCTORA" + +msgid "RECEIVED SAMPLE" +msgstr "MUESTRA RECIBIDA" + +msgid "REPETITION" +msgstr "REPETICIÓN" + +msgid "REPORT Nº" +msgstr "INFORME Nº" + +msgid "REQUESTED BY" +msgstr "SOLICITADO POR" + +msgid "RESULTS" +msgstr "RESULTADOS" + +msgid "Result" +msgstr "Resultado" + +msgid "Results Report" +msgstr "Informe de resultados" + +msgid "SAMPLE PRESENTATION" +msgstr "PRESENTACIÓN DE LA MUESTRA" + +msgid "SAMPLING DATE" +msgstr "FECHA DE MUESTREO" + +msgid "SENASA PROTOCOL N°" +msgstr "PROTOCOLO SENASA N°" + +msgid "STUDY PLAN N°" +msgstr "PLAN DE ESTUDIO N°" + +msgid "TREATMENT" +msgstr "TRATAMIENTO" + +msgid "" +"The results only refer to the analyzed samples. This report must not be " +"partially reproduced without the written approval of" +msgstr "" +"Los resultados corresponden exclusivamente a las muestras analizadas. El " +"informe no debe reproducirse parcialmente sin la aprobación escrita de" + +msgid "Unit" +msgstr "Unidad" + +msgid "VARIETY" +msgstr "VARIEDAD" + +msgid "ZONE" +msgstr "ZONA" + diff --git a/lims_report_html/report/translations/messages.pot b/lims_report_html/report/translations/messages.pot new file mode 100644 index 0000000..0994d68 --- /dev/null +++ b/lims_report_html/report/translations/messages.pot @@ -0,0 +1,113 @@ +msgid "ACTIVE INGREDIENT" +msgstr "" + +msgid "ADDRESS" +msgstr "" + +msgid "APPLICATION DATES" +msgstr "" + +msgid "Analysis" +msgstr "" + +msgid "BEGINNING OF THE ANALYSIS" +msgstr "" + +msgid "CODE OF THE SAMPLE" +msgstr "" + +msgid "CONFIRMATION SAMPLE RECEPTION" +msgstr "" + +msgid "CONTAINER" +msgstr "" + +msgid "CUSTOMER DESCRIPTION" +msgstr "" + +msgid "DAYS AFTER TREATMENT (DAT)" +msgstr "" + +msgid "DOSE" +msgstr "" + +msgid "Date" +msgstr "" + +msgid "Detection Limit" +msgstr "" + +msgid "END OF ANALYSIS" +msgstr "" + +msgid "FORMULATION TYPES" +msgstr "" + +msgid "For the SAT NRO" +msgstr "" + +msgid "LABEL" +msgstr "" + +msgid "METHODS" +msgstr "" + +msgid "Method" +msgstr "" + +msgid "OBSERVATIONS" +msgstr "" + +msgid "PRODUCER COMPANY" +msgstr "" + +msgid "RECEIVED SAMPLE" +msgstr "" + +msgid "REPETITION" +msgstr "" + +msgid "REPORT Nº" +msgstr "" + +msgid "REQUESTED BY" +msgstr "" + +msgid "RESULTS" +msgstr "" + +msgid "Result" +msgstr "" + +msgid "Results Report" +msgstr "" + +msgid "SAMPLE PRESENTATION" +msgstr "" + +msgid "SAMPLING DATE" +msgstr "" + +msgid "SENASA PROTOCOL N°" +msgstr "" + +msgid "STUDY PLAN N°" +msgstr "" + +msgid "TREATMENT" +msgstr "" + +msgid "" +"The results only refer to the analyzed samples. This report must not be " +"partially reproduced without the written approval of" +msgstr "" + +msgid "Unit" +msgstr "" + +msgid "VARIETY" +msgstr "" + +msgid "ZONE" +msgstr "" + diff --git a/lims_report_html/results_report.py b/lims_report_html/results_report.py index be17313..ed723cd 100644 --- a/lims_report_html/results_report.py +++ b/lims_report_html/results_report.py @@ -1,8 +1,10 @@ # This file is part of lims_report_html module for Tryton. # The COPYRIGHT file at the top level of this repository contains # the full copyright notices and license terms. +import os from lxml import html as lxml_html from base64 import b64encode +from babel.support import Translations as BabelTranslations from trytond.model import fields from trytond.pool import Pool, PoolMeta @@ -93,16 +95,12 @@ class ResultReport(metaclass=PoolMeta): cls.check_access() action, model = cls.get_action(data) - with Transaction().set_context(html_report=action.id): - records = [] - if model: - records = cls._get_records(ids, model, data) - #records = cls._get_dual_records(ids, model, data) - oext, content = cls._execute_html_results_report(records, data, - action) - if not isinstance(content, str): - content = bytearray(content) if bytes == str else bytes( - content) + records = [] + if model: + records = cls._get_records(ids, model, data) + oext, content = cls._execute_html_results_report(records, data, action) + if not isinstance(content, str): + content = bytearray(content) if bytes == str else bytes(content) return oext, content, cls.get_direct_print(action), cls.get_name( action) @@ -111,9 +109,17 @@ class ResultReport(metaclass=PoolMeta): def _execute_html_results_report(cls, records, data, action): documents = [] for record in records: - template = cls.get_results_report_template(action, record.id) - content = cls.render_results_report_template(action, template, - record=record, records=[record], data=data) + template_content, template_id = cls.get_results_report_template( + action, record.id) + context = Transaction().context + context['template'] = template_id + if not template_id: + context['default_translations'] = os.path.join( + os.path.dirname(__file__), 'report', 'translations') + with Transaction().set_context(**context): + content = cls.render_results_report_template(action, + template_content, record=record, records=[record], + data=data) if action.extension == 'pdf': documents.append(PdfGenerator(content, side_margin=1, extra_vertical_margin=30).render_html()) @@ -130,19 +136,33 @@ class ResultReport(metaclass=PoolMeta): @classmethod def get_results_report_template(cls, action, detail_id): ResultsDetail = Pool().get('lims.results_report.version.detail') + content, template_id = None, None detail = ResultsDetail(detail_id) - content = detail.template and detail.template.content + if detail.template: + content = detail.template.content + template_id = detail.template if not content: content = (action.report_content and action.report_content.decode('utf-8')) if not content: raise UserError(gettext('lims_report_html.msg_no_template')) - return content + return content, template_id @classmethod def render_results_report_template(cls, action, template_string, record=None, records=None, data=None): - env = cls.get_environment() + User = Pool().get('res.user') + user = User(Transaction().user) + + if data and data.get('alt_lang'): + locale = data['alt_lang'] + elif user.language: + locale = user.language.code + else: + locale = Transaction().language + with Transaction().set_context(locale=locale): + env = cls.get_results_report_environment() + report_template = env.from_string(template_string) context = cls.get_context(records, data) context.update({ @@ -154,6 +174,16 @@ class ResultReport(metaclass=PoolMeta): # print('TEMPLATE:\n', res) return res + @classmethod + def get_results_report_environment(cls): + env = cls.get_environment() + + context = Transaction().context + locale = context.get('locale').split('_')[0] + translations = TemplateTranslations(locale) + env.install_gettext_translations(translations) + return env + @classmethod def parse_images(cls, template_string): Attachment = Pool().get('ir.attachment') @@ -179,3 +209,47 @@ class ResultReport(metaclass=PoolMeta): return '' b64_image = b64encode(image).decode() return 'data:image/png;base64,%s' % b64_image + + +class TemplateTranslations: + + def __init__(self, lang='en'): + self.cache = {} + self.env = None + self.current = None + self.language = lang + self.template = None + self.set_language(lang) + + def set_language(self, lang='en'): + self.language = lang + if lang in self.cache: + self.current = self.cache[lang] + return + context = Transaction().context + if context.get('default_translations'): + default_translations = context['default_translations'] + if os.path.isdir(default_translations): + self.current = BabelTranslations.load( + dirname=default_translations, locales=[lang]) + self.cache[lang] = self.current + else: + self.template = context.get('template', -1) + + def ugettext(self, message): + ReportTemplate = Pool().get('lims.result_report.template') + if self.current: + return self.current.ugettext(message) + elif self.template: + return ReportTemplate.gettext(self.template, message, + self.language) + return message + + def ngettext(self, singular, plural, n): + ReportTemplate = Pool().get('lims.result_report.template') + if self.current: + return self.current.ugettext(singular, plural, n) + elif self.template: + return ReportTemplate.gettext(self.template, singular, + self.language) + return singular diff --git a/lims_report_html/view/template_form.xml b/lims_report_html/view/template_form.xml index e7575af..81f4da3 100644 --- a/lims_report_html/view/template_form.xml +++ b/lims_report_html/view/template_form.xml @@ -6,5 +6,8 @@ + + + diff --git a/lims_report_html/view/template_translation_form.xml b/lims_report_html/view/template_translation_form.xml new file mode 100644 index 0000000..3ee1f54 --- /dev/null +++ b/lims_report_html/view/template_translation_form.xml @@ -0,0 +1,12 @@ +
+