diff --git a/app/main/views/jobs.py b/app/main/views/jobs.py index 62ff957d5..fb63f9319 100644 --- a/app/main/views/jobs.py +++ b/app/main/views/jobs.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +from datetime import datetime + from flask import ( Response, abort, @@ -13,7 +15,11 @@ from flask import ( ) from flask_login import current_user from notifications_python_client.errors import HTTPError -from notifications_utils.letter_timings import get_letter_timings +from notifications_utils.letter_timings import ( + CANCELLABLE_JOB_LETTER_STATUSES, + get_letter_timings, + letter_can_be_cancelled, +) from notifications_utils.template import Template, WithSubjectTemplate from app import ( @@ -30,6 +36,7 @@ from app.utils import ( generate_next_dict, generate_notifications_csv, generate_previous_dict, + get_letter_printing_statement, get_page_from_request, get_time_left, parse_filter_args, @@ -96,6 +103,8 @@ def view_job(service_id, job_id): 'letter has' if job['notification_count'] == 1 else 'letters have', printing_today_or_tomorrow() ) + partials = get_job_partials(job, template) + can_cancel_letter_job = partials["can_letter_job_be_cancelled"] return render_template( 'views/jobs/job.html', @@ -103,7 +112,6 @@ def view_job(service_id, job_id): uploaded_file_name=job['original_file_name'], template_id=job['template'], job_id=job_id, - template_type=template["template_type"], status=request.args.get('status', ''), updates_url=url_for( ".view_job_updates", @@ -111,12 +119,13 @@ def view_job(service_id, job_id): job_id=job['id'], status=request.args.get('status', ''), ), - partials=get_job_partials(job, template), + partials=partials, just_sent=bool( request.args.get('just_sent') == 'yes' and template['template_type'] == 'letter' ), just_sent_message=just_sent_message, + can_cancel_letter_job=can_cancel_letter_job, ) @@ -420,7 +429,20 @@ def get_job_partials(job, template): status=filter_args['status'] ) service_data_retention_days = current_service.get_days_of_retention(template['template_type']) - + can_letter_job_be_cancelled = False + if template["template_type"] == "letter": + not_cancellable = [ + n for n in notifications["notifications"] if n["status"] not in CANCELLABLE_JOB_LETTER_STATUSES + ] + job_created = job["created_at"][:-6] + if job["job_status"] != "finished": + can_letter_job_be_cancelled = "This job is still being processed. Wait a couple of minutes and try again." + elif not letter_can_be_cancelled( + "created", datetime.strptime(job_created, '%Y-%m-%dT%H:%M:%S.%f') + ) or len(not_cancellable) != 0: + can_letter_job_be_cancelled = "Cancel sending those letters" + else: + can_letter_job_be_cancelled = True return { 'counts': counts, 'notifications': render_template( @@ -443,8 +465,11 @@ def get_job_partials(job, template): ), 'status': render_template( 'partials/jobs/status.html', - job=job + job=job, + template_type=template["template_type"], + letter_print_day=get_letter_printing_statement("created", job["created_at"]) ), + 'can_letter_job_be_cancelled': can_letter_job_be_cancelled, } diff --git a/app/main/views/notifications.py b/app/main/views/notifications.py index 6c55c4b2a..28ac9b9b1 100644 --- a/app/main/views/notifications.py +++ b/app/main/views/notifications.py @@ -2,7 +2,7 @@ import base64 import io import os -from datetime import datetime, timedelta +from datetime import datetime from dateutil import parser from flask import ( @@ -22,11 +22,9 @@ from notifications_utils.letter_timings import ( letter_can_be_cancelled, ) from notifications_utils.pdf import pdf_page_count -from notifications_utils.timezones import utc_string_to_aware_gmt_datetime from PyPDF2.utils import PdfReadError from app import ( - _format_datetime_short, current_service, format_date_numeric, job_api_client, @@ -40,9 +38,9 @@ from app.utils import ( FAILURE_STATUSES, generate_notifications_csv, get_help_argument, + get_letter_printing_statement, get_template, parse_filter_args, - printing_today_or_tomorrow, set_status_filters, user_has_permissions, ) @@ -166,18 +164,6 @@ def cancel_letter(service_id, notification_id): return view_notification(service_id, notification_id) -def get_letter_printing_statement(status, created_at): - created_at_dt = parser.parse(created_at).replace(tzinfo=None) - - if letter_can_be_cancelled(status, created_at_dt): - return 'Printing starts {} at 5:30pm'.format(printing_today_or_tomorrow()) - else: - printed_datetime = utc_string_to_aware_gmt_datetime(created_at) + timedelta(hours=6, minutes=30) - printed_date = _format_datetime_short(printed_datetime) - - return 'Printed on {}'.format(printed_date) - - def get_preview_error_image(): path = os.path.join(os.path.dirname(__file__), "..", "..", "static", "images", "preview_error.png") with open(path, "rb") as file: diff --git a/app/navigation.py b/app/navigation.py index 6a8ac94e0..c893f8210 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -134,6 +134,7 @@ class HeaderNavigation(Navigation): 'cancel_invited_user', 'cancel_job', 'cancel_letter', + 'cancel_letter_job', 'check_and_resend_text_code', 'check_and_resend_verification_code', 'check_messages', @@ -441,6 +442,7 @@ class MainNavigation(Navigation): 'cancel_invited_user', 'cancel_job', 'cancel_letter', + 'cancel_letter_job', 'check_and_resend_text_code', 'check_and_resend_verification_code', 'check_messages_preview', @@ -637,6 +639,7 @@ class CaseworkNavigation(Navigation): 'cancel_invited_user', 'cancel_job', 'cancel_letter', + 'cancel_letter_job', 'check_and_resend_text_code', 'check_and_resend_verification_code', 'check_messages', @@ -925,6 +928,7 @@ class OrgNavigation(Navigation): 'cancel_invited_user', 'cancel_job', 'cancel_letter', + 'cancel_letter_job', 'check_and_resend_text_code', 'check_and_resend_verification_code', 'check_messages', diff --git a/app/templates/partials/jobs/status.html b/app/templates/partials/jobs/status.html index c243ce572..1fdf08b05 100644 --- a/app/templates/partials/jobs/status.html +++ b/app/templates/partials/jobs/status.html @@ -3,11 +3,21 @@ {% if job.scheduled_for %} {% if job.processing_started %} Sent by {{ job.created_by.name }} on {{ job.processing_started|format_datetime_short }} + {% if template_type == "letter" %} +

+ {{ letter_print_day }} +

+ {% endif %} {% else %} Uploaded by {{ job.created_by.name }} on {{ job.created_at|format_datetime_short }} {% endif %} {% else %} Sent by {{ job.created_by.name }} on {{ job.created_at|format_datetime_short }} + {% if template_type == "letter" %} +

+ {{ letter_print_day }} +

+ {% endif %} {% endif %}

diff --git a/app/templates/views/jobs/job.html b/app/templates/views/jobs/job.html index 8128fbceb..2325f71c9 100644 --- a/app/templates/views/jobs/job.html +++ b/app/templates/views/jobs/job.html @@ -21,11 +21,15 @@ {{ ajax_block(partials, updates_url, 'counts', finished=finished) }} {{ ajax_block(partials, updates_url, 'notifications', finished=finished) }} - {% if template_type == "letter" %} + {% if can_cancel_letter_job %}