From e70af3d79f2c4300366a6fc2c98a876be3ec8741 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Fri, 17 May 2024 16:13:28 +0200 Subject: [PATCH] shopinvader: Fix product url computation triggers --- shopinvader/models/__init__.py | 1 + shopinvader/models/ir_translation.py | 37 ++++++++++++++++++++++++++++ shopinvader/tests/test_product.py | 25 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 shopinvader/models/ir_translation.py diff --git a/shopinvader/models/__init__.py b/shopinvader/models/__init__.py index c1307db40d..b6da3d170a 100644 --- a/shopinvader/models/__init__.py +++ b/shopinvader/models/__init__.py @@ -20,3 +20,4 @@ from . import shopinvader_variant from . import res_config_settings from . import res_partner +from . import ir_translation diff --git a/shopinvader/models/ir_translation.py b/shopinvader/models/ir_translation.py new file mode 100644 index 0000000000..d1283f0ef3 --- /dev/null +++ b/shopinvader/models/ir_translation.py @@ -0,0 +1,37 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from itertools import groupby + +from odoo import models + + +class IrTranslation(models.Model): + _inherit = "ir.translation" + + def write(self, vals): + # Because updating translations from the wizard writes directly on + # ir.translation, updating a product's name translation does not trigger + # the computation of the url. + # To fix that, adding a hook here, filtering as soon and as much as possible + # translation records in order to avoid too much extra cost. + res = super().write(vals) + tmpl_name_records = self.filtered( + lambda record: record.name == "product.template,name" + ) + if not tmpl_name_records: + return res + sorted_records = tmpl_name_records.sorted(lambda record: record.lang) + translation_groups = groupby(sorted_records, key=lambda record: record.lang) + for lang_name, translation_list in translation_groups: + lang = self.env["res.lang"]._lang_get(lang_name) + if not lang: + continue + templates = self.env["product.template"].browse( + [translation.res_id for translation in translation_list] + ) + template_bindings = templates.shopinvader_bind_ids.filtered( + lambda tmpl: tmpl.lang_id == lang and tmpl.url_builder == "auto" + ) + template_bindings._compute_automatic_url_key() + return res diff --git a/shopinvader/tests/test_product.py b/shopinvader/tests/test_product.py index 7ba0488256..9b2e229681 100644 --- a/shopinvader/tests/test_product.py +++ b/shopinvader/tests/test_product.py @@ -990,6 +990,31 @@ def test_main_product_multi_language(self): for shopinvader_variant in prod.shopinvader_bind_ids: self.assertTrue(shopinvader_variant.main) + def test_translation_update_url(self): + lang_fr = self._install_lang("base.lang_fr") + lang_en = self.env.ref("base.lang_en") + self.backend.lang_ids |= lang_fr + product = self.env.ref("product.product_product_4") + product.name = "customizable desk" + product.with_context(lang=lang_fr.code).name = "bureau modifiable" + binding_fr = product.shopinvader_bind_ids.filtered( + lambda bind: bind.lang_id == lang_fr + ) + binding_en = product.shopinvader_bind_ids.filtered( + lambda bind: bind.lang_id == lang_en + ) + self.assertEqual(binding_en.url_key, "customizable-desk") + self.assertEqual(binding_fr.url_key, "bureau-modifiable") + translation_name_fr = self.env["ir.translation"].search( + [("name", "=", "product.template,name"), ("lang", "=", lang_fr.code)] + ) + self.assertEqual(translation_name_fr.value, "bureau modifiable") + product.with_context(lang=lang_fr.code).name = "bureau customisable" + binding_fr.invalidate_cache() + product.invalidate_cache() + self.assertEqual(binding_en.url_key, "customizable-desk") + self.assertEqual(binding_fr.url_key, "bureau-customisable") + def test_create_shopinvader_category_from_product_category(self): categ = self.env["product.category"].search([])[0] lang = self.env["res.lang"]._lang_get(self.env.user.lang)