diff --git a/report_py3o/models/_py3o_parser_context.py b/report_py3o/models/_py3o_parser_context.py
new file mode 100644
index 000000000..d42949cd9
--- /dev/null
+++ b/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', '').
+ replace('\t', ''))
+ 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)
diff --git a/report_py3o/models/py3o_report.py b/report_py3o/models/py3o_report.py
index 29b947f57..c1eda37fe 100644
--- a/report_py3o/models/py3o_report.py
+++ b/report_py3o/models/py3o_report.py
@@ -6,7 +6,6 @@ from base64 import b64decode
from io import BytesIO
import logging
import os
-import cgi
from contextlib import closing
import subprocess
@@ -16,13 +15,13 @@ import tempfile
from zipfile import ZipFile, ZIP_DEFLATED
from odoo import api, fields, models, tools, _
+from ._py3o_parser_context import Py3oParserContext
logger = logging.getLogger(__name__)
try:
from py3o.template import Template
from py3o import formats
- from genshi.core import Markup
except ImportError:
logger.debug('Cannot import py3o.template')
try:
@@ -60,21 +59,9 @@ def py3o_report_extender(report_xml_id=None):
return fct1
-def format_multiline_value(value):
- if value:
- return Markup(cgi.escape(value).replace('\n', '').
- replace('\t', ''))
- return ""
-
-
@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):
@@ -190,20 +177,23 @@ class Py3oReport(models.TransientModel):
return tmpl_data
@api.multi
- def _extend_parser_context(self, context_instance, report_xml):
+ def _extend_parser_context(self, context, report_xml):
# add default extenders
for fct in _extender_functions.get(None, []):
- fct(report_xml, context_instance)
+ fct(report_xml, context)
# add extenders for registered on the template
xml_id = report_xml.get_external_id().get(report_xml.id)
if xml_id in _extender_functions:
for fct in _extender_functions[xml_id]:
- fct(report_xml, context_instance)
+ fct(report_xml, context)
@api.multi
def _get_parser_context(self, model_instance, data):
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
self._extend_parser_context(context, report_xml)
return context
diff --git a/report_py3o/tests/test_report_py3o.py b/report_py3o/tests/test_report_py3o.py
index c29c0e98b..f89a99519 100644
--- a/report_py3o/tests/test_report_py3o.py
+++ b/report_py3o/tests/test_report_py3o.py
@@ -15,7 +15,8 @@ from odoo.tests.common import TransactionCase
from odoo.exceptions import ValidationError
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
import logging