summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorwan <wan@odoo.com>2019-10-01 08:28:42 +0000
committerMartin Trigaux <mat@odoo.com>2019-10-01 10:05:17 +0000
commit63de98b9b4a329705a5faaab74bc641e6b29eb54 (patch)
treefff61ab5fb72d1059190e069c0e0d137e09e40a8 /odoo
parentf28f787c10ad320b562610952f9e26279872f8b7 (diff)
[FIX] *: remove en_US as fallback for lang code
en_US may not be activated as it is possible to create a database in another language using the database manager. When trying to install a chart of account, the tax return entry tried to format a date at the installation of the module, with no lang in the context. The fallback was made on en_US but an error is raised if that language is not activated. As it is a very common scenario to retrieve a language from the context, add a generic tool method to do it. Replace and closes odoo/odoo#37629 closes odoo/odoo#37568 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/base/models/ir_qweb.py5
-rw-r--r--odoo/addons/base/models/ir_qweb_fields.py7
-rw-r--r--odoo/models.py4
-rw-r--r--odoo/osv/expression.py3
-rw-r--r--odoo/tools/misc.py30
5 files changed, 31 insertions, 18 deletions
diff --git a/odoo/addons/base/models/ir_qweb.py b/odoo/addons/base/models/ir_qweb.py
index 0ddb06744e0..07fe2d1592f 100644
--- a/odoo/addons/base/models/ir_qweb.py
+++ b/odoo/addons/base/models/ir_qweb.py
@@ -13,6 +13,7 @@ from werkzeug import urls
from odoo import api, models, tools
from odoo.tools.safe_eval import assert_valid_codeobj, _BUILTINS, _SAFE_OPCODES
+from odoo.tools.misc import get_lang
from odoo.http import request
from odoo.modules.module import get_resource_path
@@ -112,7 +113,7 @@ class IrQWeb(models.AbstractModel, QWeb):
return super(IrQWeb, self).compile(id_or_xml_id, options=options)
def load(self, name, options):
- lang = options.get('lang', 'en_US')
+ lang = options.get('lang', get_lang(self.env).code)
env = self.env
if lang != env.context.get('lang'):
env = env(context=dict(env.context, lang=lang))
@@ -148,7 +149,7 @@ class IrQWeb(models.AbstractModel, QWeb):
# compile directives
def _compile_directive_lang(self, el, options):
- lang = el.attrib.pop('t-lang', 'en_US')
+ lang = el.attrib.pop('t-lang', get_lang(self.env).code)
if el.get('t-call-options'):
el.set('t-call-options', el.get('t-call-options')[0:-1] + u', "lang": %s}' % lang)
else:
diff --git a/odoo/addons/base/models/ir_qweb_fields.py b/odoo/addons/base/models/ir_qweb_fields.py
index c275707377b..329d9b3c55b 100644
--- a/odoo/addons/base/models/ir_qweb_fields.py
+++ b/odoo/addons/base/models/ir_qweb_fields.py
@@ -10,6 +10,7 @@ from lxml import etree
import math
from odoo.tools import html_escape as escape, posix_to_ldml, safe_eval, float_utils, format_date, format_duration, pycompat
+from odoo.tools.misc import get_lang
import logging
_logger = logging.getLogger(__name__)
@@ -130,13 +131,11 @@ class FieldConverter(models.AbstractModel):
""" user_lang()
Fetches the res.lang record corresponding to the language code stored
- in the user's context. Fallbacks to en_US if no lang is present in the
- context *or the language code is not valid*.
+ in the user's context.
:returns: Model[res.lang]
"""
- lang_code = self._context.get('lang') or 'en_US'
- return self.env['res.lang']._lang_get(lang_code)
+ return get_lang(self.env)
class IntegerConverter(models.AbstractModel):
diff --git a/odoo/models.py b/odoo/models.py
index 0a076effedd..479b86bbf01 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -56,7 +56,7 @@ from .tools import frozendict, lazy_classproperty, lazy_property, ormcache, \
groupby
from .tools.config import config
from .tools.func import frame_codeinfo
-from .tools.misc import CountingStream, clean_context, DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
+from .tools.misc import CountingStream, clean_context, DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT, get_lang
from .tools.safe_eval import safe_eval
from .tools.translate import _
from .tools import date_utils
@@ -1991,7 +1991,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
if ftype == 'many2one':
value = value[0]
elif ftype in ('date', 'datetime'):
- locale = self._context.get('lang') or 'en_US'
+ locale = get_lang(self.env).code
fmt = DEFAULT_SERVER_DATETIME_FORMAT if ftype == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
tzinfo = None
range_start = value
diff --git a/odoo/osv/expression.py b/odoo/osv/expression.py
index e15ea963abd..38d503af0f9 100644
--- a/odoo/osv/expression.py
+++ b/odoo/osv/expression.py
@@ -123,6 +123,7 @@ from zlib import crc32
from datetime import date, datetime, time
import odoo.modules
from odoo.tools import pycompat
+from odoo.tools.misc import get_lang
from ..models import MAGIC_COLUMNS, BaseModel
import odoo.tools as tools
@@ -1145,7 +1146,7 @@ class expression(object):
params = (
model._name + ',' + left,
- model.env.lang or 'en_US',
+ get_lang(model.env).code,
'model',
right,
)
diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py
index a9268db1eed..b65cd23cf6f 100644
--- a/odoo/tools/misc.py
+++ b/odoo/tools/misc.py
@@ -1162,6 +1162,21 @@ else:
def html_escape(text):
return werkzeug.utils.escape(text)
+
+def get_lang(env, lang_code=False):
+ """
+ Retrieve the first lang object installed, by checking the parameter lang_code,
+ the context and then the company. If no lang is installed from those variables,
+ fallback on the first lang installed in the system.
+ :param str lang_code: the locale (i.e. en_US)
+ :return res.lang: the first lang found that is installed on the system.
+ """
+ langs = [code for code, _ in env['res.lang'].get_installed()]
+ for code in [lang_code, env.context.get('lang'), env.user.company_id.partner_id.lang, langs[0]]:
+ if code in langs:
+ return env['res.lang']._lang_get(code)
+
+
def formatLang(env, value, digits=None, grouping=True, monetary=False, dp=False, currency_obj=False):
"""
Assuming 'Account' decimal.precision=3:
@@ -1182,9 +1197,7 @@ def formatLang(env, value, digits=None, grouping=True, monetary=False, dp=False,
if isinstance(value, str) and not value:
return ''
- langs = [code for code, _ in env['res.lang'].get_installed()]
- lang_code = env.context['lang'] if env.context.get('lang') in langs else (env.user.company_id.partner_id.lang or langs[0])
- lang_obj = env['res.lang']._lang_get(lang_code)
+ lang_obj = get_lang(env)
res = lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
@@ -1221,7 +1234,7 @@ def format_date(env, value, lang_code=False, date_format=False):
else:
value = odoo.fields.Datetime.from_string(value)
- lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US')
+ lang = get_lang(env, lang_code)
locale = babel.Locale.parse(lang.code)
if not date_format:
date_format = posix_to_ldml(lang.date_format, locale=locale)
@@ -1240,7 +1253,7 @@ def parse_date(env, value, lang_code=False):
:return: date object from the localized string
:rtype: datetime.date
'''
- lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US')
+ lang = get_lang(env, lang_code)
locale = babel.Locale.parse(lang.code)
try:
return babel.dates.parse_date(value, locale=locale)
@@ -1271,8 +1284,7 @@ def format_datetime(env, value, tz=False, dt_format='medium', lang_code=False):
except Exception:
localized_datetime = utc_datetime
- lang_code = lang_code or env.context.get('lang') or 'en_US'
- lang = env['res.lang']._lang_get(lang_code)
+ lang = get_lang(env, lang_code)
locale = babel.Locale.parse(lang.code or lang_code) # lang can be inactive, so `lang`is empty
if not dt_format:
@@ -1302,7 +1314,7 @@ def format_time(env, value, tz=False, time_format='medium', lang_code=False):
if not value:
return ''
- lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US')
+ lang = get_lang(env, lang_code)
locale = babel.Locale.parse(lang.code)
if not time_format:
time_format = posix_to_ldml(lang.time_format, locale=locale)
@@ -1320,7 +1332,7 @@ def _format_time_ago(env, time_delta, lang_code=False, add_direction=True):
def format_amount(env, amount, currency, lang_code=False):
fmt = "%.{0}f".format(currency.decimal_places)
- lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US')
+ lang = get_lang(env, lang_code)
formatted_amount = lang.format(fmt, currency.round(amount), grouping=True, monetary=True)\
.replace(r' ', u'\N{NO-BREAK SPACE}').replace(r'-', u'-\N{ZERO WIDTH NO-BREAK SPACE}')