From 8edd9f79f8e727a0e08a8fa734279d5c5a55bded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 2 Oct 2024 17:02:55 +0200 Subject: [PATCH] Use equality operators when stringify in domain clause with singleton Closes #13557 --- sao/src/common.js | 14 +++++++++++--- sao/tests/sao.js | 2 ++ tryton/tryton/common/domain_parser.py | 12 +++++++++--- tryton/tryton/tests/test_common_domain_parser.py | 4 ++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/sao/src/common.js b/sao/src/common.js index d53b749dc1..9ccb3e0963 100644 --- a/sao/src/common.js +++ b/sao/src/common.js @@ -1298,10 +1298,18 @@ .replace('not', '!').trim(); } if (operator.endsWith('in')) { - if (operator == 'not in') { - operator = '!'; + if (value instanceof Array && value.length == 1) { + if (operator == 'not in') { + operator = '!='; + } else { + operator = '='; + } } else { - operator = ''; + if (operator == 'not in') { + operator = '!'; + } else { + operator = ''; + } } } var formatted_value = this.format_value(field, value, target); diff --git a/sao/tests/sao.js b/sao/tests/sao.js index d2022bbe71..82fe7c7f62 100644 --- a/sao/tests/sao.js +++ b/sao/tests/sao.js @@ -2318,7 +2318,9 @@ [[['name', 'ilike', 'Doe\\%']], 'Name: =Doe%'], [[['name', 'not ilike', '%Doe%']], 'Name: !Doe'], [[['name', 'in', ['John', 'Jane']]], 'Name: John;Jane'], + [[['name', 'in', ['John']]], 'Name: =John'], [[['name', 'not in', ['John', 'Jane']]], 'Name: !John;Jane'], + [[['name', 'not in', ['John']]], 'Name: !=John'], [[ ['name', 'ilike', '%Doe%'], ['name', 'ilike', '%Jane%'] diff --git a/tryton/tryton/common/domain_parser.py b/tryton/tryton/common/domain_parser.py index b369b3bb49..e1280c1199 100644 --- a/tryton/tryton/common/domain_parser.py +++ b/tryton/tryton/common/domain_parser.py @@ -647,10 +647,16 @@ class DomainParser(object): operator = operator.rstrip(def_operator ).replace('not', '!').strip() if operator.endswith('in'): - if operator == 'not in': - operator = '!' + if isinstance(value, (list, tuple)) and len(value) == 1: + if operator == 'not in': + operator = '!=' + else: + operator = '=' else: - operator = '' + if operator == 'not in': + operator = '!' + else: + operator = '' formatted_value = format_value(field, value, target, self.context) if (operator in OPERATORS and field['type'] in ('char', 'text', 'selection') diff --git a/tryton/tryton/tests/test_common_domain_parser.py b/tryton/tryton/tests/test_common_domain_parser.py index f9812ec343..4f7dd5a3d3 100644 --- a/tryton/tryton/tests/test_common_domain_parser.py +++ b/tryton/tryton/tests/test_common_domain_parser.py @@ -681,9 +681,13 @@ class DomainParserTestCase(TestCase): dom.string([('name', 'not ilike', '%Doe%')]), 'Name: !Doe') self.assertEqual( dom.string([('name', 'in', ['John', 'Jane'])]), 'Name: John;Jane') + self.assertEqual( + dom.string([('name', 'in', ['John'])]), 'Name: =John') self.assertEqual( dom.string([('name', 'not in', ['John', 'Jane'])]), 'Name: !John;Jane') + self.assertEqual( + dom.string([('name', 'not in', ['John'])]), 'Name: !=John') self.assertEqual( dom.string([ ('name', 'ilike', '%Doe%'),