from datetime import datetime, timedelta
from string import ascii_uppercase

from dateutil.parser import parse
from flask import abort, flash, jsonify, redirect, render_template, request, url_for
from flask_babel import _
from flask_babel import lazy_gettext as _l
from flask_login import current_user
from markupsafe import Markup
from notifications_python_client.errors import HTTPError
from notifications_utils.formatters import nl2br
from notifications_utils.recipients import first_column_headings

from app import (
    current_service,
    service_api_client,
    template_api_prefill_client,
    template_folder_api_client,
    template_statistics_client,
)
from app.main import main
from app.main.forms import (
    CreateTemplateForm,
    EmailTemplateForm,
    LetterTemplateForm,
    LetterTemplatePostageForm,
    SearchByNameForm,
    SetTemplateSenderForm,
    SMSTemplateForm,
    TemplateAndFoldersSelectionForm,
    TemplateFolderForm,
)
from app.main.views.send import get_example_csv_rows, get_sender_details
from app.models.service import Service
from app.models.template_list import TemplateList, TemplateLists
from app.template_previews import TemplatePreview, get_page_count_for_letter
from app.utils import (
    email_or_sms_not_enabled,
    get_template,
    should_skip_template_page,
    user_has_permissions,
    user_is_platform_admin,
)

form_objects = {
    "email": EmailTemplateForm,
    "sms": SMSTemplateForm,
    "letter": LetterTemplateForm,
}


def get_email_preview_template(template, template_id, service_id):
    email_preview_template = get_template(
        template,
        current_service,
        letter_preview_url=url_for(
            ".view_letter_template_preview",
            service_id=service_id,
            template_id=template_id,
            filetype="png",
        ),
        show_recipient=True,
        page_count=get_page_count_for_letter(template),
    )

    return email_preview_template


@main.route("/services/<service_id>/templates/<uuid:template_id>")
@user_has_permissions()
def view_template(service_id, template_id):
    template = current_service.get_template(template_id)
    template_folder = current_service.get_template_folder(template["folder"])

    user_has_template_permission = current_user.has_template_folder_permission(template_folder)

    if should_skip_template_page(template["template_type"]):
        return redirect(url_for(".send_one_off", service_id=service_id, template_id=template_id))

    return render_template(
        "views/templates/template.html",
        template=get_email_preview_template(template, template_id, service_id),
        template_postage=template["postage"],
        user_has_template_permission=user_has_template_permission,
    )


@main.route("/services/<service_id>/start-tour/<uuid:template_id>")
@user_has_permissions("view_activity")
def start_tour(service_id, template_id):

    template = current_service.get_template(template_id)

    if template["template_type"] != "email":
        abort(404)

    return render_template(
        "views/templates/start-tour.html",
        template=get_template(
            template,
            current_service,
            show_recipient=True,
        ),
        help="1",
    )


@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"],
)
@user_has_permissions()
def choose_template(service_id, template_type="all", template_folder_id=None):
    template_folder = current_service.get_template_folder(template_folder_id)

    user_has_template_folder_permission = current_user.has_template_folder_permission(template_folder)

    template_list = TemplateList(current_service, template_type, template_folder_id, current_user)

    templates_and_folders_form = TemplateAndFoldersSelectionForm(
        all_template_folders=current_service.get_user_template_folders(current_user),
        template_list=template_list,
        template_type=template_type,
        allow_adding_letter_template=current_service.has_permission("letter"),
        allow_adding_copy_of_template=(current_service.all_templates or len(current_user.service_ids) > 1),
    )
    option_hints = {template_folder_id: "current folder"}

    if request.method == "POST" and templates_and_folders_form.validate_on_submit():
        if not current_user.has_permissions("manage_templates"):
            abort(403)
        try:
            return process_folder_management_form(templates_and_folders_form, template_folder_id)
        except HTTPError as e:
            flash(e.message)

    if "templates_and_folders" in templates_and_folders_form.errors:
        flash(_("Select at least one template or folder"))

    initial_state = request.args.get("initial_state")
    if request.method == "GET" and initial_state:
        templates_and_folders_form.op = initial_state

    sending_view = request.args.get("view") == "sending"

    return render_template(
        "views/templates/choose.html",
        current_template_folder_id=template_folder_id,
        template_folder_path=current_service.get_template_folder_path(template_folder_id),
        template_list=template_list,
        show_search_box=current_service.count_of_templates_and_folders > 7,
        show_template_nav=(current_service.has_multiple_template_types and (len(current_service.all_templates) > 2)),
        sending_view=sending_view,
        template_nav_items=get_template_nav_items(template_folder_id, sending_view),
        template_type=template_type,
        search_form=SearchByNameForm(),
        templates_and_folders_form=templates_and_folders_form,
        move_to_children=templates_and_folders_form.move_to.children(),
        user_has_template_folder_permission=user_has_template_folder_permission,
        option_hints=option_hints,
    )


def process_folder_management_form(form, current_folder_id):
    current_service.get_template_folder_with_user_permission_or_403(current_folder_id, current_user)
    new_folder_id = None

    if form.is_add_folder_op:
        new_folder_id = template_folder_api_client.create_template_folder(
            current_service.id, name=form.get_folder_name(), 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)


def get_template_nav_label(value):
    return {
        "all": _l("All"),
        "sms": _l("Text message"),
        "email": _l("Email"),
        "letter": _l("Letter"),
    }[value]


def get_template_nav_items(template_folder_id, sending_view):
    return [
        (
            get_template_nav_label(key),
            key,
            url_for(
                ".choose_template",
                service_id=current_service.id,
                template_type=key,
                template_folder_id=template_folder_id,
                view="sending" if sending_view else None,
            ),
            "",
        )
        for key in ["all"] + current_service.available_template_types
    ]


@main.route("/services/<service_id>/templates/<template_id>.<filetype>")
@user_has_permissions()
def view_letter_template_preview(service_id, template_id, filetype):
    if filetype not in ("pdf", "png"):
        abort(404)

    db_template = current_service.get_template(template_id)

    return TemplatePreview.from_database_object(db_template, filetype, page=request.args.get("page"))


@main.route("/templates/letter-preview-image/<filename>")
@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)


def _view_template_version(service_id, template_id, version, letters_as_pdf=False):
    return dict(
        template=get_template(
            current_service.get_template(template_id, version=version),
            current_service,
            letter_preview_url=url_for(
                ".view_template_version_preview",
                service_id=service_id,
                template_id=template_id,
                version=version,
                filetype="png",
            )
            if not letters_as_pdf
            else None,
        )
    )


@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>")
@user_has_permissions()
def view_template_version(service_id, template_id, version):
    return render_template(
        "views/templates/template_history.html",
        **_view_template_version(service_id=service_id, template_id=template_id, version=version),
    )


