[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
This commit is contained in:
Martin Trigaux
2018-07-19 09:21:15 +02:00
parent 02f38beffb
commit 2472bdb3a1
2 changed files with 39 additions and 0 deletions
@@ -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;
"""
+31
View File
@@ -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):