From 889d6014757807eeb3f8826f6f407b6d0eb2157d Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 25 Oct 2019 13:27:46 +0100 Subject: [PATCH] Put usage summary back on the dashboard This reverts 1b1839ad301725c179a2f5b5d1fe43b66ea41e50, which removed the usage from the dashboard because it was causing performance problems: > **The yearly usage section on the dashboard page takes too log as a > result services with large yearly stats are timing out.** > > As a short term fix we have taken the yearly stats off the dashboard. > > There is a plan to create permanent statistic tables to warehouse the > data. The long term fix (the fact tables) is now in place, so it should be OK to bring this back. This is part of a wider piece of work to refresh the dashboard page now that jobs are moving to their own page. --- app/main/views/dashboard.py | 16 +++++- app/templates/views/dashboard/_usage.html | 16 ++++-- app/templates/views/dashboard/dashboard.html | 9 ++++ tests/app/main/views/test_accept_invite.py | 3 ++ tests/app/main/views/test_dashboard.py | 52 +++++++++++++++++++- tests/app/main/views/test_sign_out.py | 1 + 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index a48761d0f..950c2cc01 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -299,7 +299,14 @@ def get_dashboard_partials(service_id): ) for key, value in dashboard_totals[0].items() ) - + free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year( + current_service.id, + get_current_financial_year(), + ) + yearly_usage = billing_api_client.get_service_usage( + service_id, + get_current_financial_year(), + ) return { 'upcoming': render_template( 'views/dashboard/_upcoming.html', @@ -332,7 +339,12 @@ def get_dashboard_partials(service_id): 'views/dashboard/_jobs.html', jobs=immediate_jobs ), - 'has_jobs': bool(immediate_jobs) + 'has_jobs': bool(immediate_jobs), + 'usage': render_template( + 'views/dashboard/_usage.html', + column_width=column_width, + **calculate_usage(yearly_usage, free_sms_allowance), + ), } diff --git a/app/templates/views/dashboard/_usage.html b/app/templates/views/dashboard/_usage.html index 7a908d53c..6dc53b630 100644 --- a/app/templates/views/dashboard/_usage.html +++ b/app/templates/views/dashboard/_usage.html @@ -1,16 +1,16 @@ {% from "components/big-number.html" import big_number %}
-
+
{{ big_number("Unlimited", 'free email allowance', smaller=True) }}
-
+
{% if sms_chargeable %} {{ big_number( - total_sms_cost, + sms_chargeable * sms_rate, 'spent on text messages', currency="£", smaller=True @@ -20,4 +20,14 @@ {% endif %}
+
+
+ {{ big_number( + letter_cost, + 'spent on letters', + currency="£", + smaller=True + ) }} +
+
diff --git a/app/templates/views/dashboard/dashboard.html b/app/templates/views/dashboard/dashboard.html index 718187a7b..ea02f16e7 100644 --- a/app/templates/views/dashboard/dashboard.html +++ b/app/templates/views/dashboard/dashboard.html @@ -43,6 +43,15 @@ ) }} {% endif %} + {% if current_user.has_permissions('manage_service') %} +

This year

