From 5bf0d8fe708d1ecc6afdec5c953cef0b139300ca Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Tue, 19 Apr 2016 12:57:55 +0100 Subject: [PATCH] Show all statistics fetched on the dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to align all our stats to be for the last 7 days. This means summing up the stats response from the API to make the Big Number. Previously the big number was counting sent notifications as successful. This commit changes it to only look at delivered notifications. Right now, the API doesn’t have a way of filtering to only show the last 7 days. So for the moment the dashboard will show statistics for all time. The upshot of this is that we can link from the dashboard to the activity page when there are failures. --- app/main/views/dashboard.py | 69 +++++++++++-------- app/templates/components/big-number.html | 10 ++- .../views/dashboard/template-statistics.html | 5 +- app/templates/views/dashboard/today.html | 15 ++-- tests/app/main/views/test_dashboard.py | 4 +- 5 files changed, 60 insertions(+), 43 deletions(-) diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index 81d1caeed..520888e04 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,25 +30,21 @@ 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) return redirect(url_for("main.tour", service_id=service_id, 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)['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") @@ -60,8 +57,12 @@ def service_dashboard_updates(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)['data'] + ), + template_statistics=aggregate_usage( + template_statistics_client.get_template_statistics_for_service(service_id) + ) ) }) @@ -71,24 +72,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/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..5fd096c9b 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -83,9 +83,9 @@ def test_should_show_recent_templates_on_dashboard(app_, 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')