[12.0][MIG] improvement py3o_report_extender
parent
701f1f6c7d
commit
64ce3fd0b8
|
@ -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)
|
|
@ -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):
|
def default_extend(report_xml, context):
|
||||||
# add the base64decode function to be able do decode binary fields into
|
context['report_xml'] = report_xml
|
||||||
# the template
|
|
||||||
localcontext['b64decode'] = b64decode
|
|
||||||
localcontext['report_xml'] = report_xml
|
|
||||||
localcontext['format_multiline_value'] = format_multiline_value
|
|
||||||
localcontext['html_sanitize'] = tools.html2plaintext
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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…
Reference in New Issue