diff --git a/app/__init__.py b/app/__init__.py index 37781f2ef..a244407d6 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -385,6 +385,7 @@ def format_notification_status(status, template_type): 'sent': 'Delivered', 'pending-virus-check': 'Pending virus check', 'virus-scan-failed': 'Virus detected', + 'returned-letter': 'Delivered', } }[template_type].get(status, status) @@ -410,6 +411,7 @@ def format_notification_status_as_field_status(status, notification_type): 'accepted': None, 'pending-virus-check': None, 'virus-scan-failed': 'error', + 'returned-letter': None, } }.get( notification_type, diff --git a/app/main/forms.py b/app/main/forms.py index 1106bc12f..e16364980 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1067,3 +1067,12 @@ class ServiceDataRetentionEditForm(StripWhitespaceForm): validators=[validators.NumberRange(min=3, max=90, message="Must be between 3 and 90")], ) + + +class ReturnedLettersForm(StripWhitespaceForm): + references = TextAreaField( + u'Letter references', + validators=[ + DataRequired(message="Can’t be empty"), + ] + ) diff --git a/app/main/views/platform_admin.py b/app/main/views/platform_admin.py index 2074a5f90..ed710a50c 100644 --- a/app/main/views/platform_admin.py +++ b/app/main/views/platform_admin.py @@ -1,16 +1,19 @@ import itertools +import re from datetime import datetime -from flask import abort, render_template, request, url_for +from flask import abort, flash, redirect, render_template, request, url_for from flask_login import login_required +from notifications_python_client.errors import HTTPError from app import ( complaint_api_client, + letter_jobs_client, platform_stats_api_client, service_api_client, ) from app.main import main -from app.main.forms import DateFilterForm +from app.main.forms import DateFilterForm, ReturnedLettersForm from app.statistics_utils import ( get_formatted_percentage, get_formatted_percentage_two_dp, @@ -202,6 +205,41 @@ def platform_admin_list_complaints(): ) +@main.route("/platform-admin/returned-letters", methods=["GET", "POST"]) +@login_required +@user_is_platform_admin +def platform_admin_returned_letters(): + form = ReturnedLettersForm() + + if form.validate_on_submit(): + references = [ + re.sub('NOTIFY00[0-9]', '', r.strip()) + for r in form.references.data.split('\n') + if r.strip() + ] + + try: + letter_jobs_client.submit_returned_letters(references) + except HTTPError as error: + if error.status_code == 400: + error_references = [ + re.match('references (.*) does not match', e['message']).group(1) + for e in error.message + ] + form.references.errors.append("Invalid references: {}".format(', '.join(error_references))) + else: + raise error + else: + flash('Submitted {} letter references'.format(len(references)), 'default') + return redirect( + url_for('.platform_admin_returned_letters') + ) + return render_template( + 'views/platform-admin/returned-letters.html', + form=form, + ) + + def sum_service_usage(service): total = 0 for notification_type in service['statistics'].keys(): diff --git a/app/navigation.py b/app/navigation.py index f95426767..1b9e556a5 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -81,6 +81,7 @@ class HeaderNavigation(Navigation): 'organisations', 'platform_admin', 'platform_admin_list_complaints', + 'platform_admin_returned_letters', 'suspend_service', 'trial_services', 'update_email_branding', @@ -440,6 +441,7 @@ class MainNavigation(Navigation): 'organisations', 'platform_admin', 'platform_admin_list_complaints', + 'platform_admin_returned_letters', 'pricing', 'privacy', 'public_agreement', @@ -624,6 +626,7 @@ class CaseworkNavigation(Navigation): 'organisations', 'platform_admin', 'platform_admin_list_complaints', + 'platform_admin_returned_letters', 'pricing', 'privacy', 'public_agreement', @@ -848,6 +851,7 @@ class OrgNavigation(Navigation): 'organisations', 'platform_admin', 'platform_admin_list_complaints', + 'platform_admin_returned_letters', 'pricing', 'privacy', 'public_agreement', diff --git a/app/notify_client/letter_jobs_client.py b/app/notify_client/letter_jobs_client.py index efa35e696..079d31e12 100644 --- a/app/notify_client/letter_jobs_client.py +++ b/app/notify_client/letter_jobs_client.py @@ -14,3 +14,9 @@ class LetterJobsClient(NotifyAdminAPIClient): url='/send-letter-jobs', data={"job_ids": job_ids} )['data'] + + def submit_returned_letters(self, references): + return self.post( + url='/letters/returned', + data={'references': references} + ) diff --git a/app/templates/views/platform-admin/_base_template.html b/app/templates/views/platform-admin/_base_template.html index 7ea7ce43c..9f93036a7 100644 --- a/app/templates/views/platform-admin/_base_template.html +++ b/app/templates/views/platform-admin/_base_template.html @@ -21,7 +21,8 @@ ('Letter jobs', url_for('main.letter_jobs')), ('Inbound SMS numbers', url_for('main.inbound_sms_admin')), ('Find users by email', url_for('main.find_users_by_email')), - ('Email Complaints', url_for('main.platform_admin_list_complaints')) + ('Email Complaints', url_for('main.platform_admin_list_complaints')), + ('Returned letters', url_for('main.platform_admin_returned_letters')), ] %}