diff --git a/odoo/addons/test_new_api/demo_data.xml b/odoo/addons/test_new_api/demo_data.xml index 9edab779fcc..ff048467183 100644 --- a/odoo/addons/test_new_api/demo_data.xml +++ b/odoo/addons/test_new_api/demo_data.xml @@ -16,6 +16,7 @@ Hey dude! + hello @@ -27,6 +28,11 @@ This is a much longer message + + + first@example.localhost + + diff --git a/odoo/addons/test_new_api/models.py b/odoo/addons/test_new_api/models.py index eec467cd7b4..4f5fbb5ea5e 100644 --- a/odoo/addons/test_new_api/models.py +++ b/odoo/addons/test_new_api/models.py @@ -72,7 +72,7 @@ class Discussion(models.Model): categories = fields.Many2many('test_new_api.category', 'test_new_api_discussion_category', 'discussion', 'category') participants = fields.Many2many('res.users') - messages = fields.One2many('test_new_api.message', 'discussion') + messages = fields.One2many('test_new_api.message', 'discussion', copy=True) message_concat = fields.Text(string='Message concatenate') important_messages = fields.One2many('test_new_api.message', 'discussion', domain=[('important', '=', True)]) @@ -125,6 +125,7 @@ class Message(models.Model): 'res.partner', compute='_compute_author_partner', search='_search_author_partner') important = fields.Boolean() + label = fields.Char(translate=True) @api.one @api.constrains('author', 'discussion') diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 45815c6f031..05e736c7361 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -862,6 +862,40 @@ class TestFields(common.TransactionCase): self.assertEqual(len(discussion.important_messages), 2) self.assertEqual(len(discussion.very_important_messages), 2) + def test_80_copy(self): + Translations = self.env['ir.translation'] + discussion = self.env.ref('test_new_api.discussion_0') + message = self.env.ref('test_new_api.message_0_0') + message1 = self.env.ref('test_new_api.message_0_1') + + email = self.env.ref('test_new_api.emailmessage_0_0') + self.assertEqual(email.message, message) + + french = self.env['res.lang']._lang_get('fr_FR') + french.active = True + + def count(msg): + # return the number of translations of msg.label + return Translations.search_count([ + ('name', '=', 'test_new_api.message,label'), + ('res_id', '=', msg.id), + ]) + + # set a translation for message.label + email.with_context(lang='fr_FR').label = "bonjour" + self.assertEqual(count(message), 1) + self.assertEqual(count(message1), 0) + + # setting the parent record should not copy its translations + email.copy({'message': message1.id}) + self.assertEqual(count(message), 1) + self.assertEqual(count(message1), 0) + + # setting a one2many should not copy translations on the lines + discussion.copy({'messages': [(6, 0, message1.ids)]}) + self.assertEqual(count(message), 1) + self.assertEqual(count(message1), 0) + class TestX2many(common.TransactionCase): def test_search_many2many(self): diff --git a/odoo/models.py b/odoo/models.py index e32b35a5870..79997061504 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3824,7 +3824,13 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): return [default] @api.multi - def copy_translations(old, new): + def copy_translations(old, new, excluded=()): + """ Recursively copy the translations from original to new record + + :param old: the original record + :param new: the new record (copy of the original one) + :param excluded: a container of user-provided field names + """ # avoid recursion through already copied records in case of circular relationship if '__copy_translations_seen' not in old._context: old = old.with_context(__copy_translations_seen=defaultdict(set)) @@ -3850,13 +3856,20 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): if not field.copy: continue - if field.type == 'one2many': + if field.inherited and field.related[0] in excluded: + # inherited fields that come from a user-provided parent record + # must not copy translations, as the parent record is not a copy + # of the old parent record + continue + + if field.type == 'one2many' and field.name not in excluded: # we must recursively copy the translations for o2m; here we # rely on the order of the ids to match the translations as # foreseen in copy_data() old_lines = old[name].sorted(key='id') new_lines = new[name].sorted(key='id') for (old_line, new_line) in pycompat.izip(old_lines, new_lines): + # don't pass excluded as it is not about those lines old_line.copy_translations(new_line) elif field.translate: @@ -3896,7 +3909,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): vals = self.copy_data(default)[0] # To avoid to create a translation in the lang of the user, copy_translation will do it new = self.with_context(lang=None).create(vals) - self.with_context(from_copy_translation=True).copy_translations(new) + self.with_context(from_copy_translation=True).copy_translations(new, excluded=default or ()) return new @api.multi