From ef181c33dd32541fe340ecf7c2b3ae77db43e25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 27 Apr 2022 17:51:52 +0200 Subject: [PATCH] Negate the origin expression of Many2Many with 'not where' operator issue11425 review403401002 --- trytond/model/fields/many2many.py | 6 ++++-- trytond/tests/test_field_many2many.py | 15 +++++++++++++++ trytond/tests/test_field_one2many.py | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/trytond/model/fields/many2many.py b/trytond/model/fields/many2many.py index ff30450e68..54ccf3c0c3 100644 --- a/trytond/model/fields/many2many.py +++ b/trytond/model/fields/many2many.py @@ -460,7 +460,7 @@ class Many2Many(Field): relation_domain.append( (self.origin, 'like', Model.__name__ + ',%')) else: - relation_domain = [self.target, operator, value] + relation_domain = [self.target, 'where', value] rule_domain = Rule.domain_get(Relation.__name__, mode='read') if rule_domain: relation_domain = [relation_domain, rule_domain] @@ -477,7 +477,9 @@ class Many2Many(Field): query_table = convert_from(None, relation_tables) query = query_table.select(origin, where=expression) expression = table.id.in_(query) - if operator.startswith('!') or operator.startswith('not '): + if operator == 'not where': + expression = ~expression + elif operator.startswith('!') or operator.startswith('not '): expression |= ~table.id.in_(relation.select(origin)) return expression diff --git a/trytond/tests/test_field_many2many.py b/trytond/tests/test_field_many2many.py index b254b4aab7..bd517e399e 100644 --- a/trytond/tests/test_field_many2many.py +++ b/trytond/tests/test_field_many2many.py @@ -243,6 +243,21 @@ class CommonTestCaseMixin: self.assertListEqual(many2manys, []) + @with_transaction() + def test_search_not_where_others(self): + "Test search many2many not where with others" + Many2Many = self.Many2Many() + many2many, = Many2Many.create([{ + 'targets': [('create', [ + {'name': "Target"}, {'name': "Foo"}])], + }]) + + many2manys = Many2Many.search([ + ('targets', 'not where', [('name', '=', "Target")]), + ]) + + self.assertListEqual(many2manys, []) + @with_transaction() def test_write_write(self): "Test write many2many write" diff --git a/trytond/tests/test_field_one2many.py b/trytond/tests/test_field_one2many.py index 48c382b9b9..a6d62a89bf 100644 --- a/trytond/tests/test_field_one2many.py +++ b/trytond/tests/test_field_one2many.py @@ -305,6 +305,21 @@ class CommonTestCaseMixin: self.assertListEqual(one2manys, []) + @with_transaction() + def test_search_not_where_others(self): + "Test search one2many not where with others" + One2Many = self.One2Many() + one2many, = One2Many.create([{ + 'targets': [('create', [ + {'name': "Target"}, {'name': "Foo"}])], + }]) + + one2manys = One2Many.search([ + ('targets', 'not where', [('name', '=', "Target")]), + ]) + + self.assertListEqual(one2manys, []) + @with_transaction() def test_write_write(self): "Test write one2many write"