Browse Source

[12.0][MIG] improvement py3o_report_extender

pull/258/head
Gilles Meyomesse 6 years ago
committed by Laurent Mignon (ACSONE)
parent
commit
74f58a3423
  1. 96
      report_py3o/models/_py3o_parser_context.py
  2. 30
      report_py3o/models/py3o_report.py
  3. 3
      report_py3o/tests/test_report_py3o.py

96
report_py3o/models/_py3o_parser_context.py

@ -0,0 +1,96 @@
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import html
import time
import logging
from base64 import b64decode
from odoo.tools import misc, mail
logger = logging.getLogger(__name__)
try:
from genshi.core import Markup
except ImportError:
logger.debug('Cannot import py3o.template')
def format_multiline_value(value):
if value:
return Markup(html.escape(value).replace('\n', '<text:line-break/>').
replace('\t', '<text:s/><text:s/><text:s/><text:s/>'))
return ""
def display_address(address_record, without_company=False):
return address_record.display_address(without_company=without_company)
class Py3oParserContext(object):
def __init__(self, env):
self._env = env
self.localcontext = {
# Odoo default format methods
'o_format_lang': self._format_lang,
# prefixes with o_ to avoid nameclash with default method provided
# by py3o.template
'o_format_date': self._format_date,
# give access to the time lib
'time': time,
# keeps methods from report_sxw to ease migration
'display_address': display_address,
'formatLang': self._old_format_lang,
'format_multiline_value': format_multiline_value,
'html_sanitize': mail.html2plaintext,
'b64decode': b64decode,
}
def _format_lang(self, _env, value, digits=None, grouping=True,
monetary=False, dp=False, currency_obj=False,
no_break_space=True):
formatted_value = misc.formatLang(
_env, value, digits=digits, grouping=grouping,
monetary=monetary, dp=dp, currency_obj=currency_obj)
if currency_obj and currency_obj.symbol and no_break_space:
parts = []
if currency_obj.position == 'after':
parts = formatted_value.rsplit(" ", 1)
elif currency_obj and currency_obj.position == 'before':
parts = formatted_value.split(" ", 1)
if parts:
formatted_value = "\N{NO-BREAK SPACE}".join(parts)
return formatted_value
def _format_date(self, value, lang_code=False, date_format=False):
return misc.format_date(
self._env, value, lang_code=lang_code, date_format=date_format)
def _old_format_lang(self, value, digits=None, date=False, date_time=False,
grouping=True, monetary=False, dp=False,
currency_obj=False):
"""
:param value: The value to format
:param digits: Number of digits to display by default
:param date: True if value must be formatted as a date (default False)
:param date_time: True if value must be formatted as a datetime
(default False)
:param grouping: If value is float and grouping is True, the value will
be formatted with the appropriate separators between
figures according to the current lang specifications
:param monetary: If value is float and monetary is True and grouping is
True the value will be formatted according to the
monetary format defined for the current lang
:param dp: Decimal precision
:param currency_obj: If provided the currency symbol will be added to
value at position defined by the currency object
:return: The formatted value
"""
if not date and not date_time:
return self._format_lang(
self._env, value, digits=digits, grouping=grouping,
monetary=monetary, dp=dp, currency_obj=currency_obj,
no_break_space=True)
return self._format_date(self._env, value)

30
report_py3o/models/py3o_report.py

@ -6,7 +6,6 @@ from base64 import b64decode
from io import BytesIO from io import BytesIO
import logging import logging
import os import os
import cgi
from contextlib import closing from contextlib import closing
import subprocess import subprocess
@ -16,13 +15,13 @@ import tempfile
from zipfile import ZipFile, ZIP_DEFLATED from zipfile import ZipFile, ZIP_DEFLATED
from odoo import api, fields, models, tools, _ from odoo import api, fields, models, tools, _
from ._py3o_parser_context import Py3oParserContext
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
try: try:
from py3o.template import Template from py3o.template import Template
from py3o import formats from py3o import formats
from genshi.core import Markup
except ImportError: except ImportError:
logger.debug('Cannot import py3o.template') logger.debug('Cannot import py3o.template')
try: try:
@ -60,21 +59,9 @@ def py3o_report_extender(report_xml_id=None):
return fct1 return fct1
def format_multiline_value(value):
if value:
return Markup(cgi.escape(value).replace('\n', '<text:line-break/>').
replace('\t', '<text:s/><text:s/><text:s/><text:s/>'))
return ""
@py3o_report_extender() @py3o_report_extender()
def default_extend(report_xml, localcontext):
# add the base64decode function to be able do decode binary fields into
# the template
localcontext['b64decode'] = b64decode
localcontext['report_xml'] = report_xml
localcontext['format_multiline_value'] = format_multiline_value
localcontext['html_sanitize'] = tools.html2plaintext
def default_extend(report_xml, context):
context['report_xml'] = report_xml
class Py3oReport(models.TransientModel): class Py3oReport(models.TransientModel):
@ -190,20 +177,23 @@ class Py3oReport(models.TransientModel):
return tmpl_data return tmpl_data
@api.multi @api.multi
def _extend_parser_context(self, context_instance, report_xml):
def _extend_parser_context(self, context, report_xml):
# add default extenders # add default extenders
for fct in _extender_functions.get(None, []): for fct in _extender_functions.get(None, []):
fct(report_xml, context_instance)
fct(report_xml, context)
# add extenders for registered on the template # add extenders for registered on the template
xml_id = report_xml.get_external_id().get(report_xml.id) xml_id = report_xml.get_external_id().get(report_xml.id)
if xml_id in _extender_functions: if xml_id in _extender_functions:
for fct in _extender_functions[xml_id]: for fct in _extender_functions[xml_id]:
fct(report_xml, context_instance)
fct(report_xml, context)
@api.multi @api.multi
def _get_parser_context(self, model_instance, data): def _get_parser_context(self, model_instance, data):
report_xml = self.ir_actions_report_id report_xml = self.ir_actions_report_id
context = report_xml._get_rendering_context(model_instance.ids, data)
context = Py3oParserContext(self.env).localcontext
context.update(
report_xml._get_rendering_context(model_instance.ids, data)
)
context['objects'] = model_instance context['objects'] = model_instance
self._extend_parser_context(context, report_xml) self._extend_parser_context(context, report_xml)
return context return context

3
report_py3o/tests/test_report_py3o.py

@ -15,7 +15,8 @@ from odoo.tests.common import TransactionCase
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.addons.base.tests.test_mimetypes import PNG from odoo.addons.base.tests.test_mimetypes import PNG
from ..models.py3o_report import TemplateNotFound, format_multiline_value
from ..models.py3o_report import TemplateNotFound
from ..models._py3o_parser_context import format_multiline_value
from base64 import b64encode from base64 import b64encode
import logging import logging

Loading…
Cancel
Save