Fix domain parser for Reference field when there is no value but a target

Closes #14413
(grafted from 332b8107a181f3c14e0e3c39eed393bab0cc619b)

--HG--
branch : 6.0
This commit is contained in:
Cédric Krier
2025-12-14 20:12:58 +01:00
parent 139db54944
commit ca03769eaf
4 changed files with 19 additions and 6 deletions
+4 -3
View File
@@ -1204,11 +1204,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);
@@ -2149,7 +2150,7 @@
break;
}
}
return target + ',' + value;
return target + ',' + (value || '');
};
var converts = {
+4
View File
@@ -1930,6 +1930,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']])
]],
@@ -2250,6 +2253,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'],
+4 -3
View File
@@ -361,7 +361,7 @@ def format_value(field, value, target=None, context=None, _quote_empty=False):
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:
@@ -617,10 +617,11 @@ class DomainParser(object):
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]
@@ -768,6 +768,9 @@ class DomainParserTestCase(TestCase):
self.assertEqual(
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')
@@ -1081,6 +1084,10 @@ class DomainParserTestCase(TestCase):
rlist(dom.parse_clause([('Reference', None, 'Spam,bar')])), [
('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']),