diff --git a/app/main/views/platform_admin.py b/app/main/views/platform_admin.py
index 6c8a0923c..260a2e486 100644
--- a/app/main/views/platform_admin.py
+++ b/app/main/views/platform_admin.py
@@ -381,6 +381,46 @@ def get_daily_volumes():
return render_template('views/platform-admin/daily-volumes-report.html', form=form)
+@main.route("/platform-admin/reports/daily-sms-provider-volumes-report", methods=['GET', 'POST'])
+@user_is_platform_admin
+def get_daily_sms_provider_volumes():
+ form = BillingReportDateFilterForm()
+
+ if form.validate_on_submit():
+ start_date = form.start_date.data
+ end_date = form.end_date.data
+ headers = [
+ "day",
+ "provider",
+ "sms totals",
+ "sms fragment totals",
+ "sms chargeable units",
+ "sms cost",
+ ]
+ result = billing_api_client.get_data_for_daily_sms_provider_volumes_report(start_date, end_date)
+
+ rows = [
+ [
+ r["day"],
+ r["provider"],
+ r["sms_totals"],
+ r["sms_fragment_totals"],
+ r["sms_chargeable_units"],
+ r["sms_cost"]
+ ]
+ for r in result
+ ]
+ if rows:
+ return Spreadsheet.from_rows([headers] + rows).as_csv_data, 200, {
+ 'Content-Type': 'text/csv; charset=utf-8',
+ 'Content-Disposition':
+ f'attachment; filename="Daily SMS provider volumes report from {start_date} to {end_date}.csv"'
+ }
+ else:
+ flash('No results for dates')
+ return render_template('views/platform-admin/daily-sms-provider-volumes-report.html', form=form)
+
+
@main.route("/platform-admin/complaints")
@user_is_platform_admin
def platform_admin_list_complaints():
diff --git a/app/navigation.py b/app/navigation.py
index a364fd4d4..6053b960d 100644
--- a/app/navigation.py
+++ b/app/navigation.py
@@ -95,6 +95,7 @@ class HeaderNavigation(Navigation):
'notifications_sent_by_service',
'get_billing_report',
'get_daily_volumes',
+ 'get_daily_sms_provider_volumes',
'get_volumes_by_service',
'organisations',
'platform_admin',
diff --git a/app/notify_client/billing_api_client.py b/app/notify_client/billing_api_client.py
index 08b5ce52c..44634ff4e 100644
--- a/app/notify_client/billing_api_client.py
+++ b/app/notify_client/billing_api_client.py
@@ -55,5 +55,14 @@ class BillingAPIClient(NotifyAdminAPIClient):
'end_date': str(end_date),
})
+ def get_data_for_daily_sms_provider_volumes_report(self, start_date, end_date):
+ return self.get(
+ url='/platform-stats/daily-sms-provider-volumes-report',
+ params={
+ 'start_date': str(start_date),
+ 'end_date': str(end_date),
+ }
+ )
+
billing_api_client = BillingAPIClient()
diff --git a/app/templates/views/platform-admin/daily-sms-provider-volumes-report.html b/app/templates/views/platform-admin/daily-sms-provider-volumes-report.html
new file mode 100644
index 000000000..73b3ca4ae
--- /dev/null
+++ b/app/templates/views/platform-admin/daily-sms-provider-volumes-report.html
@@ -0,0 +1,47 @@
+{% extends "views/platform-admin/_base_template.html" %}
+{% from "components/form.html" import form_wrapper %}
+{% from "components/table.html" import mapping_table, row, text_field %}
+
+{% block per_page_title %}
+ Daily SMS provider volumes Report
+{% endblock %}
+
+{% block platform_admin_content %}
+
+
+ Daily SMS provider volumes Report
+
+
+ {% call form_wrapper() %}
+ {{ form.start_date(param_extensions={"hint": {"text": "Use the format YYYY-MM-DD"}}) }}
+ {{ form.end_date(param_extensions={"hint": {"text": "Use the format YYYY-MM-DD"}}) }}
+ {{ page_footer('Download report') }}
+ {% endcall %}
+
+
+ Data included in the report
+
+
+ {% call mapping_table(
+ caption='Descriptions of daily SMS provider volumes data',
+ field_headings=['Name', 'Description'],
+ field_headings_visible=True,
+ caption_visible=False
+ ) %}
+ {% for message_length, description in [
+ ('day', 'The whole business day in BST'),
+ ('provider', 'The SMS provider'),
+ ('sms totals', 'The number of text messages sent'),
+ ('sms fragments', 'The number of text message fragments sent'),
+ ('sms chargeable units', 'The number of text message fragments sent times the rate multiplier'),
+ ('sms cost', 'The cost of text messages sent'),
+ ] %}
+ {% call row() %}
+ {{ text_field(message_length) }}
+ {{ text_field(description | safe) }}
+ {% endcall %}
+ {% endfor %}
+ {% endcall %}
+
+
+{% endblock %}
diff --git a/app/templates/views/platform-admin/reports.html b/app/templates/views/platform-admin/reports.html
index dda3f18ff..8dd36ffef 100644
--- a/app/templates/views/platform-admin/reports.html
+++ b/app/templates/views/platform-admin/reports.html
@@ -25,4 +25,7 @@
Daily volumes Report
+
+ Daily SMS provider volumes Report
+
{% endblock %}
diff --git a/tests/app/main/views/test_platform_admin.py b/tests/app/main/views/test_platform_admin.py
index b106d4255..e6b0e8f2b 100644
--- a/tests/app/main/views/test_platform_admin.py
+++ b/tests/app/main/views/test_platform_admin.py
@@ -1113,3 +1113,46 @@ def test_get_daily_volumes_report_when_calls_api_and_download_data(
'\r\n'
)
+
+
+def test_get_daily_sms_provider_volumes_report_when_calls_api_and_download_data(
+ client_request,
+ platform_admin_user,
+ mocker
+):
+ mocker.patch(
+ "app.main.views.platform_admin.billing_api_client.get_data_for_daily_sms_provider_volumes_report",
+ return_value=[{
+ "day": '2019-01-01',
+ "provider": 'foo',
+ "sms_totals": 20,
+ "sms_fragment_totals": 40,
+ "sms_chargeable_units": 60,
+ "sms_cost": 80,
+ }]
+ )
+
+ client_request.login(platform_admin_user)
+ response = client_request.post_response(
+ 'main.get_daily_sms_provider_volumes',
+ _data={'start_date': '2019-01-01', 'end_date': '2019-03-31'},
+ _expected_status=200,
+ )
+
+ assert response.content_type == 'text/csv; charset=utf-8'
+ assert response.headers['Content-Disposition'] == (
+ 'attachment; filename="Daily SMS provider volumes report from {} to {}.csv"'.format('2019-01-01', '2019-03-31')
+ )
+
+ assert response.get_data(as_text=True) == (
+ "day,provider,sms totals,sms fragment totals,sms chargeable units,sms cost\r\n" +
+
+ '2019-01-01,' +
+ 'foo,' +
+ '20,' +
+ '40,' +
+ '60,' +
+ '80'
+
+ '\r\n'
+ )
diff --git a/tests/app/test_navigation.py b/tests/app/test_navigation.py
index 06eccdd28..5b6d1eda5 100644
--- a/tests/app/test_navigation.py
+++ b/tests/app/test_navigation.py
@@ -132,6 +132,7 @@ EXCLUDED_ENDPOINTS = tuple(map(Navigation.get_endpoint_with_blueprint, {
'forgot_password',
'get_billing_report',
'get_daily_volumes',
+ 'get_daily_sms_provider_volumes',
'get_volumes_by_service',
'get_example_csv',
'get_notifications_as_json',