@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>.<filetype>")
@user_has_permissions()
def view_template_version_preview(service_id, template_id, version, filetype):
    db_template = current_service.get_template(template_id, version=version)
    return TemplatePreview.from_database_object(db_template, filetype)


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(
            "New letter template",
            "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,
            )
        )


@main.route("/services/<service_id>/templates/create", methods=["GET", "POST"])
@main.route("/services/<service_id>/templates/folders/<template_folder_id>/create", methods=["GET", "POST"])
@main.route("/services/<service_id>/templates/<template_type>/create", methods=["GET", "POST"])
@main.route("/services/<service_id>/templates/<template_type>/folders/<template_folder_id>/create", methods=["GET", "POST"])
@user_has_permissions("manage_templates")
def create_template(service_id, template_type="all", template_folder_id=None):
    form = CreateTemplateForm()

    if request.method == "POST" and form.validate_on_submit():
        try:
            return _add_template_by_type(
                form.what_type.data,
                template_folder_id,
            )
        except HTTPError as e:
            flash(e.message)
    return render_template(
        "views/templates/create.html",
        service_id=service_id,
        template_folder_id=template_folder_id,
        template_type=template_type,
        form=form,
        disabled_options={},
        option_hints={},
    )


@main.route("/services/<service_id>/templates/copy")
@main.route("/services/<service_id>/templates/all/copy")
@main.route("/services/<service_id>/templates/email/copy")
@main.route("/services/<service_id>/templates/sms/copy")
@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>")
@main.route("/services/<service_id>/templates/all/folders/<uuid:from_folder>/copy")
@user_has_permissions("manage_templates")
def choose_template_to_copy(
    service_id,
    from_service=None,
    from_folder=None,
):

    if from_folder and from_service is None:
        from_service = service_id

    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, user=current_user),
            template_folder_path=service.get_template_folder_path(from_folder),
            from_service=service,
            search_form=SearchByNameForm(),
        )

    else:
        return render_template(
            "views/templates/copy.html",
            services_templates_and_folders=TemplateLists(current_user),
            search_form=SearchByNameForm(),
        )


@main.route("/services/<service_id>/templates/copy/<uuid:template_id>", methods=["GET", "POST"])
@user_has_permissions("manage_templates")
def copy_template(service_id, template_id):
    from_service = request.args.get("from_service")

    current_user.belongs_to_service_or_403(from_service)

    template = service_api_client.get_service_template(from_service, str(template_id))["data"]

    template_folder = template_folder_api_client.get_template_folder(from_service, template["folder"])
    if not current_user.has_template_folder_permission(template_folder):
        abort(403)

    if request.method == "POST":
        return add_service_template(
            service_id,
            template["template_type"],
            template_folder_id=template_folder.get("id"),
        )

    template["template_content"] = template["content"]
    template["name"] = _get_template_copy_name(template, current_service.all_templates)
    form = form_objects[template["template_type"]](**template)

    return render_template(
        f"views/edit-{template['template_type']}-template.html",
        form=form,
        template=template,
        heading=_l("Copy email template") if template["template_type"] == "email" else _l("Copy text message template"),
        service_id=service_id,
        services=current_user.service_ids,
    )


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"])


@main.route("/services/<service_id>/templates/action-blocked/<notification_type>/<return_to>/<template_id>")
@user_has_permissions("manage_templates")
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,
    )


@main.route(
    "/services/<service_id>/templates/folders/<template_folder_id>/manage",
    methods=["GET", "POST"],
)
@user_has_permissions("manage_templates")
def manage_template_folder(service_id, template_folder_id):
    template_folder = current_service.get_template_folder_with_user_permission_or_403(template_folder_id, current_user)
    form = TemplateFolderForm(
        name=template_folder["name"],
        users_with_permission=template_folder.get("users_with_permission", None),
        all_service_users=[user for user in current_service.active_users if user.id != current_user.id],
    )
    if form.validate_on_submit():
        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
        template_folder_api_client.update_template_folder(
            current_service.id,
            template_folder_id,
            name=form.name.data,
            users_with_permission=users_with_permission,
        )
        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),
        current_service_id=current_service.id,
        template_folder_id=template_folder_id,
        template_type="all",
    )


@main.route(
    "/services/<service_id>/templates/folders/<template_folder_id>/delete",
    methods=["GET", "POST"],
)
@user_has_permissions("manage_templates")
def delete_template_folder(service_id, template_folder_id):
    template_folder = current_service.get_template_folder_with_user_permission_or_403(template_folder_id, current_user)

    if len(current_service.get_template_folders_and_templates(template_type="all", template_folder_id=template_folder_id)) > 0:
        flash(_l("You must empty this folder before you can delete it"), "info")
        return redirect(
            url_for(
                ".choose_template",
                service_id=service_id,
                template_type="all",
                template_folder_id=template_folder_id,
            )
        )

    if request.method == "POST":

        try:
            template_folder_api_client.delete_template_folder(current_service.id, template_folder_id)

            return redirect(
                url_for(
                    ".choose_template",
                    service_id=service_id,
                    template_folder_id=template_folder["parent_id"],
                )
            )
        except HTTPError as e:
            msg = _l("Folder is not empty")
            if e.status_code == 400 and msg in e.message:
                flash(_("You must empty this folder before you can delete it"), "info")
                return redirect(
                    url_for(
                        ".choose_template",
                        service_id=service_id,
                        template_type="all",
                        template_folder_id=template_folder_id,
                    )
                )
            else:
                abort(500, e)
    else:
        flash(
            "{} ‘{}’ {}".format(
                _l("Are you sure you want to delete the"),
                template_folder["name"],
                _l("folder?"),
            ),
            "delete",
        )
        return manage_template_folder(service_id, template_folder_id)


@main.route("/services/templates/<template_id>/get-data", methods=["POST"])
def get_template_data(template_id):
    data = template_api_prefill_client.get_template(template_id)
    return jsonify({"result": data})


