diff --git a/app/main/views/platform_admin.py b/app/main/views/platform_admin.py
index 10e43fb4b..303a1fea5 100644
--- a/app/main/views/platform_admin.py
+++ b/app/main/views/platform_admin.py
@@ -313,6 +313,74 @@ def get_billing_report():
return render_template('views/platform-admin/get-billing-report.html', form=form)
+@main.route("/platform-admin/reports/volumes-by-service", methods=['GET', 'POST'])
+@user_is_platform_admin
+def get_volumes_by_service():
+ form = BillingReportDateFilterForm()
+
+ if form.validate_on_submit():
+ start_date = form.start_date.data
+ end_date = form.end_date.data
+ headers = [
+ "organisation_id", "organisation_name", "service_id", "service_name",
+ "free_allowance", "sms_notifications", "sms chargeable units", "email_totals",
+ "letter_totals", "letter_cost", "letter_sheet_totals"
+ ]
+ result = billing_api_client.get_data_for_volumes_by_service_report(start_date, end_date)
+
+ rows = [
+ [
+ r["organisation_id"], r["organisation_name"], r["service_id"], r["service_name"],
+ r["free_allowance"], r["sms_notifications"], r["sms_chargeable_units"], r["email_totals"],
+ r["letter_totals"], r["letter_cost"], r["letter_sheet_totals"]
+ ]
+ 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': 'attachment; filename="Volumes by service report from {} to {}.csv"'.format(
+ start_date, end_date
+ )
+ }
+ else:
+ flash('No results for dates')
+ return render_template('views/platform-admin/volumes-by-service-report.html', form=form)
+
+
+@main.route("/platform-admin/reports/daily-volumes-report", methods=['GET', 'POST'])
+@user_is_platform_admin
+def get_daily_volumes():
+ form = BillingReportDateFilterForm()
+
+ if form.validate_on_submit():
+ start_date = form.start_date.data
+ end_date = form.end_date.data
+ headers = [
+ "day", "sms totals", "sms fragment totals", "sms chargeable units",
+ "email totals", "letter totals", "letter sheet totals"
+ ]
+ result = billing_api_client.get_data_for_daily_volumes_report(start_date, end_date)
+
+ rows = [
+ [
+ r["day"], r["sms_totals"], r["sms_fragment_totals"], r["sms_chargeable_units"],
+ r["email_totals"], r["letter_totals"], r["letter_sheet_totals"]
+ ]
+ 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': 'attachment; filename="Daily volumes report from {} to {}.csv"'.format(
+ start_date, end_date
+ )
+ }
+ else:
+ flash('No results for dates')
+ return render_template('views/platform-admin/daily-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 7a72749c6..110a1557a 100644
--- a/app/navigation.py
+++ b/app/navigation.py
@@ -92,6 +92,8 @@ class HeaderNavigation(Navigation):
'live_services_csv',
'notifications_sent_by_service',
'get_billing_report',
+ 'get_daily_volumes',
+ 'get_volumes_by_service',
'organisations',
'platform_admin',
'platform_admin_list_complaints',
diff --git a/app/notify_client/billing_api_client.py b/app/notify_client/billing_api_client.py
index ed083692e..08b5ce52c 100644
--- a/app/notify_client/billing_api_client.py
+++ b/app/notify_client/billing_api_client.py
@@ -41,5 +41,19 @@ class BillingAPIClient(NotifyAdminAPIClient):
'end_date': str(end_date),
})
+ def get_data_for_volumes_by_service_report(self, start_date, end_date):
+ return self.get(url='/platform-stats/volumes-by-service',
+ params={
+ 'start_date': str(start_date),
+ 'end_date': str(end_date),
+ })
+
+ def get_data_for_daily_volumes_report(self, start_date, end_date):
+ return self.get(url='/platform-stats/daily-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-volumes-report.html b/app/templates/views/platform-admin/daily-volumes-report.html
new file mode 100644
index 000000000..dbe24918b
--- /dev/null
+++ b/app/templates/views/platform-admin/daily-volumes-report.html
@@ -0,0 +1,48 @@
+{% 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 volumes report
+{% endblock %}
+
+{% block platform_admin_content %}
+
+
+ Daily 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 volumes data',
+ field_headings=['Name', 'Description'],
+ field_headings_visible=True,
+ caption_visible=False
+ ) %}
+ {% for message_length, charge in [
+ ('day', 'The whole business day in BST.'),
+ ('sms totals', 'The number of text messages sent'),
+ ('sms chargeable units', 'The number of text message fragments sent'),
+ ('sms_fragments_times_multiplier', 'The number of text message fragments sent times the rate multiplier'),
+ ('email totals', 'The number of emails sent'),
+ ('letter totals', 'The number of letters sent'),
+ ('letter sheet totals', The number of sheets sent)
+ ] %}
+ {% call row() %}
+ {{ text_field(message_length) }}
+ {{ text_field(charge | safe) }}
+ {% endcall %}
+ {% endfor %}
+ {% endcall %}
+
+
+{% endblock %}
diff --git a/app/templates/views/platform-admin/reports.html b/app/templates/views/platform-admin/reports.html
index 8d56460a9..dda3f18ff 100644
--- a/app/templates/views/platform-admin/reports.html
+++ b/app/templates/views/platform-admin/reports.html
@@ -19,4 +19,10 @@
Billing Report
+
+ Volumes by service Report
+
+
+ Daily volumes Report
+
{% endblock %}
diff --git a/app/templates/views/platform-admin/volumes-by-service-report.html b/app/templates/views/platform-admin/volumes-by-service-report.html
new file mode 100644
index 000000000..1ae33d8b2
--- /dev/null
+++ b/app/templates/views/platform-admin/volumes-by-service-report.html
@@ -0,0 +1,46 @@
+{% 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 %}
+ Volumes by service report
+{% endblock %}
+
+{% block platform_admin_content %}
+
+
+ Volumes by service 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 volumes by service data',
+ field_headings=['Name', 'Description'],
+ field_headings_visible=True,
+ caption_visible=False
+ ) %}
+ {% for message_length, charge in [
+ ('free allowance', 'Free allowance set for the service. This is the latest free allowance for the date range given'),
+ ('sms notifications', 'The number of text messages sent by the service.'),
+ ('sms volume', 'The number of text message fragments times the rate multiplier sent by the service.'),
+ ('email totals', 'The number of emails sent by a service'),
+ ('letter totals', 'The number of letters sent by a service'),
+ ] %}
+ {% call row() %}
+ {{ text_field(message_length) }}
+ {{ text_field(charge | safe) }}
+ {% endcall %}
+ {% endfor %}
+ {% endcall %}
+
+
+{% endblock %}
diff --git a/tests/app/notify_client/test_billing_client.py b/tests/app/notify_client/test_billing_client.py
index e29a80bdc..b3c29509b 100644
--- a/tests/app/notify_client/test_billing_client.py
+++ b/tests/app/notify_client/test_billing_client.py
@@ -41,3 +41,21 @@ def test_post_free_sms_fragment_limit_for_year_endpoint(mocker, api_user_active)
url='/service/{}/billing/free-sms-fragment-limit'.format(service_id),
data=sms_limit_data
)
+
+
+def test_get_data_for_volumes_by_service_report(mocker, api_user_active):
+ mock_get = mocker.patch('app.notify_client.billing_api_client.BillingAPIClient.get')
+ client = BillingAPIClient()
+
+ client.get_data_for_volumes_by_service_report('2022-03-01', '2022-03-31')
+ mock_get.assert_called_once_with(url='/platform-stats/volumes-by-service',
+ params={'start_date': '2022-03-01', 'end_date': '2022-03-31'})
+
+
+def test_get_data_for_daily_volumes_report(mocker, api_user_active):
+ mock_get = mocker.patch('app.notify_client.billing_api_client.BillingAPIClient.get')
+ client = BillingAPIClient()
+
+ client.get_data_for_daily_volumes_report('2022-03-01', '2022-03-31')
+ mock_get.assert_called_once_with(url='/platform-stats/daily-volumes-report',
+ params={'start_date': '2022-03-01', 'end_date': '2022-03-31'})
diff --git a/tests/app/test_navigation.py b/tests/app/test_navigation.py
index 4cb615f34..8477a9581 100644
--- a/tests/app/test_navigation.py
+++ b/tests/app/test_navigation.py
@@ -131,6 +131,8 @@ EXCLUDED_ENDPOINTS = tuple(map(Navigation.get_endpoint_with_blueprint, {
'find_users_by_email',
'forgot_password',
'get_billing_report',
+ 'get_daily_volumes',
+ 'get_volumes_by_service',
'get_example_csv',
'get_notifications_as_json',
'get_started',