From 3c38a7be0522886724b8cf04ef4b575de1c125a6 Mon Sep 17 00:00:00 2001
From: Chris Hill-Scott
Date: Fri, 3 May 2019 14:32:02 +0100
Subject: [PATCH] Provide Performance Platform report as Excel file
This is the format we need to upload it in, so this means not having to
manually re-save it as Excel.
---
app/main/views/platform_admin.py | 10 ++++-----
app/navigation.py | 8 +++----
.../views/platform-admin/reports.html | 2 +-
app/utils.py | 17 ++++++++++++++-
tests/app/main/views/test_platform_admin.py | 21 +++++++++++--------
5 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/app/main/views/platform_admin.py b/app/main/views/platform_admin.py
index b23277674..37abf57a0 100644
--- a/app/main/views/platform_admin.py
+++ b/app/main/views/platform_admin.py
@@ -238,10 +238,10 @@ def live_services_csv():
}
-@main.route("/platform-admin/reports/performance-platform.csv")
+@main.route("/platform-admin/reports/performance-platform.xlsx")
@login_required
@user_is_platform_admin
-def performance_platform_csv():
+def performance_platform_xlsx():
results = service_api_client.get_live_services_data()["data"]
live_services_columns = ["service_id", "agency", "service_name", "_timestamp", "service", "count"]
live_services_data = []
@@ -258,9 +258,9 @@ def performance_platform_csv():
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(
+ return Spreadsheet.from_rows(live_services_data).as_excel_file, 200, {
+ 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'Content-Disposition': 'attachment; filename="{} performance platform report.xlsx"'.format(
format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
)
}
diff --git a/app/navigation.py b/app/navigation.py
index ee7a5ac42..972323802 100644
--- a/app/navigation.py
+++ b/app/navigation.py
@@ -87,7 +87,7 @@ class HeaderNavigation(Navigation):
'live_services',
'live_services_csv',
'organisations',
- 'performance_platform_csv',
+ 'performance_platform_xlsx',
'platform_admin',
'platform_admin_letter_validation_preview',
'platform_admin_list_complaints',
@@ -496,7 +496,7 @@ class MainNavigation(Navigation):
'organisation_preview_letter_branding',
'organisation_settings',
'organisations',
- 'performance_platform_csv',
+ 'performance_platform_xlsx',
'platform_admin',
'platform_admin_letter_validation_preview',
'platform_admin_list_complaints',
@@ -713,7 +713,7 @@ class CaseworkNavigation(Navigation):
'organisation_preview_letter_branding',
'organisation_settings',
'organisations',
- 'performance_platform_csv',
+ 'performance_platform_xlsx',
'platform_admin_letter_validation_preview',
'platform_admin_list_complaints',
'platform_admin_reports',
@@ -970,7 +970,7 @@ class OrgNavigation(Navigation):
'old_terms',
'old_using_notify',
'organisations',
- 'performance_platform_csv',
+ 'performance_platform_xlsx',
'platform_admin',
'platform_admin_letter_validation_preview',
'platform_admin_list_complaints',
diff --git a/app/templates/views/platform-admin/reports.html b/app/templates/views/platform-admin/reports.html
index 2135c388c..bed419859 100644
--- a/app/templates/views/platform-admin/reports.html
+++ b/app/templates/views/platform-admin/reports.html
@@ -15,6 +15,6 @@
- Download performance platform csv report
+ Download performance platform report (.xlsx)
{% endblock %}
diff --git a/app/utils.py b/app/utils.py
index ce47074cf..83774dc06 100644
--- a/app/utils.py
+++ b/app/utils.py
@@ -4,7 +4,7 @@ import re
import unicodedata
from datetime import datetime, time, timedelta, timezone
from functools import wraps
-from io import StringIO
+from io import BytesIO, StringIO
from itertools import chain
from os import path
from urllib.parse import urlparse
@@ -12,6 +12,7 @@ from urllib.parse import urlparse
import ago
import dateutil
import pyexcel
+import pyexcel_xlsx
import yaml
from flask import abort, current_app, redirect, request, session, url_for
from flask_login import current_user
@@ -278,6 +279,20 @@ class Spreadsheet():
pyexcel.free_resources()
return instance
+ @property
+ def as_rows(self):
+ return list(csv.reader(
+ self.as_csv_data.strip().splitlines(),
+ quoting=csv.QUOTE_MINIMAL,
+ skipinitialspace=True,
+ ))
+
+ @property
+ def as_excel_file(self):
+ io = BytesIO()
+ pyexcel_xlsx.save_data(io, {'Sheet 1': self.as_rows})
+ return io.getvalue()
+
def get_help_argument():
return request.args.get('help') if request.args.get('help') in ('1', '2', '3') else None
diff --git a/tests/app/main/views/test_platform_admin.py b/tests/app/main/views/test_platform_admin.py
index 6cb8c965b..d3aabed6b 100644
--- a/tests/app/main/views/test_platform_admin.py
+++ b/tests/app/main/views/test_platform_admin.py
@@ -4,6 +4,7 @@ import uuid
from functools import partial
from unittest.mock import ANY, call
+import pyexcel
import pytest
import requests_mock
from bs4 import BeautifulSoup
@@ -946,8 +947,8 @@ def test_reports_page(
).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'
+ 'a', text="Download performance platform report (.xlsx)"
+ ).attrs['href'] == '/platform-admin/reports/performance-platform.xlsx'
def test_get_live_services_report(client, platform_admin_user, mocker):
@@ -1000,11 +1001,13 @@ def test_get_performance_platform_report(client, platform_admin_user, mocker):
'letter_volume_intent': 0, 'sms_totals': 0, 'email_totals': 0, 'letter_totals': 0},
]}
)
- response = client.get(url_for('main.performance_platform_csv'))
+ response = client.get(url_for('main.performance_platform_xlsx'))
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,,govuk-notify,1'
- )
+ assert pyexcel.get_array(
+ file_type='xlsx',
+ file_stream=response.get_data(),
+ ) == [
+ ['service_id', 'agency', 'service_name', '_timestamp', 'service', 'count'],
+ ['1', 'Forest', 'jessie the oak tree', '2014-03-29T00:00:00Z', 'govuk-notify', '1'],
+ ['2', 'Forest', 'james the pine tree', '', 'govuk-notify', '1'],
+ ]