@main.route("/services/<service_id>/templates/add-<template_type>", methods=["GET", "POST"])
@main.route(
    "/services/<service_id>/templates/folders/<template_folder_id>/add-<template_type>",
    methods=["GET", "POST"],
)
@user_has_permissions("manage_templates")
def add_service_template(service_id, template_type, template_folder_id=None):

    if template_type not in ["sms", "email", "letter"]:
        abort(404)
    if not current_service.has_permission("letter") and template_type == "letter":
        abort(403)

    form = form_objects[template_type]()
    if form.validate_on_submit():
        if form.process_type.data != "normal":
            abort_403_if_not_admin_user()
        try:
            new_template = service_api_client.create_service_template(
                form.name.data,
                template_type,
                form.template_content.data,
                service_id,
                form.subject.data if hasattr(form, "subject") else None,
                form.process_type.data,
                template_folder_id,
            )
        except HTTPError as e:
            if (
                e.status_code == 400
                and "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:
            flash(_("'{}' template saved").format(form.name.data), "default_with_tick")

            return redirect(
                url_for(
                    ".view_template",
                    service_id=service_id,
                    template_id=new_template["data"]["id"],
                )
            )

    if email_or_sms_not_enabled(template_type, current_service.permissions):
        return redirect(
            url_for(
                ".action_blocked",
                service_id=service_id,
                notification_type=template_type,
                template_folder_id=template_folder_id,
                return_to="templates",
                template_id="0",
            )
        )
    else:
        return render_template(
            f"views/edit-{template_type}-template.html",
            form=form,
            template_type=template_type,
            template_folder_id=template_folder_id,
            service_id=service_id,
            heading=_l("New email template") if template_type == "email" else _l("New text message template"),
        )


def abort_403_if_not_admin_user():
    if not current_user.platform_admin:
        abort(403)


@main.route("/services/<service_id>/templates/<template_id>/edit", methods=["GET", "POST"])
@user_has_permissions("manage_templates")
def edit_service_template(service_id, template_id):
    template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
    template["template_content"] = template["content"]
    form = form_objects[template["template_type"]](**template)
    if form.validate_on_submit():
        if form.process_type.data != template["process_type"]:
            abort_403_if_not_admin_user()

        subject = form.subject.data if hasattr(form, "subject") else None

        new_template_data = {
            "name": form.name.data,
            "content": form.template_content.data,
            "subject": subject,
            "template_type": template["template_type"],
            "id": template["id"],
            "process_type": form.process_type.data,
            "reply_to_text": template["reply_to_text"],
        }

        new_template = get_template(new_template_data, current_service)
        template_change = get_template(template, current_service).compare_to(new_template)
        if template_change.placeholders_added and not request.form.get("confirm"):
            example_column_headings = first_column_headings[new_template.template_type] + list(new_template.placeholders)
            return render_template(
                "views/templates/breaking-change.html",
                template_change=template_change,
                new_template=new_template,
                column_headings=list(ascii_uppercase[: len(example_column_headings)]),
                example_rows=[
                    example_column_headings,
                    get_example_csv_rows(new_template),
                    get_example_csv_rows(new_template),
                ],
                form=form,
            )
        try:
            service_api_client.update_service_template(
                template_id,
                form.name.data,
                template["template_type"],
                form.template_content.data,
                service_id,
                subject,
                form.process_type.data,
            )
        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:
            flash(_("'{}' template saved").format(form.name.data), "default_with_tick")

            return redirect(url_for(".view_template", service_id=service_id, template_id=template_id))

    if email_or_sms_not_enabled(template["template_type"], current_service.permissions):
        return redirect(
            url_for(
                ".action_blocked",
                service_id=service_id,
                notification_type=template["template_type"],
                return_to="view_template",
                template_id=template_id,
            )
        )
    else:
        return render_template(
            f"views/edit-{template['template_type']}-template.html",
            form=form,
            template=template,
            heading=_l("Edit email template") if template["template_type"] == "email" else _l("Edit text message template"),
        )


@main.route("/services/<service_id>/templates/<template_id>/delete", methods=["GET", "POST"])
@user_has_permissions("manage_templates")
def delete_service_template(service_id, template_id):
    template = current_service.get_template_with_user_permission_or_403(template_id, current_user)

    if request.method == "POST":
        service_api_client.delete_service_template(service_id, template_id)
        return redirect(
            url_for(
                ".choose_template",
                service_id=service_id,
                template_folder_id=template["folder"],
            )
        )

    try:
        last_used_notification = template_statistics_client.get_template_statistics_for_template(service_id, template["id"])

        last_used_text = ""
        if not last_used_notification:
            last_used_text = _l("more than seven days")
        else:
            last_used_date = parse(last_used_notification["created_at"]).replace(tzinfo=None)
            last_used_text = get_human_readable_delta(last_used_date, datetime.utcnow())

        message = "{} {} {}".format(_l("This template was last used"), last_used_text, _l("ago."))

    except HTTPError as e:
        if e.status_code == 404:
            message = None
        else:
            raise e

    flash(
        [
            "{} ‘{}’?".format(_l("Are you sure you want to delete"), template["name"]),
            message,
        ],
        "delete",
    )
    return render_template(
        "views/templates/template.html",
        template=get_email_preview_template(template, template["id"], service_id),
        user_has_template_permission=True,
    )


@main.route("/services/<service_id>/templates/<template_id>/redact", methods=["GET"])
@user_has_permissions("manage_templates")
def confirm_redact_template(service_id, template_id):
    template = current_service.get_template_with_user_permission_or_403(template_id, current_user)

    return render_template(
        "views/templates/template.html",
        template=get_email_preview_template(template, template["id"], service_id),
        user_has_template_permission=True,
        show_redaction_message=True,
    )


@main.route("/services/<service_id>/templates/<template_id>/redact", methods=["POST"])
@user_has_permissions("manage_templates")
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,
        )
    )


@main.route("/services/<service_id>/templates/<template_id>/versions")
@user_has_permissions("view_activity")
def view_template_versions(service_id, template_id):
    return render_template(
        "views/templates/choose_history.html",
        versions=[
            get_template(
                template,
                current_service,
                letter_preview_url=url_for(
                    ".view_template_version_preview",
                    service_id=service_id,
                    template_id=template_id,
                    version=template["version"],
                    filetype="png",
                ),
            )
            for template in service_api_client.get_service_template_versions(service_id, template_id)["data"]
        ],
    )


@main.route(
    "/services/<service_id>/templates/<template_id>/set-template-sender",
    methods=["GET", "POST"],
)
@user_has_permissions("manage_templates")
def set_template_sender(service_id, template_id):
    template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
    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,
    )


@main.route(
    "/services/<service_id>/templates/<template_id>/edit-postage",
    methods=["GET", "POST"],
)
@user_has_permissions("manage_templates")
def edit_template_postage(service_id, template_id):
    template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
    if template["template_type"] != "letter":
        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"],
    )


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


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)
        return "{} minute{}".format(minutes, "" if minutes == 1 else "s")
    elif delta < timedelta(days=1):
        hours = int(delta.seconds / 3600)
        return "{} hour{}".format(hours, "" if hours == 1 else "s")
    else:
        days = delta.days
        return "{} day{}".format(days, "" if days == 1 else "s")

