[MIG] datetime_formatter: Migration to 13.0

pull/2274/head
Víctor Martínez 2021-02-24 14:32:57 +01:00 committed by tautvydas.banevicius
parent 3e73fefc38
commit 8aed91993e
5 changed files with 26 additions and 51 deletions

View File

@ -6,7 +6,7 @@
{
"name": "Date & Time Formatter",
"summary": "Helper functions to give correct format to date[time] fields",
"version": "12.0.1.0.0",
"version": "13.0.1.0.0",
"category": "Tools",
"website": "https://github.com/OCA/server-tools",
"author": "Grupo ESOC Ingeniería de Servicios, "
@ -14,5 +14,5 @@
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["base",],
"depends": ["base"],
}

View File

@ -17,14 +17,11 @@ 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
@ -32,26 +29,17 @@ class ResLang(models.Model):
"""
# 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
or self.env.context.get("lang")
or self.env.user.lang
or first_installed.code
)
# Get DB lang record
record = self.search([("code", "=", lang)])
try:
record.ensure_one()
except ValueError:
@ -59,7 +47,6 @@ class ResLang(models.Model):
raise UserError(_("Best matched language (%s) not found.") % lang)
else:
record = first_installed
return record
@api.model
@ -67,30 +54,24 @@ class ResLang(models.Model):
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 = []
@ -99,7 +80,6 @@ class ResLang(models.Model):
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:
@ -107,14 +87,11 @@ class ResLang(models.Model):
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)

View File

@ -3,3 +3,4 @@
* Jairo Llopis
* Vicent Cubells
* Ernesto Tejeda
* Víctor Martínez

View File

@ -8,42 +8,49 @@ from odoo.tests.common import TransactionCase
class BasicCase(TransactionCase):
def setUp(self):
super().setUp()
self.langs = ("en_US", "es_ES", "it_IT", "pt_PT", "zh_CN")
self.langs = (
self.env.ref("base.lang_en"),
self.env.ref("base.lang_es"),
self.env.ref("base.lang_it"),
self.env.ref("base.lang_pt"),
self.env.ref("base.lang_zh_CN"),
)
self.rl = self.env["res.lang"]
for lang in self.langs:
if not self.rl.search([("code", "=", lang)]):
self.rl.load_lang(lang)
self.rl.load_lang(lang.code)
def test_explicit(self):
"""When an explicit lang is used."""
for lang in self.langs:
self.assertEqual(self.rl.best_match(lang).code, lang)
self.assertEqual(self.rl.best_match(lang.code).code, lang.code)
def test_record(self):
"""When called from a ``res.lang`` record."""
rl = self.rl.with_context(lang="it_IT")
rl.env.user.lang = "pt_PT"
for lang in self.langs:
self.assertEqual(rl.search([("code", "=", lang)]).best_match().code, lang)
self.assertEqual(
rl.search([("code", "=", lang.code)]).best_match().code, lang.code
)
def test_context(self):
"""When called with a lang in context."""
self.env.user.lang = "pt_PT"
for lang in self.langs:
self.assertEqual(self.rl.with_context(lang=lang).best_match().code, lang)
self.assertEqual(
self.rl.with_context(lang=lang.code).best_match().code, lang.code
)
def test_user(self):
"""When lang not specified in context."""
for lang in self.langs:
self.env.user.lang = lang
self.env.user.lang = lang.code
# Lang is False in context
self.assertEqual(self.rl.with_context(lang=False).best_match().code, lang)
self.assertEqual(
self.rl.with_context(lang=False).best_match().code, lang.code
)
# Lang not found in context
self.assertEqual(self.rl.with_context(dict()).best_match().code, lang)
self.assertEqual(self.rl.with_context(dict()).best_match().code, lang.code)
def test_first_installed(self):
"""When falling back to first installed language."""
@ -56,10 +63,8 @@ class BasicCase(TransactionCase):
self.env.user.lang = False
self.rl = self.rl.with_context(lang=False)
first = self.rl.search([("active", "=", True)], limit=1)
# Safe mode
self.assertEqual(self.rl.best_match("fake_LANG").code, first.code)
# Unsafe mode
with self.assertRaises(UserError):
self.rl.best_match("fake_LANG", failure_safe=False)

View File

@ -27,12 +27,10 @@ class FormatterCase(TransactionCase):
def tearDown(self):
# This should be returned
self.expected = self.dt.strftime(self.format)
# Pass a datetime object
self.assertEqual(
self.expected, self.rl.datetime_formatter(self.dt, **self.kwargs)
)
# When the date comes as a string
if isinstance(self.dt, datetime.datetime):
self.dt_str = self.dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
@ -40,17 +38,14 @@ class FormatterCase(TransactionCase):
self.dt_str = self.dt.strftime(DEFAULT_SERVER_DATE_FORMAT)
elif isinstance(self.dt, datetime.time):
self.dt_str = self.dt.strftime(DEFAULT_SERVER_TIME_FORMAT)
# Pass a string
self.assertEqual(
self.expected, self.rl.datetime_formatter(self.dt_str, **self.kwargs)
)
# Pass a unicode
self.assertEqual(
self.expected, self.rl.datetime_formatter(str(self.dt_str), **self.kwargs)
)
super().tearDown()
def test_datetime(self):
@ -69,14 +64,11 @@ class FormatterCase(TransactionCase):
self.format = self.t_fmt
self.kwargs = {"template": MODE_TIME}
self.dt = self.dt.time()
# Test float times
for n in range(50):
n = n + random()
# Patch values with >= 24 hours
fmt = self.format.replace("%H", "%02d" % n)
time = (datetime.datetime.min + datetime.timedelta(hours=n)).time()
self.assertEqual(
time.strftime(fmt), self.rl.datetime_formatter(n, **self.kwargs)