[FIMP] base: remove all translations when writing False

This "bugprovement" resolve the old issue of writing on a translatable
field a falsy value.

Before this commit, only the translation value was removed. When no
translation is present (or when the value is not set), the value is
retrieved directly from the source field.

Before 18d9c2cab2, it was still possible to go around this issue by
removing manually all ir.translation entries and writing with a user
in en_US.
This is no longer possible as writing on a translatable field always
uses translations when in multi-language environment, without
exception of en_US.

When writing a falsy value on a field, the expected behaviour is to
reset the value and see that falsy value after saving, not the old
value stored on the source model.

Remove all translations and force to update the column.

Removing one individual translation is still possible in the
translation popup.

Task id: 2062415

closes odoo/odoo#37077

Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This commit is contained in:
Martin Trigaux
2019-09-18 14:56:41 +00:00
parent 2425c7b223
commit 543a5523a3
2 changed files with 62 additions and 4 deletions
+52
View File
@@ -481,6 +481,58 @@ class TestTranslationWrite(TransactionCase):
])
def test_05_remove_multi(self):
self.env['res.lang'].load_lang('fr_FR')
langs = self.env['res.lang'].get_installed()
self.assertEqual([('en_US', 'English (US)'), ('fr_FR', 'French / Français')], langs,
"Test did not started with expected languages")
belgium = self.env.ref('base.be')
# vat_label is translatable and not required
belgium.with_context(lang='en_US').write({'vat_label': 'VAT'})
# create translations if not exists
self.env['ir.translation']._upsert_translations([{
'type': 'model',
'name': 'res.country,vat_label',
'lang': 'en_US',
'res_id': belgium.id,
'src': 'VAT',
'value': 'VAT',
'state': 'translated',
}, {
'type': 'model',
'name': 'res.country,vat_label',
'lang': 'fr_FR',
'res_id': belgium.id,
'src': 'VAT',
'value': 'TVA',
'state': 'translated',
}])
# remove the value
belgium.with_context(lang='fr_FR').write({'vat_label': False})
# should recover the initial value from db
self.assertEqual(
False, belgium.with_context(lang='fr_FR').vat_label,
"Value was not reset"
)
self.assertEqual(
False, belgium.with_context(lang='en_US').vat_label,
"Value was not reset in other languages"
)
self.assertEqual(
False, belgium.with_context(lang=None).vat_label,
"Value was not reset on the field model"
)
translations = self.env['ir.translation'].search([
('name', '=', 'res.country,vat_label'),
('res_id', '=', belgium.id),
])
self.assertEqual(len(translations), 0, "Translations were not removed")
def test_field_selection(self):
""" Test translations of field selections. """
field = self.env['ir.model']._fields['state']
+10 -4
View File
@@ -1435,8 +1435,8 @@ class _String(Field):
update_column = True
update_trans = True
elif lang != 'en_US':
# update the translations only
update_column = False
# update the translations only except if emptying
update_column = cache_value is None
update_trans = True
# update towrite if modifying the source
@@ -1445,7 +1445,7 @@ class _String(Field):
for rid in real_recs._ids:
# cache_value is already in database format
towrite[rid][self.name] = cache_value
if self.translate is True:
if self.translate is True and cache_value is not None:
tname = "%s,%s" % (records._name, self.name)
records.env['ir.translation']._set_source(tname, real_recs._ids, value)
@@ -1464,7 +1464,13 @@ class _String(Field):
source_recs[self.name] = value
source_value = value
tname = "%s,%s" % (self.model_name, self.name)
if single_lang:
if value is None:
records.env['ir.translation'].search([
('name', '=', tname),
('type', '=', 'model'),
('res_id', 'in', real_recs._ids)
]).unlink()
elif single_lang:
records.env['ir.translation']._update_translations([dict(
src=source_value,
value=value,