2016-06-06 11:09:46 +01:00
|
|
|
|
from datetime import datetime, timedelta
|
2016-05-31 14:18:35 +01:00
|
|
|
|
from string import ascii_uppercase
|
2016-05-27 16:21:29 +01:00
|
|
|
|
|
2016-06-06 11:42:40 +01:00
|
|
|
|
from dateutil.parser import parse
|
2018-03-02 14:03:32 +00:00
|
|
|
|
from flask import abort, flash, redirect, render_template, request, url_for
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from flask_login import current_user, login_required
|
2018-01-03 10:44:36 +00:00
|
|
|
|
from markupsafe import Markup
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from notifications_python_client.errors import HTTPError
|
2018-01-03 10:44:36 +00:00
|
|
|
|
from notifications_utils.formatters import nl2br
|
2016-11-10 13:39:05 +00:00
|
|
|
|
from notifications_utils.recipients import first_column_headings
|
2016-04-12 09:55:51 +01:00
|
|
|
|
|
2018-07-19 12:30:04 +01:00
|
|
|
|
from app import (
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
service_api_client,
|
2018-11-01 17:11:58 +00:00
|
|
|
|
template_folder_api_client,
|
2018-07-19 12:30:04 +01:00
|
|
|
|
template_statistics_client,
|
|
|
|
|
|
user_api_client,
|
|
|
|
|
|
)
|
2015-12-20 00:00:01 +00:00
|
|
|
|
from app.main import main
|
2017-03-14 10:46:38 +00:00
|
|
|
|
from app.main.forms import (
|
|
|
|
|
|
EmailTemplateForm,
|
|
|
|
|
|
LetterTemplateForm,
|
2019-01-29 15:43:59 +00:00
|
|
|
|
LetterTemplatePostageForm,
|
2019-02-06 17:32:13 +00:00
|
|
|
|
SearchByNameForm,
|
2018-01-03 10:44:36 +00:00
|
|
|
|
SetTemplateSenderForm,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
SMSTemplateForm,
|
2018-11-08 11:56:29 +00:00
|
|
|
|
TemplateAndFoldersSelectionForm,
|
2018-11-01 17:11:58 +00:00
|
|
|
|
TemplateFolderForm,
|
2017-03-14 10:46:38 +00:00
|
|
|
|
)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
from app.main.views.send import get_example_csv_rows, get_sender_details
|
2018-10-26 16:30:37 +01:00
|
|
|
|
from app.models.service import Service
|
2019-01-07 14:49:33 +00:00
|
|
|
|
from app.models.template_list import TemplateList, TemplateLists
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from app.template_previews import TemplatePreview, get_page_count_for_letter
|
|
|
|
|
|
from app.utils import (
|
|
|
|
|
|
email_or_sms_not_enabled,
|
|
|
|
|
|
get_template,
|
2018-08-09 16:29:51 +01:00
|
|
|
|
should_skip_template_page,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
user_has_permissions,
|
2019-02-15 14:47:39 +00:00
|
|
|
|
user_is_platform_admin,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
)
|
2015-12-20 00:00:01 +00:00
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
form_objects = {
|
|
|
|
|
|
'email': EmailTemplateForm,
|
2016-11-08 13:12:07 +00:00
|
|
|
|
'sms': SMSTemplateForm,
|
|
|
|
|
|
'letter': LetterTemplateForm
|
2016-02-22 14:45:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-13 15:28:33 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<uuid:template_id>")
|
2016-04-12 09:55:51 +01:00
|
|
|
|
@login_required
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-04-12 09:55:51 +01:00
|
|
|
|
def view_template(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template(template_id)
|
2019-03-20 17:27:22 +00:00
|
|
|
|
template_folder = current_service.get_template_folder(template['folder'])
|
|
|
|
|
|
|
|
|
|
|
|
if not current_service.has_permission("edit_folder_permissions"):
|
|
|
|
|
|
user_has_template_permission = True
|
|
|
|
|
|
else:
|
|
|
|
|
|
user_has_template_permission = current_user.has_template_folder_permission(template_folder)
|
2019-03-19 16:25:44 +00:00
|
|
|
|
|
2018-08-09 16:29:51 +01:00
|
|
|
|
if should_skip_template_page(template['template_type']):
|
2018-06-12 16:17:20 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.send_one_off', service_id=service_id, template_id=template_id
|
|
|
|
|
|
))
|
2017-10-05 15:47:12 +01:00
|
|
|
|
if template["template_type"] == "letter":
|
|
|
|
|
|
letter_contact_details = service_api_client.get_letter_contacts(service_id)
|
|
|
|
|
|
default_letter_contact_block_id = next(
|
2017-12-12 12:16:17 +00:00
|
|
|
|
(x['id'] for x in letter_contact_details if x['is_default']), None
|
2017-10-18 14:51:26 +01:00
|
|
|
|
)
|
2017-10-05 15:47:12 +01:00
|
|
|
|
else:
|
|
|
|
|
|
default_letter_contact_block_id = None
|
2016-04-12 09:55:51 +01:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/template.html',
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template=get_template(
|
2017-04-20 10:40:15 +01:00
|
|
|
|
template,
|
2016-12-08 11:50:59 +00:00
|
|
|
|
current_service,
|
2016-12-20 14:38:34 +00:00
|
|
|
|
expand_emails=True,
|
2017-04-28 16:04:52 +01:00
|
|
|
|
letter_preview_url=url_for(
|
|
|
|
|
|
'.view_letter_template_preview',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
2017-03-10 17:39:38 +00:00
|
|
|
|
show_recipient=True,
|
2017-05-11 12:01:51 +01:00
|
|
|
|
page_count=get_page_count_for_letter(template),
|
2017-04-20 10:40:15 +01:00
|
|
|
|
),
|
2018-12-18 15:43:36 +00:00
|
|
|
|
template_postage=template["postage"],
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_permission=user_has_template_permission,
|
2017-10-16 16:35:35 +01:00
|
|
|
|
default_letter_contact_block_id=default_letter_contact_block_id,
|
2016-04-12 09:55:51 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-29 10:02:53 +01:00
|
|
|
|
@main.route("/services/<service_id>/start-tour/<uuid:template_id>")
|
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('view_activity')
|
2017-06-29 10:02:53 +01:00
|
|
|
|
def start_tour(service_id, template_id):
|
|
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template(template_id)
|
2017-06-29 10:02:53 +01:00
|
|
|
|
|
|
|
|
|
|
if template['template_type'] != 'sms':
|
|
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/start-tour.html',
|
|
|
|
|
|
template=get_template(
|
|
|
|
|
|
template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
show_recipient=True,
|
|
|
|
|
|
),
|
|
|
|
|
|
help='1',
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-08 14:46:18 +00:00
|
|
|
|
@main.route("/services/<service_id>/templates", methods=['GET', 'POST'])
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/folders/<template_folder_id>", methods=['GET', 'POST'])
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/<template_type>", methods=['GET', 'POST'])
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/<template_type>/folders/<template_folder_id>", methods=['GET', 'POST'])
|
2017-06-13 15:28:33 +01:00
|
|
|
|
@login_required
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2018-11-05 16:25:19 +00:00
|
|
|
|
def choose_template(service_id, template_type='all', template_folder_id=None):
|
2019-03-20 17:27:22 +00:00
|
|
|
|
template_folder = current_service.get_template_folder(template_folder_id)
|
|
|
|
|
|
|
|
|
|
|
|
if not current_service.has_permission("edit_folder_permissions"):
|
|
|
|
|
|
user_has_template_folder_permission = True
|
|
|
|
|
|
else:
|
|
|
|
|
|
user_has_template_folder_permission = current_user.has_template_folder_permission(template_folder)
|
2017-06-13 15:27:29 +01:00
|
|
|
|
|
2019-03-11 14:13:56 +00:00
|
|
|
|
template_list = TemplateList(current_service, template_type, template_folder_id, current_user)
|
2018-11-23 16:29:21 +00:00
|
|
|
|
|
2018-11-08 14:16:46 +00:00
|
|
|
|
templates_and_folders_form = TemplateAndFoldersSelectionForm(
|
2019-03-11 14:13:56 +00:00
|
|
|
|
all_template_folders=current_service.get_user_template_folders(current_user),
|
2018-11-23 16:29:21 +00:00
|
|
|
|
template_list=template_list,
|
2018-11-08 14:16:46 +00:00
|
|
|
|
template_type=template_type,
|
2018-11-28 13:48:13 +00:00
|
|
|
|
allow_adding_letter_template=current_service.has_permission('letter'),
|
|
|
|
|
|
allow_adding_copy_of_template=(
|
2019-02-20 14:54:16 +00:00
|
|
|
|
current_service.all_templates or len(current_user.services) > 1
|
2018-11-28 13:48:13 +00:00
|
|
|
|
),
|
2018-11-08 14:16:46 +00:00
|
|
|
|
)
|
2019-01-02 17:12:18 +00:00
|
|
|
|
option_hints = {template_folder_id: 'current folder'}
|
2018-12-18 14:40:53 +00:00
|
|
|
|
|
2018-11-20 18:03:57 +00:00
|
|
|
|
if request.method == 'POST' and templates_and_folders_form.validate_on_submit():
|
2019-02-11 16:06:46 +00:00
|
|
|
|
if not current_user.has_permissions('manage_templates'):
|
2018-11-20 18:03:57 +00:00
|
|
|
|
abort(403)
|
2018-12-05 11:30:47 +00:00
|
|
|
|
try:
|
|
|
|
|
|
return process_folder_management_form(templates_and_folders_form, template_folder_id)
|
2018-12-17 15:24:24 +00:00
|
|
|
|
except HTTPError as e:
|
2018-12-05 11:30:47 +00:00
|
|
|
|
flash(e.message)
|
2018-11-14 17:30:22 +00:00
|
|
|
|
|
2018-12-07 16:38:48 +00:00
|
|
|
|
if 'templates_and_folders' in templates_and_folders_form.errors:
|
|
|
|
|
|
flash('Select at least one template or folder')
|
|
|
|
|
|
|
2019-02-14 16:27:13 +00:00
|
|
|
|
initial_state = request.args.get('initial_state')
|
|
|
|
|
|
if request.method == 'GET' and initial_state:
|
|
|
|
|
|
templates_and_folders_form.op = initial_state
|
|
|
|
|
|
|
2017-06-13 15:28:33 +01:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/choose.html',
|
2018-11-06 13:06:35 +00:00
|
|
|
|
current_template_folder_id=template_folder_id,
|
2018-11-05 16:25:19 +00:00
|
|
|
|
template_folder_path=current_service.get_template_folder_path(template_folder_id),
|
2018-11-23 16:29:21 +00:00
|
|
|
|
template_list=template_list,
|
2018-11-20 12:18:18 +00:00
|
|
|
|
show_search_box=current_service.count_of_templates_and_folders > 7,
|
2018-10-25 07:59:50 +01:00
|
|
|
|
show_template_nav=(
|
|
|
|
|
|
current_service.has_multiple_template_types
|
2018-11-05 15:26:59 +00:00
|
|
|
|
and (len(current_service.all_templates) > 2)
|
2018-10-25 07:59:50 +01:00
|
|
|
|
),
|
2018-11-08 14:16:46 +00:00
|
|
|
|
template_nav_items=get_template_nav_items(template_folder_id),
|
2017-06-13 15:28:33 +01:00
|
|
|
|
template_type=template_type,
|
2019-02-06 17:32:13 +00:00
|
|
|
|
search_form=SearchByNameForm(),
|
2018-12-04 14:47:05 +00:00
|
|
|
|
templates_and_folders_form=templates_and_folders_form,
|
2019-01-02 17:12:18 +00:00
|
|
|
|
move_to_children=templates_and_folders_form.move_to.children(),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_folder_permission=user_has_template_folder_permission,
|
2019-01-02 17:12:18 +00:00
|
|
|
|
option_hints=option_hints
|
2017-06-13 15:28:33 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-15 17:31:07 +00:00
|
|
|
|
def process_folder_management_form(form, current_folder_id):
|
2019-03-20 17:26:51 +00:00
|
|
|
|
current_service.get_template_folder_with_user_permission_or_403(current_folder_id, current_user)
|
2018-11-15 17:31:07 +00:00
|
|
|
|
new_folder_id = None
|
2018-11-08 14:46:18 +00:00
|
|
|
|
|
2018-11-28 13:48:13 +00:00
|
|
|
|
if form.is_add_template_op:
|
|
|
|
|
|
return _add_template_by_type(
|
|
|
|
|
|
form.add_template_by_template_type.data,
|
|
|
|
|
|
current_folder_id,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if form.is_add_folder_op:
|
2018-11-15 17:31:07 +00:00
|
|
|
|
new_folder_id = template_folder_api_client.create_template_folder(
|
|
|
|
|
|
current_service.id,
|
2018-11-20 18:03:57 +00:00
|
|
|
|
name=form.get_folder_name(),
|
2018-11-15 17:31:07 +00:00
|
|
|
|
parent_id=current_folder_id
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if form.is_move_op:
|
|
|
|
|
|
# if we've just made a folder, we also want to move there
|
|
|
|
|
|
move_to_id = new_folder_id or form.move_to.data
|
|
|
|
|
|
|
|
|
|
|
|
current_service.move_to_folder(
|
|
|
|
|
|
ids_to_move=form.templates_and_folders.data,
|
|
|
|
|
|
move_to=move_to_id
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return redirect(request.url)
|
2018-11-08 14:46:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
2018-11-12 09:16:14 +00:00
|
|
|
|
def get_template_nav_label(value):
|
|
|
|
|
|
return {
|
|
|
|
|
|
'all': 'All',
|
|
|
|
|
|
'sms': 'Text message',
|
|
|
|
|
|
'email': 'Email',
|
|
|
|
|
|
'letter': 'Letter',
|
|
|
|
|
|
}[value]
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-08 14:16:46 +00:00
|
|
|
|
def get_template_nav_items(template_folder_id):
|
|
|
|
|
|
return [
|
|
|
|
|
|
(
|
2018-11-12 09:16:14 +00:00
|
|
|
|
get_template_nav_label(key),
|
2018-11-08 14:16:46 +00:00
|
|
|
|
key,
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
'.choose_template', service_id=current_service.id,
|
|
|
|
|
|
template_type=key, template_folder_id=template_folder_id
|
|
|
|
|
|
),
|
|
|
|
|
|
''
|
|
|
|
|
|
)
|
2018-11-12 09:16:14 +00:00
|
|
|
|
for key in ['all'] + current_service.available_template_types
|
2018-11-08 14:16:46 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-04-10 17:25:08 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>.<filetype>")
|
2016-11-27 18:10:18 +00:00
|
|
|
|
@login_required
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2017-04-10 18:12:00 +01:00
|
|
|
|
def view_letter_template_preview(service_id, template_id, filetype):
|
2017-04-12 12:12:11 +01:00
|
|
|
|
if filetype not in ('pdf', 'png'):
|
|
|
|
|
|
abort(404)
|
2016-11-27 18:10:18 +00:00
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template(template_id)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
2017-04-20 10:40:15 +01:00
|
|
|
|
return TemplatePreview.from_database_object(db_template, filetype, page=request.args.get('page'))
|
2016-11-28 11:01:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-02-15 14:47:39 +00:00
|
|
|
|
@main.route("/templates/letter-preview-image/<filename>")
|
|
|
|
|
|
@login_required
|
|
|
|
|
|
@user_is_platform_admin
|
|
|
|
|
|
def letter_branding_preview_image(filename):
|
|
|
|
|
|
template = {
|
|
|
|
|
|
'subject': 'An example letter',
|
|
|
|
|
|
'content': (
|
|
|
|
|
|
'Lorem Ipsum is simply dummy text of the printing and typesetting '
|
|
|
|
|
|
'industry.\n\nLorem Ipsum has been the industry’s standard dummy '
|
|
|
|
|
|
'text ever since the 1500s, when an unknown printer took a galley '
|
|
|
|
|
|
'of type and scrambled it to make a type specimen book.\n\n'
|
|
|
|
|
|
'# History\n\nIt has survived not only\n\n'
|
|
|
|
|
|
'* five centuries\n'
|
|
|
|
|
|
'* but also the leap into electronic typesetting\n\n'
|
|
|
|
|
|
'It was popularised in the 1960s with the release of Letraset '
|
|
|
|
|
|
'sheets containing Lorem Ipsum passages, and more recently with '
|
|
|
|
|
|
'desktop publishing software like Aldus PageMaker including '
|
|
|
|
|
|
'versions of Lorem Ipsum.\n\n'
|
|
|
|
|
|
'The point of using Lorem Ipsum is that it has a more-or-less '
|
|
|
|
|
|
'normal distribution of letters, as opposed to using ‘Content '
|
|
|
|
|
|
'here, content here’, making it look like readable English.'
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
filename = None if filename == 'no-branding' else filename
|
|
|
|
|
|
|
|
|
|
|
|
return TemplatePreview.from_example_template(template, filename)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-20 11:56:22 +00:00
|
|
|
|
def _view_template_version(service_id, template_id, version, letters_as_pdf=False):
|
|
|
|
|
|
return dict(template=get_template(
|
2019-03-19 16:25:44 +00:00
|
|
|
|
current_service.get_template(template_id, version=version),
|
2016-12-20 11:56:22 +00:00
|
|
|
|
current_service,
|
|
|
|
|
|
expand_emails=True,
|
2016-12-20 14:38:34 +00:00
|
|
|
|
letter_preview_url=url_for(
|
2017-04-28 16:04:52 +01:00
|
|
|
|
'.view_template_version_preview',
|
2016-12-20 14:38:34 +00:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
version=version,
|
2017-04-28 16:04:52 +01:00
|
|
|
|
filetype='png',
|
2016-12-20 14:38:34 +00:00
|
|
|
|
) if not letters_as_pdf else None
|
2016-12-20 11:56:22 +00:00
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-05-11 11:20:45 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>")
|
|
|
|
|
|
@login_required
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-05-11 11:20:45 +01:00
|
|
|
|
def view_template_version(service_id, template_id, version):
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/template_history.html',
|
2016-12-20 11:56:22 +00:00
|
|
|
|
**_view_template_version(service_id=service_id, template_id=template_id, version=version)
|
2016-05-11 11:20:45 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-04-10 17:25:08 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>.<filetype>")
|
2016-12-20 14:38:34 +00:00
|
|
|
|
@login_required
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2017-04-10 17:25:08 +01:00
|
|
|
|
def view_template_version_preview(service_id, template_id, version, filetype):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template(template_id, version=version)
|
2017-04-10 17:25:08 +01:00
|
|
|
|
return TemplatePreview.from_database_object(db_template, filetype)
|
2016-12-20 14:38:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
2018-11-28 13:48:13 +00:00
|
|
|
|
def _add_template_by_type(template_type, template_folder_id):
|
|
|
|
|
|
|
|
|
|
|
|
if template_type == 'copy-existing':
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.choose_template_to_copy',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
if template_type == 'letter':
|
|
|
|
|
|
blank_letter = service_api_client.create_service_template(
|
2019-02-21 10:51:01 +00:00
|
|
|
|
'New letter template',
|
2018-11-28 13:48:13 +00:00
|
|
|
|
'letter',
|
|
|
|
|
|
'Body',
|
|
|
|
|
|
current_service.id,
|
|
|
|
|
|
'Main heading',
|
|
|
|
|
|
'normal',
|
|
|
|
|
|
template_folder_id
|
|
|
|
|
|
)
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.view_template',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
template_id=blank_letter['data']['id'],
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
if email_or_sms_not_enabled(template_type, current_service.permissions):
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.action_blocked',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
notification_type=template_type,
|
|
|
|
|
|
return_to='add_new_template',
|
|
|
|
|
|
template_id='0'
|
|
|
|
|
|
))
|
|
|
|
|
|
else:
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.add_service_template',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
template_type=template_type,
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-07-19 12:30:04 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/copy")
|
2019-01-07 14:49:33 +00:00
|
|
|
|
@main.route("/services/<service_id>/templates/copy/from-folder/<uuid:from_folder>")
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/copy/from-service/<uuid:from_service>")
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/copy/from-service/<uuid:from_service>/from-folder/<uuid:from_folder>")
|
2018-07-19 12:30:04 +01:00
|
|
|
|
@login_required
|
|
|
|
|
|
@user_has_permissions('manage_templates')
|
2019-01-07 14:49:33 +00:00
|
|
|
|
def choose_template_to_copy(
|
|
|
|
|
|
service_id,
|
|
|
|
|
|
from_service=None,
|
|
|
|
|
|
from_folder=None,
|
|
|
|
|
|
):
|
|
|
|
|
|
|
|
|
|
|
|
if from_service:
|
|
|
|
|
|
|
|
|
|
|
|
current_user.belongs_to_service_or_403(from_service)
|
|
|
|
|
|
service = Service(
|
|
|
|
|
|
service_api_client.get_service(from_service)['data']
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/copy.html',
|
|
|
|
|
|
services_templates_and_folders=TemplateList(
|
|
|
|
|
|
service,
|
|
|
|
|
|
template_folder_id=from_folder,
|
2019-03-11 14:13:56 +00:00
|
|
|
|
user=current_user
|
2019-01-07 14:49:33 +00:00
|
|
|
|
),
|
|
|
|
|
|
template_folder_path=service.get_template_folder_path(from_folder),
|
|
|
|
|
|
from_service=service,
|
2019-02-06 17:32:13 +00:00
|
|
|
|
search_form=SearchByNameForm(),
|
2019-01-07 14:49:33 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/copy.html',
|
|
|
|
|
|
services_templates_and_folders=TemplateLists([
|
|
|
|
|
|
Service(service) for service in
|
|
|
|
|
|
user_api_client.get_services_for_user(current_user)
|
2019-03-11 14:13:56 +00:00
|
|
|
|
], user=current_user),
|
2019-02-06 17:32:13 +00:00
|
|
|
|
search_form=SearchByNameForm(),
|
2019-01-07 14:49:33 +00:00
|
|
|
|
)
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/copy/<uuid:template_id>", methods=['GET', 'POST'])
|
|
|
|
|
|
@login_required
|
|
|
|
|
|
@user_has_permissions('manage_templates')
|
|
|
|
|
|
def copy_template(service_id, template_id):
|
2019-04-03 13:59:44 +01:00
|
|
|
|
from_service = request.args.get('from_service')
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
2019-04-03 13:59:44 +01:00
|
|
|
|
current_user.belongs_to_service_or_403(from_service)
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
2019-04-03 13:59:44 +01:00
|
|
|
|
template = service_api_client.get_service_template(from_service, str(template_id))['data']
|
2018-07-31 16:20:10 +01:00
|
|
|
|
|
2019-04-03 13:59:44 +01:00
|
|
|
|
template_folder = template_folder_api_client.get_template_folder(from_service, template['folder'])
|
2019-03-20 16:41:01 +00:00
|
|
|
|
if (
|
|
|
|
|
|
current_service.has_permission('edit_folder_permissions') and
|
|
|
|
|
|
not current_user.has_template_folder_permission(template_folder)
|
|
|
|
|
|
):
|
|
|
|
|
|
abort(403)
|
|
|
|
|
|
|
2018-07-31 16:20:10 +01:00
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
|
return add_service_template(service_id, template['template_type'])
|
|
|
|
|
|
|
2018-07-19 12:30:04 +01:00
|
|
|
|
template['template_content'] = template['content']
|
2018-11-13 15:06:39 +00:00
|
|
|
|
template['name'] = _get_template_copy_name(template, current_service.all_templates)
|
2018-07-19 12:30:04 +01:00
|
|
|
|
form = form_objects[template['template_type']](**template)
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/edit-{}-template.html'.format(template['template_type']),
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
template_type=template['template_type'],
|
|
|
|
|
|
heading_action='Add',
|
|
|
|
|
|
services=user_api_client.get_service_ids_for_user(current_user),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-13 15:06:39 +00:00
|
|
|
|
def _get_template_copy_name(template, existing_templates):
|
|
|
|
|
|
|
|
|
|
|
|
template_names = [existing['name'] for existing in existing_templates]
|
|
|
|
|
|
|
|
|
|
|
|
for index in reversed(range(1, 10)):
|
|
|
|
|
|
if '{} (copy {})'.format(template['name'], index) in template_names:
|
|
|
|
|
|
return '{} (copy {})'.format(template['name'], index + 1)
|
|
|
|
|
|
|
|
|
|
|
|
if '{} (copy)'.format(template['name']) in template_names:
|
|
|
|
|
|
return '{} (copy 2)'.format(template['name'])
|
|
|
|
|
|
|
|
|
|
|
|
return '{} (copy)'.format(template['name'])
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-30 10:55:59 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/action-blocked/<notification_type>/<return_to>/<template_id>")
|
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2017-06-30 10:55:59 +01:00
|
|
|
|
def action_blocked(service_id, notification_type, return_to, template_id):
|
|
|
|
|
|
if notification_type == 'sms':
|
|
|
|
|
|
notification_type = 'text messages'
|
|
|
|
|
|
elif notification_type == 'email':
|
|
|
|
|
|
notification_type = 'emails'
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/action_blocked.html',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=notification_type,
|
|
|
|
|
|
return_to=return_to,
|
|
|
|
|
|
template_id=template_id
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-12 16:37:37 +00:00
|
|
|
|
@main.route("/services/<service_id>/templates/folders/<template_folder_id>/manage", methods=['GET', 'POST'])
|
2018-11-13 17:56:47 +00:00
|
|
|
|
@login_required
|
|
|
|
|
|
@user_has_permissions('manage_templates')
|
2018-11-12 16:37:37 +00:00
|
|
|
|
def manage_template_folder(service_id, template_folder_id):
|
2019-03-20 17:26:51 +00:00
|
|
|
|
template_folder = current_service.get_template_folder_with_user_permission_or_403(template_folder_id, current_user)
|
2018-11-13 16:05:05 +00:00
|
|
|
|
form = TemplateFolderForm(
|
2019-03-20 17:26:51 +00:00
|
|
|
|
name=template_folder['name'],
|
|
|
|
|
|
users_with_permission=template_folder.get('users_with_permission', None),
|
2019-03-18 16:12:12 +00:00
|
|
|
|
all_service_users=[user for user in current_service.active_users if user.id != current_user.id]
|
2018-11-13 16:05:05 +00:00
|
|
|
|
)
|
2018-11-12 16:37:37 +00:00
|
|
|
|
if form.validate_on_submit():
|
2019-04-02 12:26:41 +01:00
|
|
|
|
if current_user.has_permissions("manage_service") and form.users_with_permission.all_service_users:
|
|
|
|
|
|
users_with_permission = form.users_with_permission.data + [current_user.id]
|
|
|
|
|
|
else:
|
|
|
|
|
|
users_with_permission = None
|
2018-11-12 16:37:37 +00:00
|
|
|
|
template_folder_api_client.update_template_folder(
|
2019-03-15 17:19:18 +00:00
|
|
|
|
current_service.id,
|
|
|
|
|
|
template_folder_id,
|
|
|
|
|
|
name=form.name.data,
|
2019-03-18 16:12:12 +00:00
|
|
|
|
users_with_permission=users_with_permission
|
2018-11-12 16:37:37 +00:00
|
|
|
|
)
|
|
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for('.choose_template', service_id=service_id, template_folder_id=template_folder_id)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/manage-template-folder.html',
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
template_folder_path=current_service.get_template_folder_path(template_folder_id),
|
2018-11-13 15:49:25 +00:00
|
|
|
|
current_service_id=current_service.id,
|
2018-11-16 11:21:27 +00:00
|
|
|
|
template_folder_id=template_folder_id,
|
2019-03-15 14:13:27 +00:00
|
|
|
|
template_type="all",
|
2018-11-12 16:37:37 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-13 17:56:47 +00:00
|
|
|
|
@main.route("/services/<service_id>/templates/folders/<template_folder_id>/delete", methods=['GET', 'POST'])
|
|
|
|
|
|
@login_required
|
|
|
|
|
|
@user_has_permissions('manage_templates')
|
2018-11-13 15:49:25 +00:00
|
|
|
|
def delete_template_folder(service_id, template_folder_id):
|
2019-03-20 17:26:51 +00:00
|
|
|
|
template_folder = current_service.get_template_folder_with_user_permission_or_403(template_folder_id, current_user)
|
2018-11-20 10:43:56 +00:00
|
|
|
|
|
2018-11-14 15:57:23 +00:00
|
|
|
|
if len(current_service.get_template_folders_and_templates(
|
|
|
|
|
|
template_type="all", template_folder_id=template_folder_id
|
|
|
|
|
|
)) > 0:
|
2019-03-20 17:04:44 +00:00
|
|
|
|
flash("You must empty this folder before you can delete it", 'info')
|
2018-11-14 17:07:23 +00:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
'.choose_template', service_id=service_id, template_type="all", template_folder_id=template_folder_id
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-14 15:57:23 +00:00
|
|
|
|
|
2018-11-14 12:16:57 +00:00
|
|
|
|
if request.method == 'POST':
|
2019-03-20 17:04:44 +00:00
|
|
|
|
|
2018-11-14 12:16:57 +00:00
|
|
|
|
try:
|
|
|
|
|
|
template_folder_api_client.delete_template_folder(current_service.id, template_folder_id)
|
2018-11-13 17:56:47 +00:00
|
|
|
|
|
2018-11-14 12:16:57 +00:00
|
|
|
|
return redirect(
|
2018-11-20 10:44:09 +00:00
|
|
|
|
url_for('.choose_template', service_id=service_id, template_folder_id=template_folder['parent_id'])
|
2018-11-14 12:16:57 +00:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
msg = "Folder is not empty"
|
|
|
|
|
|
if e.status_code == 400 and msg in e.message:
|
2018-11-20 10:43:56 +00:00
|
|
|
|
flash("You must empty this folder before you can delete it", 'info')
|
2018-11-14 17:07:23 +00:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
'.choose_template',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_type="all",
|
|
|
|
|
|
template_folder_id=template_folder_id
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-14 12:16:57 +00:00
|
|
|
|
else:
|
|
|
|
|
|
abort(500, e)
|
2019-03-20 17:04:44 +00:00
|
|
|
|
else:
|
|
|
|
|
|
flash("Are you sure you want to delete the ‘{}’ folder?".format(template_folder['name']), 'delete')
|
|
|
|
|
|
return manage_template_folder(service_id, template_folder_id)
|
2018-11-13 15:49:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
@main.route("/services/<service_id>/templates/add-<template_type>", methods=['GET', 'POST'])
|
2018-11-06 13:06:35 +00:00
|
|
|
|
@main.route("/services/<service_id>/templates/folders/<template_folder_id>/add-<template_type>",
|
|
|
|
|
|
methods=['GET', 'POST'])
|
2016-01-11 16:03:41 +00:00
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2018-11-06 13:06:35 +00:00
|
|
|
|
def add_service_template(service_id, template_type, template_folder_id=None):
|
2017-01-18 15:11:34 +00:00
|
|
|
|
|
2016-11-08 13:12:07 +00:00
|
|
|
|
if template_type not in ['sms', 'email', 'letter']:
|
2016-02-22 14:45:13 +00:00
|
|
|
|
abort(404)
|
2018-07-20 08:42:01 +01:00
|
|
|
|
if not current_service.has_permission('letter') and template_type == 'letter':
|
2016-11-08 13:12:07 +00:00
|
|
|
|
abort(403)
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
form = form_objects[template_type]()
|
2016-01-19 15:54:12 +00:00
|
|
|
|
if form.validate_on_submit():
|
2017-01-18 15:11:34 +00:00
|
|
|
|
if form.process_type.data == 'priority':
|
|
|
|
|
|
abort_403_if_not_admin_user()
|
2016-04-29 09:38:59 +01:00
|
|
|
|
try:
|
2017-03-14 13:39:21 +00:00
|
|
|
|
new_template = service_api_client.create_service_template(
|
2016-04-29 09:38:59 +01:00
|
|
|
|
form.name.data,
|
|
|
|
|
|
template_type,
|
|
|
|
|
|
form.template_content.data,
|
|
|
|
|
|
service_id,
|
2017-01-18 15:11:34 +00:00
|
|
|
|
form.subject.data if hasattr(form, 'subject') else None,
|
2018-11-08 15:53:33 +00:00
|
|
|
|
form.process_type.data,
|
|
|
|
|
|
template_folder_id
|
2016-04-29 09:38:59 +01:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as e:
|
2017-02-15 15:06:47 +00:00
|
|
|
|
if (
|
2019-01-29 15:43:59 +00:00
|
|
|
|
e.status_code == 400
|
|
|
|
|
|
and 'content' in e.message
|
|
|
|
|
|
and any(['character count greater than' in x for x in e.message['content']])
|
2017-02-15 15:06:47 +00:00
|
|
|
|
):
|
|
|
|
|
|
form.template_content.errors.extend(e.message['content'])
|
2016-04-29 09:38:59 +01:00
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
|
|
|
|
|
else:
|
|
|
|
|
|
return redirect(
|
2017-03-14 13:39:21 +00:00
|
|
|
|
url_for('.view_template', service_id=service_id, template_id=new_template['data']['id'])
|
2016-04-29 09:38:59 +01:00
|
|
|
|
)
|
2017-07-04 17:25:35 +01:00
|
|
|
|
|
2018-07-20 08:42:01 +01:00
|
|
|
|
if email_or_sms_not_enabled(template_type, current_service.permissions):
|
2017-06-30 10:55:59 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.action_blocked',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=template_type,
|
|
|
|
|
|
return_to='templates',
|
|
|
|
|
|
template_id='0'
|
|
|
|
|
|
))
|
|
|
|
|
|
else:
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/edit-{}-template.html'.format(template_type),
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
template_type=template_type,
|
2019-02-21 12:02:21 +00:00
|
|
|
|
heading_action='New',
|
2017-06-30 10:55:59 +01:00
|
|
|
|
)
|
2016-01-13 13:24:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-18 15:11:34 +00:00
|
|
|
|
def abort_403_if_not_admin_user():
|
2018-02-27 16:45:20 +00:00
|
|
|
|
if not current_user.platform_admin:
|
2017-01-18 15:11:34 +00:00
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-04-12 09:55:51 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/edit", methods=['GET', 'POST'])
|
2016-01-13 13:24:06 +00:00
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2016-01-19 15:54:12 +00:00
|
|
|
|
def edit_service_template(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2016-01-22 12:15:47 +00:00
|
|
|
|
template['template_content'] = template['content']
|
2016-02-22 14:45:13 +00:00
|
|
|
|
form = form_objects[template['template_type']](**template)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
if form.validate_on_submit():
|
2017-01-18 15:11:34 +00:00
|
|
|
|
if form.process_type.data != template['process_type']:
|
|
|
|
|
|
abort_403_if_not_admin_user()
|
|
|
|
|
|
|
2017-04-14 08:52:02 +01:00
|
|
|
|
subject = form.subject.data if hasattr(form, 'subject') else None
|
2018-12-18 18:22:03 +00:00
|
|
|
|
|
|
|
|
|
|
new_template_data = {
|
2016-05-27 16:21:29 +01:00
|
|
|
|
'name': form.name.data,
|
|
|
|
|
|
'content': form.template_content.data,
|
|
|
|
|
|
'subject': subject,
|
|
|
|
|
|
'template_type': template['template_type'],
|
2017-01-18 15:11:34 +00:00
|
|
|
|
'id': template['id'],
|
2018-01-03 10:44:36 +00:00
|
|
|
|
'process_type': form.process_type.data,
|
2018-12-18 18:22:03 +00:00
|
|
|
|
'reply_to_text': template['reply_to_text'],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
new_template = get_template(new_template_data, current_service)
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template_change = get_template(template, current_service).compare_to(new_template)
|
2017-05-17 13:05:18 +01:00
|
|
|
|
if template_change.placeholders_added and not request.form.get('confirm'):
|
2017-04-06 10:22:09 +01:00
|
|
|
|
example_column_headings = (
|
2019-01-29 15:43:59 +00:00
|
|
|
|
first_column_headings[new_template.template_type] + list(new_template.placeholders)
|
2017-04-06 10:22:09 +01:00
|
|
|
|
)
|
2016-05-27 16:21:29 +01:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/breaking-change.html',
|
|
|
|
|
|
template_change=template_change,
|
2017-03-06 13:08:27 +00:00
|
|
|
|
new_template=new_template,
|
2017-04-06 10:22:09 +01:00
|
|
|
|
column_headings=list(ascii_uppercase[:len(example_column_headings)]),
|
2016-05-27 16:21:29 +01:00
|
|
|
|
example_rows=[
|
2017-04-06 10:22:09 +01:00
|
|
|
|
example_column_headings,
|
2016-05-27 16:21:29 +01:00
|
|
|
|
get_example_csv_rows(new_template),
|
|
|
|
|
|
get_example_csv_rows(new_template)
|
|
|
|
|
|
],
|
|
|
|
|
|
form=form
|
|
|
|
|
|
)
|
2016-04-29 09:38:59 +01:00
|
|
|
|
try:
|
|
|
|
|
|
service_api_client.update_service_template(
|
|
|
|
|
|
template_id,
|
|
|
|
|
|
form.name.data,
|
|
|
|
|
|
template['template_type'],
|
|
|
|
|
|
form.template_content.data,
|
|
|
|
|
|
service_id,
|
2017-01-18 15:11:34 +00:00
|
|
|
|
subject,
|
2018-12-18 18:22:03 +00:00
|
|
|
|
form.process_type.data,
|
2016-04-29 09:38:59 +01:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
if e.status_code == 400:
|
|
|
|
|
|
if 'content' in e.message and any(['character count greater than' in x for x in e.message['content']]):
|
|
|
|
|
|
form.template_content.errors.extend(e.message['content'])
|
|
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
|
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
|
|
|
|
|
else:
|
|
|
|
|
|
return redirect(url_for(
|
2016-06-06 10:12:21 +01:00
|
|
|
|
'.view_template',
|
2016-04-29 09:38:59 +01:00
|
|
|
|
service_id=service_id,
|
2016-06-06 10:12:21 +01:00
|
|
|
|
template_id=template_id
|
2016-04-29 09:38:59 +01:00
|
|
|
|
))
|
2017-06-30 10:55:59 +01:00
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
if email_or_sms_not_enabled(template['template_type'], current_service.permissions):
|
2017-06-30 10:55:59 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.action_blocked',
|
|
|
|
|
|
service_id=service_id,
|
2019-03-19 16:25:44 +00:00
|
|
|
|
notification_type=template['template_type'],
|
2017-06-30 10:55:59 +01:00
|
|
|
|
return_to='view_template',
|
|
|
|
|
|
template_id=template_id
|
|
|
|
|
|
))
|
|
|
|
|
|
else:
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/edit-{}-template.html'.format(template['template_type']),
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
template_type=template['template_type'],
|
2018-07-31 16:20:10 +01:00
|
|
|
|
heading_action='Edit',
|
2017-06-30 10:55:59 +01:00
|
|
|
|
)
|
2016-01-14 09:44:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-04-12 14:19:51 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/delete", methods=['GET', 'POST'])
|
2016-01-14 09:44:06 +00:00
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2016-01-19 15:54:12 +00:00
|
|
|
|
def delete_service_template(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
|
2016-01-22 11:36:49 +00:00
|
|
|
|
if request.method == 'POST':
|
2016-03-30 10:23:39 +01:00
|
|
|
|
service_api_client.delete_service_template(service_id, template_id)
|
2016-02-22 14:45:13 +00:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.choose_template',
|
|
|
|
|
|
service_id=service_id,
|
2019-02-13 17:46:35 +00:00
|
|
|
|
template_folder_id=template['folder'],
|
2016-02-22 14:45:13 +00:00
|
|
|
|
))
|
2016-01-19 15:54:12 +00:00
|
|
|
|
|
2016-08-22 16:25:35 +01:00
|
|
|
|
try:
|
|
|
|
|
|
last_used_notification = template_statistics_client.get_template_statistics_for_template(
|
|
|
|
|
|
service_id, template['id']
|
|
|
|
|
|
)
|
2018-11-16 11:03:16 +00:00
|
|
|
|
message = 'This template was last used {} ago.'.format(
|
2017-07-26 12:04:07 +01:00
|
|
|
|
'more than seven days' if not last_used_notification else get_human_readable_delta(
|
2016-08-22 16:25:35 +01:00
|
|
|
|
parse(last_used_notification['created_at']).replace(tzinfo=None),
|
2017-07-24 14:50:56 +01:00
|
|
|
|
datetime.utcnow()
|
|
|
|
|
|
)
|
2016-08-22 16:25:35 +01:00
|
|
|
|
)
|
2017-07-26 12:04:07 +01:00
|
|
|
|
|
2016-08-22 16:25:35 +01:00
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
if e.status_code == 404:
|
2017-07-24 14:55:39 +01:00
|
|
|
|
message = None
|
2016-08-24 11:26:34 +01:00
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
2016-08-22 16:25:35 +01:00
|
|
|
|
|
2018-11-15 17:14:03 +00:00
|
|
|
|
flash(["Are you sure you want to delete ‘{}’?".format(template['name']), message], 'delete')
|
2016-01-19 15:54:12 +00:00
|
|
|
|
return render_template(
|
2017-04-18 13:01:58 +01:00
|
|
|
|
'views/templates/template.html',
|
|
|
|
|
|
template=get_template(
|
|
|
|
|
|
template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
expand_emails=True,
|
2017-04-28 16:04:52 +01:00
|
|
|
|
letter_preview_url=url_for(
|
|
|
|
|
|
'.view_letter_template_preview',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template['id'],
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
2017-04-18 13:01:58 +01:00
|
|
|
|
show_recipient=True,
|
2017-10-16 16:35:35 +01:00
|
|
|
|
),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_permission=True,
|
2017-04-18 13:01:58 +01:00
|
|
|
|
)
|
2016-05-11 11:20:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-06-27 14:35:37 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/redact", methods=['GET'])
|
2017-06-26 14:41:00 +01:00
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2017-06-27 14:35:37 +01:00
|
|
|
|
def confirm_redact_template(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2017-10-16 16:35:35 +01:00
|
|
|
|
|
2017-06-26 14:41:00 +01:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/template.html',
|
|
|
|
|
|
template=get_template(
|
2017-10-16 16:35:35 +01:00
|
|
|
|
template,
|
2017-06-26 14:41:00 +01:00
|
|
|
|
current_service,
|
|
|
|
|
|
expand_emails=True,
|
|
|
|
|
|
letter_preview_url=url_for(
|
|
|
|
|
|
'.view_letter_template_preview',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
|
|
|
|
|
show_recipient=True,
|
|
|
|
|
|
),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_permission=True,
|
2017-06-26 14:41:00 +01:00
|
|
|
|
show_redaction_message=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-27 14:35:37 +01:00
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/redact", methods=['POST'])
|
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2017-06-27 14:35:37 +01:00
|
|
|
|
def redact_template(service_id, template_id):
|
|
|
|
|
|
|
|
|
|
|
|
service_api_client.redact_service_template(service_id, template_id)
|
|
|
|
|
|
|
|
|
|
|
|
flash(
|
|
|
|
|
|
'Personalised content will be hidden for messages sent with this template',
|
|
|
|
|
|
'default_with_tick'
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.view_template',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-05-11 11:20:45 +01:00
|
|
|
|
@main.route('/services/<service_id>/templates/<template_id>/versions')
|
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('view_activity')
|
2016-05-11 11:20:45 +01:00
|
|
|
|
def view_template_versions(service_id, template_id):
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/choose_history.html',
|
2016-12-08 11:50:59 +00:00
|
|
|
|
versions=[
|
2016-12-20 14:38:34 +00:00
|
|
|
|
get_template(
|
|
|
|
|
|
template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
expand_emails=True,
|
|
|
|
|
|
letter_preview_url=url_for(
|
2017-04-28 16:04:52 +01:00
|
|
|
|
'.view_template_version_preview',
|
2016-12-20 14:38:34 +00:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
version=template['version'],
|
2017-04-28 16:04:52 +01:00
|
|
|
|
filetype='png',
|
2016-12-20 14:38:34 +00:00
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-12-08 11:50:59 +00:00
|
|
|
|
for template in service_api_client.get_service_template_versions(service_id, template_id)['data']
|
|
|
|
|
|
]
|
2016-05-11 11:20:45 +01:00
|
|
|
|
)
|
2016-06-06 11:09:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-01-03 10:44:36 +00:00
|
|
|
|
@main.route('/services/<service_id>/templates/<template_id>/set-template-sender', methods=['GET', 'POST'])
|
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
|
@user_has_permissions('manage_templates')
|
2018-01-03 10:44:36 +00:00
|
|
|
|
def set_template_sender(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
sender_details = get_template_sender_form_dict(service_id, template)
|
|
|
|
|
|
no_senders = sender_details.get('no_senders', False)
|
|
|
|
|
|
|
|
|
|
|
|
form = SetTemplateSenderForm(
|
|
|
|
|
|
sender=sender_details['current_choice'],
|
|
|
|
|
|
sender_choices=sender_details['value_and_label'],
|
|
|
|
|
|
)
|
|
|
|
|
|
option_hints = {sender_details['default_sender']: '(Default)'}
|
|
|
|
|
|
|
|
|
|
|
|
if form.validate_on_submit():
|
|
|
|
|
|
service_api_client.update_service_template_sender(
|
|
|
|
|
|
service_id,
|
|
|
|
|
|
template_id,
|
|
|
|
|
|
form.sender.data if form.sender.data else None,
|
|
|
|
|
|
)
|
|
|
|
|
|
return redirect(url_for('.view_template', service_id=service_id, template_id=template_id))
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/set-template-sender.html',
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
no_senders=no_senders,
|
|
|
|
|
|
option_hints=option_hints
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-29 15:43:59 +00:00
|
|
|
|
@main.route('/services/<service_id>/templates/<template_id>/edit-postage', methods=['GET', 'POST'])
|
|
|
|
|
|
@login_required
|
|
|
|
|
|
@user_has_permissions('manage_templates')
|
|
|
|
|
|
def edit_template_postage(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2019-02-04 16:55:00 +00:00
|
|
|
|
if template["template_type"] != "letter":
|
2019-01-29 15:43:59 +00:00
|
|
|
|
abort(404)
|
|
|
|
|
|
form = LetterTemplatePostageForm(**template)
|
|
|
|
|
|
if form.validate_on_submit():
|
|
|
|
|
|
postage = form.postage.data
|
|
|
|
|
|
service_api_client.update_service_template_postage(service_id, template_id, postage)
|
|
|
|
|
|
|
|
|
|
|
|
return redirect(url_for('.view_template', service_id=service_id, template_id=template_id))
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/edit-template-postage.html',
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
template_postage=template["postage"]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-01-03 10:44:36 +00:00
|
|
|
|
def get_template_sender_form_dict(service_id, template):
|
|
|
|
|
|
context = {
|
|
|
|
|
|
'email': {
|
|
|
|
|
|
'field_name': 'email_address'
|
|
|
|
|
|
},
|
|
|
|
|
|
'letter': {
|
|
|
|
|
|
'field_name': 'contact_block'
|
|
|
|
|
|
},
|
|
|
|
|
|
'sms': {
|
|
|
|
|
|
'field_name': 'sms_sender'
|
|
|
|
|
|
}
|
|
|
|
|
|
}[template['template_type']]
|
|
|
|
|
|
|
|
|
|
|
|
sender_format = context['field_name']
|
|
|
|
|
|
service_senders = get_sender_details(service_id, template['template_type'])
|
|
|
|
|
|
context['default_sender'] = next(
|
|
|
|
|
|
(x['id'] for x in service_senders if x['is_default']), "Not set"
|
|
|
|
|
|
)
|
|
|
|
|
|
if not service_senders:
|
|
|
|
|
|
context['no_senders'] = True
|
|
|
|
|
|
|
|
|
|
|
|
context['value_and_label'] = [(sender['id'], Markup(nl2br(sender[sender_format]))) for sender in service_senders]
|
|
|
|
|
|
context['value_and_label'].insert(0, ('', 'Blank')) # Add blank option to start of list
|
|
|
|
|
|
|
|
|
|
|
|
context['current_choice'] = template['service_letter_contact'] if template['service_letter_contact'] else ''
|
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-06-06 11:09:46 +01:00
|
|
|
|
def get_human_readable_delta(from_time, until_time):
|
|
|
|
|
|
delta = until_time - from_time
|
|
|
|
|
|
if delta < timedelta(seconds=60):
|
|
|
|
|
|
return 'under a minute'
|
|
|
|
|
|
elif delta < timedelta(hours=1):
|
|
|
|
|
|
minutes = int(delta.seconds / 60)
|
2016-06-06 11:42:40 +01:00
|
|
|
|
return '{} minute{}'.format(minutes, '' if minutes == 1 else 's')
|
2016-06-06 11:09:46 +01:00
|
|
|
|
elif delta < timedelta(days=1):
|
|
|
|
|
|
hours = int(delta.seconds / 3600)
|
2016-06-06 11:42:40 +01:00
|
|
|
|
return '{} hour{}'.format(hours, '' if hours == 1 else 's')
|
2016-06-06 11:09:46 +01:00
|
|
|
|
else:
|
|
|
|
|
|
days = delta.days
|
2016-06-06 11:42:40 +01:00
|
|
|
|
return '{} day{}'.format(days, '' if days == 1 else 's')
|