[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
Closes #18438
Closes #18440
This commit is contained in:
Raphael Collet
2017-10-17 13:50:00 +02:00
committed by Nicolas Martinelli
parent b85bd35823
commit 9ae78328ec
2 changed files with 31 additions and 2 deletions
@@ -528,6 +528,30 @@ class TestNewFields(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 TestMagicFields(common.TransactionCase):
+7 -2
View File
@@ -861,8 +861,13 @@ class one2many(_column):
# Must use write() to recompute parent_store structure if needed
obj.write(cr, user, act[2], {self._fields_id:id}, context=context or {})
ids2 = act[2] or [0]
cr.execute('select id from '+_table+' where '+self._fields_id+'=%s and id <> ALL (%s)', (id,ids2))
ids3 = map(lambda x:x[0], cr.fetchall())
# if the o2m has a static domain we must respect it when unlinking
domain = (self._domain(original_obj)
if callable(self._domain) else self._domain)
extra_domain = domain or []
ids3 = obj.search(cr, user, [(self._fields_id,'=',id), ('id','not in',ids2)] + extra_domain, context=context)
# If the model has cascade deletion, we delete the rows because it is the intended behavior,
# otherwise we only nullify the reverse foreign key column.
inverse_field = obj._fields.get(self._fields_id)
if getattr(inverse_field, "ondelete", None) == "cascade":
obj.unlink(cr, user, ids3, context=context)