backoffice: sort by criticality and receipt_time (#76644) #537
|
@ -137,38 +137,35 @@ def test_backoffice_criticality_in_formdef_listing_order(pub):
|
|||
data_class = formdef.data_class()
|
||||
data_class.wipe()
|
||||
|
||||
for i in range(0, 4):
|
||||
for i in range(0, 10):
|
||||
formdata = data_class()
|
||||
formdata.data = {}
|
||||
formdata.just_created()
|
||||
formdata.jump_status('new')
|
||||
formdata.receipt_time = datetime.datetime(2015, 1, 1, 10, i).timetuple()
|
||||
if i < 8:
|
||||
if i % 3 == 0:
|
||||
formdata.set_criticality_level(1)
|
||||
if i % 3 == 1:
|
||||
formdata.set_criticality_level(2)
|
||||
if i % 3 == 2:
|
||||
formdata.set_criticality_level(3)
|
||||
formdata.store()
|
||||
|
||||
formdata1, formdata2, formdata3, formdata4 = [
|
||||
x for x in formdef.data_class().select() if x.status == 'wf-new'
|
||||
][:4]
|
||||
|
||||
formdata1.set_criticality_level(1)
|
||||
formdata1.store()
|
||||
formdata1_str = '>%s<' % formdata1.get_display_id()
|
||||
formdata2.set_criticality_level(2)
|
||||
formdata2.store()
|
||||
formdata2_str = '>%s<' % formdata2.get_display_id()
|
||||
formdata3.set_criticality_level(2)
|
||||
formdata3.store()
|
||||
formdata3_str = '>%s<' % formdata3.get_display_id()
|
||||
formdata4_str = '>%s<' % formdata4.get_display_id()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/?order_by=-criticality_level&limit=100')
|
||||
assert resp.text.index(formdata1_str) > resp.text.index(formdata2_str)
|
||||
assert resp.text.index(formdata1_str) > resp.text.index(formdata3_str)
|
||||
assert resp.text.index(formdata1_str) < resp.text.index(formdata4_str)
|
||||
order = [8, 6, 5, 3, 2, 7, 4, 1, 10, 9]
|
||||
for i, o in enumerate(order):
|
||||
if i == 9:
|
||||
break
|
||||
assert resp.text.index('>1-%s<' % o) < resp.text.index('>1-%s<' % order[i + 1])
|
||||
|
||||
resp = app.get('/backoffice/management/form-title/?order_by=criticality_level&limit=100')
|
||||
assert resp.text.index(formdata1_str) < resp.text.index(formdata2_str)
|
||||
assert resp.text.index(formdata1_str) < resp.text.index(formdata3_str)
|
||||
assert resp.text.index(formdata1_str) > resp.text.index(formdata4_str)
|
||||
reversed_order = list(reversed(order))
|
||||
for i, o in enumerate(reversed_order):
|
||||
if i == 9:
|
||||
break
|
||||
assert resp.text.index('>1-%s<' % o) < resp.text.index('>1-%s<' % reversed_order[i + 1])
|
||||
|
||||
|
||||
def test_backoffice_criticality_in_global_listing_order(pub):
|
||||
|
|
|
@ -361,7 +361,12 @@ class FormDef(StorableObject):
|
|||
elif field.store_display_value:
|
||||
order_by += "_display"
|
||||
break
|
||||
return '%s%s' % (direction, order_by)
|
||||
order_by = '%s%s' % (direction, order_by)
|
||||
if order_by == 'criticality_level':
|
||||
order_by = [order_by, 'receipt_time']
|
||||
elif order_by == '-criticality_level':
|
||||
order_by = [order_by, '-receipt_time']
|
||||
return order_by
|
||||
|
||||
def has_admin_access(self, user):
|
||||
# return True if user 1/ is global administrator for this type of object, or
|
||||
|
|
54
wcs/sql.py
54
wcs/sql.py
|
@ -1855,28 +1855,44 @@ class SqlMixin:
|
|||
def get_order_by_clause(cls, order_by):
|
||||
if not order_by:
|
||||
return ''
|
||||
# [SEC_ORDER] security note: it is not possible to use
|
||||
# prepared statements for ORDER BY clauses, therefore input
|
||||
# is controlled beforehand (see misc.get_order_by_or_400).
|
||||
direction = 'ASC'
|
||||
if order_by.startswith('-'):
|
||||
order_by = order_by[1:]
|
||||
direction = 'DESC'
|
||||
if '->' in order_by:
|
||||
# sort on field of block field: f42->'data'->0->>'bf13e4d8a8-fb08-4808-b5ae-02d6247949b9'
|
||||
parts = order_by.split('->')
|
||||
order_by = '%s->%s' % (parts[0].replace('-', '_'), '->'.join(parts[1:]))
|
||||
else:
|
||||
order_by = order_by.replace('-', '_')
|
||||
|
||||
fields = ['formdef_name', 'user_name'] # global view fields
|
||||
fields.extend([x[0] for x in cls._table_static_fields])
|
||||
fields.extend(cls.get_data_fields())
|
||||
if order_by.split('->')[0] not in fields:
|
||||
# for a sort on field of block field, just check the existence of the block field
|
||||
def _get_order_by_part(part):
|
||||
# [SEC_ORDER] security note: it is not possible to use
|
||||
# prepared statements for ORDER BY clauses, therefore input
|
||||
# is controlled beforehand (see misc.get_order_by_or_400).
|
||||
direction = 'ASC'
|
||||
if part.startswith('-'):
|
||||
part = part[1:]
|
||||
direction = 'DESC'
|
||||
if '->' in part:
|
||||
# sort on field of block field: f42->'data'->0->>'bf13e4d8a8-fb08-4808-b5ae-02d6247949b9'
|
||||
parts = part.split('->')
|
||||
part = '%s->%s' % (parts[0].replace('-', '_'), '->'.join(parts[1:]))
|
||||
else:
|
||||
part = part.replace('-', '_')
|
||||
|
||||
fields = ['formdef_name', 'user_name'] # global view fields
|
||||
fields.extend([x[0] for x in cls._table_static_fields])
|
||||
fields.extend(cls.get_data_fields())
|
||||
if part.split('->')[0] not in fields:
|
||||
# for a sort on field of block field, just check the existence of the block field
|
||||
return None, None
|
||||
return part, direction
|
||||
|
||||
if not isinstance(order_by, list):
|
||||
order_by = [order_by]
|
||||
|
||||
ordering = []
|
||||
for part in order_by:
|
||||
order, direction = _get_order_by_part(part)
|
||||
if order is None:
|
||||
continue
|
||||
ordering.append(f'{order} {direction}')
|
||||
|
||||
if not ordering:
|
||||
return ''
|
||||
|
||||
return ' ORDER BY %s %s' % (order_by, direction)
|
||||
return ' ORDER BY %s' % ', '.join(ordering)
|
||||
|
||||
@classmethod
|
||||
@guard_postgres
|
||||
|
|
Loading…
Reference in New Issue