[FIX] models: filtered_domain on Falsy date/datetime fields
The purpose of this patch is to avoid `filtered_domain` to crash with
domains on date/datetime fields when the fields are `False` on some
records:
records.filtered_domain([('date', '<', '2019-10-28')])
closes odoo/odoo#39449
X-original-commit: dae379adebedb3ed9bd38a2d6925ba6aefef1e7f
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
@@ -617,6 +617,15 @@ class TestFields(common.TransactionCase):
|
||||
self.assertTrue(record.filtered_domain([('date', '<', '2012-05-02')]))
|
||||
self.assertTrue(record.filtered_domain([('date', '<', date(2012, 5, 2))]))
|
||||
self.assertTrue(record.filtered_domain([('date', '<', datetime(2012, 5, 2, 12, 0, 0))]))
|
||||
self.assertTrue(record.filtered_domain([('date', '!=', False)]))
|
||||
self.assertFalse(record.filtered_domain([('date', '=', False)]))
|
||||
|
||||
record.date = None
|
||||
self.assertFalse(record.filtered_domain([('date', '<', '2012-05-02')]))
|
||||
self.assertFalse(record.filtered_domain([('date', '<', date(2012, 5, 2))]))
|
||||
self.assertFalse(record.filtered_domain([('date', '<', datetime(2012, 5, 2, 12, 0, 0))]))
|
||||
self.assertFalse(record.filtered_domain([('date', '!=', False)]))
|
||||
self.assertTrue(record.filtered_domain([('date', '=', False)]))
|
||||
|
||||
def test_21_datetime(self):
|
||||
""" test datetime fields """
|
||||
@@ -647,6 +656,15 @@ class TestFields(common.TransactionCase):
|
||||
self.assertTrue(record.filtered_domain([('moment', '<', '2012-05-02')]))
|
||||
self.assertTrue(record.filtered_domain([('moment', '<', date(2012, 5, 2))]))
|
||||
self.assertTrue(record.filtered_domain([('moment', '<', datetime(2012, 5, 1, 12, 0, 0))]))
|
||||
self.assertTrue(record.filtered_domain([('moment', '!=', False)]))
|
||||
self.assertFalse(record.filtered_domain([('moment', '=', False)]))
|
||||
|
||||
record.moment = None
|
||||
self.assertFalse(record.filtered_domain([('moment', '<', '2012-05-02')]))
|
||||
self.assertFalse(record.filtered_domain([('moment', '<', date(2012, 5, 2))]))
|
||||
self.assertFalse(record.filtered_domain([('moment', '<', datetime(2012, 5, 2, 12, 0, 0))]))
|
||||
self.assertFalse(record.filtered_domain([('moment', '!=', False)]))
|
||||
self.assertTrue(record.filtered_domain([('moment', '=', False)]))
|
||||
|
||||
def test_21_date_datetime_helpers(self):
|
||||
""" test date/datetime fields helpers """
|
||||
|
||||
+21
-15
@@ -5132,7 +5132,15 @@ Record ids: %(records)s
|
||||
(key, comparator, value) = d
|
||||
if key.endswith('.id'):
|
||||
key = key[:-3]
|
||||
if key == 'id': key=''
|
||||
if key == 'id':
|
||||
key = ''
|
||||
# determine the field with the final type for values
|
||||
field = None
|
||||
if key:
|
||||
model = self.browse()
|
||||
for fname in key.split('.'):
|
||||
field = model._fields[fname]
|
||||
model = model[fname]
|
||||
if comparator in ('like', 'ilike', '=like', '=ilike', 'not ilike', 'not like'):
|
||||
value_esc = value.replace('_', '?').replace('%', '*').replace('[', '?')
|
||||
records = self.browse()
|
||||
@@ -5149,16 +5157,14 @@ Record ids: %(records)s
|
||||
data = data.mapped('display_name')
|
||||
else:
|
||||
data = data and data.ids or [False]
|
||||
else:
|
||||
true_data = next((d for d in data if d), None)
|
||||
if isinstance(true_data, datetime.date):
|
||||
# convert all date and datetime values to datetime
|
||||
normalize = Datetime.to_datetime
|
||||
if isinstance(value, (list, tuple)):
|
||||
value = [normalize(v) for v in value]
|
||||
else:
|
||||
value = normalize(value)
|
||||
data = [normalize(d) for d in data]
|
||||
elif field and field.type in ('date', 'datetime'):
|
||||
# convert all date and datetime values to datetime
|
||||
normalize = Datetime.to_datetime
|
||||
if isinstance(value, (list, tuple)):
|
||||
value = [normalize(v) for v in value]
|
||||
else:
|
||||
value = normalize(value)
|
||||
data = [normalize(d) for d in data]
|
||||
if comparator in ('in', 'not in'):
|
||||
if not (isinstance(value, list) or isinstance(value, tuple)):
|
||||
value = [value]
|
||||
@@ -5168,13 +5174,13 @@ Record ids: %(records)s
|
||||
elif comparator == 'in':
|
||||
ok = any(map(lambda x: x in data, value))
|
||||
elif comparator == '<':
|
||||
ok = any(map(lambda x: x < value, data))
|
||||
ok = any(map(lambda x: x is not None and x < value, data))
|
||||
elif comparator == '>':
|
||||
ok = any(map(lambda x: x > value, data))
|
||||
ok = any(map(lambda x: x is not None and x > value, data))
|
||||
elif comparator == '<=':
|
||||
ok = any(map(lambda x: x <= value, data))
|
||||
ok = any(map(lambda x: x is not None and x <= value, data))
|
||||
elif comparator == '>=':
|
||||
ok = any(map(lambda x: x >= value, data))
|
||||
ok = any(map(lambda x: x is not None and x >= value, data))
|
||||
elif comparator in ('!=', '<>'):
|
||||
ok = value not in data
|
||||
elif comparator == 'not in':
|
||||
|
||||
Reference in New Issue
Block a user