details:   https://code.tryton.org/tryton/commit/332b8107a181
branch:    default
user:      Cédric Krier <[email protected]>
date:      Thu Dec 11 18:27:45 2025 +0100
description:
        Fix domain parser for Reference field when there is no value but a 
target

        Closes #14413
diffstat:

 sao/src/common.js                                |  7 ++++---
 sao/tests/sao.js                                 |  4 ++++
 tryton/tryton/common/domain_parser.py            |  7 ++++---
 tryton/tryton/tests/test_common_domain_parser.py |  7 +++++++
 4 files changed, 19 insertions(+), 6 deletions(-)

diffs (107 lines):

diff -r 09df3cc6f53e -r 332b8107a181 sao/src/common.js
--- a/sao/src/common.js Fri Dec 12 18:58:01 2025 +0100
+++ b/sao/src/common.js Thu Dec 11 18:27:45 2025 +0100
@@ -1275,7 +1275,8 @@
                 var name = clause[0];
                 var operator = clause[1];
                 var value = clause[2];
-                if (name.endsWith('.rec_name') && value) {
+                if (name.endsWith('.rec_name')
+                    && (value || (clause.length > 3))) {
                     name = name.slice(0, -9);
                 }
                 if (!(name in this.fields)) {
@@ -1853,7 +1854,7 @@
                         var split = this.split_target_value(field, value);
                         target = split[0];
                         value = split[1];
-                        if (target && value) {
+                        if (target) {
                             field_name += '.rec_name';
                         }
                     } else if (field.type == 'multiselection') {
@@ -2207,7 +2208,7 @@
                         break;
                     }
                 }
-                return target + ',' + value;
+                return target + ',' + (value || '');
             };
 
             var converts = {
diff -r 09df3cc6f53e -r 332b8107a181 sao/tests/sao.js
--- a/sao/tests/sao.js  Fri Dec 12 18:58:01 2025 +0100
+++ b/sao/tests/sao.js  Thu Dec 11 18:27:45 2025 +0100
@@ -2040,6 +2040,9 @@
         [[c(['Reference', null, 'Spam,bar'])], [
             c(['reference.rec_name', 'ilike', '%bar%', 'spam'])
             ]],
+        [[c(['Reference', null, 'Spam,'])], [
+            c(['reference.rec_name', 'ilike', '%', 'spam'])
+            ]],
         [[c(['Reference', null, ['foo', 'bar']])], [
             c(['reference', 'in', ['foo', 'bar']])
             ]],
@@ -2374,6 +2377,7 @@
         [[['multiselection', 'not in', ['foo', 'bar']]], "MultiSelection: 
!Foo;Bar"],
         [[['reference', 'ilike', '%foo%']], 'Reference: foo'],
         [[['reference', 'ilike', '%bar%', 'spam']], 'Reference: Spam,bar'],
+        [[['reference.rec_name', '=', null, 'spam']], 'Reference: =Spam,'],
         [[['reference', 'in', ['foo', 'bar']]], 'Reference: foo;bar'],
         [[['many2one', 'ilike', '%John%']], 'Many2One: John'],
         [[['many2one.rec_name', 'in', ['John', 'Jane']]], 'Many2One: 
John;Jane'],
diff -r 09df3cc6f53e -r 332b8107a181 tryton/tryton/common/domain_parser.py
--- a/tryton/tryton/common/domain_parser.py     Fri Dec 12 18:58:01 2025 +0100
+++ b/tryton/tryton/common/domain_parser.py     Thu Dec 11 18:27:45 2025 +0100
@@ -368,7 +368,7 @@
         if not target:
             return format_selection()
         selections = dict(field['selection'])
-        return '%s,%s' % (selections.get(target, target), value)
+        return '%s,%s' % (selections.get(target, target), value or '')
 
     def format_datetime():
         if not value:
@@ -624,7 +624,8 @@
                     or clause[0] in ('AND', 'OR')):
                 return '(%s)' % self.string(clause)
             name, operator, value = clause[:3]
-            if name.endswith('.rec_name') and value:
+            if (name.endswith('.rec_name')
+                    and (value or len(clause) > 3)):
                 name = name[:-9]
             if name not in self.fields:
                 if value is not None and is_full_text(value):
@@ -851,7 +852,7 @@
                     target = None
                     if field['type'] == 'reference':
                         target, value = split_target_value(field, value)
-                        if target and value:
+                        if target:
                             field_name += '.rec_name'
                     elif field['type'] == 'multiselection':
                         if value is not None and not isinstance(value, list):
diff -r 09df3cc6f53e -r 332b8107a181 
tryton/tryton/tests/test_common_domain_parser.py
--- a/tryton/tryton/tests/test_common_domain_parser.py  Fri Dec 12 18:58:01 
2025 +0100
+++ b/tryton/tryton/tests/test_common_domain_parser.py  Thu Dec 11 18:27:45 
2025 +0100
@@ -773,6 +773,9 @@
             dom.string([('reference.rec_name', 'ilike', '%bar%', 'spam')]),
             'Reference: Spam,bar')
         self.assertEqual(
+            dom.string([('reference.rec_name', '=', None, 'spam')]),
+            "Reference: =Spam,")
+        self.assertEqual(
             dom.string([('reference', 'in', ['foo', 'bar'])]),
             'Reference: foo;bar')
         self.assertEqual(
@@ -1107,6 +1110,10 @@
                 ('reference.rec_name', 'ilike', '%bar%', 'spam'),
                 ])
         self.assertEqual(
+            rlist(dom.parse_clause([('Reference', None, 'Spam,')])), [
+                ('reference.rec_name', 'ilike', '%', 'spam'),
+                ])
+        self.assertEqual(
             rlist(dom.parse_clause([('Reference', None, ['foo', 'bar'])])), [
                 ('reference', 'in', ['foo', 'bar']),
                 ])

Reply via email to