From e6c04ef556feba0e18cfca5090c49c3b84dc46a4 Mon Sep 17 00:00:00 2001 From: Ben Thorner Date: Tue, 26 Apr 2022 17:37:34 +0100 Subject: [PATCH] Support variable rates for annual usage stats Note: I've removed the pricing assertion in the "0_free_allowance" test as it's covered elsewhere - the value of the test is really to check that we don't show the remainder if there never was any. --- app/main/views/dashboard.py | 5 +-- app/templates/views/usage.html | 16 +++++---- tests/app/main/views/test_dashboard.py | 48 +++++++++++++++++++++----- tests/conftest.py | 8 ++++- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index 913676a1d..fc6210fac 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -328,8 +328,6 @@ def get_dashboard_totals(statistics): def get_annual_usage_breakdown(usage, free_sms_fragment_limit): sms = get_usage_breakdown_by_type(usage, 'sms') - # this relies on the assumption: only one SMS rate per financial year. - sms_rate = 0 if len(sms) == 0 else sms[0].get("rate", 0) sms_chargeable_units = sum(row['chargeable_units'] for row in sms) sms_free_allowance = free_sms_fragment_limit sms_cost = sum(row['cost'] for row in sms) @@ -346,9 +344,8 @@ def get_annual_usage_breakdown(usage, free_sms_fragment_limit): 'sms_free_allowance': sms_free_allowance, 'sms_sent': sms_chargeable_units, 'sms_allowance_remaining': max(0, (sms_free_allowance - sms_chargeable_units)), - 'sms_charged': max(0, sms_chargeable_units - sms_free_allowance), 'sms_cost': sms_cost, - 'sms_rate': sms_rate, + 'sms_breakdown': sms, 'letter_sent': letters_sent, 'letter_cost': letters_cost } diff --git a/app/templates/views/usage.html b/app/templates/views/usage.html index b062edfee..a9bd086b0 100644 --- a/app/templates/views/usage.html +++ b/app/templates/views/usage.html @@ -33,13 +33,15 @@ {% if sms_free_allowance > 0 %} {{ big_number(sms_allowance_remaining, 'free allowance remaining', smaller=True) }} {% endif %} - {% if sms_charged %} - {{ big_number( - sms_charged, - 'at {:.2f} pence per message'.format(sms_rate * 100), - smaller=True - ) }} - {% endif %} + {% for row in sms_breakdown %} + {% if row.charged_units > 0 %} + {{ big_number( + row.charged_units, + 'at {:.2f} pence per message'.format(row.rate * 100), + smaller=True + ) }} + {% endif %} + {% endfor %}
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 4e2341f22..3e87f9c7f 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -1021,7 +1021,8 @@ def test_usage_page( assert '250,000 free allowance' in sms_column assert '0 free allowance remaining' in sms_column assert '£29.85 spent' in sms_column - assert '1,800 at 1.65 pence' in sms_column + assert '1,500 at 1.65 pence' in sms_column + assert '300 at 1.70 pence' in sms_column letter_column = normalize_spaces(annual_usage[2].text + annual_usage[5].text) assert 'Letters' in letter_column @@ -1029,6 +1030,37 @@ def test_usage_page( assert '£30.00 spent' in letter_column +@freeze_time("2012-03-31 12:12:12") +def test_usage_page_no_sms_spend( + mocker, + client_request, + mock_get_billable_units, + mock_get_free_sms_fragment_limit +): + mocker.patch('app.billing_api_client.get_service_usage', return_value=[ + { + "notification_type": "sms", + "chargeable_units": 1000, + "charged_units": 0, + "rate": 0.0165, + "cost": 0 + } + ]) + + page = client_request.get( + 'main.usage', + service_id=SERVICE_ONE_ID, + ) + + annual_usage = page.find_all('div', {'class': 'govuk-grid-column-one-third'}) + sms_column = normalize_spaces(annual_usage[1].text + annual_usage[4].text) + assert 'Text messages' in sms_column + assert '250,000 free allowance' in sms_column + assert '249,000 free allowance remaining' in sms_column + assert '£0.00 spent' in sms_column + assert 'pence per message' not in sms_column + + @freeze_time("2012-03-31 12:12:12") def test_usage_page_monthly_breakdown( client_request, @@ -1141,14 +1173,12 @@ def test_usage_page_with_0_free_allowance( service_id=SERVICE_ONE_ID, year=2020, ) - assert normalize_spaces( - page.select('main .govuk-grid-column-one-third')[1].text - ) == ( - 'Text messages ' - '251,800 sent ' - '0 free allowance ' - '251,800 at 1.65 pence per message' - ) + + annual_usage = page.select('main .govuk-grid-column-one-third') + sms_column = normalize_spaces(annual_usage[1].text) + + assert '0 free allowance' in sms_column + assert 'free allowance remaining' not in sms_column def test_usage_page_with_year_argument( diff --git a/tests/conftest.py b/tests/conftest.py index 68f7b7231..fbd2470b8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2320,6 +2320,7 @@ def mock_get_usage(mocker, service_one, fake_uuid): "notification_type": "email", "chargeable_units": 1000, "notifications_sent": 1000, + "charged_units": 1000, "rate": 0.00, "cost": 0 }, @@ -2327,6 +2328,7 @@ def mock_get_usage(mocker, service_one, fake_uuid): "notification_type": "sms", "chargeable_units": 251500, "notifications_sent": 105000, + "charged_units": 1500, "rate": 0.0165, "cost": 24.75 # 250K free allowance }, @@ -2334,13 +2336,15 @@ def mock_get_usage(mocker, service_one, fake_uuid): "notification_type": "sms", "chargeable_units": 300, "notifications_sent": 300, - "rate": 0.0165, + "charged_units": 300, + "rate": 0.017, "cost": 5.1 }, { "notification_type": "letter", "chargeable_units": 300, "notifications_sent": 100, + "charged_units": 300, "rate": 0.1, "cost": 30 }, @@ -2466,6 +2470,7 @@ def mock_get_future_usage(mocker, service_one, fake_uuid): 'notification_type': 'sms', 'chargeable_units': 0, 'notifications_sent': 0, + 'charged_units': 0, 'rate': 0.0158, 'cost': 0 }, @@ -2473,6 +2478,7 @@ def mock_get_future_usage(mocker, service_one, fake_uuid): 'notification_type': 'email', 'chargeable_units': 0, 'notifications_sent': 0, + 'charged_units': 0, 'rate': 0.0, 'cost': 0 }