diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index df5076e82..2fea2ddfd 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -1,6 +1,7 @@ from datetime import date from collections import namedtuple from itertools import groupby +from functools import reduce from flask import ( render_template, @@ -29,40 +30,36 @@ from app.utils import user_has_permissions @login_required @user_has_permissions('view_activity', admin_override=True) def service_dashboard(service_id): - templates = service_api_client.get_service_templates(service_id)['data'] - jobs = job_api_client.get_job(service_id)['data'] if session.get('invited_user'): session.pop('invited_user', None) session['service_id'] = service_id return redirect(url_for("main.tour", page=1)) - statistics = statistics_api_client.get_statistics_for_service(service_id)['data'] - template_statistics = aggregate_usage(template_statistics_client.get_template_statistics_for_service(service_id)) - return render_template( 'views/dashboard/dashboard.html', - jobs=jobs[:5], - more_jobs_to_show=(len(jobs) > 5), - free_text_messages_remaining='250,000', - spent_this_month='0.00', - statistics=add_rates_to(statistics), - templates=templates, - template_statistics=template_statistics) + statistics=add_rates_to( + statistics_api_client.get_statistics_for_service(service_id, limit_days=7)['data'] + ), + templates=service_api_client.get_service_templates(service_id)['data'], + template_statistics=aggregate_usage( + template_statistics_client.get_template_statistics_for_service(service_id) + ) + ) @main.route("/services//dashboard.json") @login_required def service_dashboard_updates(service_id): - - statistics = statistics_api_client.get_statistics_for_service(service_id)['data'] - template_statistics = aggregate_usage(template_statistics_client.get_template_statistics_for_service(service_id)) - return jsonify(**{ 'today': render_template( 'views/dashboard/today.html', - statistics=add_rates_to(statistics), - template_statistics=template_statistics + statistics=add_rates_to( + statistics_api_client.get_statistics_for_service(service_id, limit_days=7)['data'] + ), + template_statistics=aggregate_usage( + template_statistics_client.get_template_statistics_for_service(service_id) + ) ) }) @@ -72,24 +69,32 @@ def add_rates_to(delivery_statistics): if not delivery_statistics or not delivery_statistics[0]: return {} - today = None - latest_stats = {} - if delivery_statistics[0]['day'] == date.today().strftime('%Y-%m-%d'): - today = delivery_statistics[0] - latest_stats = delivery_statistics[0] + sum_of_statistics = reduce( + lambda x, y: { + key: x.get(key, 0) + y.get(key, 0) + for key in [ + 'emails_delivered', + 'emails_requested', + 'emails_failed', + 'sms_requested', + 'sms_delivered', + 'sms_failed' + ] + }, + delivery_statistics + ) - latest_stats.update({ - 'emails_failure_rate': ( - "{0:.1f}".format((float(today['emails_failed']) / today['emails_requested'] * 100)) - if today and today['emails_requested'] else 0 + return dict( + emails_failure_rate=( + "{0:.1f}".format((float(sum_of_statistics['emails_failed']) / sum_of_statistics['emails_requested'] * 100)) + if sum_of_statistics.get('emails_requested') else 0 ), - 'sms_failure_rate': ( - "{0:.1f}".format((float(today['sms_failed']) / today['sms_requested'] * 100)) - if today and today['sms_requested'] else 0 - ) - }) - - return latest_stats + sms_failure_rate=( + "{0:.1f}".format((float(sum_of_statistics['sms_failed']) / sum_of_statistics['sms_requested'] * 100)) + if sum_of_statistics.get('sms_requested') else 0 + ), + **sum_of_statistics + ) def aggregate_usage(template_statistics): diff --git a/app/notify_client/statistics_api_client.py b/app/notify_client/statistics_api_client.py index 9ef40bbd6..3d4292c36 100644 --- a/app/notify_client/statistics_api_client.py +++ b/app/notify_client/statistics_api_client.py @@ -12,7 +12,10 @@ class StatisticsApiClient(BaseAPIClient): self.client_id = app.config['ADMIN_CLIENT_USER_NAME'] self.secret = app.config['ADMIN_CLIENT_SECRET'] - def get_statistics_for_service(self, service_id): + def get_statistics_for_service(self, service_id, limit_days=None): + params = {} + if limit_days is not None: + params['limit_days'] = limit_days return self.get( url='/service/{}/notifications-statistics'.format(service_id), ) diff --git a/app/templates/components/big-number.html b/app/templates/components/big-number.html index 403228219..1b608e7e9 100644 --- a/app/templates/components/big-number.html +++ b/app/templates/components/big-number.html @@ -6,12 +6,18 @@ {% endmacro %} -{% macro big_number_with_status(number, label, failures, failure_percentage, danger_zone=False) %} +{% macro big_number_with_status(number, label, failures, failure_percentage, danger_zone=False, failure_link=None) %}
{{ big_number(number, label) }}
{% if failures %} - {{ failures }} failed – {{ failure_percentage }}% + {% if failure_link %} + + {{ failures }} failed – {{ failure_percentage }}% + + {% else %} + {{ failures }} failed – {{ failure_percentage }}% + {% endif %} {% else %} No failures {% endif %} diff --git a/app/templates/views/dashboard/template-statistics.html b/app/templates/views/dashboard/template-statistics.html index 2a995f1c5..d3a75867d 100644 --- a/app/templates/views/dashboard/template-statistics.html +++ b/app/templates/views/dashboard/template-statistics.html @@ -1,9 +1,10 @@ {% from "components/table.html" import list_table, field, hidden_field_heading, right_aligned_field_heading %} {% call(item, row_number) list_table( template_statistics, - caption="In the last 7 days", + caption="By template", + caption_visible=False, empty_message='You haven’t set up any templates yet', - field_headings=['Template', hidden_field_heading('Type'), right_aligned_field_heading('Messages sent')] + field_headings=['Template', hidden_field_heading('Type'), right_aligned_field_heading('Messages processed')] ) %} {% call field() %} diff --git a/app/templates/views/dashboard/today.html b/app/templates/views/dashboard/today.html index 3cb871454..7912ffae7 100644 --- a/app/templates/views/dashboard/today.html +++ b/app/templates/views/dashboard/today.html @@ -1,16 +1,17 @@ {% from "components/big-number.html" import big_number_with_status %}

- Sent today + In the last 7 days

-
+
{{ big_number_with_status( - statistics.get('emails_requested', 0), - 'email' if statistics.get('emails_requested') == 1 else 'emails', + statistics.get('emails_delivered', 0), + 'email' if statistics.get('emails_delivered') == 1 else 'emails', statistics.get('emails_failed'), statistics.get('emails_failure_rate', 0.0), - statistics.get('emails_failure_rate', 0)|float > 3 + statistics.get('emails_failure_rate', 0)|float > 3, + failure_link=url_for(".view_notifications", service_id=current_service.id, template_type='email', status='failed') ) }}
@@ -19,10 +20,10 @@ 'text message' if statistics.get('sms_requested') == 1 else 'text messages', statistics.get('sms_failed'), statistics.get('sms_failure_rate', 0.0), - statistics.get('sms_failure_rate', 0)|float > 3 + statistics.get('sms_failure_rate', 0)|float > 3, + failure_link=url_for(".view_notifications", service_id=current_service.id, template_type='sms', status='failed') ) }}
{% include 'views/dashboard/template-statistics.html' %} - diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 34c79627f..9717e60c2 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -77,15 +77,15 @@ def test_should_show_recent_templates_on_dashboard(app_, assert response.status_code == 200 response.get_data(as_text=True) - mock_get_service_statistics.assert_called_once_with(SERVICE_ONE_ID) + mock_get_service_statistics.assert_called_once_with(SERVICE_ONE_ID, limit_days=7) mock_template_stats.assert_called_once_with(SERVICE_ONE_ID) page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') headers = [header.text.strip() for header in page.find_all('h2')] assert 'Test Service' in headers - assert 'Sent today' in headers + assert 'In the last 7 days' in headers template_usage_headers = [th.text.strip() for th in page.thead.find_all('th')] - for th in ['Template', 'Type', 'Messages sent']: + for th in ['Template', 'Type', 'Messages processed']: assert th in template_usage_headers table_rows = page.tbody.find_all('tr') diff --git a/tests/conftest.py b/tests/conftest.py index 82bd4b678..d6dbdad17 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -172,7 +172,7 @@ def mock_delete_service(mocker, mock_get_service): @pytest.fixture(scope='function') def mock_get_service_statistics(mocker): - def _create(service_id): + def _create(service_id, limit_days=None): return {'data': [{}]} return mocker.patch(