mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-06-23 08:49:46 -04:00
Add downloadable report for org usage
This is so org level users can use this data easier for things like determining spending per service. We do not include sms fragments sent column and remove other sms columns consistency. Do not add sms fragments sent column for now until we agree on an unambiguous name for it. The data in this column is sms billing units multiplied by international sms weighing. My favourite for a clear name would be 'text message credits used', but we need a naming strategy for this.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from functools import partial
|
||||
|
||||
from flask import flash, redirect, render_template, request, session, url_for
|
||||
@@ -43,6 +44,7 @@ from app.main.views.dashboard import (
|
||||
from app.main.views.service_settings import get_branding_as_value_and_label
|
||||
from app.models.organisation import Organisation, Organisations
|
||||
from app.models.user import InvitedOrgUser, User
|
||||
from app.utils.csv import Spreadsheet
|
||||
from app.utils.user import user_has_permissions, user_is_platform_admin
|
||||
|
||||
|
||||
@@ -158,16 +160,46 @@ def organisation_dashboard(org_id):
|
||||
for key in ('emails_sent', 'sms_cost', 'letter_cost')
|
||||
},
|
||||
download_link=url_for(
|
||||
'.download_services_report_for_org',
|
||||
'.download_organisation_usage_report',
|
||||
org_id=org_id,
|
||||
selected_year=year
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@main.route("/organisations/<uuid:org_id>", methods=['GET'])
|
||||
@main.route("/organisations/<uuid:org_id>/download-usage-report.csv", methods=['GET'])
|
||||
@user_has_permissions()
|
||||
def download_services_report_for_org(org_id):
|
||||
pass
|
||||
def download_organisation_usage_report(org_id):
|
||||
selected_year = request.args.get('selected_year')
|
||||
services_usage = current_organisation.services_and_usage(
|
||||
financial_year=selected_year
|
||||
)['services']
|
||||
|
||||
column_names = OrderedDict([
|
||||
('service_id', 'Service ID'),
|
||||
('service_name', 'Service Name'),
|
||||
('emails_sent', 'Emails sent'),
|
||||
('sms_remainder', 'Free text message allowance remaining'),
|
||||
('sms_cost', 'Spent on text messages (£)'),
|
||||
('letter_cost', 'Spent on letters (£)')
|
||||
])
|
||||
|
||||
org_usage_data = [[x for x in column_names.values()]]
|
||||
|
||||
for service in services_usage:
|
||||
org_usage_data.append([service[attribute] for attribute in column_names.keys()])
|
||||
|
||||
return Spreadsheet.from_rows(org_usage_data).as_csv_data, 200, {
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition': (
|
||||
'inline;'
|
||||
'filename="{} organisation usage report for year {}'
|
||||
' - generated on {}.csv"'.format(
|
||||
current_organisation.name,
|
||||
selected_year,
|
||||
datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@main.route("/organisations/<uuid:org_id>/trial-services", methods=['GET'])
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="js-stick-at-bottom-when-scrolling">
|
||||
<p class="bottom-gutter">
|
||||
<p class="govuk-!-margin-bottom-1">
|
||||
<a href="{{ download_link }}" download="download" class="govuk-link govuk-link--no-visited-state govuk-!-font-weight-bold">Download this report</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -624,6 +624,7 @@ def test_organisation_services_hides_search_bar_for_7_or_fewer_services(
|
||||
assert not page.select_one('.live-search')
|
||||
|
||||
|
||||
@freeze_time("2021-11-12 11:09:00.061258")
|
||||
def test_organisation_services_links_to_downloadable_report(
|
||||
client_request,
|
||||
mock_get_organisation,
|
||||
@@ -651,7 +652,62 @@ def test_organisation_services_links_to_downloadable_report(
|
||||
page = client_request.get('.organisation_dashboard', org_id=ORGANISATION_ID)
|
||||
|
||||
link_to_report = page.find('a', text="Download this report")
|
||||
assert link_to_report.attrs["href"] == url_for('.download_services_report_for_org', org_id=ORGANISATION_ID)
|
||||
assert link_to_report.attrs["href"] == url_for(
|
||||
'.download_organisation_usage_report',
|
||||
org_id=ORGANISATION_ID,
|
||||
selected_year=2021
|
||||
)
|
||||
|
||||
|
||||
@freeze_time("2021-11-12 11:09:00.061258")
|
||||
def test_download_organisation_usage_report(
|
||||
client_request,
|
||||
mock_get_organisation,
|
||||
mocker,
|
||||
active_user_with_permissions,
|
||||
fake_uuid,
|
||||
):
|
||||
mocker.patch(
|
||||
'app.organisations_client.get_services_and_usage',
|
||||
return_value={"services": [
|
||||
{
|
||||
'service_id': SERVICE_ONE_ID,
|
||||
'service_name': 'Service 1',
|
||||
'chargeable_billable_sms': 22,
|
||||
'emails_sent': 13000,
|
||||
'free_sms_limit': 100,
|
||||
'letter_cost': 30.50,
|
||||
'sms_billable_units': 122,
|
||||
'sms_cost': 1.93,
|
||||
'sms_remainder': None
|
||||
},
|
||||
{
|
||||
'service_id': SERVICE_TWO_ID,
|
||||
'service_name': 'Service 1',
|
||||
'chargeable_billable_sms': 222,
|
||||
'emails_sent': 23000,
|
||||
'free_sms_limit': 250000,
|
||||
'letter_cost': 60.50,
|
||||
'sms_billable_units': 322,
|
||||
'sms_cost': 3.93,
|
||||
'sms_remainder': None
|
||||
},
|
||||
]}
|
||||
)
|
||||
client_request.login(active_user_with_permissions)
|
||||
csv_report = client_request.get(
|
||||
'.download_organisation_usage_report',
|
||||
org_id=ORGANISATION_ID,
|
||||
selected_year=2021,
|
||||
_test_page_title=False
|
||||
)
|
||||
|
||||
assert csv_report.string == (
|
||||
"Service ID,Service Name,Emails sent,Free text message allowance remaining,"
|
||||
"Spent on text messages (£),Spent on letters (£)"
|
||||
"\r\n596364a0-858e-42c8-9062-a8fe822260eb,Service 1,13000,,1.93,30.5"
|
||||
"\r\n147ad62a-2951-4fa1-9ca0-093cd1a52c52,Service 1,23000,,3.93,60.5\r\n"
|
||||
)
|
||||
|
||||
|
||||
def test_organisation_trial_mode_services_shows_all_non_live_services(
|
||||
|
||||
@@ -89,6 +89,7 @@ EXCLUDED_ENDPOINTS = tuple(map(Navigation.get_endpoint_with_blueprint, {
|
||||
'documentation',
|
||||
'download_contact_list',
|
||||
'download_notifications_csv',
|
||||
'download_organisation_usage_report',
|
||||
'edit_and_format_messages',
|
||||
'edit_data_retention',
|
||||
'edit_organisation_agreement',
|
||||
|
||||
Reference in New Issue
Block a user