[FIX] translate.py: fallback on base lang if noterm
When there is a language and its base language translation files in a
module, in 12.0 an empty translation in the language translation file
will not fallback on the base language.
eg.
fr.po : {'one': 'un', 'seventy': 'soixante-dix'}
fr_BE.po: {'one': '', 'seventy': 'septante'}
=> the translation in fr_BE will be {'one': '', 'seventy': 'septante'}
but before 7288b477 it would have been {'one': 'un', 'seventy': 'septante'}
With this commit, an empty translation is no longer created so does not
override base language.
Also the intention of d84b795b0a that was also lost is restored by
upserting only noupdate==false translation, and inserting the other
ones.
opw-1904638
closes #28297
This commit is contained in:
@@ -132,20 +132,23 @@ class IrTranslationImport(object):
|
||||
if hasattr(field, 'translate') and callable(field.translate):
|
||||
src_relevant_fields.append("%s,%s" % (model, field_name))
|
||||
|
||||
# Step 2: insert new or upsert translations
|
||||
count = 0
|
||||
# Step 2: insert new or upsert non-noupdate translations
|
||||
if self._overwrite:
|
||||
cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments)
|
||||
SELECT name, lang, res_id, src, type, value, module, state, comments
|
||||
FROM %s
|
||||
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);
|
||||
""" % (self._model_table, self._table))
|
||||
count = cr.rowcount
|
||||
count += cr.rowcount
|
||||
cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments)
|
||||
SELECT name, lang, res_id, src, type, value, module, state, comments
|
||||
FROM %s
|
||||
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);
|
||||
""" % (self._model_table, self._table))
|
||||
@@ -154,6 +157,7 @@ class IrTranslationImport(object):
|
||||
SELECT name, lang, res_id, src, type, value, module, state, comments
|
||||
FROM %s
|
||||
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);
|
||||
""" % (self._model_table, self._table))
|
||||
@@ -162,17 +166,18 @@ class IrTranslationImport(object):
|
||||
SELECT name, lang, res_id, src, type, value, module, state, comments
|
||||
FROM %s
|
||||
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);
|
||||
""" % (self._model_table, self._table))
|
||||
count += cr.rowcount
|
||||
else:
|
||||
cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments)
|
||||
SELECT name, lang, res_id, src, type, value, module, state, comments
|
||||
FROM %s
|
||||
ON CONFLICT DO NOTHING;
|
||||
""" % (self._model_table, self._table))
|
||||
count = cr.rowcount
|
||||
cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments)
|
||||
SELECT name, lang, res_id, src, type, value, module, state, comments
|
||||
FROM %s
|
||||
WHERE %s
|
||||
ON CONFLICT DO NOTHING;
|
||||
""" % (self._model_table, self._table, 'noupdate IS TRUE' if self._overwrite else 'TRUE'))
|
||||
count += cr.rowcount
|
||||
|
||||
if self._debug:
|
||||
cr.execute("SELECT COUNT(*) FROM ONLY %s" % self._model_table)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# This is a test PO file, not a true french translation.
|
||||
# See the POT file for further information.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 6.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-10-17 12:36+0000\n"
|
||||
"PO-Revision-Date: 2012-10-17 12:36+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: test_translation_import
|
||||
#: code:addons/test_translation_import/models.py:14
|
||||
#, python-format
|
||||
msgid "Ijkl"
|
||||
msgstr "Ijkl in belgian french"
|
||||
|
||||
#. module: test_translation_import
|
||||
#: model:ir.model,name:test_translation_import.model_test_translation_import
|
||||
msgid "test.translation.import"
|
||||
msgstr "test.translation.import in belgian french"
|
||||
|
||||
#. module: test_translation_import
|
||||
#: model:ir.model.fields,help:test_translation_import.field_test_translation_import__name
|
||||
msgid "Efgh"
|
||||
msgstr ""
|
||||
|
||||
#. module: test_translation_import
|
||||
#: code:addons/base/models/ford.py:43
|
||||
msgid "Test translation with a code type but different line number in pot"
|
||||
msgstr ""
|
||||
@@ -17,8 +17,10 @@ class TestTermCount(common.TransactionCase):
|
||||
Just make sure we have as many translation entries as we wanted.
|
||||
"""
|
||||
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr.po', 'fr_FR', module_name='test_translation_import', verbose=False)
|
||||
ids = self.env['ir.translation'].search(
|
||||
[('src', '=', '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB')])
|
||||
ids = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_FR'),
|
||||
('src', '=', '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB'),
|
||||
])
|
||||
self.assertEqual(len(ids), 2)
|
||||
|
||||
def test_noupdate(self):
|
||||
@@ -34,25 +36,56 @@ class TestTermCount(common.TransactionCase):
|
||||
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr.po', 'fr_FR', module_name='test_translation_import', verbose=False, context={'overwrite': True})
|
||||
|
||||
# trans_load invalidates ormcache but not record cache
|
||||
menu.clear_caches()
|
||||
menu.env.cache.invalidate()
|
||||
self.assertEqual(menu.name, "New Name")
|
||||
self.assertEqual(menu.with_context(lang='fr_FR').name, "Nouveau nom")
|
||||
|
||||
def test_lang_with_base(self):
|
||||
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr.po', 'fr_BE', module_name='test_translation_import', verbose=False)
|
||||
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr_BE.po', 'fr_BE', module_name='test_translation_import', verbose=False, context={'overwrite': True})
|
||||
|
||||
# language override base language
|
||||
translations = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_BE'),
|
||||
('value', '=like', '% belgian french'),
|
||||
])
|
||||
self.assertEqual(len(translations), 2)
|
||||
|
||||
# not specified localized language fallback on base language
|
||||
translations = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_BE'),
|
||||
('src', '=', 'Efgh'),
|
||||
('value', '=', 'Efgh in french'),
|
||||
])
|
||||
self.assertEqual(len(translations), 1)
|
||||
translations = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_BE'),
|
||||
('src', '=', 'Test translation with a code type but different line number in pot'),
|
||||
('value', '=', 'Test traduction avec un type code mais différent numéro de ligne dans le pot'),
|
||||
])
|
||||
self.assertEqual(len(translations), 1)
|
||||
|
||||
def test_no_duplicate(self):
|
||||
"""
|
||||
Just make sure we do not create duplicated translation with 'code' type
|
||||
"""
|
||||
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr.po', 'fr_FR', module_name='test_translation_import', verbose=False)
|
||||
ids = self.env['ir.translation'].search(
|
||||
[('src', '=', 'Test translation with two code lines')])
|
||||
ids = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_FR'),
|
||||
('src', '=', 'Test translation with two code lines'),
|
||||
])
|
||||
self.assertEqual(len(ids), 1)
|
||||
|
||||
ids = self.env['ir.translation'].search(
|
||||
[('src', '=', 'Test translation with a code type but different line number in pot')])
|
||||
ids = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_FR'),
|
||||
('src', '=', 'Test translation with a code type but different line number in pot'),
|
||||
])
|
||||
self.assertEqual(len(ids), 1)
|
||||
|
||||
ids = self.env['ir.translation'].search(
|
||||
[('src', '=', 'Test translation with two code type and model')])
|
||||
ids = self.env['ir.translation'].search([
|
||||
('lang', '=', 'fr_FR'),
|
||||
('src', '=', 'Test translation with two code type and model'),
|
||||
])
|
||||
self.assertEqual(len(ids), 2)
|
||||
self.assertEqual(len(ids.filtered(lambda t: t.type == 'code')), 1)
|
||||
|
||||
@@ -68,7 +101,7 @@ class TestTermCount(common.TransactionCase):
|
||||
# Check if the not translated key is empty string
|
||||
update_translations()
|
||||
translation = self.env['ir.translation'].search_count([('src', '=', 'Efgh'), ('value', '=', '')])
|
||||
self.assertTrue(translation, 'The translation of "Efgh" should be empty')
|
||||
self.assertFalse(translation, 'An empty translation is not imported')
|
||||
|
||||
# Modify the value translated for the equal value of the key
|
||||
menu = self.env.ref('test_translation_import.menu_test_translation_import')
|
||||
|
||||
@@ -1102,6 +1102,10 @@ 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']:
|
||||
return
|
||||
|
||||
if use_pot_reference:
|
||||
# discard the target from the POT targets.
|
||||
src = dic['src']
|
||||
|
||||
Reference in New Issue
Block a user