Merge pull request #3170 from alphagov/show-users-why-their-precompiled-letter-failed-validation

Show users why their precompiled letter failed validation
This commit is contained in:
Pea (Malgorzata Tyczynska)
2019-11-07 11:23:30 +00:00
committed by GitHub
19 changed files with 134 additions and 86 deletions

View File

@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import base64
import io
import json
import os
from datetime import datetime
@@ -39,6 +40,7 @@ from app.utils import (
generate_notifications_csv,
get_help_argument,
get_letter_printing_statement,
get_letter_validation_error,
get_template,
parse_filter_args,
set_status_filters,
@@ -53,13 +55,21 @@ def view_notification(service_id, notification_id):
notification['template'].update({'reply_to_text': notification['reply_to_text']})
personalisation = get_all_personalisation_from_notification(notification)
error_message = None
if notification['template']['is_precompiled_letter']:
try:
file_contents = view_letter_notification_as_preview(
service_id, notification_id, "pdf"
file_contents, metadata = view_letter_notification_as_preview(
service_id, notification_id, "pdf", with_metadata=True
)
page_count = pdf_page_count(io.BytesIO(file_contents))
page_count = int(
metadata["page_count"]
) if metadata.get("page_count") else pdf_page_count(io.BytesIO(file_contents))
if notification["status"] == "validation-failed":
invalid_pages = metadata.get("invalid_pages")
invalid_pages = json.loads(invalid_pages) if invalid_pages else invalid_pages
error_message = get_letter_validation_error(
metadata.get("message"), invalid_pages, page_count
)
except PdfReadError:
return render_template(
'views/notifications/invalid_precompiled_letter.html',
@@ -119,6 +129,7 @@ def view_notification(service_id, notification_id):
'views/notifications/notification.html',
finished=(notification['status'] in (DELIVERED_STATUSES + FAILURE_STATUSES)),
notification_status=notification['status'],
message=error_message,
uploaded_file_name='Report',
template=template,
job=job,
@@ -171,31 +182,28 @@ def get_preview_error_image():
@main.route("/services/<service_id>/notification/<uuid:notification_id>.<filetype>")
@user_has_permissions('view_activity')
def view_letter_notification_as_preview(service_id, notification_id, filetype):
def view_letter_notification_as_preview(
service_id, notification_id, filetype, with_metadata=False
):
if filetype not in ('pdf', 'png'):
abort(404)
notification = notification_api_client.get_notification(service_id, str(notification_id))
try:
if notification['status'] == "validation-failed":
preview = notification_api_client.get_notification_letter_preview_with_overlay(
service_id,
notification_id,
filetype,
page=request.args.get('page')
)
else:
preview = notification_api_client.get_notification_letter_preview(
service_id,
notification_id,
filetype,
page=request.args.get('page')
)
preview = notification_api_client.get_notification_letter_preview(
service_id,
notification_id,
filetype,
page=request.args.get('page')
)
display_file = base64.b64decode(preview['content'])
except APIError:
display_file = get_preview_error_image()
preview = {"metadata": {}}
if with_metadata:
return display_file, preview['metadata']
return display_file

View File

@@ -5,6 +5,7 @@ from datetime import datetime
from flask import abort, flash, redirect, render_template, request, url_for
from notifications_python_client.errors import HTTPError
from notifications_utils import LETTER_MAX_PAGE_COUNT
from requests import RequestException
from app import (
@@ -34,6 +35,7 @@ from app.utils import (
Spreadsheet,
generate_next_dict,
generate_previous_dict,
get_letter_validation_error,
get_page_from_request,
user_has_permissions,
user_is_platform_admin,
@@ -397,7 +399,7 @@ def service_letter_validation_preview(service_id):
def letter_validation_preview(from_platform_admin):
message, pages, result = None, [], None
message, pages, passed_validation, error_code = None, [], None, None
form = PDFUploadForm()
view_location = 'views/platform-admin/letter-validation-preview.html' \
@@ -410,7 +412,8 @@ def letter_validation_preview(from_platform_admin):
if not virus_free:
return render_template(
view_location,
form=form, message="Document did not pass the virus scan", pages=pages, result=result
form=form, message="Document did not pass the virus scan",
pages=pages, passed_validation=passed_validation
), 400
try:
@@ -419,26 +422,38 @@ def letter_validation_preview(from_platform_admin):
view_location,
form=form,
message="File must be less than 2MB",
pages=pages, result=result
pages=pages, passed_validation=passed_validation
), 400
pdf_file.seek(0)
response = validate_letter(pdf_file)
response.raise_for_status()
if response.status_code == 200:
pages, message, result = response.json()["pages"], response.json()["message"], response.json()["result"]
pages, message = response.json()["pages"], response.json()["message"],
passed_validation = response.json()["result"]
invalid_pages = response.json().get('invalid_pages')
page_count = len(pages)
if page_count > LETTER_MAX_PAGE_COUNT:
message = "letter-too-long"
passed_validation = False
if not passed_validation:
error_code = message
message = get_letter_validation_error(
message, invalid_pages=invalid_pages, page_count=page_count
)
except RequestException as error:
if error.response and error.response.status_code == 400:
message = "Something was wrong with the file you tried to upload. Please upload a valid PDF file."
return render_template(
view_location,
form=form, message=message, pages=pages, result=result
form=form, message=message, pages=pages, passed_validation=passed_validation
), 400
else:
raise error
return render_template(
view_location,
form=form, message=message, pages=pages, result=result
form=form, message=message, pages=pages, passed_validation=passed_validation, error_code=error_code
)

View File

@@ -145,13 +145,13 @@ def uploaded_letter_preview(service_id, file_id):
original_filename = metadata.get('filename')
page_count = metadata.get('page_count')
status = metadata.get('status')
error_message = metadata.get('message')
error_shortcode = metadata.get('message')
invalid_pages = metadata.get('invalid_pages')
if invalid_pages:
invalid_pages = json.loads(invalid_pages)
error = get_letter_validation_error(error_message, invalid_pages, page_count)
error_message = get_letter_validation_error(error_shortcode, invalid_pages, page_count)
template_dict = service_api_client.get_precompiled_template(service_id)
# Override pre compiled letter template postage to none as it has not yet been picked even though
# the pre compiled letter template has its postage set as second class as the DB currently requires
@@ -177,7 +177,8 @@ def uploaded_letter_preview(service_id, file_id):
template=template,
status=status,
file_id=file_id,
error=error,
message=error_message,
error_code=error_shortcode,
form=form,
)