diff --git a/odoo/addons/base/tests/test_translate.py b/odoo/addons/base/tests/test_translate.py index f83ac3ff25239f611f8b3d06fa04a462d722c52e..de263db821b28dc0cbffbf9487298ef642301323 100644 --- a/odoo/addons/base/tests/test_translate.py +++ b/odoo/addons/base/tests/test_translate.py @@ -758,6 +758,27 @@ class TestTranslationWrite(TransactionCase): with self.assertRaises(UserError): self.category.update_field_translations('name', {'fr_FR': {'English Name': 'French Name'}}) + def test_update_field_translations_for_empty(self): + self.env['res.lang']._activate_lang('nl_NL') + self.env['res.lang']._activate_lang('fr_FR') + group = self.env['res.groups'].create({'name': 'test_group', 'comment': False}) + + groupEN = group.with_context(lang='en_US') + groupFR = group.with_context(lang='fr_FR') + groupNL = group.with_context(lang='nl_NL') + self.assertEqual(groupEN.comment, False) + groupFR.update_field_translations('comment', {'nl_NL': 'Dutch Name', 'fr_FR': 'French Name'}) + self.assertEqual(groupEN.comment, 'French Name', 'fr_FR value as the current env.lang is chosen as the default en_US value') + self.assertEqual(groupFR.comment, 'French Name') + self.assertEqual(groupNL.comment, 'Dutch Name') + + group.comment = False + groupFR.update_field_translations('comment', {'nl_NL': False, 'fr_FR': False}) + groupFR.flush_recordset() + self.cr.execute("SELECT comment FROM res_groups WHERE id = %s", (group.id,)) + (comment,) = self.cr.fetchone() + self.assertEqual(comment, None) + def test_field_selection(self): """ Test translations of field selections. """ self.env['res.lang']._activate_lang('fr_FR') diff --git a/odoo/models.py b/odoo/models.py index f736d1352ed8b9b13d67a248f604b2505b0fe1ea..8f2bac890ea22ed1df49428f6251ed1d23a97ab1 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3045,10 +3045,20 @@ class BaseModel(metaclass=MetaModel): lang: translation if isinstance(translation, str) else None for lang, translation in translations.items() } + if not translations: + return False + + translation_fallback = translations['en_US'] if translations.get('en_US') is not None \ + else translations[self.env.lang] if translations.get(self.env.lang) is not None \ + else next((v for v in translations.values() if v is not None), None) self.invalidate_recordset([field_name]) self._cr.execute(f''' - UPDATE {self._table} SET {field_name} = jsonb_strip_nulls({field_name} || %s) WHERE id = %s - ''', (Json(translations), self.id)) + UPDATE {self._table} + SET {field_name} = NULLIF( + jsonb_strip_nulls(%s || COALESCE("{field_name}", '{{}}'::jsonb) || %s), + '{{}}'::jsonb) + WHERE id = %s + ''', (Json({'en_US': translation_fallback}), Json(translations), self.id)) self.modified([field_name]) else: # Note: