diff --git a/sao/src/common.js b/sao/src/common.js index 0686ffd498..91c169d1b6 100644 --- a/sao/src/common.js +++ b/sao/src/common.js @@ -1245,10 +1245,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 d3885b5dcc..cd3f40a009 100644 --- a/sao/tests/sao.js +++ b/sao/tests/sao.js @@ -2192,7 +2192,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 30f2922174..dbf2bf8ae6 100644 --- a/tryton/tryton/common/domain_parser.py +++ b/tryton/tryton/common/domain_parser.py @@ -645,10 +645,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 19c8fbcf1b..25b15d952d 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%'),