mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-17 21:20:32 -04:00
Merge pull request #2934 from alphagov/live-services-csv
Add Live services and Performance platform csv reports
This commit is contained in:
@@ -10,6 +10,7 @@ from requests import RequestException
|
||||
|
||||
from app import (
|
||||
complaint_api_client,
|
||||
format_date_numeric,
|
||||
letter_jobs_client,
|
||||
platform_stats_api_client,
|
||||
service_api_client,
|
||||
@@ -28,6 +29,7 @@ from app.statistics_utils import (
|
||||
)
|
||||
from app.template_previews import validate_letter
|
||||
from app.utils import (
|
||||
Spreadsheet,
|
||||
generate_next_dict,
|
||||
generate_previous_dict,
|
||||
get_page_from_request,
|
||||
@@ -187,6 +189,79 @@ def platform_admin_services():
|
||||
)
|
||||
|
||||
|
||||
@main.route("/platform-admin/reports")
|
||||
@login_required
|
||||
@user_is_platform_admin
|
||||
def platform_admin_reports():
|
||||
return render_template(
|
||||
'views/platform-admin/reports.html'
|
||||
)
|
||||
|
||||
|
||||
@main.route("/platform-admin/reports/live-services.csv")
|
||||
@login_required
|
||||
@user_is_platform_admin
|
||||
def live_services_csv():
|
||||
results = service_api_client.get_live_services_data()["data"]
|
||||
live_services_columns = [
|
||||
"Service ID", "Organisation", "Service name", "Consent to research", "Main contact",
|
||||
"Contact email", "Contact mobile", "Live date", "SMS volume intent", "Email volume intent",
|
||||
"Letter volume intent", "SMS sent this year", "Emails sent this year", "Letters sent this year"
|
||||
]
|
||||
live_services_data = []
|
||||
live_services_data.append(live_services_columns)
|
||||
for row in results:
|
||||
live_services_data.append([
|
||||
row["service_id"],
|
||||
row["organisation_name"],
|
||||
row["service_name"],
|
||||
row["consent_to_research"],
|
||||
row["contact_name"],
|
||||
row["contact_email"],
|
||||
row["contact_mobile"],
|
||||
datetime.strptime(row["live_date"], '%a, %d %b %Y %X %Z').strftime("%d-%m-%Y"),
|
||||
row["sms_volume_intent"],
|
||||
row["email_volume_intent"],
|
||||
row["letter_volume_intent"],
|
||||
row["sms_totals"],
|
||||
row["email_totals"],
|
||||
row["letter_totals"],
|
||||
])
|
||||
|
||||
return Spreadsheet.from_rows(live_services_data).as_csv_data, 200, {
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition': 'inline; filename="{} live services report.csv"'.format(
|
||||
format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@main.route("/platform-admin/reports/performance-platform.csv")
|
||||
@login_required
|
||||
@user_is_platform_admin
|
||||
def performance_platform_csv():
|
||||
results = service_api_client.get_live_services_data()["data"]
|
||||
live_services_columns = ["service_id", "agency", "service_name", "_timestamp", "service", "count"]
|
||||
live_services_data = []
|
||||
live_services_data.append(live_services_columns)
|
||||
for row in results:
|
||||
live_services_data.append([
|
||||
row["service_id"],
|
||||
row["organisation_name"],
|
||||
row["service_name"],
|
||||
datetime.strptime(row["live_date"], '%a, %d %b %Y %X %Z').strftime("%Y-%m-%dT%H:%M:%S") + "Z",
|
||||
"govuk-notify",
|
||||
1
|
||||
])
|
||||
|
||||
return Spreadsheet.from_rows(live_services_data).as_csv_data, 200, {
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition': 'inline; filename="{} performance platform report.csv"'.format(
|
||||
format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@main.route("/platform-admin/complaints")
|
||||
@login_required
|
||||
@user_is_platform_admin
|
||||
|
||||
@@ -85,10 +85,13 @@ class HeaderNavigation(Navigation):
|
||||
'find_users_by_email',
|
||||
'letter_branding',
|
||||
'live_services',
|
||||
'live_services_csv',
|
||||
'organisations',
|
||||
'performance_platform_csv',
|
||||
'platform_admin',
|
||||
'platform_admin_letter_validation_preview',
|
||||
'platform_admin_list_complaints',
|
||||
'platform_admin_reports',
|
||||
'platform_admin_returned_letters',
|
||||
'suspend_service',
|
||||
'trial_services',
|
||||
@@ -476,6 +479,7 @@ class MainNavigation(Navigation):
|
||||
'letter_branding',
|
||||
'letter_branding_preview_image',
|
||||
'live_services',
|
||||
'live_services_csv',
|
||||
'letter_template',
|
||||
'message_status',
|
||||
'manage_org_users',
|
||||
@@ -490,9 +494,11 @@ class MainNavigation(Navigation):
|
||||
'organisation_preview_letter_branding',
|
||||
'organisation_settings',
|
||||
'organisations',
|
||||
'performance_platform_csv',
|
||||
'platform_admin',
|
||||
'platform_admin_letter_validation_preview',
|
||||
'platform_admin_list_complaints',
|
||||
'platform_admin_reports',
|
||||
'platform_admin_returned_letters',
|
||||
'pricing',
|
||||
'privacy',
|
||||
@@ -688,6 +694,7 @@ class CaseworkNavigation(Navigation):
|
||||
'letter_template',
|
||||
'link_service_to_organisation',
|
||||
'live_services',
|
||||
'live_services_csv',
|
||||
'manage_org_users',
|
||||
'manage_template_folder',
|
||||
'manage_users',
|
||||
@@ -704,8 +711,10 @@ class CaseworkNavigation(Navigation):
|
||||
'organisation_preview_letter_branding',
|
||||
'organisation_settings',
|
||||
'organisations',
|
||||
'performance_platform_csv',
|
||||
'platform_admin_letter_validation_preview',
|
||||
'platform_admin_list_complaints',
|
||||
'platform_admin_reports',
|
||||
'platform_admin_returned_letters',
|
||||
'platform_admin',
|
||||
'pricing',
|
||||
@@ -946,6 +955,7 @@ class OrgNavigation(Navigation):
|
||||
'letter_template',
|
||||
'link_service_to_organisation',
|
||||
'live_services',
|
||||
'live_services_csv',
|
||||
'manage_template_folder',
|
||||
'manage_users',
|
||||
'message_status',
|
||||
@@ -957,9 +967,11 @@ class OrgNavigation(Navigation):
|
||||
'old_terms',
|
||||
'old_using_notify',
|
||||
'organisations',
|
||||
'performance_platform_csv',
|
||||
'platform_admin',
|
||||
'platform_admin_letter_validation_preview',
|
||||
'platform_admin_list_complaints',
|
||||
'platform_admin_reports',
|
||||
'platform_admin_returned_letters',
|
||||
'pricing',
|
||||
'privacy',
|
||||
|
||||
@@ -48,6 +48,12 @@ class ServiceAPIClient(NotifyAdminAPIClient):
|
||||
"""
|
||||
return self.get('/service', params=params_dict)
|
||||
|
||||
def get_live_services_data(self, params_dict=None):
|
||||
"""
|
||||
Retrieve a list of live services data with contact names and notification counts.
|
||||
"""
|
||||
return self.get('/service/live-services-data', params=params_dict)
|
||||
|
||||
def get_active_services(self, params_dict=None):
|
||||
"""
|
||||
Retrieve a list of active services.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
('Trial mode services', url_for('main.trial_services')),
|
||||
('Organisations', url_for('main.organisations')),
|
||||
('Providers', url_for('main.view_providers')),
|
||||
('Reports', url_for('main.platform_admin_reports')),
|
||||
('Email branding', url_for('main.email_branding')),
|
||||
('Letter branding', url_for('main.letter_branding')),
|
||||
('Inbound SMS numbers', url_for('main.inbound_sms_admin')),
|
||||
|
||||
20
app/templates/views/platform-admin/reports.html
Normal file
20
app/templates/views/platform-admin/reports.html
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends "views/platform-admin/_base_template.html" %}
|
||||
|
||||
{% block per_page_title %}
|
||||
Platform admin
|
||||
{% endblock %}
|
||||
|
||||
{% block platform_admin_content %}
|
||||
|
||||
<h1 class="heading-large">
|
||||
Reports
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<a target="_blank" href="{{ url_for('main.live_services_csv') }}">Download live services csv report</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a target="_blank" href="{{ url_for('main.performance_platform_csv') }}">Download performance platform csv report</a>
|
||||
<p>
|
||||
{% endblock %}
|
||||
@@ -246,7 +246,6 @@ class Spreadsheet():
|
||||
def from_rows(cls, rows, filename=''):
|
||||
with StringIO() as converted:
|
||||
output = csv.writer(converted)
|
||||
|
||||
for row in rows:
|
||||
output.writerow(row)
|
||||
return cls(converted.getvalue(), filename)
|
||||
|
||||
@@ -927,3 +927,84 @@ def test_clear_cache_requires_option(client_request, platform_admin_user, mocker
|
||||
|
||||
assert normalize_spaces(page.find('span', class_='error-message').text) == 'Not a valid choice'
|
||||
assert not redis.delete_cache_keys_by_pattern.called
|
||||
|
||||
|
||||
def test_reports_page(
|
||||
client,
|
||||
platform_admin_user,
|
||||
mocker
|
||||
):
|
||||
mock_get_user(mocker, user=platform_admin_user)
|
||||
client.login(platform_admin_user)
|
||||
|
||||
response = client.get(url_for('main.platform_admin_reports'))
|
||||
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.find(
|
||||
'a', text="Download live services csv report"
|
||||
).attrs['href'] == '/platform-admin/reports/live-services.csv'
|
||||
|
||||
assert page.find(
|
||||
'a', text="Download performance platform csv report"
|
||||
).attrs['href'] == '/platform-admin/reports/performance-platform.csv'
|
||||
|
||||
|
||||
def test_get_live_services_report(client, platform_admin_user, mocker):
|
||||
mock_get_user(mocker, user=platform_admin_user)
|
||||
client.login(platform_admin_user)
|
||||
|
||||
mocker.patch(
|
||||
'app.service_api_client.get_live_services_data',
|
||||
return_value={'data': [
|
||||
{'service_id': 1, 'service_name': 'jessie the oak tree', 'organisation_name': 'Forest',
|
||||
'consent_to_research': True, 'contact_name': 'Forest fairy',
|
||||
'contact_email': 'forest.fairy@digital.cabinet-office.gov.uk', 'contact_mobile': '+447700900986',
|
||||
'live_date': 'Sat, 29 Mar 2014 00:00:00 GMT', 'sms_volume_intent': 100, 'email_volume_intent': 50,
|
||||
'letter_volume_intent': 20, 'sms_totals': 300, 'email_totals': 1200, 'letter_totals': 0},
|
||||
{'service_id': 2, 'service_name': 'james the pine tree', 'organisation_name': 'Forest',
|
||||
'consent_to_research': None, 'contact_name': None,
|
||||
'contact_email': None, 'contact_mobile': None,
|
||||
'live_date': 'Tue, 15 Mar 2016 00:00:00 GMT', 'sms_volume_intent': None, 'email_volume_intent': 60,
|
||||
'letter_volume_intent': 0, 'sms_totals': 0, 'email_totals': 0, 'letter_totals': 0},
|
||||
]}
|
||||
)
|
||||
response = client.get(url_for('main.live_services_csv'))
|
||||
assert response.status_code == 200
|
||||
report = response.get_data(as_text=True)
|
||||
assert report.strip() == (
|
||||
'Service ID,Organisation,Service name,Consent to research,Main contact,Contact email,Contact mobile,'
|
||||
+ 'Live date,SMS volume intent,Email volume intent,Letter volume intent,SMS sent this year,'
|
||||
+ 'Emails sent this year,Letters sent this year\r\n1,Forest,jessie the oak tree,True,Forest fairy,'
|
||||
+ 'forest.fairy@digital.cabinet-office.gov.uk,+447700900986,29-03-2014,100,50,20,300,1200,0\r\n2,Forest,'
|
||||
+ 'james the pine tree,,,,,15-03-2016,,60,0,0,0,0'
|
||||
)
|
||||
|
||||
|
||||
def test_get_performance_platform_report(client, platform_admin_user, mocker):
|
||||
mock_get_user(mocker, user=platform_admin_user)
|
||||
client.login(platform_admin_user)
|
||||
|
||||
mocker.patch(
|
||||
'app.service_api_client.get_live_services_data',
|
||||
return_value={'data': [
|
||||
{'service_id': 1, 'service_name': 'jessie the oak tree', 'organisation_name': 'Forest',
|
||||
'consent_to_research': True, 'contact_name': 'Forest fairy',
|
||||
'contact_email': 'forest.fairy@digital.cabinet-office.gov.uk', 'contact_mobile': '+447700900986',
|
||||
'live_date': 'Sat, 29 Mar 2014 00:00:00 GMT', 'sms_volume_intent': 100, 'email_volume_intent': 50,
|
||||
'letter_volume_intent': 20, 'sms_totals': 300, 'email_totals': 1200, 'letter_totals': 0},
|
||||
{'service_id': 2, 'service_name': 'james the pine tree', 'organisation_name': 'Forest',
|
||||
'consent_to_research': None, 'contact_name': None,
|
||||
'contact_email': None, 'contact_mobile': None,
|
||||
'live_date': 'Tue, 15 Mar 2016 00:00:00 GMT', 'sms_volume_intent': None, 'email_volume_intent': 60,
|
||||
'letter_volume_intent': 0, 'sms_totals': 0, 'email_totals': 0, 'letter_totals': 0},
|
||||
]}
|
||||
)
|
||||
response = client.get(url_for('main.performance_platform_csv'))
|
||||
assert response.status_code == 200
|
||||
report = response.get_data(as_text=True)
|
||||
assert report.strip() == (
|
||||
'service_id,agency,service_name,_timestamp,service,count'
|
||||
+ '\r\n1,Forest,jessie the oak tree,2014-03-29T00:00:00Z,govuk-notify,1'
|
||||
+ '\r\n2,Forest,james the pine tree,2016-03-15T00:00:00Z,govuk-notify,1'
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user