[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:
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user