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.

121 lines
4.2 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis
  3. # © 2016 Tecnativa, S.L. - Vicent Cubells
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. from datetime import datetime, timedelta
  6. from openerp import api, fields, models
  7. from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
  8. DEFAULT_SERVER_TIME_FORMAT)
  9. from . import exceptions as ex
  10. # Available modes for :param:`.ResLang.datetime_formatter.template`
  11. MODE_DATETIME = "MODE_DATETIME"
  12. MODE_DATE = "MODE_DATE"
  13. MODE_TIME = "MODE_TIME"
  14. class ResLang(models.Model):
  15. _inherit = "res.lang"
  16. @api.model
  17. @api.returns('self')
  18. def best_match(self, lang=None, failure_safe=True):
  19. """Get best match of current default lang.
  20. :param str lang:
  21. If a language in the form of "en_US" is supplied, it will have the
  22. highest priority.
  23. :param bool failure_safe:
  24. If ``False`` and the best matched language is not found installed,
  25. an exception will be raised. Otherwise, the first installed
  26. language found in the DB will be returned.
  27. """
  28. # Find some installed language, as fallback
  29. first_installed = self.search([("active", "=", True)], limit=1)
  30. if not lang:
  31. lang = (
  32. # Object's language, if called like
  33. # ``record.lang.datetime_formatter(datetime_obj)``
  34. (self.ids and self[0].code) or
  35. # Context language
  36. self.env.context.get("lang") or
  37. # User's language
  38. self.env.user.lang or
  39. # First installed language found
  40. first_installed.code)
  41. # Get DB lang record
  42. record = self.search([("code", "=", lang)])
  43. try:
  44. record.ensure_one()
  45. except ValueError:
  46. if not failure_safe:
  47. raise ex.BestMatchedLanguageNotFoundError(lang)
  48. else:
  49. record = first_installed
  50. return record
  51. @api.model
  52. def datetime_formatter(self, value, lang=None, template=MODE_DATETIME,
  53. separator=" ", failure_safe=True):
  54. """Convert a datetime field to lang's default format.
  55. :type value: `str`, `float` or `datetime.datetime`
  56. :param value:
  57. Datetime that will be formatted to the user's preferred format.
  58. :param str lang:
  59. See :param:`lang` from :meth:`~.best_match`.
  60. :param bool failure_safe:
  61. See :param:`failure_safe` from :meth:`~.best_match`.
  62. :param str template:
  63. Will be used to format :param:`value`. If it is one of the special
  64. constants :const:`MODE_DATETIME`, :const:`MODE_DATE` or
  65. :const:`MODE_TIME`, it will use the :param:`lang`'s default
  66. template for that mode.
  67. :param str separator:
  68. Only used when :param:`template` is :const:`MODE_DATETIME`, as the
  69. separator between the date and time parts.
  70. """
  71. # Get the correct lang
  72. lang = self.best_match(lang)
  73. # Get the template
  74. if template in {MODE_DATETIME, MODE_DATE, MODE_TIME}:
  75. defaults = []
  76. if "DATE" in template:
  77. defaults.append(lang.date_format or
  78. DEFAULT_SERVER_DATE_FORMAT)
  79. if "TIME" in template:
  80. defaults.append(lang.time_format or
  81. DEFAULT_SERVER_TIME_FORMAT)
  82. template = separator.join(defaults)
  83. # Convert str to datetime objects
  84. if isinstance(value, (str, unicode)):
  85. try:
  86. value = fields.Datetime.from_string(value)
  87. except ValueError:
  88. # Probably failed due to value being only time
  89. value = datetime.strptime(value, DEFAULT_SERVER_TIME_FORMAT)
  90. # Time-only fields are floats for Odoo
  91. elif isinstance(value, float):
  92. # Patch values >= 24 hours
  93. if value >= 24:
  94. template = template.replace("%H", "%d" % value)
  95. # Convert to time
  96. value = (datetime.min + timedelta(hours=value)).time()
  97. return value.strftime(template)