details:   https://code.tryton.org/tryton/commit/8930ead64030
branch:    7.4
user:      Cédric Krier <[email protected]>
date:      Sun Dec 14 20:12:17 2025 +0100
description:
        Fix domain parser for Reference field when there is no value but a 
target

        Closes #14413
        (grafted from 332b8107a181f3c14e0e3c39eed393bab0cc619b)
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 (98 lines):

diff -r fd821aa67b53 -r 8930ead64030 sao/src/common.js
--- a/sao/src/common.js Wed Dec 10 16:09:44 2025 +0100
+++ b/sao/src/common.js Sun Dec 14 20:12:17 2025 +0100
@@ -1257,11 +1257,12 @@
                 var name = clause[0];
                 var operator = clause[1];
                 var value = clause[2];
-                if (name.endsWith('.rec_name')) {
+                if (name.endsWith('.rec_name')
+                    && (value || (clause.length > 3))) {
                     name = name.slice(0, -9);
                 }
                 if (!(name in this.fields)) {
-                    if (this.is_full_text(value)) {
+                    if ((value !== null) && this.is_full_text(value)) {
                         value = value.slice(1, -1);
                     }
                     return this.quote(value);
@@ -2183,7 +2184,7 @@
                         break;
                     }
                 }
-                return target + ',' + value;
+                return target + ',' + (value || '');
             };
 
             var converts = {
diff -r fd821aa67b53 -r 8930ead64030 sao/tests/sao.js
--- a/sao/tests/sao.js  Wed Dec 10 16:09:44 2025 +0100
+++ b/sao/tests/sao.js  Sun Dec 14 20:12:17 2025 +0100
@@ -2048,6 +2048,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']])
             ]],
@@ -2376,6 +2379,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 fd821aa67b53 -r 8930ead64030 tryton/tryton/common/domain_parser.py
--- a/tryton/tryton/common/domain_parser.py     Wed Dec 10 16:09:44 2025 +0100
+++ b/tryton/tryton/common/domain_parser.py     Sun Dec 14 20:12:17 2025 +0100
@@ -363,7 +363,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:
@@ -619,10 +619,11 @@
                     or clause[0] in ('AND', 'OR')):
                 return '(%s)' % self.string(clause)
             name, operator, value = clause[:3]
-            if name.endswith('.rec_name'):
+            if (name.endswith('.rec_name')
+                    and (value or len(clause) > 3)):
                 name = name[:-9]
             if name not in self.fields:
-                if is_full_text(value):
+                if value is not None and is_full_text(value):
                     value = value[1:-1]
                 return quote(value)
             field = self.fields[name]
diff -r fd821aa67b53 -r 8930ead64030 
tryton/tryton/tests/test_common_domain_parser.py
--- a/tryton/tryton/tests/test_common_domain_parser.py  Wed Dec 10 16:09:44 
2025 +0100
+++ b/tryton/tryton/tests/test_common_domain_parser.py  Sun Dec 14 20:12:17 
2025 +0100
@@ -769,6 +769,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(
@@ -1094,6 +1097,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