2016-01-06 11:03:29 +00:00
|
|
|
|
# -*- coding: utf-8 -*-
|
2016-01-13 17:32:40 +00:00
|
|
|
|
|
2020-05-11 14:20:53 +01:00
|
|
|
|
from functools import partial
|
|
|
|
|
|
|
2016-01-13 17:32:40 +00:00
|
|
|
|
from flask import (
|
2018-02-20 11:22:17 +00:00
|
|
|
|
Response,
|
2016-03-02 17:36:20 +00:00
|
|
|
|
abort,
|
2019-06-18 15:52:29 +01:00
|
|
|
|
flash,
|
2016-03-16 16:57:10 +00:00
|
|
|
|
jsonify,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
redirect,
|
|
|
|
|
|
render_template,
|
2016-04-13 12:50:28 +01:00
|
|
|
|
request,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
stream_with_context,
|
2016-04-28 15:50:05 +01:00
|
|
|
|
url_for,
|
2016-01-13 17:32:40 +00:00
|
|
|
|
)
|
2019-07-01 15:22:08 +01:00
|
|
|
|
from flask_login import current_user
|
2019-06-18 15:52:29 +01:00
|
|
|
|
from notifications_python_client.errors import HTTPError
|
2020-04-15 17:58:57 +01:00
|
|
|
|
from notifications_utils.template import (
|
|
|
|
|
|
EmailPreviewTemplate,
|
|
|
|
|
|
LetterPreviewTemplate,
|
2020-04-22 16:03:37 +01:00
|
|
|
|
SMSBodyPreviewTemplate,
|
2020-04-15 17:58:57 +01:00
|
|
|
|
)
|
2016-01-11 16:03:41 +00:00
|
|
|
|
|
2016-04-04 16:53:52 +01:00
|
|
|
|
from app import (
|
2018-02-20 11:22:17 +00:00
|
|
|
|
current_service,
|
|
|
|
|
|
format_datetime_short,
|
2019-07-08 14:09:29 +01:00
|
|
|
|
format_thousands,
|
2016-04-04 16:53:52 +01:00
|
|
|
|
notification_api_client,
|
|
|
|
|
|
service_api_client,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
)
|
2015-12-17 11:14:19 +00:00
|
|
|
|
from app.main import main
|
2017-05-30 13:51:25 +01:00
|
|
|
|
from app.main.forms import SearchNotificationsForm
|
2020-01-08 12:23:09 +00:00
|
|
|
|
from app.models.job import Job
|
2016-03-29 22:50:40 +01:00
|
|
|
|
from app.utils import (
|
2016-10-10 14:50:59 +01:00
|
|
|
|
generate_next_dict,
|
2016-10-05 17:45:04 +01:00
|
|
|
|
generate_notifications_csv,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
generate_previous_dict,
|
2019-06-18 18:00:36 +01:00
|
|
|
|
get_letter_printing_statement,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
get_page_from_request,
|
|
|
|
|
|
get_time_left,
|
|
|
|
|
|
parse_filter_args,
|
2018-11-27 16:49:01 +00:00
|
|
|
|
printing_today_or_tomorrow,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
set_status_filters,
|
|
|
|
|
|
user_has_permissions,
|
2018-01-12 12:06:07 +00:00
|
|
|
|
)
|
2015-12-18 10:26:56 +00:00
|
|
|
|
|
2015-12-17 11:14:19 +00:00
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/jobs")
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-01-15 17:46:09 +00:00
|
|
|
|
def view_jobs(service_id):
|
2020-03-02 13:48:32 +00:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'main.uploads',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
))
|
2015-12-17 11:14:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>")
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-01-15 17:46:09 +00:00
|
|
|
|
def view_job(service_id, job_id):
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job = Job.from_id(job_id, service_id=current_service.id)
|
|
|
|
|
|
if job.cancelled:
|
2016-09-01 15:46:16 +01:00
|
|
|
|
abort(404)
|
|
|
|
|
|
|
2017-12-30 16:54:39 +00:00
|
|
|
|
filter_args = parse_filter_args(request.args)
|
|
|
|
|
|
filter_args['status'] = set_status_filters(filter_args)
|
2016-06-28 11:23:43 +01:00
|
|
|
|
|
2019-04-16 10:34:46 +01:00
|
|
|
|
just_sent_message = 'Your {} been sent. Printing starts {} at 5:30pm.'.format(
|
2020-01-08 12:23:09 +00:00
|
|
|
|
'letter has' if job.notification_count == 1 else 'letters have',
|
2020-05-11 10:52:30 +01:00
|
|
|
|
printing_today_or_tomorrow(job.created_at)
|
2018-11-29 11:37:38 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2016-03-10 11:53:29 +00:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/jobs/job.html',
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job=job,
|
2016-06-28 09:21:46 +01:00
|
|
|
|
status=request.args.get('status', ''),
|
|
|
|
|
|
updates_url=url_for(
|
|
|
|
|
|
".view_job_updates",
|
|
|
|
|
|
service_id=service_id,
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job_id=job.id,
|
2016-07-19 09:09:20 +01:00
|
|
|
|
status=request.args.get('status', ''),
|
2016-06-28 11:23:43 +01:00
|
|
|
|
),
|
2020-01-08 12:23:09 +00:00
|
|
|
|
partials=get_job_partials(job),
|
2020-03-03 14:27:13 +00:00
|
|
|
|
just_sent=request.args.get('just_sent') == 'yes',
|
2018-11-29 11:37:38 +00:00
|
|
|
|
just_sent_message=just_sent_message,
|
2016-03-10 11:53:29 +00:00
|
|
|
|
)
|
2015-12-17 11:14:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>.csv")
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('view_activity')
|
2016-06-07 11:41:20 +01:00
|
|
|
|
def view_job_csv(service_id, job_id):
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job = Job.from_id(job_id, service_id=service_id)
|
2017-12-30 16:54:39 +00:00
|
|
|
|
filter_args = parse_filter_args(request.args)
|
|
|
|
|
|
filter_args['status'] = set_status_filters(filter_args)
|
2016-06-07 11:41:20 +01:00
|
|
|
|
|
2017-01-06 17:41:24 +00:00
|
|
|
|
return Response(
|
2017-03-13 14:53:19 +00:00
|
|
|
|
stream_with_context(
|
|
|
|
|
|
generate_notifications_csv(
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
job_id=job_id,
|
|
|
|
|
|
status=filter_args.get('status'),
|
|
|
|
|
|
page=request.args.get('page', 1),
|
2017-04-20 14:57:31 +01:00
|
|
|
|
page_size=5000,
|
2018-02-16 11:35:36 +00:00
|
|
|
|
format_for_csv=True,
|
2020-01-08 12:23:09 +00:00
|
|
|
|
template_type=job.template_type,
|
2017-03-13 14:53:19 +00:00
|
|
|
|
)
|
2016-06-07 11:41:20 +01:00
|
|
|
|
),
|
2017-01-06 17:41:24 +00:00
|
|
|
|
mimetype='text/csv',
|
|
|
|
|
|
headers={
|
2016-06-07 11:41:20 +01:00
|
|
|
|
'Content-Disposition': 'inline; filename="{} - {}.csv"'.format(
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job.template['name'],
|
|
|
|
|
|
format_datetime_short(job.created_at)
|
2017-03-13 14:53:19 +00:00
|
|
|
|
)
|
|
|
|
|
|
}
|
2016-06-07 11:41:20 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>", methods=['POST'])
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('send_messages')
|
2016-09-01 15:40:49 +01:00
|
|
|
|
def cancel_job(service_id, job_id):
|
2020-01-08 12:23:09 +00:00
|
|
|
|
Job.from_id(job_id, service_id=service_id).cancel()
|
2016-09-01 15:40:49 +01:00
|
|
|
|
return redirect(url_for('main.service_dashboard', service_id=service_id))
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>/cancel", methods=['GET', 'POST'])
|
2019-06-18 15:52:29 +01:00
|
|
|
|
@user_has_permissions()
|
|
|
|
|
|
def cancel_letter_job(service_id, job_id):
|
|
|
|
|
|
if request.method == 'POST':
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job = Job.from_id(job_id, service_id=service_id)
|
|
|
|
|
|
|
|
|
|
|
|
if job.status != 'finished' or job.notifications_created < job.notification_count:
|
2019-06-24 17:57:04 +01:00
|
|
|
|
flash("We are still processing these letters, please try again in a minute.", 'try again')
|
|
|
|
|
|
return view_job(service_id, job_id)
|
2019-06-18 15:52:29 +01:00
|
|
|
|
try:
|
2020-01-08 12:23:09 +00:00
|
|
|
|
number_of_letters = job.cancel()
|
2019-06-18 15:52:29 +01:00
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
flash(e.message, 'dangerous')
|
|
|
|
|
|
return redirect(url_for('main.view_job', service_id=service_id, job_id=job_id))
|
2019-07-08 14:09:29 +01:00
|
|
|
|
flash("Cancelled {} letters from {}".format(
|
2020-01-08 12:23:09 +00:00
|
|
|
|
format_thousands(number_of_letters), job.original_file_name
|
2019-06-24 17:57:04 +01:00
|
|
|
|
), 'default_with_tick')
|
2019-06-18 15:52:29 +01:00
|
|
|
|
return redirect(url_for('main.service_dashboard', service_id=service_id))
|
|
|
|
|
|
|
2019-06-24 17:57:04 +01:00
|
|
|
|
flash("Are you sure you want to cancel sending these letters?", 'cancel')
|
2019-06-18 15:52:29 +01:00
|
|
|
|
return view_job(service_id, job_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>.json")
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-03-02 17:36:20 +00:00
|
|
|
|
def view_job_updates(service_id, job_id):
|
2017-07-13 11:28:37 +01:00
|
|
|
|
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job = Job.from_id(job_id, service_id=service_id)
|
2017-07-13 11:28:37 +01:00
|
|
|
|
|
2020-01-08 12:23:09 +00:00
|
|
|
|
return jsonify(**get_job_partials(job))
|
2016-03-02 17:36:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route('/services/<uuid:service_id>/notifications', methods=['GET', 'POST'])
|
2019-11-04 11:20:08 +00:00
|
|
|
|
@main.route('/services/<uuid:service_id>/notifications/<template_type:message_type>', methods=['GET', 'POST'])
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2018-06-13 14:16:10 +01:00
|
|
|
|
def view_notifications(service_id, message_type=None):
|
2016-09-27 15:07:40 +01:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/notifications.html',
|
|
|
|
|
|
partials=get_notifications(service_id, message_type),
|
|
|
|
|
|
message_type=message_type,
|
2017-05-30 13:51:25 +01:00
|
|
|
|
status=request.args.get('status') or 'sending,delivered,failed',
|
2017-05-30 12:55:13 +01:00
|
|
|
|
page=request.args.get('page', 1),
|
2017-06-13 11:05:57 +01:00
|
|
|
|
to=request.form.get('to', ''),
|
2018-08-07 14:44:09 +01:00
|
|
|
|
search_form=SearchNotificationsForm(
|
|
|
|
|
|
message_type=message_type,
|
|
|
|
|
|
to=request.form.get('to', ''),
|
|
|
|
|
|
),
|
2019-12-13 14:27:56 +00:00
|
|
|
|
things_you_can_search_by={
|
|
|
|
|
|
'email': ['email address'],
|
|
|
|
|
|
'sms': ['phone number'],
|
2020-04-21 13:55:23 +01:00
|
|
|
|
# This should become ‘postal address’ not ‘first line…’ once
|
|
|
|
|
|
# we’ve finished populating normalised addresses
|
|
|
|
|
|
'letter': ['first line of address', 'file name'],
|
|
|
|
|
|
# We say recipient here because combining all 3 types, plus
|
|
|
|
|
|
# reference gets too long for the hint text
|
|
|
|
|
|
None: ['recipient'],
|
2019-12-13 14:27:56 +00:00
|
|
|
|
}.get(message_type) + {
|
|
|
|
|
|
True: ['reference'],
|
|
|
|
|
|
False: [],
|
|
|
|
|
|
}.get(bool(current_service.api_keys)),
|
2017-12-30 16:54:39 +00:00
|
|
|
|
download_link=url_for(
|
|
|
|
|
|
'.download_notifications_csv',
|
2018-07-20 08:42:01 +01:00
|
|
|
|
service_id=current_service.id,
|
2017-12-30 16:54:39 +00:00
|
|
|
|
message_type=message_type,
|
|
|
|
|
|
status=request.args.get('status')
|
|
|
|
|
|
)
|
2016-09-27 15:07:40 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route('/services/<uuid:service_id>/notifications.json', methods=['GET', 'POST'])
|
2019-11-04 11:20:08 +00:00
|
|
|
|
@main.route('/services/<uuid:service_id>/notifications/<template_type:message_type>.json', methods=['GET', 'POST'])
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2018-06-13 14:16:10 +01:00
|
|
|
|
def get_notifications_as_json(service_id, message_type=None):
|
2016-09-27 15:07:40 +01:00
|
|
|
|
return jsonify(get_notifications(
|
|
|
|
|
|
service_id, message_type, status_override=request.args.get('status')
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:20:08 +00:00
|
|
|
|
@main.route('/services/<uuid:service_id>/notifications.csv', endpoint="view_notifications_csv")
|
2019-11-29 13:03:23 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
'/services/<uuid:service_id>/notifications/<template_type:message_type>.csv',
|
|
|
|
|
|
endpoint="view_notifications_csv"
|
|
|
|
|
|
)
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-09-27 15:07:40 +01:00
|
|
|
|
def get_notifications(service_id, message_type, status_override=None):
|
2016-03-16 16:57:10 +00:00
|
|
|
|
# TODO get the api to return count of pages as well.
|
|
|
|
|
|
page = get_page_from_request()
|
|
|
|
|
|
if page is None:
|
2018-07-04 10:38:46 +01:00
|
|
|
|
abort(404, "Invalid page argument ({}).".format(request.args.get('page')))
|
2017-12-30 16:54:39 +00:00
|
|
|
|
filter_args = parse_filter_args(request.args)
|
|
|
|
|
|
filter_args['status'] = set_status_filters(filter_args)
|
2018-11-15 17:04:11 +00:00
|
|
|
|
service_data_retention_days = None
|
2020-05-06 14:30:32 +01:00
|
|
|
|
search_term = request.form.get('to', '')
|
2018-08-13 17:07:49 +01:00
|
|
|
|
|
2018-11-15 17:04:11 +00:00
|
|
|
|
if message_type is not None:
|
2018-12-03 17:57:11 +00:00
|
|
|
|
service_data_retention_days = current_service.get_days_of_retention(message_type)
|
2018-08-13 17:07:49 +01:00
|
|
|
|
|
2018-06-13 14:13:39 +01:00
|
|
|
|
if request.path.endswith('csv') and current_user.has_permissions('view_activity'):
|
2017-01-13 11:35:27 +00:00
|
|
|
|
return Response(
|
|
|
|
|
|
generate_notifications_csv(
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
page=page,
|
|
|
|
|
|
page_size=5000,
|
|
|
|
|
|
template_type=[message_type],
|
|
|
|
|
|
status=filter_args.get('status'),
|
2018-08-13 17:07:49 +01:00
|
|
|
|
limit_days=service_data_retention_days
|
2017-01-13 11:35:27 +00:00
|
|
|
|
),
|
|
|
|
|
|
mimetype='text/csv',
|
|
|
|
|
|
headers={
|
|
|
|
|
|
'Content-Disposition': 'inline; filename="notifications.csv"'}
|
|
|
|
|
|
)
|
2016-04-04 16:34:06 +01:00
|
|
|
|
notifications = notification_api_client.get_notifications_for_service(
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
page=page,
|
2018-06-13 14:16:10 +01:00
|
|
|
|
template_type=[message_type] if message_type else [],
|
2016-05-18 11:44:58 +01:00
|
|
|
|
status=filter_args.get('status'),
|
2018-08-13 17:07:49 +01:00
|
|
|
|
limit_days=service_data_retention_days,
|
2020-05-06 14:30:32 +01:00
|
|
|
|
to=search_term,
|
2017-05-30 12:55:13 +01:00
|
|
|
|
)
|
2016-10-10 14:50:59 +01:00
|
|
|
|
url_args = {
|
|
|
|
|
|
'message_type': message_type,
|
|
|
|
|
|
'status': request.args.get('status')
|
|
|
|
|
|
}
|
2016-03-16 16:57:10 +00:00
|
|
|
|
prev_page = None
|
2017-01-13 11:35:27 +00:00
|
|
|
|
|
2017-05-30 13:51:25 +01:00
|
|
|
|
if 'links' in notifications and notifications['links'].get('prev', None):
|
2016-10-10 17:15:57 +01:00
|
|
|
|
prev_page = generate_previous_dict('main.view_notifications', service_id, page, url_args=url_args)
|
2016-03-16 16:57:10 +00:00
|
|
|
|
next_page = None
|
2017-01-13 11:35:27 +00:00
|
|
|
|
|
2017-05-30 13:51:25 +01:00
|
|
|
|
if 'links' in notifications and notifications['links'].get('next', None):
|
2016-10-10 17:15:57 +01:00
|
|
|
|
next_page = generate_next_dict('main.view_notifications', service_id, page, url_args)
|
2016-10-10 14:50:59 +01:00
|
|
|
|
|
2018-06-13 14:16:10 +01:00
|
|
|
|
if message_type:
|
|
|
|
|
|
download_link = url_for(
|
|
|
|
|
|
'.view_notifications_csv',
|
2018-07-20 08:42:01 +01:00
|
|
|
|
service_id=current_service.id,
|
2018-06-13 14:16:10 +01:00
|
|
|
|
message_type=message_type,
|
|
|
|
|
|
status=request.args.get('status')
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
download_link = None
|
|
|
|
|
|
|
2016-09-27 15:07:40 +01:00
|
|
|
|
return {
|
2018-08-13 17:07:49 +01:00
|
|
|
|
'service_data_retention_days': service_data_retention_days,
|
2016-09-27 15:07:40 +01:00
|
|
|
|
'counts': render_template(
|
|
|
|
|
|
'views/activity/counts.html',
|
|
|
|
|
|
status=request.args.get('status'),
|
|
|
|
|
|
status_filters=get_status_filters(
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
message_type,
|
2018-08-13 17:07:49 +01:00
|
|
|
|
service_api_client.get_service_statistics(
|
|
|
|
|
|
service_id,
|
|
|
|
|
|
today_only=False,
|
|
|
|
|
|
limit_days=service_data_retention_days
|
|
|
|
|
|
)
|
2016-09-27 15:07:40 +01:00
|
|
|
|
)
|
|
|
|
|
|
),
|
|
|
|
|
|
'notifications': render_template(
|
|
|
|
|
|
'views/activity/notifications.html',
|
2017-06-24 17:20:00 +01:00
|
|
|
|
notifications=list(add_preview_of_content_to_notifications(
|
|
|
|
|
|
notifications['notifications']
|
|
|
|
|
|
)),
|
2016-09-27 15:07:40 +01:00
|
|
|
|
page=page,
|
2018-08-13 17:07:49 +01:00
|
|
|
|
limit_days=service_data_retention_days,
|
2016-09-27 15:07:40 +01:00
|
|
|
|
prev_page=prev_page,
|
|
|
|
|
|
next_page=next_page,
|
2020-05-07 09:50:03 +01:00
|
|
|
|
show_pagination=(not search_term),
|
2016-09-27 15:07:40 +01:00
|
|
|
|
status=request.args.get('status'),
|
2016-06-07 11:41:20 +01:00
|
|
|
|
message_type=message_type,
|
2018-06-13 14:16:10 +01:00
|
|
|
|
download_link=download_link,
|
2020-05-11 14:20:53 +01:00
|
|
|
|
single_notification_url=partial(
|
|
|
|
|
|
url_for,
|
|
|
|
|
|
'.view_notification',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
)
|
2016-06-07 11:41:20 +01:00
|
|
|
|
),
|
2016-09-27 15:07:40 +01:00
|
|
|
|
}
|
2016-03-16 16:57:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 15:19:58 +01:00
|
|
|
|
def get_status_filters(service, message_type, statistics):
|
2018-06-13 14:16:10 +01:00
|
|
|
|
if message_type is None:
|
|
|
|
|
|
stats = {
|
|
|
|
|
|
key: sum(
|
|
|
|
|
|
statistics[message_type][key]
|
|
|
|
|
|
for message_type in {'email', 'sms', 'letter'}
|
|
|
|
|
|
)
|
|
|
|
|
|
for key in {'requested', 'delivered', 'failed'}
|
|
|
|
|
|
}
|
|
|
|
|
|
else:
|
|
|
|
|
|
stats = statistics[message_type]
|
2016-07-20 15:19:58 +01:00
|
|
|
|
stats['sending'] = stats['requested'] - stats['delivered'] - stats['failed']
|
|
|
|
|
|
|
|
|
|
|
|
filters = [
|
|
|
|
|
|
# key, label, option
|
2016-08-03 09:47:27 +01:00
|
|
|
|
('requested', 'total', 'sending,delivered,failed'),
|
2016-07-20 15:19:58 +01:00
|
|
|
|
('sending', 'sending', 'sending'),
|
|
|
|
|
|
('delivered', 'delivered', 'delivered'),
|
|
|
|
|
|
('failed', 'failed', 'failed'),
|
|
|
|
|
|
]
|
|
|
|
|
|
return [
|
|
|
|
|
|
# return list containing label, option, link, count
|
|
|
|
|
|
(
|
|
|
|
|
|
label,
|
|
|
|
|
|
option,
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
'.view_notifications',
|
2018-10-26 12:13:04 +01:00
|
|
|
|
service_id=service.id,
|
2016-07-20 15:19:58 +01:00
|
|
|
|
message_type=message_type,
|
|
|
|
|
|
status=option
|
|
|
|
|
|
),
|
|
|
|
|
|
stats[key]
|
|
|
|
|
|
)
|
|
|
|
|
|
for key, label, option in filters
|
2017-01-06 17:41:24 +00:00
|
|
|
|
]
|
2016-07-20 15:19:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-07-03 15:43:28 +01:00
|
|
|
|
def _get_job_counts(job):
|
2016-06-08 16:34:26 +01:00
|
|
|
|
return [
|
|
|
|
|
|
(
|
|
|
|
|
|
label,
|
|
|
|
|
|
query_param,
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".view_job",
|
2020-01-08 12:23:09 +00:00
|
|
|
|
service_id=job.service,
|
|
|
|
|
|
job_id=job.id,
|
2016-06-08 16:34:26 +01:00
|
|
|
|
status=query_param,
|
|
|
|
|
|
),
|
|
|
|
|
|
count
|
|
|
|
|
|
) for label, query_param, count in [
|
|
|
|
|
|
[
|
2016-09-07 10:31:33 +01:00
|
|
|
|
'total', '',
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job.notification_count
|
2016-06-08 16:34:26 +01:00
|
|
|
|
],
|
|
|
|
|
|
[
|
2016-09-07 10:31:33 +01:00
|
|
|
|
'sending', 'sending',
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job.notifications_sending
|
2016-06-08 16:34:26 +01:00
|
|
|
|
],
|
|
|
|
|
|
[
|
2016-09-07 10:31:33 +01:00
|
|
|
|
'delivered', 'delivered',
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job.notifications_delivered
|
2016-06-08 16:34:26 +01:00
|
|
|
|
],
|
|
|
|
|
|
[
|
2016-09-07 10:31:33 +01:00
|
|
|
|
'failed', 'failed',
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job.notifications_failed
|
2016-06-08 16:34:26 +01:00
|
|
|
|
]
|
|
|
|
|
|
]
|
2016-09-08 09:29:08 +01:00
|
|
|
|
]
|
2016-06-28 11:23:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-01-08 12:23:09 +00:00
|
|
|
|
def get_job_partials(job):
|
2017-12-30 16:54:39 +00:00
|
|
|
|
filter_args = parse_filter_args(request.args)
|
|
|
|
|
|
filter_args['status'] = set_status_filters(filter_args)
|
2020-01-08 12:23:09 +00:00
|
|
|
|
notifications = job.get_notifications(status=filter_args['status'])
|
|
|
|
|
|
if job.template_type == 'letter':
|
2017-07-13 07:09:33 +01:00
|
|
|
|
counts = render_template(
|
|
|
|
|
|
'partials/jobs/count-letters.html',
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job=job,
|
2017-07-13 07:09:33 +01:00
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
counts = render_template(
|
2017-06-12 17:21:25 +01:00
|
|
|
|
'partials/count.html',
|
2017-07-03 15:43:28 +01:00
|
|
|
|
counts=_get_job_counts(job),
|
2019-12-30 16:53:45 +00:00
|
|
|
|
status=filter_args['status'],
|
|
|
|
|
|
notifications_deleted=(
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job.status == 'finished' and not notifications['notifications']
|
2019-12-30 16:53:45 +00:00
|
|
|
|
),
|
2017-07-13 07:09:33 +01:00
|
|
|
|
)
|
2020-01-08 12:23:09 +00:00
|
|
|
|
service_data_retention_days = current_service.get_days_of_retention(job.template_type)
|
|
|
|
|
|
|
2017-07-13 07:09:33 +01:00
|
|
|
|
return {
|
|
|
|
|
|
'counts': counts,
|
2016-06-28 11:23:43 +01:00
|
|
|
|
'notifications': render_template(
|
|
|
|
|
|
'partials/jobs/notifications.html',
|
2017-06-24 17:12:45 +01:00
|
|
|
|
notifications=list(
|
|
|
|
|
|
add_preview_of_content_to_notifications(notifications['notifications'])
|
|
|
|
|
|
),
|
2016-08-02 21:27:23 +01:00
|
|
|
|
more_than_one_page=bool(notifications.get('links', {}).get('next')),
|
2016-07-18 09:04:43 +01:00
|
|
|
|
download_link=url_for(
|
|
|
|
|
|
'.view_job_csv',
|
2018-07-20 08:42:01 +01:00
|
|
|
|
service_id=current_service.id,
|
2020-01-08 12:23:09 +00:00
|
|
|
|
job_id=job.id,
|
2016-08-05 10:18:27 +01:00
|
|
|
|
status=request.args.get('status')
|
2016-07-18 09:04:43 +01:00
|
|
|
|
),
|
2020-01-08 12:23:09 +00:00
|
|
|
|
time_left=get_time_left(job.created_at, service_data_retention_days=service_data_retention_days),
|
2017-06-24 17:12:45 +01:00
|
|
|
|
job=job,
|
2019-12-30 16:37:50 +00:00
|
|
|
|
service_data_retention_days=service_data_retention_days,
|
2016-06-28 11:23:43 +01:00
|
|
|
|
),
|
|
|
|
|
|
'status': render_template(
|
|
|
|
|
|
'partials/jobs/status.html',
|
2019-06-18 18:00:36 +01:00
|
|
|
|
job=job,
|
2020-01-08 12:23:09 +00:00
|
|
|
|
letter_print_day=get_letter_printing_statement("created", job.created_at)
|
2016-06-28 11:23:43 +01:00
|
|
|
|
),
|
|
|
|
|
|
}
|
2017-06-24 17:12:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_preview_of_content_to_notifications(notifications):
|
2017-06-24 17:29:28 +01:00
|
|
|
|
|
2017-06-24 17:20:00 +01:00
|
|
|
|
for notification in notifications:
|
2020-04-15 17:58:57 +01:00
|
|
|
|
yield(dict(
|
|
|
|
|
|
preview_of_content=get_preview_of_content(notification),
|
|
|
|
|
|
**notification
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_preview_of_content(notification):
|
|
|
|
|
|
|
|
|
|
|
|
if notification['template'].get('redact_personalisation'):
|
|
|
|
|
|
notification['personalisation'] = {}
|
|
|
|
|
|
|
|
|
|
|
|
if notification['template']['is_precompiled_letter']:
|
|
|
|
|
|
return notification['client_reference']
|
|
|
|
|
|
|
|
|
|
|
|
if notification['template']['template_type'] == 'sms':
|
2020-04-22 16:03:37 +01:00
|
|
|
|
return str(SMSBodyPreviewTemplate(
|
2020-04-15 17:58:57 +01:00
|
|
|
|
notification['template'],
|
|
|
|
|
|
notification['personalisation'],
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
if notification['template']['template_type'] == 'email':
|
|
|
|
|
|
return EmailPreviewTemplate(
|
|
|
|
|
|
notification['template'],
|
|
|
|
|
|
notification['personalisation'],
|
|
|
|
|
|
redact_missing_personalisation=True,
|
|
|
|
|
|
).subject
|
|
|
|
|
|
|
|
|
|
|
|
if notification['template']['template_type'] == 'letter':
|
|
|
|
|
|
return LetterPreviewTemplate(
|
|
|
|
|
|
notification['template'],
|
|
|
|
|
|
notification['personalisation'],
|
|
|
|
|
|
).subject
|