statistiques, ne pas (trop) confondre les champs ayant le même identifiant dans le group_by (#73562) #55
|
@ -94,15 +94,7 @@ def formdef(pub):
|
|||
)
|
||||
items_field.display_locations = ['statistics']
|
||||
block_field = fields.BlockField(id='4', label='Block Data', varname='blockdata', type='block:foobar')
|
||||
computed_field = fields.ComputedField(
|
||||
id='5',
|
||||
label='computed',
|
||||
varname='computed',
|
||||
value_template='{{ "xxx" }}',
|
||||
type='computed',
|
||||
anonymise=False,
|
||||
)
|
||||
formdef.fields = [item_field, items_field, block_field, computed_field]
|
||||
formdef.fields = [item_field, items_field, block_field]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
return formdef
|
||||
|
@ -683,6 +675,49 @@ def test_statistics_forms_count_subfilters_query(pub, formdef):
|
|||
assert resp.json['data']['series'][0]['data'] == []
|
||||
|
||||
|
||||
def test_statistics_forms_count_subfilters_query_same_varname(pub, formdef):
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = [
|
||||
fields.ItemField(id='1', varname='test', label='Test', type='item', items=['foo', 'bar']),
|
||||
fields.ItemField(
|
||||
id='2',
|
||||
varname='test',
|
||||
label='Test',
|
||||
type='item',
|
||||
items=['foo', 'bar'],
|
||||
display_locations=['statistics'],
|
||||
),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
for i in range(5):
|
||||
formdata = formdef.data_class()()
|
||||
formdata.just_created()
|
||||
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
|
||||
if i == 0:
|
||||
formdata.data['1'] = 'foo'
|
||||
if i == 1:
|
||||
formdata.data['1'] = 'bar'
|
||||
formdata.data['2'] = 'foo'
|
||||
formdata.store()
|
||||
|
||||
url = '/api/statistics/forms/count/?form=%s' % formdef.url_name
|
||||
resp = get_app(pub).get(sign_uri(url + '&filter-test=foo'))
|
||||
assert resp.json['data']['series'] == [{'data': [5], 'label': 'Forms Count'}]
|
||||
|
||||
formdef.fields[0].display_locations = ['statistics']
|
||||
formdef.store()
|
||||
|
||||
# filter criterias is "f1 == 'foo' and f2 == 'foo'" hence one result, this should be improved
|
||||
resp = get_app(pub).get(sign_uri(url + '&filter-test=foo'))
|
||||
assert resp.json['data']['series'] == [{'data': [1], 'label': 'Forms Count'}]
|
||||
|
||||
# filter criterias is "f1 == 'bar' and f2 == 'bar'" hence no results, this should be improved
|
||||
resp = get_app(pub).get(sign_uri(url + '&filter-test=bar'))
|
||||
assert resp.json['data']['series'] == [{'data': [], 'label': 'Forms Count'}]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('anonymise', [False, True])
|
||||
def test_statistics_forms_count_group_by(pub, formdef, anonymise):
|
||||
for i in range(20):
|
||||
|
@ -702,7 +737,6 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise):
|
|||
formdata.submission_channel = ''
|
||||
else:
|
||||
formdata.submission_channel = None
|
||||
formdata.data['5'] = 'Computed 1'
|
||||
elif i % 2:
|
||||
formdata.data['1'] = False
|
||||
formdata.data['2'] = 'baz'
|
||||
|
@ -715,7 +749,6 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise):
|
|||
else:
|
||||
formdata.jump_status('2')
|
||||
formdata.submission_channel = 'mail'
|
||||
formdata.data['5'] = 'Computed 2'
|
||||
else:
|
||||
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
|
||||
formdata.store()
|
||||
|
@ -808,15 +841,6 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise):
|
|||
{'data': [13, None, 4], 'label': 'Web'},
|
||||
]
|
||||
|
||||
# group by computed field
|
||||
resp = get_app(pub).get(sign_uri(url + '&group-by=computed'))
|
||||
assert resp.json['data']['x_labels'] == ['2021-01', '2021-02', '2021-03']
|
||||
assert resp.json['data']['series'] == [
|
||||
{'data': [3, None, None], 'label': 'Computed 2'},
|
||||
{'data': [13, None, None], 'label': 'Computed 1'},
|
||||
{'data': [None, None, 4], 'label': 'None'},
|
||||
]
|
||||
|
||||
# group by item field without time interval
|
||||
resp = get_app(pub).get(sign_uri(url + '&group-by=test-item&time_interval=none'))
|
||||
# Foo is first because it has a display value, baz is second because it has not, None is always last
|
||||
|
@ -859,6 +883,46 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise):
|
|||
assert resp.json['data']['series'] == [{'data': [16, 0, 4], 'label': 'Forms Count'}]
|
||||
|
||||
|
||||
def test_statistics_forms_count_group_by_same_varname(pub, formdef):
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = [
|
||||
fields.ItemField(id='1', varname='test', label='Test', type='item', items=['foo']),
|
||||
fields.ItemField(
|
||||
id='2', varname='test', label='Test', type='item', items=['bar'], display_locations=['statistics']
|
||||
),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.just_created()
|
||||
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
|
||||
formdata.data['1'] = 'foo'
|
||||
formdata.data['2'] = 'bar'
|
||||
formdata.store()
|
||||
|
||||
url = '/api/statistics/forms/count/?form=%s' % formdef.url_name
|
||||
resp = get_app(pub).get(sign_uri(url + '&group-by=test'))
|
||||
assert resp.json['data']['series'] == [{'data': [1], 'label': 'bar'}]
|
||||
|
||||
formdef.fields[0].display_locations = ['statistics']
|
||||
formdef.store()
|
||||
|
||||
# group by uses first field marked for statistics
|
||||
resp = get_app(pub).get(sign_uri(url + '&group-by=test'))
|
||||
assert resp.json['data']['series'] == [{'data': [1], 'label': 'foo'}]
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.just_created()
|
||||
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
|
||||
formdata.data['2'] = 'foo'
|
||||
formdata.store()
|
||||
|
||||
# second field is ignored
|
||||
resp = get_app(pub).get(sign_uri(url + '&group-by=test'))
|
||||
assert resp.json['data']['series'] == [{'data': [1], 'label': 'foo'}, {'data': [1], 'label': 'None'}]
|
||||
|
||||
|
||||
def test_statistics_cards_count(pub):
|
||||
carddef = CardDef()
|
||||
carddef.name = 'test 1'
|
||||
|
|
|
@ -1732,9 +1732,11 @@ class FormPage(FormdefDirectoryBase):
|
|||
raise RequestError('Invalid operator "%s" for "filter-operator"' % operator)
|
||||
return operator
|
||||
|
||||
def get_criterias_from_query(self):
|
||||
def get_criterias_from_query(self, statistics_fields_only=False):
|
||||
query_overrides = get_request().form
|
||||
return self.get_view_criterias(query_overrides, request=get_request())
|
||||
return self.get_view_criterias(
|
||||
query_overrides, request=get_request(), statistics_fields_only=statistics_fields_only
|
||||
)
|
||||
|
||||
def get_field_allowed_operators(self, field):
|
||||
operators = [
|
||||
|
@ -1776,6 +1778,7 @@ class FormPage(FormdefDirectoryBase):
|
|||
custom_view=None,
|
||||
compile_templates=False,
|
||||
keep_templates=False,
|
||||
statistics_fields_only=False,
|
||||
):
|
||||
fake_fields = [
|
||||
FakeField('internal-id', 'internal-id', _('Identifier')),
|
||||
|
@ -1825,6 +1828,9 @@ class FormPage(FormdefDirectoryBase):
|
|||
if filter_field.type not in self.get_filterable_field_types():
|
||||
continue
|
||||
|
||||
if statistics_fields_only and not getattr(filter_field, 'include_in_statistics', False):
|
||||
continue
|
||||
|
||||
filter_field_key = None
|
||||
|
||||
if filter_field.contextual_varname:
|
||||
|
|
|
@ -315,7 +315,7 @@ class FormsCountView(RestrictedView):
|
|||
)
|
||||
|
||||
def get_filters_criterias(self, formdef, form_page):
|
||||
criterias = form_page.get_criterias_from_query()
|
||||
criterias = form_page.get_criterias_from_query(statistics_fields_only=True)
|
||||
|
||||
selected_status = self.request.GET.get('filter-status')
|
||||
applied_filters = None
|
||||
|
@ -417,7 +417,10 @@ class FormsCountView(RestrictedView):
|
|||
|
||||
def get_group_by_field(self, form_page, group_by):
|
||||
fields = [
|
||||
x for x in form_page.get_formdef_fields() if getattr(x, 'contextual_varname', None) == group_by
|
||||
x
|
||||
for x in form_page.get_formdef_fields()
|
||||
if getattr(x, 'contextual_varname', None) == group_by
|
||||
and getattr(x, 'include_in_statistics', False)
|
||||
]
|
||||
if fields:
|
||||
if not hasattr(fields[0], 'block_field'): # block fields are not supported
|
||||
|
@ -470,9 +473,6 @@ class FormsCountView(RestrictedView):
|
|||
else:
|
||||
totals_kwargs['group_by'] = sql.get_field_id(group_by_field)
|
||||
|
||||
if group_by_field.type == 'computed':
|
||||
totals_kwargs['group_by'] = totals_kwargs['group_by'] + "->'data'"
|
||||
|
||||
if self.request.GET.get('hide_none_label') == 'true':
|
||||
totals_kwargs['criterias'].append(NotNull(totals_kwargs['group_by']))
|
||||
|
||||
|
|
Loading…
Reference in New Issue