|
|
# Copyright 2015, 2017 Jairo Llopis <jairo.llopis@tecnativa.com> # Copyright 2016 Tecnativa, S.L. - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from datetime import datetime, timedelta from odoo import _, api, fields, models from odoo.tools import (DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_TIME_FORMAT) from odoo.exceptions import UserError
# Available modes for :param:`.ResLang.datetime_formatter.template` MODE_DATETIME = "MODE_DATETIME" MODE_DATE = "MODE_DATE" MODE_TIME = "MODE_TIME"
class ResLang(models.Model): _inherit = "res.lang"
@api.model @api.returns('self') def best_match(self, lang=None, failure_safe=True): """Get best match of current default lang.
:param str lang: If a language in the form of "en_US" is supplied, it will have the highest priority.
:param bool failure_safe: If ``False`` and the best matched language is not found installed, an exception will be raised. Otherwise, the first installed language found in the DB will be returned. """
# Find some installed language, as fallback first_installed = self.search([("active", "=", True)], limit=1)
if not lang: lang = ( # Object's language, if called like # ``record.lang.datetime_formatter(datetime_obj)`` (self.ids and self[0].code) or
# Context language self.env.context.get("lang") or
# User's language self.env.user.lang or
# First installed language found first_installed.code)
# Get DB lang record record = self.search([("code", "=", lang)])
try: record.ensure_one() except ValueError: if not failure_safe: raise UserError( _("Best matched language (%s) not found.") % lang ) else: record = first_installed
return record
@api.model def datetime_formatter(self, value, lang=None, template=MODE_DATETIME, separator=" ", failure_safe=True): """Convert a datetime field to lang's default format.
:type value: `str`, `float` or `datetime.datetime` :param value: Datetime that will be formatted to the user's preferred format.
:param str lang: See :param:`lang` from :meth:`~.best_match`.
:param bool failure_safe: See :param:`failure_safe` from :meth:`~.best_match`.
:param str template: Will be used to format :param:`value`. If it is one of the special constants :const:`MODE_DATETIME`, :const:`MODE_DATE` or :const:`MODE_TIME`, it will use the :param:`lang`'s default template for that mode.
:param str separator: Only used when :param:`template` is :const:`MODE_DATETIME`, as the separator between the date and time parts. """
# Get the correct lang lang = self.best_match(lang)
# Get the template if template in {MODE_DATETIME, MODE_DATE, MODE_TIME}: defaults = [] if "DATE" in template: defaults.append(lang.date_format or DEFAULT_SERVER_DATE_FORMAT) if "TIME" in template: defaults.append(lang.time_format or DEFAULT_SERVER_TIME_FORMAT) template = separator.join(defaults)
# Convert str to datetime objects if isinstance(value, str): try: value = fields.Datetime.from_string(value) except ValueError: # Probably failed due to value being only time value = datetime.strptime(value, DEFAULT_SERVER_TIME_FORMAT)
# Time-only fields are floats for Odoo elif isinstance(value, float): # Patch values >= 24 hours if value >= 24: template = template.replace("%H", "%d" % value)
# Convert to time value = (datetime.min + timedelta(hours=value)).time()
return value.strftime(template)
|