[FIX] account: manage base locale in CoA loading
If we had a name that is translated in the template files with the base locale instead of the fully qualified one (i.e. `fr` instead of `fr_BE`), we would only store `fr`, which the ORM doesn't understand as there is no fallback on the generic locale (only on `en_US`) Instead of storing the translation values straight out of the record's values dictionary, we are now doing something similar as the generic `_load_module_terms`, loading only the languages being installed, and using the fallback on the generic locale there. closes odoo/odoo#113886 Signed-off-by: Laurent Smet <las@odoo.com>
This commit is contained in:
@@ -14,7 +14,8 @@ from odoo import Command, _, models, api
|
||||
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
|
||||
from odoo.addons.account import SYSCOHADA_LIST
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tools import file_open
|
||||
from odoo.tools import file_open, groupby
|
||||
from odoo.tools.translate import TranslationImporter
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -179,6 +180,7 @@ class AccountChartTemplate(models.AbstractModel):
|
||||
install_demo = False
|
||||
data = self._pre_load_data(template_code, company, template_data, data)
|
||||
self._load_data(data)
|
||||
self._load_translations(companies=company)
|
||||
self._post_load_data(template_code, company, template_data)
|
||||
|
||||
# Manual sync because disable above (delay_account_group_sync)
|
||||
@@ -405,20 +407,9 @@ class AccountChartTemplate(models.AbstractModel):
|
||||
|
||||
created_vals = {}
|
||||
for model, data in defer(list(data.items())):
|
||||
translate_vals = []
|
||||
create_vals = []
|
||||
|
||||
for xml_id, record in data.items():
|
||||
# Extract the translations from the values
|
||||
if any('@' in key for key in record):
|
||||
translate_vals.append({
|
||||
translate.split('@')[1]: value
|
||||
for translate, value in record.items()
|
||||
if '@' in translate and value
|
||||
})
|
||||
translate_vals[-1]['en_US'] = record['name']
|
||||
else:
|
||||
translate_vals.append(None)
|
||||
for key in list(record):
|
||||
if '@' in key:
|
||||
del record[key]
|
||||
@@ -435,19 +426,7 @@ class AccountChartTemplate(models.AbstractModel):
|
||||
'values': deref(record, self.env[model]),
|
||||
'noupdate': True,
|
||||
})
|
||||
created_vals[model] = created = self.env[model]._load_records(create_vals)
|
||||
|
||||
# Update the translations in batch for all languages
|
||||
translate_vals = [(r.id, Json(t)) for t, r in zip(translate_vals, created) if t]
|
||||
if translate_vals:
|
||||
self.env.cr.execute(f"""
|
||||
UPDATE "{self.env[model]._table}" AS m
|
||||
SET "name" = t.value
|
||||
FROM (
|
||||
VALUES {', '.join(['(%s, %s::jsonb)'] * (len(translate_vals)))}
|
||||
) AS t(id, value)
|
||||
WHERE m.id = t.id
|
||||
""", [v for vals in translate_vals for v in vals])
|
||||
created_vals[model] = self.env[model]._load_records(create_vals)
|
||||
return created_vals
|
||||
|
||||
def _post_load_data(self, template_code, company, template_data):
|
||||
@@ -776,3 +755,33 @@ class AccountChartTemplate(models.AbstractModel):
|
||||
except FileNotFoundError:
|
||||
_logger.debug("No file %s found for template '%s'", model, module)
|
||||
return res
|
||||
|
||||
def _load_translations(self, langs=None, companies=None):
|
||||
"""Load the translations of the chart template.
|
||||
|
||||
:param langs: the lang code to load the translations for. If one of the codes is not present,
|
||||
we are looking for it more generic locale (i.e. `en` instead of `en_US`)
|
||||
:type langs: list[str]
|
||||
:param companies: the companies to load the translations for
|
||||
:type companies: Model<res.company>
|
||||
"""
|
||||
langs = langs or [code for code, _name in self.env['res.lang'].get_installed()]
|
||||
companies = companies or self.env['res.company'].search([('chart_template', '!=', False)])
|
||||
|
||||
translation_importer = TranslationImporter(self.env.cr, verbose=False)
|
||||
for chart_template, chart_companies in groupby(companies, lambda c: c.chart_template):
|
||||
template_data = self.env['account.chart.template']._get_chart_template_data(chart_template)
|
||||
template_data.pop('template_data', None)
|
||||
for mname, data in template_data.items():
|
||||
for _xml_id, record in data.items():
|
||||
fnames = {fname.split('@')[0] for fname in record}
|
||||
for lang in langs:
|
||||
for fname in fnames:
|
||||
value = record.get(f"{fname}@{lang}")
|
||||
if not value: # manage generic locale (i.e. `fr` instead of `fr_BE`)
|
||||
value = record.get(f"{fname}@{lang.split('_')[0]}")
|
||||
if value:
|
||||
for company in chart_companies:
|
||||
xml_id = f"account.{company.id}_{_xml_id}"
|
||||
translation_importer.model_translations[mname][fname][xml_id][lang] = value
|
||||
translation_importer.save(overwrite=False)
|
||||
|
||||
@@ -68,3 +68,8 @@ class IrModule(models.Model):
|
||||
next(iter(self.account_templates)),
|
||||
self.env.company,
|
||||
)
|
||||
|
||||
def _load_module_terms(self, modules, langs, overwrite=False):
|
||||
super()._load_module_terms(modules, langs, overwrite)
|
||||
if 'account' in modules:
|
||||
self.env['account.chart.template']._load_translations(langs=langs)
|
||||
|
||||
Reference in New Issue
Block a user