+ {{ ajax_block(partials, updates_url, 'usage') }} + {{ show_more( + url_for(".usage", service_id=current_service['id']), + 'See usage' + ) }} + {% endif %} +
{% endblock %} diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py index 791d9731e..c1bc31804 100644 --- a/tests/app/main/views/test_accept_invite.py +++ b/tests/app/main/views/test_accept_invite.py @@ -148,6 +148,8 @@ def test_accepting_invite_removes_invite_from_session( mock_get_service_statistics, mock_get_template_folders, mock_get_usage, + mock_get_billable_units, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary, fake_uuid, user, @@ -471,6 +473,7 @@ def test_new_invited_user_verifies_and_added_to_service( mock_get_users_by_service, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_create_event, mocker, ): diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 323047750..20cd0464b 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -145,6 +145,7 @@ def test_get_started( mock_get_jobs, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): mocker.patch( @@ -168,6 +169,7 @@ def test_get_started_is_hidden_once_templates_exist( mock_get_jobs, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): mocker.patch( @@ -191,6 +193,7 @@ def test_inbound_messages_not_visible_to_service_without_permissions( mock_get_service_statistics, mock_get_template_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): @@ -218,6 +221,7 @@ def test_inbound_messages_shows_count_of_messages( mock_get_service_statistics, mock_get_template_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, inbound_summary_mock, expected_text ): @@ -460,6 +464,7 @@ def test_should_show_recent_templates_on_dashboard( mock_get_jobs, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): mock_template_stats = mocker.patch('app.template_statistics_client.get_template_statistics_for_service', @@ -512,6 +517,7 @@ def test_should_not_show_recent_templates_on_dashboard_if_only_one_template_used mock_get_jobs, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary, stats, ): @@ -662,6 +668,7 @@ def test_should_show_upcoming_jobs_on_dashboard( mock_get_service_statistics, mock_get_jobs, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): page = client_request.get( @@ -713,6 +720,8 @@ def test_correct_font_size_for_big_numbers( mock_get_template_statistics, mock_get_service_statistics, mock_get_jobs, + mock_get_usage, + mock_get_free_sms_fragment_limit, service_one, permissions, totals, @@ -731,7 +740,8 @@ def test_correct_font_size_for_big_numbers( service_id=service_one['id'], ) - assert len(page.select('.column-third')) == 3 + assert len(page.select_one('[data-key=totals]').select('.column-third')) == 3 + assert len(page.select_one('[data-key=usage]').select('.column-third')) == 3 assert len( page.select('.big-number-with-status {}'.format(big_number_class)) @@ -746,6 +756,7 @@ def test_should_show_recent_jobs_on_dashboard( mock_get_service_statistics, mock_get_jobs, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): page = client_request.get( @@ -1102,6 +1113,7 @@ def test_route_for_service_permissions( mock_get_template_statistics, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): with app_.test_request_context(): @@ -1154,6 +1166,7 @@ def test_service_dashboard_updates_gets_dashboard_totals( mock_get_service_statistics, mock_get_jobs, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary ): mocker.patch('app.main.views.dashboard.get_dashboard_totals', return_value={ @@ -1365,6 +1378,8 @@ def test_org_breadcrumbs_do_not_show_if_service_has_no_org( mock_get_template_statistics, mock_get_service_templates_when_no_templates_exist, mock_get_jobs, + mock_get_usage, + mock_get_free_sms_fragment_limit, ): page = client_request.get('main.service_dashboard', service_id=SERVICE_ONE_ID) @@ -1399,6 +1414,8 @@ def test_org_breadcrumbs_show_if_user_is_a_member_of_the_services_org( mock_get_template_statistics, mock_get_service_templates_when_no_templates_exist, mock_get_jobs, + mock_get_usage, + mock_get_free_sms_fragment_limit, active_user_with_permissions, client_request, ): @@ -1424,6 +1441,8 @@ def test_org_breadcrumbs_do_not_show_if_user_is_a_member_of_the_services_org_but mock_get_template_statistics, mock_get_service_templates_when_no_templates_exist, mock_get_jobs, + mock_get_usage, + mock_get_free_sms_fragment_limit, active_user_with_permissions, client_request, ): @@ -1446,6 +1465,8 @@ def test_org_breadcrumbs_show_if_user_is_platform_admin( mock_get_template_statistics, mock_get_service_templates_when_no_templates_exist, mock_get_jobs, + mock_get_usage, + mock_get_free_sms_fragment_limit, platform_admin_user, platform_admin_client, ): @@ -1463,3 +1484,32 @@ def test_org_breadcrumbs_show_if_user_is_platform_admin( 'main.organisation_dashboard', org_id=ORGANISATION_ID, ) + + +@pytest.mark.parametrize('permissions', ( + ['email', 'sms'], + ['email', 'sms', 'letter'], +)) +def test_should_show_usage_on_dashboard( + client_request, + service_one, + mock_get_service_templates, + mock_get_template_statistics, + mock_get_jobs, + mock_get_usage, + mock_get_free_sms_fragment_limit, + permissions, +): + service_one['permissions'] = permissions + page = client_request.get('main.service_dashboard', service_id=SERVICE_ONE_ID) + + assert normalize_spaces( + page.select_one('[data-key=usage]').text + ) == ( + 'Unlimited ' + 'free email allowance ' + '£36.14 ' + 'spent on text messages ' + '£0.00 ' + 'spent on letters' + ) diff --git a/tests/app/main/views/test_sign_out.py b/tests/app/main/views/test_sign_out.py index 4a2dda857..7f0506c12 100644 --- a/tests/app/main/views/test_sign_out.py +++ b/tests/app/main/views/test_sign_out.py @@ -26,6 +26,7 @@ def test_sign_out_user( mock_get_template_statistics, mock_get_service_statistics, mock_get_usage, + mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary, ): with client_request.session_transaction() as session: