From 29f1d8aa8a0ab32a379fe7928602fc8cde66f743 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 24 Aug 2022 11:07:32 +0200 Subject: [PATCH 2/2] statistics: allow group by without time interval (#63377) --- tests/api/test_statistics.py | 11 +++++++++++ wcs/sql.py | 26 ++++++++++++++++++++++++++ wcs/statistics/views.py | 9 +++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/tests/api/test_statistics.py b/tests/api/test_statistics.py index cf25d519e..64379e3f3 100644 --- a/tests/api/test_statistics.py +++ b/tests/api/test_statistics.py @@ -316,6 +316,12 @@ def test_statistics_forms_count(pub): 'err': 0, } + resp = get_app(pub).get(sign_uri('/api/statistics/forms/count/?time_interval=none')) + assert resp.json == { + 'data': {'series': [{'label': 'Forms Count', 'data': [50]}], 'x_labels': [''], 'subfilters': []}, + 'err': 0, + } + # time_interval=day is not supported get_app(pub).get(sign_uri('/api/statistics/forms/count/?time_interval=day'), status=400) @@ -664,6 +670,11 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise): {'data': [13, None, 4], 'label': 'New status'}, ] + # group by item field without time interval + resp = get_app(pub).get(sign_uri(url + '&group-by=test-item&time_interval=none')) + assert resp.json['data']['x_labels'] == ['baz', 'Foo', 'None'] + assert resp.json['data']['series'] == [{'data': [3, 13, 4], 'label': 'Forms Count'}] + # group by on block field is not supported resp = get_app(pub).get(sign_uri(url + '&group-by=blockdata_bool')) assert resp.json['data']['series'] == [{'data': [16, 0, 4], 'label': 'Forms Count'}] diff --git a/wcs/sql.py b/wcs/sql.py index f192a1900..4a33d7996 100644 --- a/wcs/sql.py +++ b/wcs/sql.py @@ -4255,6 +4255,32 @@ def get_formdef_totals(period_start=None, period_end=None, criterias=None): return result +@guard_postgres +def get_global_totals(period_start=None, period_end=None, criterias=None, group_by=None): + conn, cur = get_connection_and_cursor() + statement = 'SELECT ' + if group_by: + statement += f'{group_by}, ' + statement += 'COUNT(*) ' + + parameters = {} + statement += get_period_query( + period_start=period_start, period_end=period_end, criterias=criterias, parameters=parameters + ) + + if group_by: + statement += f' GROUP BY {group_by} ORDER BY {group_by}' + cur.execute(statement, parameters) + + result = cur.fetchall() + if not group_by: + result = [('', result[0][0])] + conn.commit() + cur.close() + + return result + + @guard_postgres def get_hour_totals(period_start=None, period_end=None, criterias=None, group_by=None): conn, cur = get_connection_and_cursor() diff --git a/wcs/statistics/views.py b/wcs/statistics/views.py index 82274d328..0f48b582d 100644 --- a/wcs/statistics/views.py +++ b/wcs/statistics/views.py @@ -73,6 +73,10 @@ class IndexView(RestrictedView): 'id': 'hour', 'label': _('Hour'), }, + { + 'id': 'none', + 'label': _('None'), + }, ], 'required': True, 'default': 'month', @@ -231,14 +235,15 @@ class FormsCountView(RestrictedView): 'year': sql.get_yearly_totals, 'weekday': sql.get_weekday_totals, 'hour': sql.get_hour_totals, + 'none': sql.get_global_totals, } if time_interval in time_interval_methods: totals = time_interval_methods[time_interval](**totals_kwargs) else: return HttpResponseBadRequest('invalid time_interval parameter') - if 'group_by' not in totals_kwargs: - x_labels = [x[0] for x in totals] + if time_interval == 'none' or 'group_by' not in totals_kwargs: + x_labels = [group_labels.get(x[0], x[0]) for x in totals] series = [{'label': self.label, 'data': [x[1] for x in totals]}] else: x_labels, series = self.get_grouped_data(totals, group_labels) -- 2.30.2