[((69, 1, 69, 66), 'app.main.main.route', 'main.route', ({(69, 12, 69, 65): '"""/services/<service_id>/templates/<uuid:template_id>"""'}, {}), "('/services/<service_id>/templates/<uuid:template_id>')", False, 'from app.main import main\n'), ((70, 1, 70, 23), 'app.utils.user_has_permissions', 'user_has_permissions', ({}, {}), '()', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((88, 1, 88, 67), 'app.main.main.route', 'main.route', ({(88, 12, 88, 66): '"""/services/<service_id>/start-tour/<uuid:template_id>"""'}, {}), "('/services/<service_id>/start-tour/<uuid:template_id>')", False, 'from app.main import main\n'), ((89, 1, 89, 38), 'app.utils.user_has_permissions', 'user_has_permissions', ({(89, 22, 89, 37): '"""view_activity"""'}, {}), "('view_activity')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((108, 1, 108, 72), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((109, 1, 112, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((113, 1, 113, 88), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((114, 1, 117, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((118, 1, 118, 23), 'app.utils.user_has_permissions', 'user_has_permissions', ({}, {}), '()', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((215, 1, 215, 72), 'app.main.main.route', 'main.route', ({(215, 12, 215, 71): '"""/services/<service_id>/templates/<template_id>.<filetype>"""'}, {}), "('/services/<service_id>/templates/<template_id>.<filetype>')", False, 'from app.main import main\n'), ((216, 1, 216, 23), 'app.utils.user_has_permissions', 'user_has_permissions', ({}, {}), '()', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((226, 1, 226, 57), 'app.main.main.route', 'main.route', ({(226, 12, 226, 56): '"""/templates/letter-preview-image/<filename>"""'}, {}), "('/templates/letter-preview-image/<filename>')", False, 'from app.main import main\n'), ((271, 1, 271, 83), 'app.main.main.route', 'main.route', ({(271, 12, 271, 82): '"""/services/<service_id>/templates/<template_id>/version/<int:version>"""'}, {}), "(\n    '/services/<service_id>/templates/<template_id>/version/<int:version>')", False, 'from app.main import main\n'), ((272, 1, 272, 23), 'app.utils.user_has_permissions', 'user_has_permissions', ({}, {}), '()', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((280, 1, 280, 94), 'app.main.main.route', 'main.route', ({(280, 12, 280, 93): '"""/services/<service_id>/templates/<template_id>/version/<int:version>.<filetype>"""'}, {}), "(\n    '/services/<service_id>/templates/<template_id>/version/<int:version>.<filetype>'\n    )", False, 'from app.main import main\n'), ((281, 1, 281, 23), 'app.utils.user_has_permissions', 'user_has_permissions', ({}, {}), '()', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((336, 1, 336, 79), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((337, 1, 337, 108), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((338, 1, 338, 95), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((339, 1, 339, 124), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((340, 1, 340, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(340, 22, 340, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((363, 1, 363, 52), 'app.main.main.route', 'main.route', ({(363, 12, 363, 51): '"""/services/<service_id>/templates/copy"""'}, {}), "('/services/<service_id>/templates/copy')", False, 'from app.main import main\n'), ((364, 1, 364, 56), 'app.main.main.route', 'main.route', ({(364, 12, 364, 55): '"""/services/<service_id>/templates/all/copy"""'}, {}), "('/services/<service_id>/templates/all/copy')", False, 'from app.main import main\n'), ((365, 1, 365, 58), 'app.main.main.route', 'main.route', ({(365, 12, 365, 57): '"""/services/<service_id>/templates/email/copy"""'}, {}), "('/services/<service_id>/templates/email/copy')", False, 'from app.main import main\n'), ((366, 1, 366, 56), 'app.main.main.route', 'main.route', ({(366, 12, 366, 55): '"""/services/<service_id>/templates/sms/copy"""'}, {}), "('/services/<service_id>/templates/sms/copy')", False, 'from app.main import main\n'), ((367, 1, 367, 83), 'app.main.main.route', 'main.route', ({(367, 12, 367, 82): '"""/services/<service_id>/templates/copy/from-folder/<uuid:from_folder>"""'}, {}), "(\n    '/services/<service_id>/templates/copy/from-folder/<uuid:from_folder>')", False, 'from app.main import main\n'), ((368, 1, 368, 85), 'app.main.main.route', 'main.route', ({(368, 12, 368, 84): '"""/services/<service_id>/templates/copy/from-service/<uuid:from_service>"""'}, {}), "(\n    '/services/<service_id>/templates/copy/from-service/<uuid:from_service>')", False, 'from app.main import main\n'), ((369, 1, 369, 116), 'app.main.main.route', 'main.route', ({(369, 12, 369, 115): '"""/services/<service_id>/templates/copy/from-service/<uuid:from_service>/from-folder/<uuid:from_folder>"""'}, {}), "(\n    '/services/<service_id>/templates/copy/from-service/<uuid:from_service>/from-folder/<uuid:from_folder>'\n    )", False, 'from app.main import main\n'), ((370, 1, 370, 83), 'app.main.main.route', 'main.route', ({(370, 12, 370, 82): '"""/services/<service_id>/templates/all/folders/<uuid:from_folder>/copy"""'}, {}), "(\n    '/services/<service_id>/templates/all/folders/<uuid:from_folder>/copy')", False, 'from app.main import main\n'), ((371, 1, 371, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(371, 22, 371, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((402, 1, 402, 96), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((403, 1, 403, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(403, 22, 403, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((450, 1, 450, 108), 'app.main.main.route', 'main.route', ({(450, 12, 450, 107): '"""/services/<service_id>/templates/action-blocked/<notification_type>/<return_to>/<template_id>"""'}, {}), "(\n    '/services/<service_id>/templates/action-blocked/<notification_type>/<return_to>/<template_id>'\n    )", False, 'from app.main import main\n'), ((451, 1, 451, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(451, 22, 451, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((467, 1, 470, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((471, 1, 471, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(471, 22, 471, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((508, 1, 511, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((512, 1, 512, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(512, 22, 512, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((565, 1, 565, 75), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((571, 1, 571, 92), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((572, 1, 575, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((576, 1, 576, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(576, 22, 576, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((645, 1, 645, 91), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((646, 1, 646, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(646, 22, 646, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((725, 1, 725, 93), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((726, 1, 726, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(726, 22, 726, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((772, 1, 772, 85), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((773, 1, 773, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(773, 22, 773, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((785, 1, 785, 86), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((786, 1, 786, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(786, 22, 786, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((805, 1, 805, 70), 'app.main.main.route', 'main.route', ({(805, 12, 805, 69): '"""/services/<service_id>/templates/<template_id>/versions"""'}, {}), "('/services/<service_id>/templates/<template_id>/versions')", False, 'from app.main import main\n'), ((806, 1, 806, 38), 'app.utils.user_has_permissions', 'user_has_permissions', ({(806, 22, 806, 37): '"""view_activity"""'}, {}), "('view_activity')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((827, 1, 830, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((831, 1, 831, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(831, 22, 831, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((860, 1, 863, 1), 'app.main.main.route', 'main.route', (), '', False, 'from app.main import main\n'), ((864, 1, 864, 41), 'app.utils.user_has_permissions', 'user_has_permissions', ({(864, 22, 864, 40): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((72, 15, 72, 56), 'app.current_service.get_template', 'current_service.get_template', ({(72, 44, 72, 55): 'template_id'}, {}), '(template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((73, 22, 73, 77), 'app.current_service.get_template_folder', 'current_service.get_template_folder', ({(73, 58, 73, 76): "template['folder']"}, {}), "(template['folder'])", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((75, 35, 75, 95), 'flask_login.current_user.has_template_folder_permission', 'current_user.has_template_folder_permission', ({(75, 79, 75, 94): 'template_folder'}, {}), '(template_folder)', False, 'from flask_login import current_user\n'), ((77, 7, 77, 59), 'app.utils.should_skip_template_page', 'should_skip_template_page', ({(77, 33, 77, 58): "template['template_type']"}, {}), "(template['template_type'])", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((92, 15, 92, 56), 'app.current_service.get_template', 'current_service.get_template', ({(92, 44, 92, 55): 'template_id'}, {}), '(template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((120, 22, 120, 77), 'app.current_service.get_template_folder', 'current_service.get_template_folder', ({(120, 58, 120, 76): 'template_folder_id'}, {}), '(template_folder_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((122, 42, 122, 102), 'flask_login.current_user.has_template_folder_permission', 'current_user.has_template_folder_permission', ({(122, 86, 122, 101): 'template_folder'}, {}), '(template_folder)', False, 'from flask_login import current_user\n'), ((124, 20, 124, 98), 'app.models.template_list.TemplateList', 'TemplateList', ({(124, 33, 124, 48): 'current_service', (124, 50, 124, 63): 'template_type', (124, 65, 124, 83): 'template_folder_id', (124, 85, 124, 97): 'current_user'}, {}), '(current_service, template_type, template_folder_id, current_user)', False, 'from app.models.template_list import TemplateList, TemplateLists\n'), ((146, 20, 146, 53), 'flask.request.args.get', 'request.args.get', ({(146, 37, 146, 52): '"""initial_state"""'}, {}), "('initial_state')", False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((171, 4, 171, 100), 'app.current_service.get_template_folder_with_user_permission_or_403', 'current_service.get_template_folder_with_user_permission_or_403', ({(171, 68, 171, 85): 'current_folder_id', (171, 87, 171, 99): 'current_user'}, {}), '(\n    current_folder_id, current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((185, 11, 185, 32), 'flask.redirect', 'redirect', ({(185, 20, 185, 31): 'request.url'}, {}), '(request.url)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((221, 18, 221, 59), 'app.current_service.get_template', 'current_service.get_template', ({(221, 47, 221, 58): 'template_id'}, {}), '(template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((250, 11, 250, 68), 'app.template_previews.TemplatePreview.from_example_template', 'TemplatePreview.from_example_template', ({(250, 49, 250, 57): 'template', (250, 59, 250, 67): 'filename'}, {}), '(template, filename)', False, 'from app.template_previews import TemplatePreview, get_page_count_for_letter\n'), ((283, 18, 283, 76), 'app.current_service.get_template', 'current_service.get_template', (), '', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((284, 11, 284, 70), 'app.template_previews.TemplatePreview.from_database_object', 'TemplatePreview.from_database_object', ({(284, 48, 284, 59): 'db_template', (284, 61, 284, 69): 'filetype'}, {}), '(db_template, filetype)', False, 'from app.template_previews import TemplatePreview, get_page_count_for_letter\n'), ((315, 7, 315, 75), 'app.utils.email_or_sms_not_enabled', 'email_or_sms_not_enabled', ({(315, 32, 315, 45): 'template_type', (315, 47, 315, 74): 'current_service.permissions'}, {}), '(template_type, current_service.permissions)', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((342, 11, 342, 31), 'app.main.forms.CreateTemplateForm', 'CreateTemplateForm', ({}, {}), '()', False, 'from app.main.forms import CreateTemplateForm, EmailTemplateForm, LetterTemplateForm, LetterTemplatePostageForm, SearchByNameForm, SetTemplateSenderForm, SMSTemplateForm, TemplateAndFoldersSelectionForm, TemplateFolderForm\n'), ((352, 11, 360, 5), 'flask.render_template', 'render_template', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((405, 19, 405, 51), 'flask.request.args.get', 'request.args.get', ({(405, 36, 405, 50): '"""from_service"""'}, {}), "('from_service')", False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((407, 4, 407, 56), 'flask_login.current_user.belongs_to_service_or_403', 'current_user.belongs_to_service_or_403', ({(407, 43, 407, 55): 'from_service'}, {}), '(from_service)', False, 'from flask_login import current_user\n'), ((411, 22, 411, 102), 'app.template_folder_api_client.get_template_folder', 'template_folder_api_client.get_template_folder', ({(411, 69, 411, 81): 'from_service', (411, 83, 411, 101): "template['folder']"}, {}), "(from_service, template['folder']\n    )", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((458, 11, 464, 5), 'flask.render_template', 'render_template', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((473, 22, 473, 119), 'app.current_service.get_template_folder_with_user_permission_or_403', 'current_service.get_template_folder_with_user_permission_or_403', ({(473, 86, 473, 104): 'template_folder_id', (473, 106, 473, 118): 'current_user'}, {}), '(\n    template_folder_id, current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((514, 22, 514, 119), 'app.current_service.get_template_folder_with_user_permission_or_403', 'current_service.get_template_folder_with_user_permission_or_403', ({(514, 86, 514, 104): 'template_folder_id', (514, 106, 514, 118): 'current_user'}, {}), '(\n    template_folder_id, current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((567, 11, 567, 64), 'app.template_api_prefill_client.get_template', 'template_api_prefill_client.get_template', ({(567, 52, 567, 63): 'template_id'}, {}), '(template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((568, 11, 568, 36), 'flask.jsonify', 'jsonify', ({(568, 19, 568, 35): "{'result': data}"}, {}), "({'result': data})", False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((618, 7, 618, 75), 'app.utils.email_or_sms_not_enabled', 'email_or_sms_not_enabled', ({(618, 32, 618, 45): 'template_type', (618, 47, 618, 74): 'current_service.permissions'}, {}), '(template_type, current_service.permissions)', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((648, 15, 648, 98), 'app.current_service.get_template_with_user_permission_or_403', 'current_service.get_template_with_user_permission_or_403', ({(648, 72, 648, 83): 'template_id', (648, 85, 648, 97): 'current_user'}, {}), '(template_id,\n    current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((706, 7, 706, 87), 'app.utils.email_or_sms_not_enabled', 'email_or_sms_not_enabled', ({(706, 32, 706, 57): "template['template_type']", (706, 59, 706, 86): 'current_service.permissions'}, {}), "(template['template_type'], current_service.permissions\n    )", False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((728, 15, 728, 98), 'app.current_service.get_template_with_user_permission_or_403', 'current_service.get_template_with_user_permission_or_403', ({(728, 72, 728, 83): 'template_id', (728, 85, 728, 97): 'current_user'}, {}), '(template_id,\n    current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((775, 15, 775, 98), 'app.current_service.get_template_with_user_permission_or_403', 'current_service.get_template_with_user_permission_or_403', ({(775, 72, 775, 83): 'template_id', (775, 85, 775, 97): 'current_user'}, {}), '(template_id,\n    current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((789, 4, 789, 71), 'app.service_api_client.redact_service_template', 'service_api_client.redact_service_template', ({(789, 47, 789, 57): 'service_id', (789, 59, 789, 70): 'template_id'}, {}), '(service_id, template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((833, 15, 833, 98), 'app.current_service.get_template_with_user_permission_or_403', 'current_service.get_template_with_user_permission_or_403', ({(833, 72, 833, 83): 'template_id', (833, 85, 833, 97): 'current_user'}, {}), '(template_id,\n    current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((837, 11, 840, 5), 'app.main.forms.SetTemplateSenderForm', 'SetTemplateSenderForm', (), '', False, 'from app.main.forms import CreateTemplateForm, EmailTemplateForm, LetterTemplateForm, LetterTemplatePostageForm, SearchByNameForm, SetTemplateSenderForm, SMSTemplateForm, TemplateAndFoldersSelectionForm, TemplateFolderForm\n'), ((851, 11, 857, 5), 'flask.render_template', 'render_template', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((866, 15, 866, 98), 'app.current_service.get_template_with_user_permission_or_403', 'current_service.get_template_with_user_permission_or_403', ({(866, 72, 866, 83): 'template_id', (866, 85, 866, 97): 'current_user'}, {}), '(template_id,\n    current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((869, 11, 869, 48), 'app.main.forms.LetterTemplatePostageForm', 'LetterTemplatePostageForm', ({}, {}), '(**template)', False, 'from app.main.forms import CreateTemplateForm, EmailTemplateForm, LetterTemplateForm, LetterTemplatePostageForm, SearchByNameForm, SetTemplateSenderForm, SMSTemplateForm, TemplateAndFoldersSelectionForm, TemplateFolderForm\n'), ((876, 11, 882, 5), 'flask.render_template', 'render_template', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((893, 22, 893, 79), 'app.main.views.send.get_sender_details', 'get_sender_details', ({(893, 41, 893, 51): 'service_id', (893, 53, 893, 78): "template['template_type']"}, {}), "(service_id, template['template_type'])", False, 'from app.main.views.send import get_example_csv_rows, get_sender_details\n'), ((95, 8, 95, 18), 'flask.abort', 'abort', ({(95, 14, 95, 17): '(404)'}, {}), '(404)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((150, 19, 150, 43), 'flask.request.args.get', 'request.args.get', ({(150, 36, 150, 42): '"""view"""'}, {}), "('view')", False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((183, 8, 183, 103), 'app.current_service.move_to_folder', 'current_service.move_to_folder', (), '', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((219, 8, 219, 18), 'flask.abort', 'abort', ({(219, 14, 219, 17): '(404)'}, {}), '(404)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((298, 23, 306, 9), 'app.service_api_client.create_service_template', 'service_api_client.create_service_template', ({(299, 12, 299, 33): '"""New letter template"""', (300, 12, 300, 20): '"""letter"""', (301, 12, 301, 18): '"""Body"""', (302, 12, 302, 30): 'current_service.id', (303, 12, 303, 26): '"""Main heading"""', (304, 12, 304, 20): '"""normal"""', (305, 12, 305, 30): 'template_folder_id'}, {}), "('New letter template', 'letter',\n    'Body', current_service.id, 'Main heading', 'normal', template_folder_id)", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((383, 8, 383, 60), 'flask_login.current_user.belongs_to_service_or_403', 'current_user.belongs_to_service_or_403', ({(383, 47, 383, 59): 'from_service'}, {}), '(from_service)', False, 'from flask_login import current_user\n'), ((412, 11, 412, 71), 'flask_login.current_user.has_template_folder_permission', 'current_user.has_template_folder_permission', ({(412, 55, 412, 70): 'template_folder'}, {}), '(template_folder)', False, 'from flask_login import current_user\n'), ((413, 8, 413, 18), 'flask.abort', 'abort', ({(413, 14, 413, 17): '(403)'}, {}), '(403)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((484, 8, 489, 9), 'app.template_folder_api_client.update_template_folder', 'template_folder_api_client.update_template_folder', (), '', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((580, 8, 580, 18), 'flask.abort', 'abort', ({(580, 14, 580, 17): '(404)'}, {}), '(404)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((582, 8, 582, 18), 'flask.abort', 'abort', ({(582, 14, 582, 17): '(403)'}, {}), '(403)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((642, 8, 642, 18), 'flask.abort', 'abort', ({(642, 14, 642, 17): '(403)'}, {}), '(403)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((667, 23, 667, 71), 'app.utils.get_template', 'get_template', ({(667, 36, 667, 53): 'new_template_data', (667, 55, 667, 70): 'current_service'}, {}), '(new_template_data, current_service)', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((731, 8, 731, 75), 'app.service_api_client.delete_service_template', 'service_api_client.delete_service_template', ({(731, 51, 731, 61): 'service_id', (731, 63, 731, 74): 'template_id'}, {}), '(service_id, template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((741, 33, 741, 124), 'app.template_statistics_client.get_template_statistics_for_template', 'template_statistics_client.get_template_statistics_for_template', ({(741, 97, 741, 107): 'service_id', (741, 109, 741, 123): "template['id']"}, {}), "(service_id,\n    template['id'])", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((792, 8, 792, 85), 'flask_babel._', '_', ({(792, 10, 792, 84): '"""Personalised content will be hidden for messages sent with this template"""'}, {}), "('Personalised content will be hidden for messages sent with this template')", False, 'from flask_babel import _\n'), ((797, 8, 801, 9), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((844, 8, 848, 9), 'app.service_api_client.update_service_template_sender', 'service_api_client.update_service_template_sender', ({(845, 12, 845, 22): 'service_id', (846, 12, 846, 23): 'template_id', (847, 12, 847, 58): '(form.sender.data if form.sender.data else None)'}, {}), '(service_id, template_id, \n    form.sender.data if form.sender.data else None)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((868, 8, 868, 18), 'flask.abort', 'abort', ({(868, 14, 868, 17): '(404)'}, {}), '(404)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((872, 8, 872, 92), 'app.service_api_client.update_service_template_postage', 'service_api_client.update_service_template_postage', ({(872, 59, 872, 69): 'service_id', (872, 71, 872, 82): 'template_id', (872, 84, 872, 91): 'postage'}, {}), '(service_id, template_id,\n    postage)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((907, 15, 907, 36), 'datetime.timedelta', 'timedelta', (), '', False, 'from datetime import datetime, timedelta\n'), ((56, 27, 61, 9), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((63, 19, 63, 54), 'app.template_previews.get_page_count_for_letter', 'get_page_count_for_letter', ({(63, 45, 63, 53): 'template'}, {}), '(template)', False, 'from app.template_previews import TemplatePreview, get_page_count_for_letter\n'), ((78, 24, 78, 96), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((99, 17, 103, 9), 'app.utils.get_template', 'get_template', (), '', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((127, 29, 127, 84), 'app.current_service.get_user_template_folders', 'current_service.get_user_template_folders', ({(127, 71, 127, 83): 'current_user'}, {}), '(current_user)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((130, 37, 130, 77), 'app.current_service.has_permission', 'current_service.has_permission', ({(130, 68, 130, 76): '"""letter"""'}, {}), "('letter')", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((136, 15, 136, 63), 'flask_login.current_user.has_permissions', 'current_user.has_permissions', ({(136, 44, 136, 62): '"""manage_templates"""'}, {}), "('manage_templates')", False, 'from flask_login import current_user\n'), ((137, 12, 137, 22), 'flask.abort', 'abort', ({(137, 18, 137, 21): '(403)'}, {}), '(403)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((144, 14, 144, 57), 'flask_babel._', '_', ({(144, 16, 144, 56): '"""Select at least one template or folder"""'}, {}), "('Select at least one template or folder')", False, 'from flask_babel import _\n'), ((155, 29, 155, 89), 'app.current_service.get_template_folder_path', 'current_service.get_template_folder_path', ({(155, 70, 155, 88): 'template_folder_id'}, {}), '(template_folder_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((162, 20, 162, 38), 'app.main.forms.SearchByNameForm', 'SearchByNameForm', ({}, {}), '()', False, 'from app.main.forms import CreateTemplateForm, EmailTemplateForm, LetterTemplateForm, LetterTemplatePostageForm, SearchByNameForm, SetTemplateSenderForm, SMSTemplateForm, TemplateAndFoldersSelectionForm, TemplateFolderForm\n'), ((190, 15, 190, 24), 'flask_babel.lazy_gettext', '_l', ({(190, 18, 190, 23): '"""All"""'}, {}), "('All')", True, 'from flask_babel import lazy_gettext as _l\n'), ((191, 15, 191, 33), 'flask_babel.lazy_gettext', '_l', ({(191, 18, 191, 32): '"""Text message"""'}, {}), "('Text message')", True, 'from flask_babel import lazy_gettext as _l\n'), ((192, 17, 192, 28), 'flask_babel.lazy_gettext', '_l', ({(192, 20, 192, 27): '"""Email"""'}, {}), "('Email')", True, 'from flask_babel import lazy_gettext as _l\n'), ((193, 18, 193, 30), 'flask_babel.lazy_gettext', '_l', ({(193, 21, 193, 29): '"""Letter"""'}, {}), "('Letter')", True, 'from flask_babel import lazy_gettext as _l\n'), ((202, 12, 208, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((223, 76, 223, 100), 'flask.request.args.get', 'request.args.get', ({(223, 93, 223, 99): '"""page"""'}, {}), "('page')", False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((291, 12, 294, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((308, 12, 312, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((317, 12, 323, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((327, 12, 332, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((480, 11, 480, 57), 'flask_login.current_user.has_permissions', 'current_user.has_permissions', ({(480, 40, 480, 56): '"""manage_service"""'}, {}), "('manage_service')", False, 'from flask_login import current_user\n'), ((491, 12, 495, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((501, 29, 501, 89), 'app.current_service.get_template_folder_path', 'current_service.get_template_folder_path', ({(501, 70, 501, 88): 'template_folder_id'}, {}), '(template_folder_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((516, 11, 516, 121), 'app.current_service.get_template_folders_and_templates', 'current_service.get_template_folders_and_templates', (), '', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((517, 14, 517, 71), 'flask_babel.lazy_gettext', '_l', ({(517, 17, 517, 70): '"""You must empty this folder before you can delete it"""'}, {}), "('You must empty this folder before you can delete it')", True, 'from flask_babel import lazy_gettext as _l\n'), ((519, 12, 524, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((530, 12, 530, 101), 'app.template_folder_api_client.delete_template_folder', 'template_folder_api_client.delete_template_folder', ({(530, 62, 530, 80): 'current_service.id', (530, 82, 530, 100): 'template_folder_id'}, {}), '(current_service.id,\n    template_folder_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((581, 11, 581, 51), 'app.current_service.has_permission', 'current_service.has_permission', ({(581, 42, 581, 50): '"""letter"""'}, {}), "('letter')", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((620, 12, 627, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((684, 12, 692, 13), 'app.service_api_client.update_service_template', 'service_api_client.update_service_template', ({(685, 16, 685, 27): 'template_id', (686, 16, 686, 30): 'form.name.data', (687, 16, 687, 41): "template['template_type']", (688, 16, 688, 42): 'form.template_content.data', (689, 16, 689, 26): 'service_id', (690, 16, 690, 23): 'subject', (691, 16, 691, 38): 'form.process_type.data'}, {}), "(template_id, form.name.data,\n    template['template_type'], form.template_content.data, service_id,\n    subject, form.process_type.data)", False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((708, 12, 714, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((733, 12, 737, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((745, 29, 745, 55), 'flask_babel.lazy_gettext', '_l', ({(745, 32, 745, 54): '"""more than seven days"""'}, {}), "('more than seven days')", True, 'from flask_babel import lazy_gettext as _l\n'), ((750, 36, 750, 69), 'flask_babel.lazy_gettext', '_l', ({(750, 39, 750, 68): '"""This template was last used"""'}, {}), "('This template was last used')", True, 'from flask_babel import lazy_gettext as _l\n'), ((750, 87, 750, 97), 'flask_babel.lazy_gettext', '_l', ({(750, 90, 750, 96): '"""ago."""'}, {}), "('ago.')", True, 'from flask_babel import lazy_gettext as _l\n'), ((849, 24, 849, 97), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((874, 24, 874, 97), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((909, 17, 909, 35), 'datetime.timedelta', 'timedelta', (), '', False, 'from datetime import datetime, timedelta\n'), ((141, 12, 141, 28), 'flask.flash', 'flash', ({(141, 18, 141, 27): 'e.message'}, {}), '(e.message)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((256, 12, 256, 70), 'app.current_service.get_template', 'current_service.get_template', (), '', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((351, 12, 351, 28), 'flask.flash', 'flash', ({(351, 18, 351, 27): 'e.message'}, {}), '(e.message)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((384, 26, 384, 70), 'app.service_api_client.get_service', 'service_api_client.get_service', ({(384, 57, 384, 69): 'from_service'}, {}), '(from_service)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n'), ((388, 43, 388, 115), 'app.models.template_list.TemplateList', 'TemplateList', (), '', False, 'from app.models.template_list import TemplateList, TemplateLists\n'), ((391, 24, 391, 42), 'app.main.forms.SearchByNameForm', 'SearchByNameForm', ({}, {}), '()', False, 'from app.main.forms import CreateTemplateForm, EmailTemplateForm, LetterTemplateForm, LetterTemplatePostageForm, SearchByNameForm, SetTemplateSenderForm, SMSTemplateForm, TemplateAndFoldersSelectionForm, TemplateFolderForm\n'), ((397, 43, 397, 70), 'app.models.template_list.TemplateLists', 'TemplateLists', ({(397, 57, 397, 69): 'current_user'}, {}), '(current_user)', False, 'from app.models.template_list import TemplateList, TemplateLists\n'), ((398, 24, 398, 42), 'app.main.forms.SearchByNameForm', 'SearchByNameForm', ({}, {}), '()', False, 'from app.main.forms import CreateTemplateForm, EmailTemplateForm, LetterTemplateForm, LetterTemplatePostageForm, SearchByNameForm, SetTemplateSenderForm, SMSTemplateForm, TemplateAndFoldersSelectionForm, TemplateFolderForm\n'), ((430, 16, 430, 41), 'flask_babel.lazy_gettext', '_l', ({(430, 19, 430, 40): '"""Copy email template"""'}, {}), "('Copy email template')", True, 'from flask_babel import lazy_gettext as _l\n'), ((430, 87, 430, 119), 'flask_babel.lazy_gettext', '_l', ({(430, 90, 430, 118): '"""Copy text message template"""'}, {}), "('Copy text message template')", True, 'from flask_babel import lazy_gettext as _l\n'), ((533, 16, 537, 17), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((540, 18, 540, 43), 'flask_babel.lazy_gettext', '_l', ({(540, 21, 540, 42): '"""Folder is not empty"""'}, {}), "('Folder is not empty')", True, 'from flask_babel import lazy_gettext as _l\n'), ((556, 16, 556, 57), 'flask_babel.lazy_gettext', '_l', ({(556, 19, 556, 56): '"""Are you sure you want to delete the"""'}, {}), "('Are you sure you want to delete the')", True, 'from flask_babel import lazy_gettext as _l\n'), ((558, 16, 558, 29), 'flask_babel.lazy_gettext', '_l', ({(558, 19, 558, 28): '"""folder?"""'}, {}), "('folder?')", True, 'from flask_babel import lazy_gettext as _l\n'), ((611, 16, 615, 17), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((668, 26, 668, 65), 'app.utils.get_template', 'get_template', ({(668, 39, 668, 47): 'template', (668, 49, 668, 64): 'current_service'}, {}), '(template, current_service)', False, 'from app.utils import email_or_sms_not_enabled, get_template, should_skip_template_page, user_has_permissions, user_is_platform_admin\n'), ((669, 54, 669, 81), 'flask.request.form.get', 'request.form.get', ({(669, 71, 669, 80): '"""confirm"""'}, {}), "('confirm')", False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((704, 28, 704, 101), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((748, 70, 748, 87), 'datetime.datetime.utcnow', 'datetime.utcnow', ({}, {}), '()', False, 'from datetime import datetime, timedelta\n'), ((760, 34, 760, 71), 'flask_babel.lazy_gettext', '_l', ({(760, 37, 760, 70): '"""Are you sure you want to delete"""'}, {}), "('Are you sure you want to delete')", True, 'from flask_babel import lazy_gettext as _l\n'), ((898, 56, 898, 84), 'notifications_utils.formatters.nl2br', 'nl2br', ({(898, 62, 898, 83): 'sender[sender_format]'}, {}), '(sender[sender_format])', False, 'from notifications_utils.formatters import nl2br\n'), ((912, 17, 912, 34), 'datetime.timedelta', 'timedelta', (), '', False, 'from datetime import datetime, timedelta\n'), ((552, 16, 552, 29), 'flask.abort', 'abort', ({(552, 22, 552, 25): '(500)', (552, 27, 552, 28): 'e'}, {}), '(500, e)', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((636, 20, 636, 44), 'flask_babel.lazy_gettext', '_l', ({(636, 23, 636, 43): '"""New email template"""'}, {}), "('New email template')", True, 'from flask_babel import lazy_gettext as _l\n'), ((636, 78, 636, 109), 'flask_babel.lazy_gettext', '_l', ({(636, 81, 636, 108): '"""New text message template"""'}, {}), "('New text message template')", True, 'from flask_babel import lazy_gettext as _l\n'), ((721, 20, 721, 45), 'flask_babel.lazy_gettext', '_l', ({(721, 23, 721, 44): '"""Edit email template"""'}, {}), "('Edit email template')", True, 'from flask_babel import lazy_gettext as _l\n'), ((721, 91, 721, 123), 'flask_babel.lazy_gettext', '_l', ({(721, 94, 721, 122): '"""Edit text message template"""'}, {}), "('Edit text message template')", True, 'from flask_babel import lazy_gettext as _l\n'), ((747, 29, 747, 72), 'dateutil.parser.parse', 'parse', ({(747, 35, 747, 71): "last_used_notification['created_at']"}, {}), "(last_used_notification['created_at'])", False, 'from dateutil.parser import parse\n'), ((258, 31, 264, 13), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((542, 22, 542, 78), 'flask_babel._', '_', ({(542, 24, 542, 77): '"""You must empty this folder before you can delete it"""'}, {}), "('You must empty this folder before you can delete it')", False, 'from flask_babel import _\n'), ((544, 20, 549, 21), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((608, 18, 608, 42), 'flask_babel._', '_', ({(608, 20, 608, 41): '"""\'{}\' template saved"""'}, {}), '("\'{}\' template saved")', False, 'from flask_babel import _\n'), ((678, 20, 678, 54), 'app.main.views.send.get_example_csv_rows', 'get_example_csv_rows', ({(678, 41, 678, 53): 'new_template'}, {}), '(new_template)', False, 'from app.main.views.send import get_example_csv_rows, get_sender_details\n'), ((679, 20, 679, 54), 'app.main.views.send.get_example_csv_rows', 'get_example_csv_rows', ({(679, 41, 679, 53): 'new_template'}, {}), '(new_template)', False, 'from app.main.views.send import get_example_csv_rows, get_sender_details\n'), ((702, 18, 702, 42), 'flask_babel._', '_', ({(702, 20, 702, 41): '"""\'{}\' template saved"""'}, {}), '("\'{}\' template saved")', False, 'from flask_babel import _\n'), ((814, 35, 820, 17), 'flask.url_for', 'url_for', (), '', False, 'from flask import abort, flash, jsonify, redirect, render_template, request, url_for\n'), ((822, 28, 822, 101), 'app.service_api_client.get_service_template_versions', 'service_api_client.get_service_template_versions', ({(822, 77, 822, 87): 'service_id', (822, 89, 822, 100): 'template_id'}, {}), '(service_id, template_id)', False, 'from app import current_service, service_api_client, template_api_prefill_client, template_folder_api_client, template_statistics_client\n')]