diff --git a/odoo/addons/base/__manifest__.py b/odoo/addons/base/__manifest__.py index 76ed56425af..366f62fe37c 100644 --- a/odoo/addons/base/__manifest__.py +++ b/odoo/addons/base/__manifest__.py @@ -84,6 +84,11 @@ The kernel of Odoo, needed for all installation. 'data/res_partner_demo.xml', 'data/res_partner_image_demo.xml', ], + 'assets': { + 'web.assets_tests': [ + 'base/static/tests/**/*', + ], + }, 'installable': True, 'auto_install': True, 'post_init_hook': 'post_init', diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index 1a2f03655cf..157dd6cae94 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -935,13 +935,9 @@ class IrModelFields(models.Model): # names of the models to patch patched_models = set() - - # write callable(self._fields[fname].translate) means changing content - translate_only = self.env.lang not in (None, 'en_US') and all(self._fields[fname].translate is True for fname in vals) - if vals and self: for item in self: - if item.state != 'manual' and not translate_only: + if item.state != 'manual': raise UserError(_('Properties of base fields cannot be altered in this manner! ' 'Please modify them through Python code, ' 'preferably through a custom addon!')) @@ -1010,6 +1006,12 @@ class IrModelFields(models.Model): return res + def update_field_translations(self, field_name, translations): + res = super().update_field_translations(field_name, translations) + if res: + self.clear_caches() + return res + def name_get(self): res = [] for field in self: diff --git a/odoo/addons/base/static/tests/test_ir_model_fields_translation.js b/odoo/addons/base/static/tests/test_ir_model_fields_translation.js new file mode 100644 index 00000000000..37633b0aba8 --- /dev/null +++ b/odoo/addons/base/static/tests/test_ir_model_fields_translation.js @@ -0,0 +1,38 @@ +/** @odoo-module **/ + +"use strict"; + +import { registry } from "@web/core/registry"; +import { stepUtils } from "@web_tour/tour_service/tour_utils"; +function checkLoginColumn(translation) { + return [ + stepUtils.showAppsMenuItem(), { + content: "Settings", + trigger: 'a[data-menu-xmlid="base.menu_administration"]', + run: 'click', + }, { + content: "Open Users & Companies", + trigger: '[data-menu-xmlid="base.menu_users"]', + run: "click", + }, { + content: "Open Users", + trigger: '[data-menu-xmlid="base.menu_action_res_users"]', + run: "click", + }, { + content: `Login column should be ${translation}`, + trigger: `[data-name="login"] span:contains("${translation}")`, + } + ] +} + +registry.category("web_tour.tours").add('ir_model_fields_translation_tour', { + test: true, + url: '/web', + steps: checkLoginColumn('Identifiant') +}); + +registry.category("web_tour.tours").add('ir_model_fields_translation_tour2', { + test: true, + url: '/web', + steps: checkLoginColumn('Identifiant2') +}); diff --git a/odoo/addons/base/tests/test_ir_model.py b/odoo/addons/base/tests/test_ir_model.py index 6b8ab8c0567..91626960c1d 100644 --- a/odoo/addons/base/tests/test_ir_model.py +++ b/odoo/addons/base/tests/test_ir_model.py @@ -4,7 +4,7 @@ from psycopg2 import IntegrityError from odoo.exceptions import ValidationError -from odoo.tests.common import TransactionCase, tagged +from odoo.tests.common import TransactionCase, HttpCase, tagged from odoo.tools import mute_logger from odoo import Command @@ -342,3 +342,18 @@ class TestEvalContext(TransactionCase): "dateutil.relativedelta.relativedelta(hours=1)") }) self.env['res.partner'].create({'name': 'foo'}).x_foo_bar_baz + +@tagged('-at_install', 'post_install') +class TestIrModelFieldsTranslation(HttpCase): + def test_ir_model_fields_translation(self): + self.env['res.lang']._activate_lang('fr_FR') + field = self.env['ir.model.fields'].search([('model_id.model', '=', 'res.users'), ('name', '=', 'login')]) + field.update_field_translations('field_description', {'fr_FR': 'Identifiant'}) + self.assertEqual(field.with_context(lang='fr_FR').field_description, 'Identifiant') + admin = self.env['res.users'].search([('login', '=', 'admin')], limit=1) + admin.lang = 'fr_FR' + # check the name column of res.users is displayed as 'Identifiant' + self.start_tour("/web", 'ir_model_fields_translation_tour', login="admin") + field.update_field_translations('field_description', {'fr_FR': 'Identifiant2'}) + # check the name column of res.users is displayed as 'Identifiant2' + self.start_tour("/web", 'ir_model_fields_translation_tour2', login="admin")