From 5f7de6226bc2c1da221bd2062631cd08689941da Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Thu, 19 Mar 2020 14:15:46 +0000 Subject: [PATCH] [FIX] website: menu translation on website MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the menu are only translated for installed language when we create a new website. When we create a new menu (eg. by installing a module) or install a new language we will only translate menu without website_id set, so the menu are not translated. With this changeset, we try to match translation of menu without website_id to menu with website_id when translations are updated: - when a language is installed/updated - when a module is installed/updated Without the changeset, the added test would fail with: - "Menu in english" != "Menu en français" Load translation add missing translation from template menu - "Menu in french" != "Menu en français" Load translation with overwriting update existing menu from template fixes #43365 opw-2209864 closes #48031 closes odoo/odoo#50498 X-original-commit: 998987f8ee148235f4025eb97a424e838ac6fc9f Signed-off-by: Nicolas Lempereur (nle) Signed-off-by: Martin Trigaux (mat) --- addons/website/models/__init__.py | 1 + addons/website/models/ir_translation.py | 45 +++++++++++++++++++++++++ addons/website/tests/test_menu.py | 41 ++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 addons/website/models/ir_translation.py diff --git a/addons/website/models/__init__.py b/addons/website/models/__init__.py index 378acd4f300..b66ecb50a24 100644 --- a/addons/website/models/__init__.py +++ b/addons/website/models/__init__.py @@ -14,6 +14,7 @@ from . import website_menu from . import website_page from . import website_rewrite from . import ir_rule +from . import ir_translation from . import ir_ui_view from . import res_company from . import res_partner diff --git a/addons/website/models/ir_translation.py b/addons/website/models/ir_translation.py new file mode 100644 index 00000000000..16528b7b27e --- /dev/null +++ b/addons/website/models/ir_translation.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + +class IrTranslation(models.Model): + _inherit = "ir.translation" + + def _load_module_terms(self, modules, langs, overwrite=False): + """ Add missing website specific translation """ + res = super()._load_module_terms(modules, langs) + + default_menu = self.env.ref('website.main_menu', raise_if_not_found=False) + + if not default_menu or not langs or not modules: + return res + + if overwrite: + conflict_clause = """ + ON CONFLICT (type, lang, name, res_id) WHERE type = 'model' + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = + (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, + EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != '' + """; + else: + conflict_clause = " ON CONFLICT DO NOTHING" + + # Add specific menu translations + self.env.cr.execute(""" + INSERT INTO ir_translation(name, lang, res_id, src, type, value, module, state, comments) + SELECT DISTINCT ON (s_menu.id, t.lang) t.name, t.lang, s_menu.id, t.src, t.type, t.value, t.module, t.state, t.comments + FROM ir_translation t + INNER JOIN website_menu o_menu + ON t.type = 'model' AND t.name = 'website.menu,name' AND t.res_id = o_menu.id + INNER JOIN website_menu s_menu + ON o_menu.name = s_menu.name AND o_menu.url = s_menu.url + INNER JOIN website_menu root_menu + ON s_menu.parent_id = root_menu.id AND root_menu.parent_id IS NULL + WHERE t.lang IN %s and t.module IN %s + AND o_menu.website_id IS NULL AND o_menu.parent_id = %s + AND s_menu.website_id IS NOT NULL""" + conflict_clause, + (tuple(langs), tuple(modules), default_menu.id)) + + return res diff --git a/addons/website/tests/test_menu.py b/addons/website/tests/test_menu.py index a410e3ed0eb..672eea114d4 100644 --- a/addons/website/tests/test_menu.py +++ b/addons/website/tests/test_menu.py @@ -65,6 +65,47 @@ class TestMenu(common.TransactionCase): Website.create({'name': 'new website'}) self.assertEqual(total_menus + 4, Menu.search_count([]), "New website's bootstraping should have duplicate default menu tree (Top/Home/Contactus/Sub Default Menu)") + def test_specific_menu_translation(self): + Translation = self.env['ir.translation'] + Website = self.env['website'] + Menu = self.env['website.menu'] + existing_menus = Menu.search([]) + + default_menu = self.env.ref('website.main_menu') + template_menu = Menu.create({ + 'parent_id': default_menu.id, + 'name': 'Menu in english', + 'url': 'turlututu', + }) + new_menus = Menu.search([]) - existing_menus + specific1, specific2 = new_menus.with_context(lang='fr_FR') - template_menu + + # create fr_FR translation for template menu + self.env.ref('base.lang_fr').active = True + template_menu.with_context(lang='fr_FR').name = 'Menu en français' + Translation.search([ + ('name', '=', 'website.menu,name'), ('res_id', '=', template_menu.id), + ]).module = 'website' + self.assertEqual(specific1.name, 'Menu in english', + 'Translating template menu does not translate specific menu') + + # have different translation for specific website + specific1.name = 'Menu in french' + + # loading translation add missing specific translation + Translation._load_module_terms(['website'], ['fr_FR']) + Menu.invalidate_cache(['name']) + self.assertEqual(specific1.name, 'Menu in french', + 'Load translation without overwriting keep existing translation') + self.assertEqual(specific2.name, 'Menu en français', + 'Load translation add missing translation from template menu') + + # loading translation with overwrite sync all translations from menu template + Translation._load_module_terms(['website'], ['fr_FR'], overwrite=True) + Menu.invalidate_cache(['name']) + self.assertEqual(specific1.name, 'Menu en français', + 'Load translation with overwriting update existing menu from template') + def test_default_menu_unlink(self): Menu = self.env['website.menu'] total_menu_items = Menu.search_count([])