From 2472bdb3a1721f5d4e051fcb83bdfda154da01b8 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 16 Jul 2018 14:57:00 +0200 Subject: [PATCH] [FIX] base: remove duplicated translation before update Since 160d6577, the translations must be unique on the source. When calling insert_missing on a field, the final step is to set the correct source on every translation to keep them synchronised. In case the translation looked like: id | lang | src | type | res_id | name ---------+-------+-----+-------+--------+------------------ 42 | fr_FR | KGM | model | 2 | product.uom,name 43 | fr_FR | kg | model | 2 | product.uom,name The final step will fail as violating the unicity constraint. Remove duplicated translations before making the update. It was chosen to keep the latest translation as it should be the most up to date (e.g. after an import creating duplicated translations). Add a non-regression test for previous change opw-1864123 Closes #25787 --- odoo/addons/base/models/ir_translation.py | 8 ++++++ odoo/addons/base/tests/test_translate.py | 31 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/odoo/addons/base/models/ir_translation.py b/odoo/addons/base/models/ir_translation.py index 0ad132d4c33..4ec7c98cf3a 100644 --- a/odoo/addons/base/models/ir_translation.py +++ b/odoo/addons/base/models/ir_translation.py @@ -616,6 +616,14 @@ class IrTranslation(models.Model): SELECT 1 FROM ir_translation WHERE lang=l.code AND type='model' AND name=%(name)s AND res_id=%(res_id)s ); + + DELETE FROM ir_translation dup + WHERE type='model' AND name=%(name)s AND res_id=%(res_id)s + AND dup.id NOT IN (SELECT MAX(t.id) + FROM ir_translation t + WHERE t.lang=dup.lang AND type='model' AND name=%(name)s AND res_id=%(res_id)s + ); + UPDATE ir_translation SET src=%(src)s WHERE type='model' AND name=%(name)s AND res_id=%(res_id)s; """ diff --git a/odoo/addons/base/tests/test_translate.py b/odoo/addons/base/tests/test_translate.py index 5bd33a4852f..e8a76b12c86 100644 --- a/odoo/addons/base/tests/test_translate.py +++ b/odoo/addons/base/tests/test_translate.py @@ -275,6 +275,37 @@ class TestTranslation(TransactionCase): self.assertEqual(categories.ids, [padawans.id, self.customers.id], "Search ordered by translated name should return Padawans (Apprentis) before Customers (Clients)") + def test_105_duplicated_translation(self): + """ Test synchronizing translations with duplicated source """ + # create a category with a French translation + padawans = self.env['res.partner.category'].create({'name': 'Padawan'}) + self.env['ir.translation'].create({ + 'type': 'model', + 'name': 'res.partner.category,name', + 'module':'base', + 'lang': 'fr_FR', + 'res_id': padawans.id, + 'value': 'Apprenti', + 'state': 'translated', + }) + # change name and insert a duplicate manually + padawans.write({'name': 'Padawans'}) + self.env['ir.translation'].create({ + 'type': 'model', + 'name': 'res.partner.category,name', + 'module':'base', + 'lang': 'fr_FR', + 'res_id': padawans.id, + 'value': 'Apprentis', + 'state': 'translated', + }) + self.env['ir.translation'].translate_fields('res.partner.category', padawans.id, 'name') + translations = self.env['ir.translation'].search([ + ('res_id', '=', padawans.id), ('name', '=', 'res.partner.category,name') + ]) + self.assertEqual(len(translations), 1, "Translations were not merged after `translate_fields` call") + self.assertEqual(translations.value, "Apprentis", "The most recent translation must stay") + class TestXMLTranslation(TransactionCase): def setUp(self):