diff options
| author | wan <wan@odoo.com> | 2019-10-01 08:28:42 +0000 |
|---|---|---|
| committer | Martin Trigaux <mat@odoo.com> | 2019-10-01 10:05:17 +0000 |
| commit | 63de98b9b4a329705a5faaab74bc641e6b29eb54 (patch) | |
| tree | fff61ab5fb72d1059190e069c0e0d137e09e40a8 /odoo | |
| parent | f28f787c10ad320b562610952f9e26279872f8b7 (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.py | 5 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_qweb_fields.py | 7 | ||||
| -rw-r--r-- | odoo/models.py | 4 | ||||
| -rw-r--r-- | odoo/osv/expression.py | 3 | ||||
| -rw-r--r-- | odoo/tools/misc.py | 30 |
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}') |
