def test_get_estimated_delivery_date_for_letter( upload_time, expected_print_time, is_printed, first_class, expected_earliest, expected_latest, ): # remove the day string from the upload_time, which is purely informational format_dt = lambda x: x.astimezone(pytz.timezone('Europe/London') ).strftime('%A %Y-%m-%d %H:%M') # noqa upload_time = upload_time.split(' ', 1)[1] timings = get_letter_timings(upload_time, postage='second') assert format_dt(timings.printed_by) == expected_print_time assert timings.is_printed == is_printed assert format_dt(timings.earliest_delivery) == expected_earliest assert format_dt(timings.latest_delivery) == expected_latest first_class_timings = get_letter_timings(upload_time, postage='first') assert format_dt(first_class_timings.printed_by) == expected_print_time assert first_class_timings.is_printed == is_printed assert format_dt(first_class_timings.earliest_delivery) == first_class assert format_dt(first_class_timings.latest_delivery) == first_class
def get_job_partials(job, template): filter_args = parse_filter_args(request.args) filter_args['status'] = set_status_filters(filter_args) notifications = notification_api_client.get_notifications_for_service( job['service'], job['id'], status=filter_args['status']) if template['template_type'] == 'letter': # there might be no notifications if the job has only just been created and the tasks haven't run yet if notifications['notifications']: postage = notifications['notifications'][0]['postage'] else: postage = template['postage'] counts = render_template( 'partials/jobs/count-letters.html', total=job.get('notification_count', 0), delivery_estimate=get_letter_timings( job['created_at'], postage=postage).earliest_delivery, ) else: counts = render_template('partials/count.html', counts=_get_job_counts(job), status=filter_args['status']) service_data_retention_days = current_service.get_days_of_retention( template['template_type']) return { 'counts': counts, 'notifications': render_template( 'partials/jobs/notifications.html', notifications=list( add_preview_of_content_to_notifications( notifications['notifications'])), more_than_one_page=bool( notifications.get('links', {}).get('next')), percentage_complete=(job['notifications_requested'] / job['notification_count'] * 100), download_link=url_for('.view_job_csv', service_id=current_service.id, job_id=job['id'], status=request.args.get('status')), time_left=get_time_left( job['created_at'], service_data_retention_days=service_data_retention_days), job=job, template=template, template_version=job['template_version'], ), 'status': render_template('partials/jobs/status.html', job=job), }
def test_get_estimated_delivery_date_for_letter( upload_time, expected_print_time, is_printed, expected_earliest, expected_latest, ): timings = get_letter_timings(upload_time) assert (timings.printed_by.astimezone( pytz.timezone('Europe/London')).strftime('%A %H:%M') ) == expected_print_time assert (timings.is_printed) == is_printed assert (timings.earliest_delivery.astimezone( pytz.timezone('Europe/London')).strftime('%A %Y-%m-%d %H:%M') ) == expected_earliest assert (timings.latest_delivery.astimezone( pytz.timezone('Europe/London')).strftime('%A %Y-%m-%d %H:%M') ) == expected_latest
def letter_timings(self): return get_letter_timings(self.created_at, postage=self.postage)
def get_job_partials(job, template): filter_args = parse_filter_args(request.args) filter_args['status'] = set_status_filters(filter_args) notifications = notification_api_client.get_notifications_for_service( job['service'], job['id'], status=filter_args['status']) if template['template_type'] == 'letter': # there might be no notifications if the job has only just been created and the tasks haven't run yet if notifications['notifications']: postage = notifications['notifications'][0]['postage'] else: postage = template['postage'] counts = render_template( 'partials/jobs/count-letters.html', total=job.get('notification_count', 0), delivery_estimate=get_letter_timings( job['created_at'], postage=postage).earliest_delivery, ) else: counts = render_template('partials/count.html', counts=_get_job_counts(job), 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 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 = False else: can_letter_job_be_cancelled = True return { 'counts': counts, 'notifications': render_template( 'partials/jobs/notifications.html', notifications=list( add_preview_of_content_to_notifications( notifications['notifications'])), more_than_one_page=bool( notifications.get('links', {}).get('next')), percentage_complete=(job['notifications_requested'] / job['notification_count'] * 100), download_link=url_for('.view_job_csv', service_id=current_service.id, job_id=job['id'], status=request.args.get('status')), time_left=get_time_left( job['created_at'], service_data_retention_days=service_data_retention_days), job=job, template=template, template_version=job['template_version'], ), 'status': render_template('partials/jobs/status.html', 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, }
def view_notification(service_id, notification_id): notification = notification_api_client.get_notification( service_id, str(notification_id)) notification['template'].update( {'reply_to_text': notification['reply_to_text']}) personalisation = get_all_personalisation_from_notification(notification) if notification['template']['is_precompiled_letter']: try: file_contents = view_letter_notification_as_preview( service_id, notification_id, "pdf") page_count = pdf_page_count(io.BytesIO(file_contents)) except PdfReadError: return render_template( 'views/notifications/invalid_precompiled_letter.html', created_at=notification['created_at']) else: page_count = get_page_count_for_letter(notification['template'], values=personalisation) if notification.get('postage'): notification['template']['postage'] = notification['postage'] template = get_template( notification['template'], current_service, letter_preview_url=url_for( '.view_letter_notification_as_preview', service_id=service_id, notification_id=notification_id, filetype='png', ), page_count=page_count, show_recipient=True, redact_missing_personalisation=True, ) template.values = personalisation if notification['job']: job = job_api_client.get_job(service_id, notification['job']['id'])['data'] else: job = None letter_print_day = get_letter_printing_statement( notification['status'], notification['created_at']) notification_created = parser.parse( notification['created_at']).replace(tzinfo=None) show_cancel_button = notification['notification_type'] == 'letter' and \ letter_can_be_cancelled(notification['status'], notification_created) if get_help_argument() or request.args.get('help') == '0': # help=0 is set when you’ve just sent a notification. We # only want to show the back link when you’ve navigated to a # notification, not when you’ve just sent it. back_link = None elif request.args.get('from_job'): back_link = url_for( 'main.view_job', service_id=current_service.id, job_id=request.args.get('from_job'), ) else: back_link = url_for( 'main.view_notifications', service_id=current_service.id, message_type=template.template_type, status='sending,delivered,failed', ) return render_template( 'views/notifications/notification.html', finished=(notification['status'] in (DELIVERED_STATUSES + FAILURE_STATUSES)), notification_status=notification['status'], uploaded_file_name='Report', template=template, job=job, updates_url=url_for(".view_notification_updates", service_id=service_id, notification_id=notification['id'], status=request.args.get('status'), help=get_help_argument()), partials=get_single_notification_partials(notification), created_by=notification.get('created_by'), created_at=notification['created_at'], updated_at=notification['updated_at'], help=get_help_argument(), estimated_letter_delivery_date=get_letter_timings( notification['created_at'], postage=notification['postage']).earliest_delivery, notification_id=notification['id'], postage=notification['postage'], can_receive_inbound=(current_service.has_permission('inbound_sms')), is_precompiled_letter=notification['template'] ['is_precompiled_letter'], letter_print_day=letter_print_day, show_cancel_button=show_cancel_button, sent_with_test_key=(notification.get('key_type') == KEY_TYPE_TEST), back_link=back_link, )
def get_job_partials(job, template): filter_args = parse_filter_args(request.args) filter_args["status"] = set_status_filters(filter_args) notifications = notification_api_client.get_notifications_for_service( job["service"], job["id"], status=filter_args["status"]) if template["template_type"] == "letter": # there might be no notifications if the job has only just been created and the tasks haven't run yet if notifications["notifications"]: postage = notifications["notifications"][0]["postage"] else: postage = template["postage"] counts = render_template( "partials/jobs/count-letters.html", total=job.get("notification_count", 0), delivery_estimate=get_letter_timings( job["created_at"], postage=postage).earliest_delivery, ) else: counts = render_template( "partials/count.html", counts=_get_job_counts(job), 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 (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 = False else: can_letter_job_be_cancelled = True return { "counts": counts, "notifications": render_template( "partials/jobs/notifications.html", notifications=list( add_preview_of_content_to_notifications( notifications["notifications"])), more_than_one_page=bool( notifications.get("links", {}).get("next")), percentage_complete=(job["notifications_requested"] / job["notification_count"] * 100), download_link=url_for( ".view_job_csv", service_id=current_service.id, job_id=job["id"], status=request.args.get("status"), ), available_until_date=get_available_until_date( job["created_at"], service_data_retention_days=service_data_retention_days, ), job=job, template=template, template_version=job["template_version"], ), "status": render_template( "partials/jobs/status.html", job=job, template=template, template_type=template["template_type"], template_version=job["template_version"], letter_print_day=get_letter_printing_statement( "created", job["created_at"]), ), "can_letter_job_be_cancelled": can_letter_job_be_cancelled, }
def test_letter_timings_only_accept_real_postage_values(): with pytest.raises(KeyError): get_letter_timings(datetime.utcnow().isoformat(), postage='foo')
def view_notification(service_id, notification_id): notification = notification_api_client.get_notification(service_id, str(notification_id)) notification["template"].update({"reply_to_text": notification["reply_to_text"]}) personalisation = get_all_personalisation_from_notification(notification) if notification["template"]["is_precompiled_letter"]: try: file_contents = view_letter_notification_as_preview(service_id, notification_id, "pdf") page_count = pdf_page_count(io.BytesIO(file_contents)) except PdfReadError: return render_template( "views/notifications/invalid_precompiled_letter.html", created_at=notification["created_at"], ) else: page_count = get_page_count_for_letter(notification["template"], values=personalisation) if notification.get("postage"): notification["template"]["postage"] = notification["postage"] template = get_template( notification["template"], current_service, letter_preview_url=url_for( ".view_letter_notification_as_preview", service_id=service_id, notification_id=notification_id, filetype="png", ), page_count=page_count, show_recipient=True, redact_missing_personalisation=True, ) template.values = personalisation if notification["job"]: job = job_api_client.get_job(service_id, notification["job"]["id"])["data"] else: job = None letter_print_day = get_letter_printing_statement(notification["status"], notification["created_at"]) notification_created = parser.parse(notification["created_at"]).replace(tzinfo=None) show_cancel_button = notification["notification_type"] == "letter" and letter_can_be_cancelled( notification["status"], notification_created ) if get_help_argument() or request.args.get("help") == "0": # help=0 is set when you’ve just sent a notification. We # only want to show the back link when you’ve navigated to a # notification, not when you’ve just sent it. back_link = None elif request.args.get("from_job"): back_link = url_for( "main.view_job", service_id=current_service.id, job_id=request.args.get("from_job"), ) else: back_link = url_for( "main.view_notifications", service_id=current_service.id, message_type=template.template_type, status="sending,delivered,failed", ) return render_template( "views/notifications/notification.html", finished=(notification["status"] in (DELIVERED_STATUSES + FAILURE_STATUSES)), notification_status=notification["status"], uploaded_file_name="Report", template=template, job=job, updates_url=url_for( ".view_notification_updates", service_id=service_id, notification_id=notification["id"], status=request.args.get("status"), help=get_help_argument(), ), partials=get_single_notification_partials(notification), created_by=notification.get("created_by"), created_at=notification["created_at"], updated_at=notification["updated_at"], help=get_help_argument(), estimated_letter_delivery_date=get_letter_timings( notification["created_at"], postage=notification["postage"] ).earliest_delivery, notification_id=notification["id"], postage=notification["postage"], can_receive_inbound=(current_service.has_permission("inbound_sms")), is_precompiled_letter=notification["template"]["is_precompiled_letter"], letter_print_day=letter_print_day, show_cancel_button=show_cancel_button, sent_with_test_key=(notification.get("key_type") == KEY_TYPE_TEST), back_link=back_link, just_sent=request.args.get("just_sent"), attachments=get_attachments(notification, "attach").values(), )