[FIX] models: copy in a given lang must keep a field's neutral value intact

Issue: when using `copy` in a given lang, the value of XML/HTML fields is
copied in its translated form, making existing translations useless.  Fix the
value of such fields by storing their original value instead.
This commit is contained in:
Raphael Collet
2017-06-14 14:26:50 +02:00
parent bc34ba015d
commit ce7f31b0b0
2 changed files with 55 additions and 4 deletions
+49
View File
@@ -222,3 +222,52 @@ class TestTranslation(TransactionCase):
categories = padawans_fr.search([('id', 'in', [self.customers.id, padawans.id])], order='name')
self.assertEqual(categories.ids, [padawans.id, self.customers.id],
"Search ordered by translated name should return Padawans (Apprentis) before Customers (Clients)")
class TestXMLTranslation(TransactionCase):
def setUp(self):
super(TestXMLTranslation, self).setUp()
self.env['ir.translation'].load_module_terms(['base'], ['fr_FR'])
def test_copy(self):
""" Create a simple view, fill in translations, and copy it. """
env_en = self.env(context={})
env_fr = self.env(context={'lang': 'fr_FR'})
archf = '<form string="%s"><div>%s</div><div>%s</div></form>'
terms_en = ('Knife', 'Fork', 'Spoon')
terms_fr = ('Couteau', 'Fourchette', 'Cuiller')
view0 = self.env['ir.ui.view'].create({
'name': 'test',
'model': 'res.partner',
'arch': archf % terms_en,
})
for src, value in zip(terms_en, terms_fr):
self.env['ir.translation'].create({
'type': 'model',
'name': 'ir.ui.view,arch_db',
'lang': 'fr_FR',
'res_id': view0.id,
'src': src,
'value': value,
})
# check translated field
self.assertEqual(view0.with_env(env_en).arch_db, archf % terms_en)
self.assertEqual(view0.with_env(env_fr).arch_db, archf % terms_fr)
# copy without lang
view1 = view0.with_env(env_en).copy({})
self.assertEqual(view1.with_env(env_en).arch_db, archf % terms_en)
self.assertEqual(view1.with_env(env_fr).arch_db, archf % terms_fr)
# copy with lang='fr_FR'
view2 = view0.with_env(env_fr).copy({})
self.assertEqual(view2.with_env(env_en).arch_db, archf % terms_en)
self.assertEqual(view2.with_env(env_fr).arch_db, archf % terms_fr)
# copy with lang='fr_FR' and translate=html_translate
self.patch(type(self.env['ir.ui.view']).arch_db, 'translate', html_translate)
view3 = view0.with_env(env_fr).copy({})
self.assertEqual(view3.with_env(env_en).arch_db, archf % terms_en)
self.assertEqual(view3.with_env(env_fr).arch_db, archf % terms_fr)
+6 -4
View File
@@ -4362,16 +4362,18 @@ class BaseModel(object):
# for translatable fields we copy their translations
trans_name, source_id, target_id = get_trans(field, old, new)
domain = [('name', '=', trans_name), ('res_id', '=', source_id)]
new_val = new_wo_lang[name]
if old.env.lang:
# the new value *without lang* must be the old value without lang
new_wo_lang[name] = old_wo_lang[name]
for vals in Translation.search_read(domain):
del vals['id']
del vals['source'] # remove source to avoid triggering _set_src
del vals['module'] # duplicated vals is not linked to any module
vals['res_id'] = target_id
if vals['lang'] == old.env.lang and field.translate is True:
# 'source' to force the call to _set_src
# 'value' needed if value is changed in copy(), want to see the new_value
vals['source'] = old_wo_lang[name]
vals['value'] = new_wo_lang[name]
# the value should be the new value (given by copy())
vals['value'] = new_val
Translation.create(vals)
@api.multi