OCA reporting engine fork for dev and update.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
4.0 KiB

  1. # Copyright 2018 ACSONE SA/NV
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
  3. import html
  4. import time
  5. import logging
  6. from base64 import b64decode
  7. from odoo.tools import misc, mail
  8. logger = logging.getLogger(__name__)
  9. try:
  10. from genshi.core import Markup
  11. except ImportError:
  12. logger.debug('Cannot import py3o.template')
  13. def format_multiline_value(value):
  14. if value:
  15. return Markup(html.escape(value).replace('\n', '<text:line-break/>').
  16. replace('\t', '<text:s/><text:s/><text:s/><text:s/>'))
  17. return ""
  18. def display_address(address_record, without_company=False):
  19. return address_record.display_address(without_company=without_company)
  20. class Py3oParserContext(object):
  21. def __init__(self, env):
  22. self._env = env
  23. self.localcontext = {
  24. 'user': self._env.user,
  25. 'lang': self._env.lang,
  26. # Odoo default format methods
  27. 'o_format_lang': self._format_lang,
  28. # prefixes with o_ to avoid nameclash with default method provided
  29. # by py3o.template
  30. 'o_format_date': self._format_date,
  31. # give access to the time lib
  32. 'time': time,
  33. # keeps methods from report_sxw to ease migration
  34. 'display_address': display_address,
  35. 'formatLang': self._old_format_lang,
  36. 'format_multiline_value': format_multiline_value,
  37. 'html_sanitize': mail.html2plaintext,
  38. 'b64decode': b64decode,
  39. }
  40. def _format_lang(self, value, lang_code=False, digits=None, grouping=True,
  41. monetary=False, dp=False, currency_obj=False,
  42. no_break_space=True):
  43. env = self._env
  44. if lang_code:
  45. context = dict(env.context, lang=lang_code)
  46. env = env(context=context)
  47. formatted_value = misc.formatLang(
  48. env, value, digits=digits, grouping=grouping,
  49. monetary=monetary, dp=dp, currency_obj=currency_obj)
  50. if currency_obj and currency_obj.symbol and no_break_space:
  51. parts = []
  52. if currency_obj.position == 'after':
  53. parts = formatted_value.rsplit(" ", 1)
  54. elif currency_obj and currency_obj.position == 'before':
  55. parts = formatted_value.split(" ", 1)
  56. if parts:
  57. formatted_value = "\N{NO-BREAK SPACE}".join(parts)
  58. return formatted_value
  59. def _format_date(self, value, lang_code=False, date_format=False):
  60. return misc.format_date(
  61. self._env, value, lang_code=lang_code, date_format=date_format)
  62. def _old_format_lang(self, value, digits=None, date=False, date_time=False,
  63. grouping=True, monetary=False, dp=False,
  64. currency_obj=False):
  65. """
  66. :param value: The value to format
  67. :param digits: Number of digits to display by default
  68. :param date: True if value must be formatted as a date (default False)
  69. :param date_time: True if value must be formatted as a datetime
  70. (default False)
  71. :param grouping: If value is float and grouping is True, the value will
  72. be formatted with the appropriate separators between
  73. figures according to the current lang specifications
  74. :param monetary: If value is float and monetary is True and grouping is
  75. True the value will be formatted according to the
  76. monetary format defined for the current lang
  77. :param dp: Decimal precision
  78. :param currency_obj: If provided the currency symbol will be added to
  79. value at position defined by the currency object
  80. :return: The formatted value
  81. """
  82. if not date and not date_time:
  83. return self._format_lang(
  84. value, digits=digits, grouping=grouping,
  85. monetary=monetary, dp=dp, currency_obj=currency_obj,
  86. no_break_space=True)
  87. return self._format_date(self._env, value)