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

Closes #14413
This commit is contained in:
Cédric Krier
2025-12-11 18:27:45 +01:00
parent 038e5d030b
commit e189e555fe
4 changed files with 19 additions and 6 deletions
+4 -3
View File
@@ -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 = {
+4
View File
@@ -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'],
+4 -3
View File
@@ -368,7 +368,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:
@@ -624,7 +624,8 @@ class DomainParser(object):
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 @@ class DomainParser(object):
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):
@@ -772,6 +772,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')
@@ -1106,6 +1109,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']),