From ed99544dfa88fa5769574a0b6db677e8f31edcd1 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 8 Jan 2019 13:36:55 +0000 Subject: [PATCH] [FIX] translate.py: really generate missing terms With 12.0's (#28297) empty translations were no longer added by default with the idea that if needed the "Generate Missing Terms" wizard should be used. But that wizard itself used what was modified so also did not added empty translation. With this changeset, empty translations are added when using the "Generate Missing Terms" wizard. fixes #29184 closes #30037 --- odoo/addons/base/models/ir_translation.py | 12 ++++++++---- odoo/addons/base/wizard/base_update_translations.py | 3 ++- .../test_translation_import/tests/test_term_count.py | 12 +++++++++--- odoo/tools/translate.py | 4 ++-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/odoo/addons/base/models/ir_translation.py b/odoo/addons/base/models/ir_translation.py index 4bc659ef6bd..15d03256ea5 100644 --- a/odoo/addons/base/models/ir_translation.py +++ b/odoo/addons/base/models/ir_translation.py @@ -141,7 +141,8 @@ class IrTranslationImport(object): WHERE type = 'code' AND noupdate IS NOT TRUE ON CONFLICT (type, lang, md5(src)) WHERE type = 'code' - DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments); + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != ''; """ % (self._model_table, self._table)) count += cr.rowcount cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) @@ -150,7 +151,8 @@ class IrTranslationImport(object): WHERE type = 'model' AND noupdate IS NOT TRUE ON CONFLICT (type, lang, name, res_id) WHERE type = 'model' - DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments); + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != ''; """ % (self._model_table, self._table)) count += cr.rowcount cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) @@ -159,7 +161,8 @@ class IrTranslationImport(object): WHERE type IN ('selection', 'constraint', 'sql_constraint') AND noupdate IS NOT TRUE ON CONFLICT (type, lang, name, md5(src)) WHERE type IN ('selection', 'constraint', 'sql_constraint') - DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments); + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != ''; """ % (self._model_table, self._table)) count += cr.rowcount cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) @@ -168,7 +171,8 @@ class IrTranslationImport(object): WHERE type = 'model_terms' AND noupdate IS NOT TRUE ON CONFLICT (type, name, lang, res_id, md5(src)) - DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments); + DO UPDATE SET (name, lang, res_id, src, type, value, module, state, comments) = (EXCLUDED.name, EXCLUDED.lang, EXCLUDED.res_id, EXCLUDED.src, EXCLUDED.type, EXCLUDED.value, EXCLUDED.module, EXCLUDED.state, EXCLUDED.comments) + WHERE EXCLUDED.value IS NOT NULL AND EXCLUDED.value != ''; """ % (self._model_table, self._table)) count += cr.rowcount cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) diff --git a/odoo/addons/base/wizard/base_update_translations.py b/odoo/addons/base/wizard/base_update_translations.py index f1dc7a10ca4..0bbfc17ab24 100644 --- a/odoo/addons/base/wizard/base_update_translations.py +++ b/odoo/addons/base/wizard/base_update_translations.py @@ -32,5 +32,6 @@ class BaseUpdateTranslations(models.TransientModel): lang_name = self._get_lang_name(this.lang) with tempfile.NamedTemporaryFile() as buf: tools.trans_export(this.lang, ['all'], buf, 'po', self._cr) - tools.trans_load_data(self._cr, buf, 'po', this.lang, lang_name=lang_name) + context = {'create_empty_translation': True} + tools.trans_load_data(self._cr, buf, 'po', this.lang, lang_name=lang_name, context=context) return {'type': 'ir.actions.act_window_close'} diff --git a/odoo/addons/test_translation_import/tests/test_term_count.py b/odoo/addons/test_translation_import/tests/test_term_count.py index 8a4976e1771..bde7bceac4f 100644 --- a/odoo/addons/test_translation_import/tests/test_term_count.py +++ b/odoo/addons/test_translation_import/tests/test_term_count.py @@ -92,17 +92,23 @@ class TestTermCount(common.TransactionCase): def test_export_empty_string(self): """When the string and the translation is equal the translation is empty""" # Export the translations - def update_translations(): + def update_translations(context=None): + context = dict(context or {}, overwrite=True) with closing(io.BytesIO()) as bufferobj: odoo.tools.trans_export('fr_FR', ['test_translation_import'], bufferobj, 'po', self.cr) bufferobj.name = 'test_translation_import/i18n/fr.po' - odoo.tools.trans_load_data(self.cr, bufferobj, 'po', 'fr_FR', verbose=False, context={'overwrite': True}) + odoo.tools.trans_load_data(self.cr, bufferobj, 'po', 'fr_FR', verbose=False, context=context) - # Check if the not translated key is empty string + # Check that the not translated key is not created update_translations() translation = self.env['ir.translation'].search_count([('src', '=', 'Efgh'), ('value', '=', '')]) self.assertFalse(translation, 'An empty translation is not imported') + # Check that "Generate Missing Terms" create empty string for not translated key + update_translations({'create_empty_translation': True}) + translation = self.env['ir.translation'].search_count([('src', '=', 'Efgh'), ('value', '=', '')]) + self.assertTrue(translation, 'The translation of "Efgh" should be empty') + # Modify the value translated for the equal value of the key menu = self.env.ref('test_translation_import.menu_test_translation_import') menu.name = "New Name" diff --git a/odoo/tools/translate.py b/odoo/tools/translate.py index ae552b6535e..e5e26799086 100644 --- a/odoo/tools/translate.py +++ b/odoo/tools/translate.py @@ -1098,8 +1098,8 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, dic['lang'] = lang dic.update(pycompat.izip(fields, row)) - # ignore empty value that may be set from base language - if not dic['value']: + # do not import empty values + if not env.context.get('create_empty_translation', False) and not dic['value']: return if use_pot_reference: