Files
notifications-admin/app/main/views/send.py

1001 lines
34 KiB
Python
Raw Normal View History

import itertools
import json
from string import ascii_uppercase
from zipfile import BadZipFile
from flask import (
abort,
current_app,
flash,
redirect,
render_template,
request,
session,
url_for,
)
from flask_login import current_user, login_required
from notifications_python_client.errors import HTTPError
from notifications_utils import SMS_CHAR_COUNT_LIMIT
from notifications_utils.columns import Columns
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
from notifications_utils.recipients import (
RecipientCSV,
first_column_headings,
optional_address_columns,
)
from notifications_utils.sanitise_text import SanitiseASCII
from orderedset import OrderedSet
from werkzeug.routing import RequestRedirect
from xlrd.biffh import XLRDError
from xlrd.xldate import XLDateError
from app import (
current_service,
job_api_client,
notification_api_client,
service_api_client,
user_api_client,
)
from app.main import main
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
from app.main.forms import (
ChooseTimeForm,
CsvUploadForm,
SetSenderForm,
get_placeholder_form_instance,
)
from app.s3_client.s3_csv_client import (
s3download,
s3upload,
set_metadata_on_csv_upload,
)
from app.template_previews import TemplatePreview, get_page_count_for_letter
from app.utils import (
Spreadsheet,
email_or_sms_not_enabled,
get_errors_for_csv,
get_help_argument,
get_template,
should_skip_template_page,
unicode_truncate,
user_has_permissions,
)
2016-03-01 15:53:58 +00:00
def get_page_headings(template_type):
return {
'email': 'Email templates',
'sms': 'Text message templates',
'letter': 'Letter templates'
}[template_type]
2016-03-01 15:53:58 +00: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):
return {
'email': ['test@example.com'] if use_example_as_example else [current_user.email_address],
'sms': ['07700 900321'] if use_example_as_example else [current_user.mobile_number],
'letter': [
(submitted_fields or {}).get(
key, get_example_letter_address(key) if use_example_as_example else key
)
for key in first_column_headings['letter']
]
}[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
)
def get_example_letter_address(key):
return {
'address line 1': 'A. Name',
'address line 2': '123 Example Street',
'postcode': 'XM4 5HQ'
}.get(key, '')
@main.route("/services/<service_id>/send/<template_id>/csv", methods=['GET', 'POST'])
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
def send_messages(service_id, template_id):
# if there's lots of data in the session, lets log it for debugging purposes
# TODO: Remove this once we're confident we have session size under control
if len(session.get('file_uploads', {}).keys()) > 2:
current_app.logger.info('session contains large file_uploads - json_len {}, keys: {}'.format(
len(json.dumps(session['file_uploads'])),
session['file_uploads'].keys())
)
db_template = service_api_client.get_service_template(service_id, template_id)['data']
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()
if email_or_sms_not_enabled(db_template['template_type'], current_service.permissions):
return redirect(url_for(
'.action_blocked',
service_id=service_id,
notification_type=db_template['template_type'],
return_to='view_template',
template_id=template_id
))
template = get_template(
db_template,
current_service,
show_recipient=True,
expand_emails=True,
letter_preview_url=url_for(
'.view_letter_template_preview',
service_id=service_id,
template_id=template_id,
filetype='png',
page_count=get_page_count_for_letter(db_template),
),
email_reply_to=email_reply_to,
sms_sender=sms_sender,
)
form = CsvUploadForm()
if form.validate_on_submit():
try:
upload_id = s3upload(
service_id,
Spreadsheet.from_file(form.file.data, filename=form.file.data.filename).as_dict,
current_app.config['AWS_REGION']
)
return redirect(url_for(
'.check_messages',
service_id=service_id,
upload_id=upload_id,
template_id=template.id,
original_file_name=form.file.data.filename,
))
except (UnicodeDecodeError, BadZipFile, XLRDError):
flash('Couldnt read {}. Try using a different file format.'.format(
form.file.data.filename
))
except (XLDateError):
flash((
'{} contains numbers or dates that Notify cant understand. '
'Try formatting all columns as text or export your file as CSV.'
).format(
form.file.data.filename
))
column_headings = get_spreadsheet_column_headings_from_template(template)
return render_template(
'views/send.html',
template=template,
column_headings=list(ascii_uppercase[:len(column_headings)]),
example=[column_headings, get_example_csv_rows(template)],
form=form
)
@main.route("/services/<service_id>/send/<template_id>.csv", methods=['GET'])
@login_required
@user_has_permissions('send_messages', 'manage_templates')
def get_example_csv(service_id, template_id):
template = get_template(
service_api_client.get_service_template(service_id, template_id)['data'], current_service
)
return Spreadsheet.from_rows([
get_spreadsheet_column_headings_from_template(template),
get_example_csv_rows(template)
]).as_csv_data, 200, {
'Content-Type': 'text/csv; charset=utf-8',
'Content-Disposition': 'inline; filename="{}.csv"'.format(template.name)
}
@main.route("/services/<service_id>/send/<template_id>/set-sender", methods=['GET', 'POST'])
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
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)
)
template = service_api_client.get_service_template(service_id, template_id)['data']
if template['template_type'] == 'letter':
return redirect_to_one_off
sender_details = get_sender_details(service_id, template['template_type'])
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']
)
option_hints = {sender_context['default_id']: '(Default)'}
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)'}
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': {
'title': 'Where should replies come back to?',
'description': 'Where should replies come back to?',
'field_name': 'email_address'
},
'letter': {
'title': 'Send to one recipient',
'description': 'What should appear in the top right of the letter?',
'field_name': 'contact_block'
},
'sms': {
'title': 'Who should the message come from?',
'description': 'Who should the message come from?',
'field_name': 'sms_sender'
}
}[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':
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']
context['value_and_label'] = [(sender['id'], sender[sender_format]) for sender in sender_details]
return context
def get_sender_details(service_id, template_type):
api_call = {
'email': service_api_client.get_reply_to_email_addresses,
'letter': service_api_client.get_letter_contacts,
'sms': service_api_client.get_sms_senders
}[template_type]
return api_call(service_id)
@main.route("/services/<service_id>/send/<template_id>/test", endpoint='send_test')
@main.route("/services/<service_id>/send/<template_id>/one-off", endpoint='send_one_off')
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
def send_test(service_id, template_id):
session['recipient'] = None
session['placeholders'] = {}
session['send_test_letter_page_count'] = None
db_template = service_api_client.get_service_template(service_id, template_id)['data']
if db_template['template_type'] == 'letter':
session['sender_id'] = None
if email_or_sms_not_enabled(db_template['template_type'], current_service.permissions):
return redirect(url_for(
'.action_blocked',
service_id=service_id,
notification_type=db_template['template_type'],
return_to='view_template',
template_id=template_id))
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
return redirect(url_for(
{
'main.send_test': '.send_test_step',
'main.send_one_off': '.send_one_off_step',
}[request.endpoint],
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
service_id=service_id,
template_id=template_id,
step_index=0,
help=get_help_argument(),
))
def get_notification_check_endpoint(service_id, template):
return redirect(url_for(
'main.check_notification',
service_id=service_id,
template_id=template.id,
# at check phase we should move to help stage 2 ("the template pulls in the data you provide")
help='2' if 'help' in request.args else None
))
@main.route(
"/services/<service_id>/send/<template_id>/test/step-<int:step_index>",
methods=['GET', 'POST'],
endpoint='send_test_step',
)
@main.route(
"/services/<service_id>/send/<template_id>/one-off/step-<int:step_index>",
methods=['GET', 'POST'],
endpoint='send_one_off_step',
)
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
def send_test_step(service_id, template_id, step_index):
if {'recipient', 'placeholders'} - set(session.keys()):
return redirect(url_for(
{
'main.send_test_step': '.send_test',
'main.send_one_off_step': '.send_one_off',
}[request.endpoint],
service_id=service_id,
template_id=template_id,
))
db_template = service_api_client.get_service_template(service_id, template_id)['data']
if not session.get('send_test_letter_page_count'):
session['send_test_letter_page_count'] = get_page_count_for_letter(db_template)
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()
template = get_template(
db_template,
current_service,
show_recipient=True,
expand_emails=True,
letter_preview_url=url_for(
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
'.send_test_preview',
service_id=service_id,
template_id=template_id,
filetype='png',
),
page_count=session['send_test_letter_page_count'],
email_reply_to=email_reply_to,
sms_sender=sms_sender
)
placeholders = fields_to_fill_in(
template,
prefill_current_user=(request.endpoint == 'main.send_test_step'),
)
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
try:
if request.endpoint == 'main.send_test_step':
current_placeholder = placeholders[step_index - 1]
else:
current_placeholder = placeholders[step_index]
except IndexError:
if all_placeholders_in_session(placeholders):
return get_notification_check_endpoint(service_id, template)
return redirect(url_for(
{
'main.send_test_step': '.send_test',
'main.send_one_off_step': '.send_one_off',
}[request.endpoint],
service_id=service_id,
template_id=template_id,
))
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
optional_placeholder = (current_placeholder in optional_address_columns)
form = get_placeholder_form_instance(
current_placeholder,
dict_to_populate_from=get_normalised_placeholders_from_session(),
template_type=template.template_type,
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
optional_placeholder=optional_placeholder,
allow_international_phone_numbers=current_service.has_permission('international_sms'),
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
)
if form.validate_on_submit():
# 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 (
step_index == 0 and
template.template_type != 'letter' and
request.endpoint != 'main.send_test_step'
):
session['recipient'] = form.placeholder_value.data
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
session['placeholders'][current_placeholder] = form.placeholder_value.data
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
if all_placeholders_in_session(placeholders):
return get_notification_check_endpoint(service_id, template)
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
return redirect(url_for(
request.endpoint,
service_id=service_id,
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
template_id=template_id,
step_index=step_index + 1,
help=get_help_argument(),
))
back_link = get_back_link(service_id, template, step_index)
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
template.values = get_recipient_and_placeholders_from_session(template.template_type)
template.values[current_placeholder] = None
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
if (
request.endpoint == 'main.send_one_off_step' and
step_index == 0 and
template.template_type != 'letter' and
not (template.template_type == 'sms' and current_user.mobile_number is None) and
current_user.has_permissions('manage_templates', 'manage_service')
):
skip_link = (
'Use my {}'.format(first_column_headings[template.template_type][0]),
url_for('.send_test_step', service_id=service_id, template_id=template.id, step_index=1),
)
else:
skip_link = None
return render_template(
'views/send-test.html',
page_title=get_send_test_page_title(
template.template_type,
get_help_argument(),
entering_recipient=not session['recipient'],
name=template.name,
),
template=template,
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
form=form,
skip_link=skip_link,
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
optional_placeholder=optional_placeholder,
back_link=back_link,
help=get_help_argument(),
link_to_upload=(
request.endpoint == 'main.send_one_off_step' and
step_index == 0
),
)
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
@main.route("/services/<service_id>/send/<template_id>/test.<filetype>", methods=['GET'])
@login_required
@user_has_permissions('send_messages')
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
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)
db_template = service_api_client.get_service_template(service_id, template_id)['data']
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
template = get_template(
db_template,
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
current_service,
letter_preview_url=url_for(
'.send_test_preview',
service_id=service_id,
template_id=template_id,
filetype='png',
),
)
template.values = get_normalised_placeholders_from_session()
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
return TemplatePreview.from_utils_template(template, filetype, page=request.args.get('page'))
def _check_messages(service_id, template_id, upload_id, preview_row, letters_as_pdf=False):
try:
# The happy path is that the job doesnt already exist, so the
# API will return a 404 and the client will raise HTTPError.
job_api_client.get_job(service_id, upload_id)
# the job exists already - so go back to the templates page
# 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.
raise RequestRedirect(url_for(
'.send_messages',
service_id=service_id,
template_id=template_id
))
except HTTPError as e:
if e.status_code != 404:
raise
users = user_api_client.get_users_for_service(service_id=service_id)
statistics = service_api_client.get_service_statistics(service_id, today_only=True)
remaining_messages = (current_service.message_limit - sum(stat['requested'] for stat in statistics.values()))
contents = s3download(service_id, upload_id)
db_template = service_api_client.get_service_template(
service_id,
str(template_id),
)['data']
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()
template = get_template(
db_template,
current_service,
show_recipient=True,
expand_emails=True,
letter_preview_url=url_for(
'.check_messages_preview',
service_id=service_id,
template_id=template_id,
upload_id=upload_id,
filetype='png',
row_index=preview_row,
) if not letters_as_pdf else None,
email_reply_to=email_reply_to,
sms_sender=sms_sender,
page_count=get_page_count_for_letter(db_template),
)
recipients = RecipientCSV(
contents,
template_type=template.template_type,
placeholders=template.placeholders,
max_initial_rows_shown=50,
max_errors_shown=50,
whitelist=itertools.chain.from_iterable(
[user.name, user.mobile_number, user.email_address] for user in users
) if current_service.trial_mode else None,
remaining_messages=remaining_messages,
international_sms=current_service.has_permission('international_sms'),
)
if request.args.get('from_test'):
# only happens if generating a letter preview test
back_link = url_for('.send_test', service_id=service_id, template_id=template.id)
choose_time_form = None
else:
back_link = url_for('.send_messages', service_id=service_id, template_id=template.id)
choose_time_form = ChooseTimeForm()
if preview_row < 2:
abort(404)
if preview_row < len(recipients) + 2:
template.values = recipients[preview_row - 2].recipient_and_personalisation
elif preview_row > 2:
abort(404)
return dict(
recipients=recipients,
template=template,
errors=recipients.has_errors,
row_errors=get_errors_for_csv(recipients, template.template_type),
count_of_recipients=len(recipients),
count_of_displayed_recipients=len(list(recipients.displayed_rows)),
original_file_name=request.args.get('original_file_name', ''),
upload_id=upload_id,
form=CsvUploadForm(),
remaining_messages=remaining_messages,
choose_time_form=choose_time_form,
back_link=back_link,
help=get_help_argument(),
trying_to_send_letters_in_trial_mode=all((
current_service.trial_mode,
template.template_type == 'letter',
)),
required_recipient_columns=OrderedSet(recipients.recipient_column_headers) - optional_address_columns,
preview_row=preview_row,
sent_previously=job_api_client.has_sent_previously(
service_id, template.id, db_template['version'], request.args.get('original_file_name', '')
)
)
@main.route("/services/<service_id>/<uuid:template_id>/check/<upload_id>", methods=['GET'])
@main.route("/services/<service_id>/<uuid:template_id>/check/<upload_id>/row-<int:row_index>", methods=['GET'])
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
def check_messages(service_id, template_id, upload_id, row_index=2):
data = _check_messages(service_id, template_id, upload_id, row_index)
if (
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']
):
return render_template('views/check/column-errors.html', **data)
if data['row_errors']:
return render_template('views/check/row-errors.html', **data)
if (
data['errors'] or
data['trying_to_send_letters_in_trial_mode']
):
return render_template('views/check/column-errors.html', **data)
data['original_file_name'] = SanitiseASCII.encode(data.get('original_file_name', ''))
metadata_kwargs = {
'notification_count': data['count_of_recipients'],
'template_id': str(template_id),
'valid': True,
'original_file_name': unicode_truncate(
data['original_file_name'],
1600,
),
}
if session.get('sender_id'):
metadata_kwargs['sender_id'] = session['sender_id']
set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs)
return render_template('views/check/ok.html', **data)
@main.route(
"/services/<service_id>/<uuid:template_id>/check/<upload_id>.<filetype>",
methods=['GET'],
)
@main.route(
"/services/<service_id>/<uuid:template_id>/check/<upload_id>/row-<int:row_index>.<filetype>",
methods=['GET'],
)
@login_required
@user_has_permissions('send_messages')
def check_messages_preview(service_id, template_id, upload_id, filetype, row_index=2):
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)
template = _check_messages(
service_id, template_id, upload_id, row_index, letters_as_pdf=True
)['template']
return TemplatePreview.from_utils_template(template, filetype, page=page)
@main.route(
"/services/<service_id>/<uuid:template_id>/check.<filetype>",
methods=['GET'],
)
@login_required
@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)
@main.route("/services/<service_id>/start-job/<upload_id>", methods=['POST'])
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
def start_job(service_id, upload_id):
job_api_client.create_job(
upload_id,
service_id,
scheduled_for=request.form.get('scheduled_for', '')
)
session.pop('sender_id', None)
return redirect(
url_for(
'main.view_job',
job_id=upload_id,
service_id=service_id,
help=request.form.get('help'),
just_sent='yes',
)
)
@main.route("/services/<service_id>/end-tour/<example_template_id>")
@login_required
@user_has_permissions('manage_templates')
def go_to_dashboard_after_tour(service_id, example_template_id):
service_api_client.delete_service_template(service_id, example_template_id)
return redirect(
url_for('main.service_dashboard', service_id=service_id)
)
def fields_to_fill_in(template, prefill_current_user=False):
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
recipient_columns = first_column_headings[template.template_type]
if 'letter' == template.template_type or not prefill_current_user:
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
return recipient_columns + list(template.placeholders)
session['recipient'] = current_user.mobile_number if template.template_type == 'sms' else current_user.email_address
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
return list(template.placeholders)
def get_normalised_placeholders_from_session():
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
return {
key: ''.join(value or [])
for key, value in session.get('placeholders', {}).items()
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
}
def get_recipient_and_placeholders_from_session(template_type):
placeholders = get_normalised_placeholders_from_session()
if template_type == 'sms':
placeholders['phone_number'] = session['recipient']
else:
placeholders['email_address'] = session['recipient']
return placeholders
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
def make_and_upload_csv_file(service_id, template):
upload_id = s3upload(
service_id,
Spreadsheet.from_dict(
session['placeholders'],
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
filename=current_app.config['TEST_MESSAGE_FILENAME']
).as_dict,
current_app.config['AWS_REGION'],
)
return redirect(url_for(
'.check_messages',
upload_id=upload_id,
service_id=service_id,
template_id=template.id,
Show one field at a time on send yourself a test The send yourself a test feature is useful for two things: - constructing an email/text message/letter without uploading a CSV file - seeing what the thing your going to send will look like (either by getting it in your inbox or downloading the PDF) - learning the concept of placeholders, ie understanding they’re thing that gets populated with _stuff_ The problem we’re seeing is that the current UI breaks when a template has a lot of placeholders. This is especially apparent with letter templates, which have a minimum of 7 placeholders by virtue of the address. The idea behind having the form fields side-by-side was to help people understand the relationship between their spreadsheet columns and the placeholders. But this means that the page was doing a lot of work, trying to teach: - replacement of placeholders - link between placeholders and spreadsheet columns The latter is better explained by the example spreadsheet shown on the upload page. So it can safely be removed from the send yourself a test page – in other words the fields don’t need to be shown side by side. Showing them one-at-a-time works well because: - it’s really obvious, even on first use, what the page is asking you to do - as your step through each placeholder, you see the message build up with the data you’ve entered – you’re learning how replacement of placeholders works by repetition This also means adding a matching endpoint for viewing each step of making the test letter as a PDF/PNG because we can’t reuse the view of the template without any placeholders filled any more.
2017-05-04 09:30:55 +01:00
from_test=True,
help=2 if get_help_argument() else 0
))
def all_placeholders_in_session(placeholders):
return all(
get_normalised_placeholders_from_session().get(placeholder, False) not in (False, None)
for placeholder in placeholders
)
def get_send_test_page_title(template_type, help_argument, entering_recipient, name=None):
if help_argument:
return 'Example text message'
if entering_recipient:
return 'Send {}'.format(name)
return 'Personalise this message'
def is_current_user_the_recipient():
2018-11-30 14:16:11 +00:00
if 'recipient' not in session:
return False
if hasattr(current_user, 'mobile_number'):
return session['recipient'] in {current_user.email_address, current_user.mobile_number}
return session['recipient'] == current_user.email_address
def get_back_link(service_id, template, step_index):
if get_help_argument():
# if we're on the check page, redirect back to the beginning. anywhere else, don't return the back link
if request.endpoint == 'main.check_notification':
return url_for(
'main.send_test',
service_id=service_id,
template_id=template.id,
help=get_help_argument()
)
else:
return None
elif step_index == 0:
if should_skip_template_page(template.template_type):
return url_for(
'.choose_template',
service_id=service_id,
)
else:
return url_for(
'.view_template',
service_id=service_id,
template_id=template.id,
)
elif is_current_user_the_recipient() and step_index > 1:
2019-01-30 12:02:45 +00:00
return url_for(
'main.send_test_step',
service_id=service_id,
template_id=template.id,
step_index=step_index - 1,
)
else:
return url_for(
'main.send_one_off_step',
service_id=service_id,
template_id=template.id,
step_index=step_index - 1,
)
@main.route("/services/<service_id>/template/<template_id>/notification/check", methods=['GET'])
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
def check_notification(service_id, template_id):
return render_template(
'views/notifications/check.html',
**_check_notification(service_id, template_id),
)
def _check_notification(service_id, template_id, exception=None):
db_template = service_api_client.get_service_template(service_id, template_id)['data']
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()
template = get_template(
db_template,
current_service,
show_recipient=True,
expand_emails=True,
email_reply_to=email_reply_to,
sms_sender=sms_sender,
letter_preview_url=url_for(
'.check_notification_preview',
service_id=service_id,
template_id=template_id,
filetype='png',
),
page_count=get_page_count_for_letter(db_template),
)
back_link = get_back_link(service_id, template, len(fields_to_fill_in(template)))
if (
(
not session.get('recipient')
and db_template['template_type'] != 'letter'
)
or not all_placeholders_in_session(template.placeholders)
):
raise RequestRedirect(back_link)
template.values = get_recipient_and_placeholders_from_session(template.template_type)
return dict(
template=template,
back_link=back_link,
help=get_help_argument(),
**(get_template_error_dict(exception) if exception else {}),
)
def get_template_error_dict(exception):
# TODO: Make API return some computer-friendly identifier as well as the end user error messages
if 'service is in trial mode' in exception.message:
error = 'not-allowed-to-send-to'
elif 'Exceeded send limits' in exception.message:
error = 'too-many-messages'
elif 'Content for template has a character count greater than the limit of' in exception.message:
error = 'message-too-long'
else:
raise exception
return {
'error': error,
'SMS_CHAR_COUNT_LIMIT': SMS_CHAR_COUNT_LIMIT,
'current_service': current_service,
# used to trigger CSV specific err msg content, so not needed for single notification errors.
'original_file_name': False
}
@main.route("/services/<service_id>/template/<template_id>/notification/check", methods=['POST'])
@login_required
@user_has_permissions('send_messages', restrict_admin_usage=True)
def send_notification(service_id, template_id):
if {'recipient', 'placeholders'} - set(session.keys()):
return redirect(url_for(
'.send_one_off',
service_id=service_id,
template_id=template_id,
))
try:
noti = notification_api_client.send_notification(
service_id,
template_id=template_id,
recipient=session['recipient'] or session['placeholders']['address line 1'],
personalisation=session['placeholders'],
sender_id=session['sender_id'] if 'sender_id' in session else None
)
except HTTPError as exception:
current_app.logger.info('Service {} could not send notification: "{}"'.format(
current_service.id,
exception.message
))
return render_template(
'views/notifications/check.html',
**_check_notification(service_id, template_id, exception),
)
session.pop('placeholders')
session.pop('recipient')
session.pop('sender_id', None)
return redirect(url_for(
'.view_notification',
service_id=service_id,
notification_id=noti['id'],
help=request.args.get('help')
))
def get_email_reply_to_address_from_session():
if session.get('sender_id'):
return current_service.get_email_reply_to_address(
session['sender_id']
)['email_address']
def get_sms_sender_from_session():
if session.get('sender_id'):
return current_service.get_sms_sender(
session['sender_id']
)['sms_sender']
def get_spreadsheet_column_headings_from_template(template):
column_headings = []
for column_heading in (
first_column_headings[template.template_type] + list(template.placeholders)
):
if column_heading not in Columns.from_keys(column_headings):
column_headings.append(column_heading)
return column_headings