2016-04-04 14:28:52 +01:00
|
|
|
|
import itertools
|
2016-05-31 14:18:35 +01:00
|
|
|
|
from string import ascii_uppercase
|
2016-05-13 21:25:59 +01:00
|
|
|
|
from zipfile import BadZipFile
|
2016-01-11 15:00:51 +00:00
|
|
|
|
|
|
|
|
|
|
from flask import (
|
2016-02-01 11:28:36 +00:00
|
|
|
|
abort,
|
2016-12-20 14:38:34 +00:00
|
|
|
|
current_app,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
flash,
|
|
|
|
|
|
redirect,
|
|
|
|
|
|
render_template,
|
|
|
|
|
|
request,
|
|
|
|
|
|
session,
|
|
|
|
|
|
url_for,
|
2016-01-11 15:00:51 +00:00
|
|
|
|
)
|
2019-07-01 15:22:08 +01:00
|
|
|
|
from flask_login import current_user
|
2017-06-29 15:31:44 +01:00
|
|
|
|
from notifications_python_client.errors import HTTPError
|
2019-10-09 14:56:18 +01:00
|
|
|
|
from notifications_utils import LETTER_MAX_PAGE_COUNT, SMS_CHAR_COUNT_LIMIT
|
2018-06-08 12:49:29 +01:00
|
|
|
|
from notifications_utils.columns import Columns
|
2019-10-09 14:56:18 +01:00
|
|
|
|
from notifications_utils.pdf import is_letter_too_long
|
2020-04-27 10:57:25 +01:00
|
|
|
|
from notifications_utils.postal_address import (
|
|
|
|
|
|
PostalAddress,
|
2020-09-07 11:49:43 +01:00
|
|
|
|
address_lines_1_to_7_keys,
|
2020-04-27 10:57:25 +01:00
|
|
|
|
)
|
2020-04-19 22:46:13 +01:00
|
|
|
|
from notifications_utils.recipients import RecipientCSV, first_column_headings
|
2018-07-12 15:14:58 +01:00
|
|
|
|
from notifications_utils.sanitise_text import SanitiseASCII
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from xlrd.biffh import XLRDError
|
2018-02-28 14:45:57 +00:00
|
|
|
|
from xlrd.xldate import XLDateError
|
2015-12-10 21:15:20 +00:00
|
|
|
|
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from app import (
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
job_api_client,
|
2020-01-22 16:13:25 +00:00
|
|
|
|
nl2br,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
notification_api_client,
|
|
|
|
|
|
service_api_client,
|
|
|
|
|
|
)
|
2019-11-29 11:40:49 +00:00
|
|
|
|
from app.main import main, no_cookie
|
2017-05-04 09:30:55 +01:00
|
|
|
|
from app.main.forms import (
|
|
|
|
|
|
ChooseTimeForm,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
CsvUploadForm,
|
2020-03-10 15:12:19 +00:00
|
|
|
|
LetterAddressForm,
|
2017-10-16 16:35:35 +01:00
|
|
|
|
SetSenderForm,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
get_placeholder_form_instance,
|
2017-05-04 09:30:55 +01:00
|
|
|
|
)
|
2020-03-16 11:05:26 +00:00
|
|
|
|
from app.models.contact_list import ContactList, ContactListsAlphabetical
|
2019-05-23 15:27:35 +01:00
|
|
|
|
from app.models.user import Users
|
2019-01-30 09:42:15 +00:00
|
|
|
|
from app.s3_client.s3_csv_client import (
|
2020-10-21 13:07:59 +01:00
|
|
|
|
get_csv_metadata,
|
2019-01-30 09:42:15 +00:00
|
|
|
|
s3download,
|
|
|
|
|
|
s3upload,
|
|
|
|
|
|
set_metadata_on_csv_upload,
|
|
|
|
|
|
)
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from app.template_previews import TemplatePreview, get_page_count_for_letter
|
2016-12-28 11:06:11 +00:00
|
|
|
|
from app.utils import (
|
2019-03-21 16:41:22 +00:00
|
|
|
|
PermanentRedirect,
|
2018-08-09 16:29:51 +01:00
|
|
|
|
should_skip_template_page,
|
2018-04-30 10:46:39 +01:00
|
|
|
|
unicode_truncate,
|
2016-12-28 11:06:11 +00:00
|
|
|
|
)
|
2021-06-09 15:15:35 +01:00
|
|
|
|
from app.utils.csv import Spreadsheet, get_errors_for_csv
|
|
|
|
|
|
from app.utils.templates import get_template
|
2021-06-09 13:19:05 +01:00
|
|
|
|
from app.utils.user import user_has_permissions
|
2016-02-22 17:17:18 +00:00
|
|
|
|
|
2020-04-27 10:57:25 +01:00
|
|
|
|
letter_address_columns = [
|
|
|
|
|
|
column.replace('_', ' ')
|
2020-09-07 11:49:43 +01:00
|
|
|
|
for column in address_lines_1_to_7_keys
|
2020-04-27 10:57:25 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
2016-03-01 15:53:58 +00:00
|
|
|
|
|
2016-05-05 08:39:36 +01:00
|
|
|
|
def get_example_csv_fields(column_headers, use_example_as_example, submitted_fields):
|
|
|
|
|
|
if use_example_as_example:
|
|
|
|
|
|
return ["example" for header in column_headers]
|
|
|
|
|
|
elif submitted_fields:
|
|
|
|
|
|
return [submitted_fields.get(header) for header in column_headers]
|
|
|
|
|
|
else:
|
|
|
|
|
|
return list(column_headers)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_example_csv_rows(template, use_example_as_example=True, submitted_fields=False):
|
2016-11-10 13:39:05 +00:00
|
|
|
|
return {
|
|
|
|
|
|
'email': ['test@example.com'] if use_example_as_example else [current_user.email_address],
|
2017-04-26 16:19:34 +01:00
|
|
|
|
'sms': ['07700 900321'] if use_example_as_example else [current_user.mobile_number],
|
2016-11-11 09:51:20 +00:00
|
|
|
|
'letter': [
|
|
|
|
|
|
(submitted_fields or {}).get(
|
|
|
|
|
|
key, get_example_letter_address(key) if use_example_as_example else key
|
|
|
|
|
|
)
|
2020-04-27 10:57:25 +01:00
|
|
|
|
for key in letter_address_columns
|
2016-11-10 13:39:05 +00:00
|
|
|
|
]
|
2018-06-08 12:49:29 +01:00
|
|
|
|
}[template.template_type] + get_example_csv_fields(
|
|
|
|
|
|
(
|
|
|
|
|
|
placeholder for placeholder in template.placeholders
|
|
|
|
|
|
if placeholder not in Columns.from_keys(
|
|
|
|
|
|
first_column_headings[template.template_type]
|
|
|
|
|
|
)
|
|
|
|
|
|
),
|
|
|
|
|
|
use_example_as_example,
|
|
|
|
|
|
submitted_fields
|
|
|
|
|
|
)
|
2016-04-01 14:31:28 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-11-11 09:51:20 +00:00
|
|
|
|
def get_example_letter_address(key):
|
|
|
|
|
|
return {
|
|
|
|
|
|
'address line 1': 'A. Name',
|
|
|
|
|
|
'address line 2': '123 Example Street',
|
2020-09-07 11:49:43 +01:00
|
|
|
|
'address line 3': 'XM4 5HQ'
|
2016-11-11 09:51:20 +00:00
|
|
|
|
}.get(key, '')
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/send/<uuid:template_id>/csv", methods=['GET', 'POST'])
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2016-02-22 17:17:18 +00:00
|
|
|
|
def send_messages(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2017-05-11 12:01:51 +01:00
|
|
|
|
|
2018-11-06 14:22:22 +00:00
|
|
|
|
email_reply_to = None
|
|
|
|
|
|
sms_sender = None
|
|
|
|
|
|
|
|
|
|
|
|
if db_template['template_type'] == 'email':
|
|
|
|
|
|
email_reply_to = get_email_reply_to_address_from_session()
|
|
|
|
|
|
elif db_template['template_type'] == 'sms':
|
|
|
|
|
|
sms_sender = get_sms_sender_from_session()
|
|
|
|
|
|
|
2020-07-01 16:43:08 +01:00
|
|
|
|
if db_template['template_type'] not in current_service.available_template_types:
|
2017-06-30 10:55:59 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.action_blocked',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=db_template['template_type'],
|
|
|
|
|
|
return_to='view_template',
|
|
|
|
|
|
template_id=template_id
|
|
|
|
|
|
))
|
|
|
|
|
|
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template = get_template(
|
2017-06-22 16:00:14 +01:00
|
|
|
|
db_template,
|
2016-12-08 11:50:59 +00:00
|
|
|
|
current_service,
|
2016-12-20 14:38:34 +00:00
|
|
|
|
show_recipient=True,
|
2017-04-28 16:04:52 +01:00
|
|
|
|
letter_preview_url=url_for(
|
2019-11-29 11:40:49 +00:00
|
|
|
|
'no_cookie.view_letter_template_preview',
|
2017-04-28 16:04:52 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
2017-06-22 16:00:14 +01:00
|
|
|
|
page_count=get_page_count_for_letter(db_template),
|
2017-04-28 16:04:52 +01:00
|
|
|
|
),
|
2018-11-06 14:22:22 +00:00
|
|
|
|
email_reply_to=email_reply_to,
|
|
|
|
|
|
sms_sender=sms_sender,
|
2016-03-29 15:59:53 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2016-01-11 15:00:51 +00:00
|
|
|
|
form = CsvUploadForm()
|
2016-01-13 17:32:40 +00:00
|
|
|
|
if form.validate_on_submit():
|
2016-01-11 15:00:51 +00:00
|
|
|
|
try:
|
2016-05-15 07:47:50 +01:00
|
|
|
|
upload_id = s3upload(
|
2016-03-07 18:47:05 +00:00
|
|
|
|
service_id,
|
2020-03-13 13:53:18 +00:00
|
|
|
|
Spreadsheet.from_file_form(form).as_dict,
|
2016-03-07 18:47:05 +00:00
|
|
|
|
current_app.config['AWS_REGION']
|
|
|
|
|
|
)
|
2020-10-23 16:10:03 +01:00
|
|
|
|
file_name_metadata = unicode_truncate(
|
|
|
|
|
|
SanitiseASCII.encode(form.file.data.filename),
|
|
|
|
|
|
1600
|
|
|
|
|
|
)
|
|
|
|
|
|
set_metadata_on_csv_upload(
|
|
|
|
|
|
service_id,
|
|
|
|
|
|
upload_id,
|
|
|
|
|
|
original_file_name=file_name_metadata
|
|
|
|
|
|
)
|
2018-03-29 17:01:35 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.check_messages',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
upload_id=upload_id,
|
|
|
|
|
|
template_id=template.id,
|
|
|
|
|
|
))
|
2016-05-13 21:25:59 +01:00
|
|
|
|
except (UnicodeDecodeError, BadZipFile, XLRDError):
|
2019-09-13 12:07:27 +01:00
|
|
|
|
flash('Could not read {}. Try using a different file format.'.format(
|
2016-05-13 21:25:59 +01:00
|
|
|
|
form.file.data.filename
|
|
|
|
|
|
))
|
2018-02-28 14:45:57 +00:00
|
|
|
|
except (XLDateError):
|
|
|
|
|
|
flash((
|
2019-09-13 10:17:19 +01:00
|
|
|
|
'{} contains numbers or dates that Notify cannot understand. '
|
2018-02-28 14:45:57 +00:00
|
|
|
|
'Try formatting all columns as ‘text’ or export your file as CSV.'
|
|
|
|
|
|
).format(
|
|
|
|
|
|
form.file.data.filename
|
|
|
|
|
|
))
|
2021-12-03 18:14:02 +00:00
|
|
|
|
elif form.errors:
|
|
|
|
|
|
# just show the first error, as we don't expect the form to have more
|
|
|
|
|
|
# than one, since it only has one field
|
|
|
|
|
|
first_field_errors = list(form.errors.values())[0]
|
|
|
|
|
|
flash(first_field_errors[0])
|
2016-01-11 15:00:51 +00:00
|
|
|
|
|
2018-06-08 12:49:29 +01:00
|
|
|
|
column_headings = get_spreadsheet_column_headings_from_template(template)
|
2016-11-10 13:39:05 +00:00
|
|
|
|
|
2016-02-08 16:36:53 +00:00
|
|
|
|
return render_template(
|
2016-02-22 17:17:18 +00:00
|
|
|
|
'views/send.html',
|
2016-02-08 16:36:53 +00:00
|
|
|
|
template=template,
|
2016-11-10 13:39:05 +00:00
|
|
|
|
column_headings=list(ascii_uppercase[:len(column_headings)]),
|
|
|
|
|
|
example=[column_headings, get_example_csv_rows(template)],
|
2020-12-16 11:05:19 +00:00
|
|
|
|
form=form,
|
2020-12-17 10:47:52 +00:00
|
|
|
|
allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS
|
2016-02-08 16:36:53 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/send/<uuid:template_id>.csv", methods=['GET'])
|
2018-03-01 10:37:55 +00:00
|
|
|
|
@user_has_permissions('send_messages', 'manage_templates')
|
2016-05-05 08:39:36 +01:00
|
|
|
|
def get_example_csv(service_id, template_id):
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template = get_template(
|
|
|
|
|
|
service_api_client.get_service_template(service_id, template_id)['data'], current_service
|
|
|
|
|
|
)
|
2016-05-15 10:47:52 +01:00
|
|
|
|
return Spreadsheet.from_rows([
|
2018-06-08 12:49:29 +01:00
|
|
|
|
get_spreadsheet_column_headings_from_template(template),
|
2016-05-15 10:47:52 +01:00
|
|
|
|
get_example_csv_rows(template)
|
|
|
|
|
|
]).as_csv_data, 200, {
|
|
|
|
|
|
'Content-Type': 'text/csv; charset=utf-8',
|
|
|
|
|
|
'Content-Disposition': 'inline; filename="{}.csv"'.format(template.name)
|
|
|
|
|
|
}
|
2015-12-10 21:15:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/send/<uuid:template_id>/set-sender", methods=['GET', 'POST'])
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2017-10-16 16:35:35 +01:00
|
|
|
|
def set_sender(service_id, template_id):
|
|
|
|
|
|
session['sender_id'] = None
|
|
|
|
|
|
redirect_to_one_off = redirect(
|
|
|
|
|
|
url_for('.send_one_off', service_id=service_id, template_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-11-02 12:07:46 +00:00
|
|
|
|
if template['template_type'] == 'letter':
|
2017-10-16 16:35:35 +01:00
|
|
|
|
return redirect_to_one_off
|
|
|
|
|
|
|
|
|
|
|
|
sender_details = get_sender_details(service_id, template['template_type'])
|
2021-02-08 17:23:47 +00:00
|
|
|
|
|
|
|
|
|
|
if len(sender_details) == 1:
|
|
|
|
|
|
session['sender_id'] = sender_details[0]['id']
|
|
|
|
|
|
|
2017-10-16 16:35:35 +01:00
|
|
|
|
if len(sender_details) <= 1:
|
|
|
|
|
|
return redirect_to_one_off
|
|
|
|
|
|
|
|
|
|
|
|
sender_context = get_sender_context(sender_details, template['template_type'])
|
|
|
|
|
|
|
|
|
|
|
|
form = SetSenderForm(
|
|
|
|
|
|
sender=sender_context['default_id'],
|
|
|
|
|
|
sender_choices=sender_context['value_and_label'],
|
|
|
|
|
|
sender_label=sender_context['description']
|
|
|
|
|
|
)
|
2018-03-01 11:04:25 +00:00
|
|
|
|
option_hints = {sender_context['default_id']: '(Default)'}
|
2017-11-02 15:48:19 +00:00
|
|
|
|
if sender_context.get('receives_text_message', None):
|
|
|
|
|
|
option_hints.update({sender_context['receives_text_message']: '(Receives replies)'})
|
|
|
|
|
|
if sender_context.get('default_and_receives', None):
|
|
|
|
|
|
option_hints = {sender_context['default_and_receives']: '(Default and receives replies)'}
|
2017-10-16 16:35:35 +01:00
|
|
|
|
|
2021-01-13 10:31:07 +00:00
|
|
|
|
# extend all radios that need hint text
|
|
|
|
|
|
form.sender.param_extensions = {'items': []}
|
|
|
|
|
|
for item_id, _item_value in form.sender.choices:
|
|
|
|
|
|
if item_id in option_hints:
|
|
|
|
|
|
extensions = {'hint': {'text': option_hints[item_id]}}
|
|
|
|
|
|
else:
|
|
|
|
|
|
extensions = {} # if no extensions needed, send an empty dict to preserve order of items
|
|
|
|
|
|
form.sender.param_extensions['items'].append(extensions)
|
|
|
|
|
|
|
2017-10-16 16:35:35 +01:00
|
|
|
|
if form.validate_on_submit():
|
|
|
|
|
|
session['sender_id'] = form.sender.data
|
|
|
|
|
|
return redirect(url_for('.send_one_off',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id))
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/templates/set-sender.html',
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
sender_context={'title': sender_context['title'], 'description': sender_context['description']},
|
|
|
|
|
|
option_hints=option_hints
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_sender_context(sender_details, template_type):
|
|
|
|
|
|
context = {
|
|
|
|
|
|
'email': {
|
2017-11-20 16:47:03 +00:00
|
|
|
|
'title': 'Where should replies come back to?',
|
|
|
|
|
|
'description': 'Where should replies come back to?',
|
2017-10-16 16:35:35 +01:00
|
|
|
|
'field_name': 'email_address'
|
|
|
|
|
|
},
|
|
|
|
|
|
'letter': {
|
2017-11-13 11:34:32 +00:00
|
|
|
|
'title': 'Send to one recipient',
|
2017-11-13 11:31:12 +00:00
|
|
|
|
'description': 'What should appear in the top right of the letter?',
|
2017-10-16 16:35:35 +01:00
|
|
|
|
'field_name': 'contact_block'
|
2017-11-02 12:07:46 +00:00
|
|
|
|
},
|
|
|
|
|
|
'sms': {
|
2017-11-20 16:26:09 +00:00
|
|
|
|
'title': 'Who should the message come from?',
|
2017-11-13 11:31:12 +00:00
|
|
|
|
'description': 'Who should the message come from?',
|
2017-11-02 12:07:46 +00:00
|
|
|
|
'field_name': 'sms_sender'
|
2017-10-16 16:35:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
}[template_type]
|
|
|
|
|
|
|
|
|
|
|
|
sender_format = context['field_name']
|
|
|
|
|
|
|
|
|
|
|
|
context['default_id'] = next(sender['id'] for sender in sender_details if sender['is_default'])
|
2017-11-02 14:58:14 +00:00
|
|
|
|
if template_type == 'sms':
|
2017-11-02 15:48:19 +00:00
|
|
|
|
inbound = [sender['id'] for sender in sender_details if sender['inbound_number_id']]
|
|
|
|
|
|
if inbound:
|
|
|
|
|
|
context['receives_text_message'] = next(iter(inbound))
|
|
|
|
|
|
if context['default_id'] == context.get('receives_text_message', None):
|
|
|
|
|
|
context['default_and_receives'] = context['default_id']
|
|
|
|
|
|
|
2020-01-22 16:13:25 +00:00
|
|
|
|
context['value_and_label'] = [(sender['id'], nl2br(sender[sender_format])) for sender in sender_details]
|
2017-10-16 16:35:35 +01:00
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_sender_details(service_id, template_type):
|
|
|
|
|
|
api_call = {
|
|
|
|
|
|
'email': service_api_client.get_reply_to_email_addresses,
|
2017-11-02 12:07:46 +00:00
|
|
|
|
'letter': service_api_client.get_letter_contacts,
|
|
|
|
|
|
'sms': service_api_client.get_sms_senders
|
2017-10-16 16:35:35 +01:00
|
|
|
|
}[template_type]
|
|
|
|
|
|
return api_call(service_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-10-07 14:51:18 +01:00
|
|
|
|
@main.route("/services/<uuid:service_id>/send/<uuid:template_id>/one-off")
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2020-10-07 14:51:18 +01:00
|
|
|
|
def send_one_off(service_id, template_id):
|
2017-06-23 17:30:34 +01:00
|
|
|
|
session['recipient'] = None
|
|
|
|
|
|
session['placeholders'] = {}
|
2017-06-30 10:55:59 +01:00
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2017-11-02 12:07:46 +00:00
|
|
|
|
if db_template['template_type'] == 'letter':
|
2017-10-16 16:35:35 +01:00
|
|
|
|
session['sender_id'] = None
|
2020-07-01 16:43:08 +01:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for('.send_one_off_letter_address', service_id=service_id, template_id=template_id)
|
|
|
|
|
|
)
|
2017-06-30 10:55:59 +01:00
|
|
|
|
|
2020-07-01 16:43:08 +01:00
|
|
|
|
if db_template['template_type'] not in current_service.available_template_types:
|
2017-06-30 10:55:59 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.action_blocked',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=db_template['template_type'],
|
|
|
|
|
|
return_to='view_template',
|
|
|
|
|
|
template_id=template_id))
|
|
|
|
|
|
|
2017-05-04 09:30:55 +01:00
|
|
|
|
return redirect(url_for(
|
2020-10-07 14:51:18 +01:00
|
|
|
|
'.send_one_off_step',
|
2017-05-04 09:30:55 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
step_index=0,
|
|
|
|
|
|
))
|
2016-03-02 17:02:41 +00:00
|
|
|
|
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2017-06-23 17:30:34 +01:00
|
|
|
|
def get_notification_check_endpoint(service_id, template):
|
2018-10-30 14:24:50 +00:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'main.check_notification',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template.id,
|
|
|
|
|
|
))
|
2017-06-23 17:30:34 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-03-10 15:12:19 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/send/<uuid:template_id>/one-off/address",
|
|
|
|
|
|
methods=['GET', 'POST']
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
|
|
|
|
|
def send_one_off_letter_address(service_id, template_id):
|
|
|
|
|
|
if {'recipient', 'placeholders'} - set(session.keys()):
|
|
|
|
|
|
# if someone has come here via a bookmark or back button they might have some stuff still in their session
|
|
|
|
|
|
return redirect(url_for('.send_one_off', service_id=service_id, template_id=template_id))
|
|
|
|
|
|
|
|
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
|
|
|
|
|
|
|
|
|
|
|
template = get_template(
|
|
|
|
|
|
db_template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
show_recipient=True,
|
|
|
|
|
|
letter_preview_url=url_for(
|
|
|
|
|
|
'no_cookie.send_test_preview',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
2020-05-15 13:55:04 +01:00
|
|
|
|
page_count=get_page_count_for_letter(db_template),
|
2020-03-10 15:12:19 +00:00
|
|
|
|
email_reply_to=None,
|
|
|
|
|
|
sms_sender=None
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2020-04-02 17:21:27 +01:00
|
|
|
|
current_session_address = PostalAddress.from_personalisation(
|
|
|
|
|
|
get_normalised_placeholders_from_session()
|
|
|
|
|
|
)
|
2020-03-12 13:56:35 +00:00
|
|
|
|
|
2020-04-27 10:57:25 +01:00
|
|
|
|
form = LetterAddressForm(
|
|
|
|
|
|
address=current_session_address.normalised,
|
|
|
|
|
|
allow_international_letters=current_service.has_permission('international_letters'),
|
|
|
|
|
|
)
|
2020-03-10 15:12:19 +00:00
|
|
|
|
|
|
|
|
|
|
if form.validate_on_submit():
|
2020-04-02 17:21:27 +01:00
|
|
|
|
session['placeholders'].update(PostalAddress(form.address.data).as_personalisation)
|
2020-03-10 15:12:19 +00:00
|
|
|
|
|
2020-10-07 14:51:18 +01:00
|
|
|
|
placeholders = fields_to_fill_in(template)
|
2020-03-10 15:12:19 +00:00
|
|
|
|
if all_placeholders_in_session(placeholders):
|
|
|
|
|
|
return get_notification_check_endpoint(service_id, template)
|
|
|
|
|
|
|
2020-09-07 11:49:43 +01:00
|
|
|
|
first_non_address_placeholder_index = len(address_lines_1_to_7_keys)
|
2020-04-27 10:57:25 +01:00
|
|
|
|
|
2020-03-10 15:12:19 +00:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'main.send_one_off_step',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
step_index=first_non_address_placeholder_index,
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/send-one-off-letter-address.html',
|
|
|
|
|
|
page_title=get_send_test_page_title(
|
|
|
|
|
|
template_type='letter',
|
|
|
|
|
|
entering_recipient=True,
|
|
|
|
|
|
name=template.name,
|
|
|
|
|
|
),
|
|
|
|
|
|
template=template,
|
|
|
|
|
|
form=form,
|
|
|
|
|
|
back_link=get_back_link(service_id, template, 0),
|
|
|
|
|
|
link_to_upload=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-25 08:55:05 +01:00
|
|
|
|
@main.route(
|
2019-11-04 11:07:55 +00:00
|
|
|
|
"/services/<uuid:service_id>/send/<uuid:template_id>/one-off/step-<int:step_index>",
|
2017-05-25 08:55:05 +01:00
|
|
|
|
methods=['GET', 'POST'],
|
|
|
|
|
|
)
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2020-10-07 14:51:18 +01:00
|
|
|
|
def send_one_off_step(service_id, template_id, step_index):
|
2017-06-23 17:30:34 +01:00
|
|
|
|
if {'recipient', 'placeholders'} - set(session.keys()):
|
2017-05-22 11:49:15 +01:00
|
|
|
|
return redirect(url_for(
|
2020-10-07 14:51:18 +01:00
|
|
|
|
".send_one_off",
|
2017-05-25 08:55:05 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
2017-05-22 11:49:15 +01:00
|
|
|
|
))
|
|
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2017-05-11 12:01:51 +01:00
|
|
|
|
|
2017-11-02 12:07:46 +00:00
|
|
|
|
email_reply_to = None
|
|
|
|
|
|
sms_sender = None
|
|
|
|
|
|
if db_template['template_type'] == 'email':
|
2018-10-26 17:31:49 +01:00
|
|
|
|
email_reply_to = get_email_reply_to_address_from_session()
|
2017-11-02 12:07:46 +00:00
|
|
|
|
elif db_template['template_type'] == 'sms':
|
2018-10-26 17:31:49 +01:00
|
|
|
|
sms_sender = get_sms_sender_from_session()
|
2020-07-21 16:06:33 +01:00
|
|
|
|
|
|
|
|
|
|
template_values = get_recipient_and_placeholders_from_session(db_template['template_type'])
|
|
|
|
|
|
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template = get_template(
|
2017-06-22 16:00:14 +01:00
|
|
|
|
db_template,
|
2016-12-08 11:50:59 +00:00
|
|
|
|
current_service,
|
2016-12-20 14:38:34 +00:00
|
|
|
|
show_recipient=True,
|
2017-04-28 16:04:52 +01:00
|
|
|
|
letter_preview_url=url_for(
|
2019-11-29 11:40:49 +00:00
|
|
|
|
'no_cookie.send_test_preview',
|
2017-04-28 16:04:52 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
2020-07-21 16:06:33 +01:00
|
|
|
|
page_count=get_page_count_for_letter(db_template, values=template_values),
|
2017-11-02 12:07:46 +00:00
|
|
|
|
email_reply_to=email_reply_to,
|
|
|
|
|
|
sms_sender=sms_sender
|
2016-05-05 08:39:36 +01:00
|
|
|
|
)
|
2016-04-03 11:30:23 +01:00
|
|
|
|
|
2020-10-07 14:51:18 +01:00
|
|
|
|
placeholders = fields_to_fill_in(template)
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2017-05-22 11:49:15 +01:00
|
|
|
|
try:
|
2019-06-06 12:24:02 +01:00
|
|
|
|
current_placeholder = placeholders[step_index]
|
2017-05-22 11:49:15 +01:00
|
|
|
|
except IndexError:
|
2017-05-25 09:18:26 +01:00
|
|
|
|
if all_placeholders_in_session(placeholders):
|
2017-06-23 17:30:34 +01:00
|
|
|
|
return get_notification_check_endpoint(service_id, template)
|
2017-05-22 11:49:15 +01:00
|
|
|
|
return redirect(url_for(
|
2020-10-07 14:51:18 +01:00
|
|
|
|
'.send_one_off',
|
2017-05-25 08:55:05 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
2017-05-22 11:49:15 +01:00
|
|
|
|
))
|
2017-06-22 16:00:14 +01:00
|
|
|
|
|
2020-03-12 13:56:35 +00:00
|
|
|
|
# if we're in a letter, we should show address block rather than "address line #" or "postcode"
|
2020-04-09 15:45:30 +01:00
|
|
|
|
if template.template_type == 'letter':
|
2020-09-07 11:49:43 +01:00
|
|
|
|
if step_index < len(address_lines_1_to_7_keys):
|
2020-04-09 15:45:30 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.send_one_off_letter_address',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
))
|
|
|
|
|
|
if current_placeholder in Columns(PostalAddress('').as_personalisation):
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
request.endpoint,
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
step_index=step_index + 1,
|
|
|
|
|
|
))
|
2020-03-12 13:56:35 +00:00
|
|
|
|
|
2017-05-04 09:30:55 +01:00
|
|
|
|
form = get_placeholder_form_instance(
|
|
|
|
|
|
current_placeholder,
|
2017-06-23 17:30:34 +01:00
|
|
|
|
dict_to_populate_from=get_normalised_placeholders_from_session(),
|
2018-03-16 14:17:43 +00:00
|
|
|
|
template_type=template.template_type,
|
2018-07-20 08:43:02 +01:00
|
|
|
|
allow_international_phone_numbers=current_service.has_permission('international_sms'),
|
2017-05-04 09:30:55 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if form.validate_on_submit():
|
2017-06-26 10:58:43 +01:00
|
|
|
|
# if it's the first input (phone/email), we store against `recipient` as well, for easier extraction.
|
|
|
|
|
|
# Only if it's not a letter.
|
|
|
|
|
|
# And only if we're not on the test route, since that will already have the user's own number set
|
|
|
|
|
|
if (
|
2019-05-28 17:44:27 +01:00
|
|
|
|
step_index == 0
|
|
|
|
|
|
and template.template_type != 'letter'
|
2017-06-26 10:58:43 +01:00
|
|
|
|
):
|
2017-06-23 17:30:34 +01:00
|
|
|
|
session['recipient'] = form.placeholder_value.data
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2017-06-23 17:30:34 +01:00
|
|
|
|
session['placeholders'][current_placeholder] = form.placeholder_value.data
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2017-05-25 09:18:26 +01:00
|
|
|
|
if all_placeholders_in_session(placeholders):
|
2017-06-23 17:30:34 +01:00
|
|
|
|
return get_notification_check_endpoint(service_id, template)
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2016-05-15 10:47:52 +01:00
|
|
|
|
return redirect(url_for(
|
2017-05-25 08:55:05 +01:00
|
|
|
|
request.endpoint,
|
2016-05-15 10:47:52 +01:00
|
|
|
|
service_id=service_id,
|
2017-05-04 09:30:55 +01:00
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
step_index=step_index + 1,
|
2016-05-15 10:47:52 +01:00
|
|
|
|
))
|
2016-03-29 15:59:53 +01:00
|
|
|
|
|
2020-04-09 16:25:48 +01:00
|
|
|
|
back_link = get_back_link(service_id, template, step_index, placeholders)
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2020-07-21 16:06:33 +01:00
|
|
|
|
template.values = template_values
|
2017-05-16 17:17:11 +01:00
|
|
|
|
template.values[current_placeholder] = None
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2016-05-05 08:39:36 +01:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/send-test.html',
|
2017-11-20 16:45:59 +00:00
|
|
|
|
page_title=get_send_test_page_title(
|
|
|
|
|
|
template.template_type,
|
2018-08-06 11:20:50 +01:00
|
|
|
|
entering_recipient=not session['recipient'],
|
|
|
|
|
|
name=template.name,
|
2017-11-20 16:45:59 +00:00
|
|
|
|
),
|
2016-05-05 08:39:36 +01:00
|
|
|
|
template=template,
|
2017-05-04 09:30:55 +01:00
|
|
|
|
form=form,
|
2020-04-09 16:37:38 +01:00
|
|
|
|
skip_link=get_skip_link(step_index, template),
|
2017-05-04 09:30:55 +01:00
|
|
|
|
back_link=back_link,
|
2018-07-18 09:48:19 +01:00
|
|
|
|
link_to_upload=(
|
2019-05-28 17:44:27 +01:00
|
|
|
|
request.endpoint == 'main.send_one_off_step'
|
|
|
|
|
|
and step_index == 0
|
2018-07-18 09:48:19 +01:00
|
|
|
|
),
|
2016-05-05 08:39:36 +01:00
|
|
|
|
)
|
2016-02-12 10:55:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-29 11:40:49 +00:00
|
|
|
|
@no_cookie.route("/services/<uuid:service_id>/send/<uuid:template_id>/test.<filetype>", methods=['GET'])
|
2018-02-28 17:22:20 +00:00
|
|
|
|
@user_has_permissions('send_messages')
|
2017-05-04 09:30:55 +01:00
|
|
|
|
def send_test_preview(service_id, template_id, filetype):
|
|
|
|
|
|
|
|
|
|
|
|
if filetype not in ('pdf', 'png'):
|
|
|
|
|
|
abort(404)
|
|
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
|
|
|
|
|
template = get_template(
|
2017-06-22 16:00:14 +01:00
|
|
|
|
db_template,
|
2017-05-04 09:30:55 +01:00
|
|
|
|
current_service,
|
|
|
|
|
|
letter_preview_url=url_for(
|
2019-11-29 11:40:49 +00:00
|
|
|
|
'no_cookie.send_test_preview',
|
2017-05-04 09:30:55 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2017-06-23 17:30:34 +01:00
|
|
|
|
template.values = get_normalised_placeholders_from_session()
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
|
|
|
|
|
return TemplatePreview.from_utils_template(template, filetype, page=request.args.get('page'))
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-13 17:51:22 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
'/services/<uuid:service_id>/send/<uuid:template_id>'
|
|
|
|
|
|
'/from-contact-list'
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions('send_messages')
|
|
|
|
|
|
def choose_from_contact_list(service_id, template_id):
|
2020-03-16 09:41:42 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(
|
|
|
|
|
|
template_id, current_user
|
|
|
|
|
|
)
|
|
|
|
|
|
template = get_template(
|
|
|
|
|
|
db_template, current_service,
|
|
|
|
|
|
)
|
2020-03-13 17:51:22 +00:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/send-contact-list.html',
|
2020-03-16 11:05:26 +00:00
|
|
|
|
contact_lists=ContactListsAlphabetical(
|
2020-03-16 09:41:42 +00:00
|
|
|
|
current_service.id,
|
|
|
|
|
|
template_type=template.template_type,
|
|
|
|
|
|
),
|
2020-03-16 10:34:05 +00:00
|
|
|
|
template=template,
|
2020-03-13 17:51:22 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-13 14:38:43 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
'/services/<uuid:service_id>/send/<uuid:template_id>'
|
|
|
|
|
|
'/from-contact-list/<uuid:contact_list_id>'
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions('send_messages')
|
|
|
|
|
|
def send_from_contact_list(service_id, template_id, contact_list_id):
|
2020-03-16 11:25:07 +00:00
|
|
|
|
contact_list = ContactList.from_id(
|
|
|
|
|
|
contact_list_id,
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
)
|
2020-03-13 14:38:43 +00:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'main.check_messages',
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
template_id=template_id,
|
2020-03-16 11:25:07 +00:00
|
|
|
|
upload_id=contact_list.copy_to_uploads(),
|
2020-03-16 17:00:34 +00:00
|
|
|
|
contact_list_id=contact_list.id,
|
2020-03-13 14:38:43 +00:00
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-05-11 08:46:42 +01:00
|
|
|
|
def _check_messages(service_id, template_id, upload_id, preview_row, letters_as_pdf=False):
|
2016-02-22 17:17:18 +00:00
|
|
|
|
|
2018-05-03 13:35:59 +01:00
|
|
|
|
try:
|
2018-04-30 12:55:56 +01:00
|
|
|
|
# The happy path is that the job doesn’t already exist, so the
|
|
|
|
|
|
# API will return a 404 and the client will raise HTTPError.
|
|
|
|
|
|
job_api_client.get_job(service_id, upload_id)
|
2018-05-03 13:35:59 +01:00
|
|
|
|
|
|
|
|
|
|
# the job exists already - so go back to the templates page
|
2018-04-30 12:55:56 +01:00
|
|
|
|
# If we just return a `redirect` (302) object here, we'll get
|
|
|
|
|
|
# errors when we try and unpack in the check_messages route.
|
|
|
|
|
|
# Rasing a werkzeug.routing redirect means that doesn't happen.
|
2019-03-21 16:41:22 +00:00
|
|
|
|
raise PermanentRedirect(url_for(
|
2019-11-29 11:40:49 +00:00
|
|
|
|
'main.send_messages',
|
2018-04-30 12:55:56 +01:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id
|
|
|
|
|
|
))
|
2018-05-03 13:35:59 +01:00
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
if e.status_code != 404:
|
|
|
|
|
|
raise
|
2018-04-30 12:55:56 +01:00
|
|
|
|
|
2021-06-23 15:56:05 +01:00
|
|
|
|
notification_count = service_api_client.get_notification_count(service_id)
|
|
|
|
|
|
remaining_messages = (current_service.message_limit - notification_count)
|
2016-04-04 14:28:52 +01:00
|
|
|
|
|
2016-03-07 18:47:05 +00:00
|
|
|
|
contents = s3download(service_id, upload_id)
|
2018-03-29 17:01:35 +01:00
|
|
|
|
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2018-03-29 17:01:35 +01:00
|
|
|
|
|
2017-11-02 12:07:46 +00:00
|
|
|
|
email_reply_to = None
|
|
|
|
|
|
sms_sender = None
|
2018-03-29 17:01:35 +01:00
|
|
|
|
if db_template['template_type'] == 'email':
|
2018-10-26 17:31:49 +01:00
|
|
|
|
email_reply_to = get_email_reply_to_address_from_session()
|
2018-03-29 17:01:35 +01:00
|
|
|
|
elif db_template['template_type'] == 'sms':
|
2018-10-26 17:31:49 +01:00
|
|
|
|
sms_sender = get_sms_sender_from_session()
|
2019-10-08 14:56:00 +01:00
|
|
|
|
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template = get_template(
|
2018-05-10 17:00:41 +01:00
|
|
|
|
db_template,
|
2016-12-08 11:50:59 +00:00
|
|
|
|
current_service,
|
2016-12-20 14:38:34 +00:00
|
|
|
|
show_recipient=True,
|
|
|
|
|
|
letter_preview_url=url_for(
|
2019-11-29 11:40:49 +00:00
|
|
|
|
'no_cookie.check_messages_preview',
|
2016-12-20 14:38:34 +00:00
|
|
|
|
service_id=service_id,
|
2018-03-29 17:01:35 +01:00
|
|
|
|
template_id=template_id,
|
2017-04-28 16:04:52 +01:00
|
|
|
|
upload_id=upload_id,
|
|
|
|
|
|
filetype='png',
|
2017-12-06 22:04:58 +00:00
|
|
|
|
row_index=preview_row,
|
2017-10-17 16:06:15 +01:00
|
|
|
|
) if not letters_as_pdf else None,
|
2017-11-02 12:07:46 +00:00
|
|
|
|
email_reply_to=email_reply_to,
|
2018-03-29 17:01:35 +01:00
|
|
|
|
sms_sender=sms_sender,
|
2019-10-08 14:56:00 +01:00
|
|
|
|
page_count=get_page_count_for_letter(db_template),
|
2016-02-26 10:54:06 +00:00
|
|
|
|
)
|
2016-03-07 18:47:05 +00:00
|
|
|
|
recipients = RecipientCSV(
|
|
|
|
|
|
contents,
|
2019-11-21 12:12:04 +00:00
|
|
|
|
template=template,
|
2016-04-07 14:30:51 +01:00
|
|
|
|
max_initial_rows_shown=50,
|
|
|
|
|
|
max_errors_shown=50,
|
2021-12-10 16:35:40 +00:00
|
|
|
|
guestlist=itertools.chain.from_iterable(
|
2019-05-23 15:27:35 +01:00
|
|
|
|
[user.name, user.mobile_number, user.email_address] for user in Users(service_id)
|
2018-07-20 08:42:01 +01:00
|
|
|
|
) if current_service.trial_mode else None,
|
2017-04-26 16:19:49 +01:00
|
|
|
|
remaining_messages=remaining_messages,
|
2020-04-27 10:57:25 +01:00
|
|
|
|
allow_international_sms=current_service.has_permission('international_sms'),
|
|
|
|
|
|
allow_international_letters=current_service.has_permission('international_letters'),
|
2016-03-07 18:47:05 +00:00
|
|
|
|
)
|
2016-02-26 10:54:06 +00:00
|
|
|
|
|
2016-07-01 07:04:55 +01:00
|
|
|
|
if request.args.get('from_test'):
|
2017-06-30 11:49:03 +01:00
|
|
|
|
# only happens if generating a letter preview test
|
2020-10-07 14:51:18 +01:00
|
|
|
|
back_link = url_for('main.send_one_off', service_id=service_id, template_id=template.id)
|
2016-08-30 09:27:24 +01:00
|
|
|
|
choose_time_form = None
|
2016-05-05 08:39:36 +01:00
|
|
|
|
else:
|
2019-11-29 11:40:49 +00:00
|
|
|
|
back_link = url_for('main.send_messages', service_id=service_id, template_id=template.id)
|
2016-08-30 09:27:24 +01:00
|
|
|
|
choose_time_form = ChooseTimeForm()
|
2016-05-05 08:39:36 +01:00
|
|
|
|
|
2018-01-15 11:35:45 +00:00
|
|
|
|
if preview_row < 2:
|
|
|
|
|
|
abort(404)
|
|
|
|
|
|
|
2018-03-05 15:57:10 +00:00
|
|
|
|
if preview_row < len(recipients) + 2:
|
|
|
|
|
|
template.values = recipients[preview_row - 2].recipient_and_personalisation
|
2018-01-15 11:35:45 +00:00
|
|
|
|
elif preview_row > 2:
|
2017-12-20 11:48:30 +00:00
|
|
|
|
abort(404)
|
|
|
|
|
|
|
2019-10-08 14:56:00 +01:00
|
|
|
|
page_count = get_page_count_for_letter(db_template, template.values)
|
2020-10-27 10:52:16 +00:00
|
|
|
|
original_file_name = get_csv_metadata(service_id, upload_id).get('original_file_name', '')
|
2019-10-08 14:56:00 +01:00
|
|
|
|
|
2016-12-20 11:56:22 +00:00
|
|
|
|
return dict(
|
2016-03-07 18:47:05 +00:00
|
|
|
|
recipients=recipients,
|
|
|
|
|
|
template=template,
|
2016-06-03 13:52:15 +01:00
|
|
|
|
errors=recipients.has_errors,
|
|
|
|
|
|
row_errors=get_errors_for_csv(recipients, template.template_type),
|
2018-03-05 15:57:10 +00:00
|
|
|
|
count_of_recipients=len(recipients),
|
|
|
|
|
|
count_of_displayed_recipients=len(list(recipients.displayed_rows)),
|
2020-10-21 13:07:59 +01:00
|
|
|
|
original_file_name=original_file_name,
|
2016-03-29 15:59:53 +01:00
|
|
|
|
upload_id=upload_id,
|
2016-04-22 09:36:42 +01:00
|
|
|
|
form=CsvUploadForm(),
|
2016-07-25 14:16:34 +01:00
|
|
|
|
remaining_messages=remaining_messages,
|
2016-08-30 09:27:24 +01:00
|
|
|
|
choose_time_form=choose_time_form,
|
2016-07-05 11:39:07 +01:00
|
|
|
|
back_link=back_link,
|
2017-08-25 14:17:23 +01:00
|
|
|
|
trying_to_send_letters_in_trial_mode=all((
|
2018-07-20 08:42:01 +01:00
|
|
|
|
current_service.trial_mode,
|
2017-08-25 14:17:23 +01:00
|
|
|
|
template.template_type == 'letter',
|
|
|
|
|
|
)),
|
2020-04-19 22:46:13 +01:00
|
|
|
|
first_recipient_column=recipients.recipient_column_headers[0],
|
2018-01-15 11:25:11 +00:00
|
|
|
|
preview_row=preview_row,
|
2019-02-04 14:08:11 +00:00
|
|
|
|
sent_previously=job_api_client.has_sent_previously(
|
2020-10-21 13:07:59 +01:00
|
|
|
|
service_id, template.id, db_template['version'], original_file_name
|
2019-10-01 15:34:46 +01:00
|
|
|
|
),
|
2019-10-01 17:16:15 +01:00
|
|
|
|
letter_too_long=is_letter_too_long(page_count),
|
2019-10-09 14:56:18 +01:00
|
|
|
|
letter_max_pages=LETTER_MAX_PAGE_COUNT,
|
2020-04-15 13:31:14 +01:00
|
|
|
|
letter_min_address_lines=PostalAddress.MIN_LINES,
|
|
|
|
|
|
letter_max_address_lines=PostalAddress.MAX_LINES,
|
2019-10-16 13:02:11 +01:00
|
|
|
|
page_count=page_count
|
2016-03-07 18:47:05 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/<uuid:template_id>/check/<uuid:upload_id>", methods=['GET'])
|
2019-11-29 13:03:23 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/<uuid:template_id>/check/<uuid:upload_id>/row-<int:row_index>",
|
|
|
|
|
|
methods=['GET']
|
|
|
|
|
|
)
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2018-03-29 17:01:35 +01:00
|
|
|
|
def check_messages(service_id, template_id, upload_id, row_index=2):
|
2017-07-20 08:59:49 +01:00
|
|
|
|
|
2018-05-11 08:46:42 +01:00
|
|
|
|
data = _check_messages(service_id, template_id, upload_id, row_index)
|
2020-12-17 10:47:52 +00:00
|
|
|
|
data['allowed_file_extensions'] = Spreadsheet.ALLOWED_FILE_EXTENSIONS
|
2017-07-20 08:59:49 +01:00
|
|
|
|
|
2017-07-20 09:10:23 +01:00
|
|
|
|
if (
|
2019-10-01 15:34:46 +01:00
|
|
|
|
data['recipients'].too_many_rows
|
|
|
|
|
|
or not data['count_of_recipients']
|
|
|
|
|
|
or not data['recipients'].has_recipient_columns
|
|
|
|
|
|
or data['recipients'].duplicate_recipient_column_headers
|
|
|
|
|
|
or data['recipients'].missing_column_headers
|
|
|
|
|
|
or data['sent_previously']
|
2017-07-20 09:10:23 +01:00
|
|
|
|
):
|
|
|
|
|
|
return render_template('views/check/column-errors.html', **data)
|
|
|
|
|
|
|
2017-07-20 08:59:49 +01:00
|
|
|
|
if data['row_errors']:
|
|
|
|
|
|
return render_template('views/check/row-errors.html', **data)
|
|
|
|
|
|
|
2017-09-14 12:21:40 +01:00
|
|
|
|
if (
|
2019-10-01 15:34:46 +01:00
|
|
|
|
data['errors']
|
|
|
|
|
|
or data['trying_to_send_letters_in_trial_mode']
|
2017-09-14 12:21:40 +01:00
|
|
|
|
):
|
2017-07-20 08:59:49 +01:00
|
|
|
|
return render_template('views/check/column-errors.html', **data)
|
|
|
|
|
|
|
2018-11-06 14:22:22 +00:00
|
|
|
|
metadata_kwargs = {
|
|
|
|
|
|
'notification_count': data['count_of_recipients'],
|
2019-11-04 12:20:09 +00:00
|
|
|
|
'template_id': template_id,
|
2018-11-06 14:22:22 +00:00
|
|
|
|
'valid': True,
|
2020-10-27 10:52:16 +00:00
|
|
|
|
'original_file_name': data.get('original_file_name', ''),
|
2018-11-06 14:22:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-15 13:51:48 +01:00
|
|
|
|
if session.get('sender_id') and data['template'].template_type != 'letter':
|
|
|
|
|
|
# sender_id is not an option for sending letters.
|
2018-11-06 14:22:22 +00:00
|
|
|
|
metadata_kwargs['sender_id'] = session['sender_id']
|
|
|
|
|
|
|
|
|
|
|
|
set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs)
|
2018-05-11 08:46:42 +01:00
|
|
|
|
|
2017-07-20 08:59:49 +01:00
|
|
|
|
return render_template('views/check/ok.html', **data)
|
2016-12-20 11:56:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-29 11:40:49 +00:00
|
|
|
|
@no_cookie.route(
|
2019-11-04 11:07:55 +00:00
|
|
|
|
"/services/<uuid:service_id>/<uuid:template_id>/check/<uuid:upload_id>.<filetype>",
|
2018-03-29 17:01:35 +01:00
|
|
|
|
methods=['GET'],
|
|
|
|
|
|
)
|
2019-11-29 11:40:49 +00:00
|
|
|
|
@no_cookie.route(
|
2019-11-04 11:07:55 +00:00
|
|
|
|
"/services/<uuid:service_id>/<uuid:template_id>/check/<uuid:upload_id>/row-<int:row_index>.<filetype>",
|
2018-03-29 17:01:35 +01:00
|
|
|
|
methods=['GET'],
|
|
|
|
|
|
)
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages')
|
2018-03-29 17:01:35 +01:00
|
|
|
|
def check_messages_preview(service_id, template_id, upload_id, filetype, row_index=2):
|
2018-10-15 14:02:13 +01:00
|
|
|
|
if filetype == 'pdf':
|
|
|
|
|
|
page = None
|
|
|
|
|
|
elif filetype == 'png':
|
|
|
|
|
|
page = request.args.get('page', 1)
|
|
|
|
|
|
else:
|
2017-04-12 12:12:11 +01:00
|
|
|
|
abort(404)
|
|
|
|
|
|
|
2016-12-20 14:38:34 +00:00
|
|
|
|
template = _check_messages(
|
2018-05-11 08:46:42 +01:00
|
|
|
|
service_id, template_id, upload_id, row_index, letters_as_pdf=True
|
2016-12-20 14:38:34 +00:00
|
|
|
|
)['template']
|
2018-10-15 14:02:13 +01:00
|
|
|
|
return TemplatePreview.from_utils_template(template, filetype, page=page)
|
2016-12-20 14:38:34 +00:00
|
|
|
|
|
2017-04-10 18:12:00 +01:00
|
|
|
|
|
2019-11-29 11:40:49 +00:00
|
|
|
|
@no_cookie.route(
|
2019-11-04 11:07:55 +00:00
|
|
|
|
"/services/<uuid:service_id>/<uuid:template_id>/check.<filetype>",
|
2018-10-30 14:24:50 +00:00
|
|
|
|
methods=['GET'],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions('send_messages')
|
|
|
|
|
|
def check_notification_preview(service_id, template_id, filetype):
|
|
|
|
|
|
if filetype == 'pdf':
|
|
|
|
|
|
page = None
|
|
|
|
|
|
elif filetype == 'png':
|
|
|
|
|
|
page = request.args.get('page', 1)
|
|
|
|
|
|
else:
|
|
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
|
|
|
|
template = _check_notification(
|
|
|
|
|
|
service_id, template_id,
|
|
|
|
|
|
)['template']
|
|
|
|
|
|
return TemplatePreview.from_utils_template(template, filetype, page=page)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/start-job/<uuid:upload_id>", methods=['POST'])
|
2018-02-28 18:13:29 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2016-03-07 18:47:05 +00:00
|
|
|
|
def start_job(service_id, upload_id):
|
|
|
|
|
|
|
2016-03-08 17:50:18 +00:00
|
|
|
|
job_api_client.create_job(
|
|
|
|
|
|
upload_id,
|
|
|
|
|
|
service_id,
|
2020-03-16 17:00:34 +00:00
|
|
|
|
scheduled_for=request.form.get('scheduled_for', ''),
|
|
|
|
|
|
contact_list_id=request.form.get('contact_list_id', ''),
|
2016-03-08 17:50:18 +00:00
|
|
|
|
)
|
2016-03-07 18:47:05 +00:00
|
|
|
|
|
2018-11-06 14:22:22 +00:00
|
|
|
|
session.pop('sender_id', None)
|
|
|
|
|
|
|
2016-03-07 18:47:05 +00:00
|
|
|
|
return redirect(
|
2017-07-13 11:28:37 +01:00
|
|
|
|
url_for(
|
|
|
|
|
|
'main.view_job',
|
|
|
|
|
|
job_id=upload_id,
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
just_sent='yes',
|
|
|
|
|
|
)
|
2016-02-17 15:49:07 +00:00
|
|
|
|
)
|
2016-07-01 10:49:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-05-25 09:18:26 +01:00
|
|
|
|
def fields_to_fill_in(template, prefill_current_user=False):
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2020-04-27 10:57:25 +01:00
|
|
|
|
if 'letter' == template.template_type:
|
|
|
|
|
|
return letter_address_columns + list(template.placeholders)
|
|
|
|
|
|
|
|
|
|
|
|
if not prefill_current_user:
|
|
|
|
|
|
return first_column_headings[template.template_type] + list(template.placeholders)
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2019-06-04 16:12:09 +01:00
|
|
|
|
if template.template_type == 'sms':
|
|
|
|
|
|
session['recipient'] = current_user.mobile_number
|
|
|
|
|
|
session['placeholders']['phone number'] = current_user.mobile_number
|
|
|
|
|
|
else:
|
|
|
|
|
|
session['recipient'] = current_user.email_address
|
|
|
|
|
|
session['placeholders']['email address'] = current_user.email_address
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
|
|
|
|
|
return list(template.placeholders)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-23 17:30:34 +01:00
|
|
|
|
def get_normalised_placeholders_from_session():
|
2020-04-02 17:21:27 +01:00
|
|
|
|
return Columns(session.get('placeholders', {}))
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-06-29 15:31:44 +01:00
|
|
|
|
def get_recipient_and_placeholders_from_session(template_type):
|
2017-06-26 14:56:14 +01:00
|
|
|
|
placeholders = get_normalised_placeholders_from_session()
|
|
|
|
|
|
|
|
|
|
|
|
if template_type == 'sms':
|
|
|
|
|
|
placeholders['phone_number'] = session['recipient']
|
|
|
|
|
|
else:
|
|
|
|
|
|
placeholders['email_address'] = session['recipient']
|
|
|
|
|
|
|
|
|
|
|
|
return placeholders
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-25 09:18:26 +01:00
|
|
|
|
def all_placeholders_in_session(placeholders):
|
|
|
|
|
|
return all(
|
2017-06-23 17:30:34 +01:00
|
|
|
|
get_normalised_placeholders_from_session().get(placeholder, False) not in (False, None)
|
2017-05-25 09:18:26 +01:00
|
|
|
|
for placeholder in placeholders
|
|
|
|
|
|
)
|
2017-05-25 13:31:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-10-05 11:55:15 +01:00
|
|
|
|
def get_send_test_page_title(template_type, entering_recipient, name=None):
|
2017-11-20 16:45:59 +00:00
|
|
|
|
if entering_recipient:
|
2018-08-06 11:20:50 +01:00
|
|
|
|
return 'Send ‘{}’'.format(name)
|
2017-11-20 16:45:59 +00:00
|
|
|
|
return 'Personalise this message'
|
2017-06-22 16:00:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-04-09 16:25:48 +01:00
|
|
|
|
def get_back_link(service_id, template, step_index, placeholders=None):
|
2020-10-05 11:55:15 +01:00
|
|
|
|
if step_index == 0:
|
2021-07-21 16:06:23 +01:00
|
|
|
|
if should_skip_template_page(template._template):
|
2018-06-13 14:32:52 +01:00
|
|
|
|
return url_for(
|
|
|
|
|
|
'.choose_template',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
)
|
2018-08-09 16:29:51 +01:00
|
|
|
|
else:
|
|
|
|
|
|
return url_for(
|
|
|
|
|
|
'.view_template',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template.id,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2020-04-09 16:25:48 +01:00
|
|
|
|
if template.template_type == 'letter' and placeholders:
|
|
|
|
|
|
# Make sure we’re not redirecting users to a page which will
|
|
|
|
|
|
# just redirect them forwards again
|
|
|
|
|
|
back_link_destination_step_index = next((
|
|
|
|
|
|
index
|
|
|
|
|
|
for index, placeholder in reversed(
|
|
|
|
|
|
list(enumerate(placeholders[:step_index]))
|
|
|
|
|
|
)
|
|
|
|
|
|
if placeholder not in Columns(
|
|
|
|
|
|
PostalAddress('').as_personalisation
|
|
|
|
|
|
)
|
|
|
|
|
|
), 1)
|
|
|
|
|
|
return get_back_link(service_id, template, back_link_destination_step_index + 1)
|
|
|
|
|
|
|
|
|
|
|
|
return url_for(
|
|
|
|
|
|
'main.send_one_off_step',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template.id,
|
|
|
|
|
|
step_index=step_index - 1,
|
|
|
|
|
|
)
|
2017-06-23 15:02:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-04-09 16:37:38 +01:00
|
|
|
|
def get_skip_link(step_index, template):
|
|
|
|
|
|
if (
|
|
|
|
|
|
request.endpoint == 'main.send_one_off_step'
|
|
|
|
|
|
and step_index == 0
|
2020-10-05 16:16:11 +01:00
|
|
|
|
and template.template_type in ("sms", "email")
|
2020-04-09 16:37:38 +01:00
|
|
|
|
and not (template.template_type == 'sms' and current_user.mobile_number is None)
|
|
|
|
|
|
and current_user.has_permissions('manage_templates', 'manage_service')
|
|
|
|
|
|
):
|
|
|
|
|
|
return (
|
|
|
|
|
|
'Use my {}'.format(first_column_headings[template.template_type][0]),
|
2020-10-05 16:16:11 +01:00
|
|
|
|
url_for('.send_one_off_to_myself', service_id=current_service.id, template_id=template.id),
|
2020-04-09 16:37:38 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-10-05 16:16:11 +01:00
|
|
|
|
@main.route("/services/<uuid:service_id>/template/<uuid:template_id>/one-off/send-to-myself", methods=['GET'])
|
|
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
|
|
|
|
|
def send_one_off_to_myself(service_id, template_id):
|
|
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
|
|
|
|
|
|
|
|
|
|
|
if db_template['template_type'] not in ("sms", "email"):
|
|
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
|
|
|
|
# We aren't concerned with creating the exact template (for example adding recipient and sender names)
|
|
|
|
|
|
# we just want to create enough to use `fields_to_fill_in`
|
|
|
|
|
|
template = get_template(
|
|
|
|
|
|
db_template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
)
|
|
|
|
|
|
fields_to_fill_in(template, prefill_current_user=True)
|
|
|
|
|
|
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'main.send_one_off_step',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
step_index=1,
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/template/<uuid:template_id>/notification/check", methods=['GET'])
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2017-06-23 15:02:20 +01:00
|
|
|
|
def check_notification(service_id, template_id):
|
2018-10-30 14:24:50 +00:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/notifications/check.html',
|
|
|
|
|
|
**_check_notification(service_id, template_id),
|
|
|
|
|
|
)
|
2017-06-29 15:31:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _check_notification(service_id, template_id, exception=None):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
2017-11-02 12:07:46 +00:00
|
|
|
|
email_reply_to = None
|
|
|
|
|
|
sms_sender = None
|
|
|
|
|
|
if db_template['template_type'] == 'email':
|
2018-10-26 17:31:49 +01:00
|
|
|
|
email_reply_to = get_email_reply_to_address_from_session()
|
2017-11-02 12:07:46 +00:00
|
|
|
|
elif db_template['template_type'] == 'sms':
|
2018-10-26 17:31:49 +01:00
|
|
|
|
sms_sender = get_sms_sender_from_session()
|
2017-06-23 15:02:20 +01:00
|
|
|
|
template = get_template(
|
|
|
|
|
|
db_template,
|
|
|
|
|
|
current_service,
|
2017-10-17 16:06:15 +01:00
|
|
|
|
show_recipient=True,
|
2017-11-02 12:07:46 +00:00
|
|
|
|
email_reply_to=email_reply_to,
|
2018-10-30 14:24:50 +00:00
|
|
|
|
sms_sender=sms_sender,
|
|
|
|
|
|
letter_preview_url=url_for(
|
2019-11-29 11:40:49 +00:00
|
|
|
|
'no_cookie.check_notification_preview',
|
2018-10-30 14:24:50 +00:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
filetype='png',
|
|
|
|
|
|
),
|
2019-10-08 14:56:00 +01:00
|
|
|
|
page_count=get_page_count_for_letter(db_template),
|
2017-06-23 15:02:20 +01:00
|
|
|
|
)
|
2017-06-26 17:09:51 +01:00
|
|
|
|
|
2020-04-15 15:42:25 +01:00
|
|
|
|
placeholders = fields_to_fill_in(template)
|
|
|
|
|
|
|
|
|
|
|
|
back_link = get_back_link(service_id, template, len(placeholders), placeholders)
|
2017-06-26 17:09:51 +01:00
|
|
|
|
|
|
|
|
|
|
if (
|
2018-10-30 14:24:50 +00:00
|
|
|
|
(
|
|
|
|
|
|
not session.get('recipient')
|
|
|
|
|
|
and db_template['template_type'] != 'letter'
|
|
|
|
|
|
)
|
|
|
|
|
|
or not all_placeholders_in_session(template.placeholders)
|
2017-06-26 17:09:51 +01:00
|
|
|
|
):
|
2019-03-21 16:41:22 +00:00
|
|
|
|
raise PermanentRedirect(back_link)
|
2017-06-26 17:09:51 +01:00
|
|
|
|
|
2017-06-29 15:31:44 +01:00
|
|
|
|
template.values = get_recipient_and_placeholders_from_session(template.template_type)
|
2019-10-08 14:56:00 +01:00
|
|
|
|
page_count = get_page_count_for_letter(db_template, template.values)
|
2020-07-21 16:06:33 +01:00
|
|
|
|
template.page_count = page_count
|
2018-10-30 14:24:50 +00:00
|
|
|
|
return dict(
|
2017-06-23 15:02:20 +01:00
|
|
|
|
template=template,
|
|
|
|
|
|
back_link=back_link,
|
2019-10-01 17:16:15 +01:00
|
|
|
|
letter_too_long=is_letter_too_long(page_count),
|
2019-10-09 14:56:18 +01:00
|
|
|
|
letter_max_pages=LETTER_MAX_PAGE_COUNT,
|
2019-10-16 13:02:11 +01:00
|
|
|
|
page_count=page_count,
|
2018-10-30 14:24:50 +00:00
|
|
|
|
**(get_template_error_dict(exception) if exception else {}),
|
2017-06-23 15:02:20 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-29 15:31:44 +01:00
|
|
|
|
def get_template_error_dict(exception):
|
2017-06-29 16:06:36 +01:00
|
|
|
|
# TODO: Make API return some computer-friendly identifier as well as the end user error messages
|
2017-07-27 16:28:49 +01:00
|
|
|
|
if 'service is in trial mode' in exception.message:
|
2017-06-29 15:31:44 +01:00
|
|
|
|
error = 'not-allowed-to-send-to'
|
2017-07-27 16:28:49 +01:00
|
|
|
|
elif 'Exceeded send limits' in exception.message:
|
2017-06-29 16:06:36 +01:00
|
|
|
|
error = 'too-many-messages'
|
2020-03-09 17:03:22 +00:00
|
|
|
|
# the error from the api is changing for message-too-long, but we need both until the api is deployed.
|
2017-07-27 16:28:49 +01:00
|
|
|
|
elif 'Content for template has a character count greater than the limit of' in exception.message:
|
2017-06-29 16:06:36 +01:00
|
|
|
|
error = 'message-too-long'
|
2020-03-09 17:03:22 +00:00
|
|
|
|
elif 'Text messages cannot be longer than' in exception.message:
|
|
|
|
|
|
error = 'message-too-long'
|
2017-06-29 15:31:44 +01:00
|
|
|
|
else:
|
|
|
|
|
|
raise exception
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
'error': error,
|
2018-08-16 16:51:32 +01:00
|
|
|
|
'SMS_CHAR_COUNT_LIMIT': SMS_CHAR_COUNT_LIMIT,
|
2017-06-29 16:06:36 +01:00
|
|
|
|
'current_service': current_service,
|
|
|
|
|
|
|
|
|
|
|
|
# used to trigger CSV specific err msg content, so not needed for single notification errors.
|
|
|
|
|
|
'original_file_name': False
|
2017-06-29 15:31:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/template/<uuid:template_id>/notification/check", methods=['POST'])
|
2018-03-01 11:04:25 +00:00
|
|
|
|
@user_has_permissions('send_messages', restrict_admin_usage=True)
|
2017-06-23 15:02:20 +01:00
|
|
|
|
def send_notification(service_id, template_id):
|
2017-06-23 17:30:34 +01:00
|
|
|
|
if {'recipient', 'placeholders'} - set(session.keys()):
|
2017-06-23 15:02:20 +01:00
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.send_one_off',
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
))
|
2019-03-19 16:25:44 +00:00
|
|
|
|
|
|
|
|
|
|
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
|
|
|
|
|
|
|
2017-06-29 15:31:44 +01:00
|
|
|
|
try:
|
|
|
|
|
|
noti = notification_api_client.send_notification(
|
|
|
|
|
|
service_id,
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template_id=db_template['id'],
|
2020-04-07 12:59:34 +01:00
|
|
|
|
recipient=session['recipient'] or Columns(session['placeholders'])['address line 1'],
|
2017-10-16 16:35:35 +01:00
|
|
|
|
personalisation=session['placeholders'],
|
|
|
|
|
|
sender_id=session['sender_id'] if 'sender_id' in session else None
|
2017-06-29 15:31:44 +01:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as exception:
|
2017-06-29 16:06:36 +01:00
|
|
|
|
current_app.logger.info('Service {} could not send notification: "{}"'.format(
|
2018-07-20 08:42:01 +01:00
|
|
|
|
current_service.id,
|
2017-06-29 16:06:36 +01:00
|
|
|
|
exception.message
|
|
|
|
|
|
))
|
2018-10-30 14:24:50 +00:00
|
|
|
|
return render_template(
|
|
|
|
|
|
'views/notifications/check.html',
|
|
|
|
|
|
**_check_notification(service_id, template_id, exception),
|
|
|
|
|
|
)
|
2017-06-23 15:02:20 +01:00
|
|
|
|
|
2017-06-23 17:30:34 +01:00
|
|
|
|
session.pop('placeholders')
|
|
|
|
|
|
session.pop('recipient')
|
2017-10-16 16:35:35 +01:00
|
|
|
|
session.pop('sender_id', None)
|
2017-06-23 15:02:20 +01:00
|
|
|
|
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
|
'.view_notification',
|
|
|
|
|
|
service_id=service_id,
|
2017-06-30 11:49:03 +01:00
|
|
|
|
notification_id=noti['id'],
|
2020-10-05 11:55:15 +01:00
|
|
|
|
# used to show the final step of the tour (help=3) or not show
|
|
|
|
|
|
# a back link on a just sent one off notification (help=0)
|
2017-06-30 11:49:03 +01:00
|
|
|
|
help=request.args.get('help')
|
2017-06-23 15:02:20 +01:00
|
|
|
|
))
|
2017-10-17 16:06:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-10-26 17:31:49 +01:00
|
|
|
|
def get_email_reply_to_address_from_session():
|
2017-10-17 16:06:15 +01:00
|
|
|
|
if session.get('sender_id'):
|
2018-10-26 17:31:49 +01:00
|
|
|
|
return current_service.get_email_reply_to_address(
|
|
|
|
|
|
session['sender_id']
|
2017-10-17 16:06:15 +01:00
|
|
|
|
)['email_address']
|
2017-11-02 12:07:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
2018-10-26 17:31:49 +01:00
|
|
|
|
def get_sms_sender_from_session():
|
2017-11-02 12:07:46 +00:00
|
|
|
|
if session.get('sender_id'):
|
2018-10-26 17:31:49 +01:00
|
|
|
|
return current_service.get_sms_sender(
|
|
|
|
|
|
session['sender_id']
|
2017-11-02 12:07:46 +00:00
|
|
|
|
)['sms_sender']
|
2018-06-08 12:49:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_spreadsheet_column_headings_from_template(template):
|
|
|
|
|
|
column_headings = []
|
|
|
|
|
|
|
2020-04-27 10:57:25 +01:00
|
|
|
|
if template.template_type == 'letter':
|
|
|
|
|
|
# We want to avoid showing `address line 7` for now
|
|
|
|
|
|
recipient_columns = letter_address_columns
|
|
|
|
|
|
else:
|
|
|
|
|
|
recipient_columns = first_column_headings[template.template_type]
|
|
|
|
|
|
|
2018-06-08 12:49:29 +01:00
|
|
|
|
for column_heading in (
|
2020-04-27 10:57:25 +01:00
|
|
|
|
recipient_columns + list(template.placeholders)
|
2018-06-08 12:49:29 +01:00
|
|
|
|
):
|
|
|
|
|
|
if column_heading not in Columns.from_keys(column_headings):
|
|
|
|
|
|
column_headings.append(column_heading)
|
|
|
|
|
|
|
|
|
|
|
|
return column_headings
|