From fcf6ef476ced0953e6faf88b7bbf9881923de4d5 Mon Sep 17 00:00:00 2001 From: Raphael Collet <rco@odoo.com> Date: Thu, 31 Aug 2017 14:46:34 +0200 Subject: [PATCH] [FIX] fields: writing on a one2many with a domain should not remove all lines Specifically, the command `(6, 0, ids)` should only unlink/detach the lines that satisfy to the field's domain. Test from #18440 opw-756983 --- .../test_new_api/tests/test_new_fields.py | 24 +++++++++++++++++++ odoo/fields.py | 9 ++++--- 2 files changed, 28 insertions(+), 5 deletions(-) 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 9deaee1a5f0a..dc5b9936c7a1 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -697,6 +697,30 @@ class TestFields(common.TransactionCase): self.assertFalse(discussion.very_important_messages) self.assertFalse(message.exists()) + def test_70_x2many_write(self): + discussion = self.env.ref('test_new_api.discussion_0') + Message = self.env['test_new_api.message'] + # There must be 3 messages, 0 important + self.assertEqual(len(discussion.messages), 3) + self.assertEqual(len(discussion.important_messages), 0) + self.assertEqual(len(discussion.very_important_messages), 0) + discussion.important_messages = [(0, 0, { + 'body': 'What is the answer?', + 'important': True, + })] + # There must be 4 messages, 1 important + self.assertEqual(len(discussion.messages), 4) + self.assertEqual(len(discussion.important_messages), 1) + self.assertEqual(len(discussion.very_important_messages), 1) + discussion.very_important_messages |= Message.new({ + 'body': '42', + 'important': True, + }) + # There must be 5 messages, 2 important + self.assertEqual(len(discussion.messages), 5) + self.assertEqual(len(discussion.important_messages), 2) + self.assertEqual(len(discussion.very_important_messages), 2) + class TestHtmlField(common.TransactionCase): diff --git a/odoo/fields.py b/odoo/fields.py index 60aefa9bc25d..50209746c10e 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -2205,14 +2205,13 @@ class One2many(_RelationalMulti): elif act[0] == 6: record = records[-1] comodel.browse(act[2]).write({inverse: record.id}) - query = "SELECT id FROM %s WHERE %s=%%s AND id <> ALL(%%s)" % (comodel._table, inverse) - comodel._cr.execute(query, (record.id, act[2] or [0])) - lines = comodel.browse([row[0] for row in comodel._cr.fetchall()]) + domain = self.domain(records) if callable(self.domain) else self.domain + domain = domain + [(inverse, 'in', records.ids), ('id', 'not in', act[2] or [0])] inverse_field = comodel._fields[inverse] if inverse_field.ondelete == 'cascade': - lines.unlink() + comodel.search(domain).unlink() else: - lines.write({inverse: False}) + comodel.search(domain).write({inverse: False}) class Many2many(_RelationalMulti): -- GitLab