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: