diff --git a/app/assets/stylesheets/views/dashboard.scss b/app/assets/stylesheets/views/dashboard.scss index 39d8e82ee..76a5e834c 100644 --- a/app/assets/stylesheets/views/dashboard.scss +++ b/app/assets/stylesheets/views/dashboard.scss @@ -62,6 +62,10 @@ margin-top: -10px; } + &-filename-unlinked { + @include core-19; + } + &-hint { @include core-16; display: block; diff --git a/app/main/views/returned_letters.py b/app/main/views/returned_letters.py index 09f3db4ab..a381b1312 100644 --- a/app/main/views/returned_letters.py +++ b/app/main/views/returned_letters.py @@ -17,6 +17,24 @@ def returned_letter_summary(service_id): ) +@main.route("/services//returned-letters/", methods=["GET"]) +@user_has_permissions('view_activity') +def returned_letters(service_id, reported_at): + + page_size = 50 + returned_letters = service_api_client.get_returned_letters(service_id, reported_at) + count_of_returned_letters = len(returned_letters) + + return render_template( + 'views/returned-letters.html', + returned_letters=returned_letters[:page_size], + reported_at=reported_at, + more_than_one_page=(count_of_returned_letters > page_size), + page_size=page_size, + count_of_returned_letters=count_of_returned_letters, + ) + + @main.route("/services//returned-letters/.csv", methods=["GET"]) @user_has_permissions('view_activity') def returned_letters_report(service_id, reported_at): diff --git a/app/navigation.py b/app/navigation.py index fe2f2092b..354483c7d 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -243,6 +243,7 @@ class HeaderNavigation(Navigation): 'resend_email_verification', 'resume_service', 'returned_letter_summary', + 'returned_letters', 'returned_letters_report', 'revoke_api_key', 'robots', @@ -567,6 +568,7 @@ class MainNavigation(Navigation): 'resend_email_verification', 'resume_service', 'returned_letter_summary', + 'returned_letters', 'returned_letters_report', 'roadmap', 'robots', @@ -806,6 +808,7 @@ class CaseworkNavigation(Navigation): 'resend_email_verification', 'resume_service', 'returned_letter_summary', + 'returned_letters', 'returned_letters_report', 'revoke_api_key', 'roadmap', @@ -1084,6 +1087,7 @@ class OrgNavigation(Navigation): 'resend_email_verification', 'resume_service', 'returned_letter_summary', + 'returned_letters', 'returned_letters_report', 'revoke_api_key', 'roadmap', diff --git a/app/templates/views/returned-letter-summary.html b/app/templates/views/returned-letter-summary.html index 38106526f..4071b30c3 100644 --- a/app/templates/views/returned-letter-summary.html +++ b/app/templates/views/returned-letter-summary.html @@ -20,8 +20,8 @@ field_headings_visible=False ) %} {% call field() %} - {{ item.reported_at | format_date_normal }} + {{ item.reported_at | format_date_normal }}

{{ item.returned_letter_count}} {{ message_count_label(item.returned_letter_count, 'letter', suffix='')}}

diff --git a/app/templates/views/returned-letters.html b/app/templates/views/returned-letters.html new file mode 100644 index 000000000..98e71e94c --- /dev/null +++ b/app/templates/views/returned-letters.html @@ -0,0 +1,57 @@ +{% from "components/table.html" import list_table, field %} +{% from "components/message-count-label.html" import message_count_label %} +{% from "components/page-header.html" import page_header %} +{% extends "withnav_template.html" %} + +{% block service_page_title %} + Returned letters for {{ reported_at|format_date_normal }} +{% endblock %} + +{% block maincolumn_content %} + +{{ page_header( + 'Returned letters for {}'.format(reported_at|format_date_normal), + back_link=url_for('main.returned_letter_summary', service_id=current_service.id) +) }} + +

+ Download this report +

+ +
+ {% call(item, row_number) list_table( + returned_letters, + caption="Returned letters for {}".format(today), + caption_visible=False, + empty_message='If you have returned letter reports they will be listed here', + field_headings=['Template name', 'Originally sent'], + field_headings_visible=False + ) %} + {% call field() %} + {{ item.template_name or item.uploaded_letter_file_name }} + + {% if item.client_reference %} + Reference {{ item.client_reference }} + {% elif item.original_file_name %} + Sent from {{ item.original_file_name }} + {% else %} + No reference provided + {% endif %} + + {% endcall %} + {% call field(align='right') %} + + + Originally sent {{ item.created_at|format_date_normal }} + + + {% endcall %} + {% endcall %} + {% if more_than_one_page %} + + {% endif %} +
+ +{% endblock %} diff --git a/tests/app/main/views/test_returned_letters.py b/tests/app/main/views/test_returned_letters.py index 1b205f1be..d1039a833 100644 --- a/tests/app/main/views/test_returned_letters.py +++ b/tests/app/main/views/test_returned_letters.py @@ -1,3 +1,5 @@ +import uuid + from flask import url_for from tests.conftest import SERVICE_ONE_ID, normalize_spaces @@ -22,9 +24,11 @@ def test_returned_letter_summary( '24 December 2019 ' '30 letters' ) - assert page.select_one('.table-field-left-aligned a')['href'] == url_for('.returned_letters_report', - service_id=SERVICE_ONE_ID, - reported_at='2019-12-24') + assert page.select_one('.table-field-left-aligned a')['href'] == url_for( + '.returned_letters', + service_id=SERVICE_ONE_ID, + reported_at='2019-12-24', + ) def test_returned_letter_summary_with_one_letter( @@ -48,6 +52,94 @@ def test_returned_letter_summary_with_one_letter( ) +def test_returned_letters_page( + client_request, + mocker +): + data = [ + { + 'notification_id': uuid.uuid4(), + 'client_reference': client_reference, + 'created_at': '2019-12-24 13:30', + 'email_address': 'test@gov.uk', + 'template_name': template_name, + 'template_id': uuid.uuid4(), + 'template_version': None, + 'original_file_name': original_file_name, + 'job_row_number': None, + 'uploaded_letter_file_name': 'test_letter.pdf', + } + for client_reference, template_name, original_file_name, uploaded_letter_file_name in ( + ('ABC123', 'Example template', None, None), + (None, 'Example template', 'Example spreadsheet.xlsx', None), + (None, 'Example template', None, None), + ('DEF456', None, None, 'Example precompiled.pdf'), + (None, None, None, 'Example one-off.pdf'), + ) + ] + mocker.patch('app.service_api_client.get_returned_letters', return_value=data) + + page = client_request.get( + 'main.returned_letters', + service_id=SERVICE_ONE_ID, + reported_at='2019-12-24', + ) + + assert [ + 'Template name Originally sent', + 'Example template Reference ABC123 Originally sent 24 December 2019', + 'Example template Sent from Example spreadsheet.xlsx Originally sent 24 December 2019', + 'Example template No reference provided Originally sent 24 December 2019', + 'test_letter.pdf Reference DEF456 Originally sent 24 December 2019', + 'test_letter.pdf No reference provided Originally sent 24 December 2019', + ] == [ + normalize_spaces(row.text) for row in page.select('tr') + ] + + +def test_returned_letters_page_with_many_letters( + client_request, + mocker +): + data = [ + { + 'notification_id': uuid.uuid4(), + 'client_reference': None, + 'created_at': '2019-12-24 13:30', + 'email_address': 'test@gov.uk', + 'template_name': 'Example template', + 'template_id': uuid.uuid4(), + 'template_version': None, + 'original_file_name': None, + 'job_row_number': None, + 'uploaded_letter_file_name': None, + } + ] * 51 + mocker.patch('app.service_api_client.get_returned_letters', return_value=data) + + page = client_request.get( + 'main.returned_letters', + service_id=SERVICE_ONE_ID, + reported_at='2019-12-24', + ) + + assert len(data) == 51 + assert len(page.select('tbody tr')) == 50 + assert normalize_spaces( + page.select_one('.table-show-more-link').text + ) == ( + 'Only showing the first 50 of 51 rows' + ) + assert page.select_one('a[download]').text == ( + 'Download this report' + ) + assert page.select_one('a[download]')['href'] == url_for( + '.returned_letters_report', + service_id=SERVICE_ONE_ID, + reported_at='2019-12-24', + ) + + def test_returned_letters_reports( client_request, mocker