Merge pull request #1534 from alphagov/collect-service-type

Collect organisation type when user creates a service and use it to calculate text message allowance
This commit is contained in:
Chris Hill-Scott
2017-10-24 12:24:07 +01:00
committed by GitHub
15 changed files with 397 additions and 40 deletions

View File

@@ -36,6 +36,11 @@ class Config(object):
ASSETS_DEBUG = False
AWS_REGION = 'eu-west-1'
DEFAULT_SERVICE_LIMIT = 50
DEFAULT_FREE_SMS_FRAGMENT_LIMITS = {
'central': 250000,
'local': 25000,
'nhs': 25000,
}
EMAIL_EXPIRY_SECONDS = 3600 * 24 * 7 # one week
HEADER_COLOUR = '#FFBF47' # $yellow
HTTP_PROTOCOL = 'http'

View File

@@ -141,6 +141,18 @@ def sms_code():
message='Code not found')])
def organisation_type():
return RadioField(
'Who runs this service?',
choices=[
('central', 'Central government'),
('local', 'Local government'),
('nhs', 'NHS'),
],
validators=[DataRequired()],
)
class LoginForm(Form):
email_address = StringField('Email address', validators=[
Length(min=5, max=255),
@@ -213,10 +225,7 @@ class TextNotReceivedForm(Form):
mobile_number = international_phone_number()
class ServiceNameForm(Form):
def __init__(self, *args, **kwargs):
super(ServiceNameForm, self).__init__(*args, **kwargs)
class RenameServiceForm(Form):
name = StringField(
u'Service name',
validators=[
@@ -224,6 +233,28 @@ class ServiceNameForm(Form):
])
class CreateServiceForm(Form):
name = StringField(
u'Whats your service called?',
validators=[
DataRequired(message='Cant be empty')
])
organisation_type = organisation_type()
class OrganisationTypeForm(Form):
organisation_type = organisation_type()
class FreeSMSAllowance(Form):
free_sms_allowance = IntegerField(
'Numbers of text message fragments per year',
validators=[
DataRequired(message='Cant be empty')
]
)
class ConfirmPasswordForm(Form):
def __init__(self, validate_password_func, *args, **kwargs):
self.validate_password_func = validate_password_func

View File

@@ -14,7 +14,7 @@ from notifications_python_client.errors import HTTPError
from werkzeug.exceptions import abort
from app.main import main
from app.main.forms import ServiceNameForm
from app.main.forms import CreateServiceForm
from app.notify_client.models import InvitedUser
from app import (
@@ -39,13 +39,17 @@ def _add_invited_user_to_service(invited_user):
return service_id
def _create_service(service_name, email_from, form):
def _create_service(service_name, organisation_type, email_from, form):
try:
service_id = service_api_client.create_service(service_name=service_name,
message_limit=current_app.config['DEFAULT_SERVICE_LIMIT'],
restricted=True,
user_id=session['user_id'],
email_from=email_from)
service_id = service_api_client.create_service(
service_name=service_name,
organisation_type=organisation_type,
message_limit=current_app.config['DEFAULT_SERVICE_LIMIT'],
free_sms_fragment_limit=current_app.config['DEFAULT_FREE_SMS_FRAGMENT_LIMITS'].get(organisation_type),
restricted=True,
user_id=session['user_id'],
email_from=email_from,
)
session['service_id'] = service_id
return service_id, None
except HTTPError as e:
@@ -78,14 +82,14 @@ def add_service():
if not is_gov_user(current_user.email_address):
abort(403)
form = ServiceNameForm()
heading = 'Which service do you want to set up notifications for?'
form = CreateServiceForm()
heading = 'About your service'
if form.validate_on_submit():
email_from = email_safe(form.name.data)
service_name = form.name.data
service_id, error = _create_service(service_name, email_from, form)
service_id, error = _create_service(service_name, form.organisation_type.data, email_from, form)
if error:
return render_template('views/add-service.html', form=form, heading=heading)
if len(service_api_client.get_active_services({'user_id': session['user_id']}).get('data', [])) > 1:

View File

@@ -25,7 +25,7 @@ from app.main import main
from app.utils import user_has_permissions, email_safe, get_cdn_domain
from app.main.forms import (
ConfirmPasswordForm,
ServiceNameForm,
RenameServiceForm,
RequestToGoLiveForm,
ServiceReplyToEmailForm,
ServiceSmsSender,
@@ -34,6 +34,8 @@ from app.main.forms import (
LetterBranding,
ServiceInboundApiForm,
InternationalSMSForm,
OrganisationTypeForm,
FreeSMSAllowance,
)
from app import user_api_client, current_service, organisations_client, inbound_number_client
from notifications_utils.formatters import formatted_list
@@ -73,12 +75,12 @@ def service_settings(service_id):
reply_to_email_addresses = service_api_client.get_reply_to_email_addresses(service_id)
reply_to_email_address_count = len(reply_to_email_addresses)
default_reply_to_email_address = next(
(x['email_address'] for x in reply_to_email_addresses if x['is_default']), "None"
(x['email_address'] for x in reply_to_email_addresses if x['is_default']), "Not set"
)
letter_contact_details = service_api_client.get_letter_contacts(service_id)
letter_contact_details_count = len(letter_contact_details)
default_letter_contact_block = next(
(Field(x['contact_block'], html='escape') for x in letter_contact_details if x['is_default']), "None"
(Field(x['contact_block'], html='escape') for x in letter_contact_details if x['is_default']), "Not set"
)
return render_template(
'views/service-settings.html',
@@ -100,7 +102,7 @@ def service_settings(service_id):
@login_required
@user_has_permissions('manage_settings', admin_override=True)
def service_name_change(service_id):
form = ServiceNameForm()
form = RenameServiceForm()
if request.method == 'GET':
form.name.data = current_service.get('name')
@@ -574,6 +576,46 @@ def service_set_letter_contact_block(service_id):
)
@main.route("/services/<service_id>/service-settings/set-organisation-type", methods=['GET', 'POST'])
@login_required
@user_has_permissions(admin_override=True)
def set_organisation_type(service_id):
form = OrganisationTypeForm(organisation_type=current_service.get('organisation_type'))
if form.validate_on_submit():
service_api_client.update_service(
service_id,
organisation_type=form.organisation_type.data,
)
return redirect(url_for('.service_settings', service_id=service_id))
return render_template(
'views/service-settings/set-organisation-type.html',
form=form,
)
@main.route("/services/<service_id>/service-settings/set-free-sms-allowance", methods=['GET', 'POST'])
@login_required
@user_has_permissions(admin_override=True)
def set_free_sms_allowance(service_id):
form = FreeSMSAllowance(free_sms_allowance=current_service['free_sms_fragment_limit'])
if form.validate_on_submit():
service_api_client.update_service(
service_id,
free_sms_fragment_limit=form.free_sms_allowance.data,
)
return redirect(url_for('.service_settings', service_id=service_id))
return render_template(
'views/service-settings/set-free-sms-allowance.html',
form=form,
)
@main.route("/services/<service_id>/service-settings/set-branding-and-org", methods=['GET', 'POST'])
@login_required
@user_has_permissions(admin_override=True)

View File

@@ -16,12 +16,23 @@ class ServiceAPIClient(NotifyAdminAPIClient):
self.service_id = application.config['ADMIN_CLIENT_USER_NAME']
self.api_key = application.config['ADMIN_CLIENT_SECRET']
def create_service(self, service_name, message_limit, restricted, user_id, email_from):
def create_service(
self,
service_name,
organisation_type,
free_sms_fragment_limit,
message_limit,
restricted,
user_id,
email_from,
):
"""
Create a service and return the json.
"""
data = {
"name": service_name,
"organisation_type": organisation_type,
"free_sms_fragment_limit": free_sms_fragment_limit,
"active": True,
"message_limit": message_limit,
"user_id": user_id,
@@ -93,7 +104,9 @@ class ServiceAPIClient(NotifyAdminAPIClient):
'organisation',
'letter_contact_block',
'dvla_organisation',
'permissions'
'permissions',
'organisation_type',
'free_sms_fragment_limit',
}
if disallowed_attributes:
raise TypeError('Not allowed to update service attributes: {}'.format(

View File

@@ -92,6 +92,13 @@
{% endcall %}
{%- endmacro %}
{% macro optional_text_field(text, default='Not set') -%}
{{ text_field(
text or default,
status='' if text else 'default'
) }}
{%- endmacro %}
{% macro link_field(text, link) -%}
{% call field() %}
<a href="{{ link }}">{{ text }}</a>

View File

@@ -1,4 +1,5 @@
{% extends "withoutnav_template.html" %}
{% from "components/radios.html" import radios %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
@@ -12,13 +13,15 @@
<div class="column-two-thirds">
<h1 class="heading-large">
When people receive notifications, who should they be from?
About your service
</h1>
<form autocomplete="off" method="post">
{{ textbox(form.name, hint="You can change this later") }}
{{ radios(form.organisation_type) }}
{{ page_footer('Add service') }}
</form>

View File

@@ -1,7 +1,7 @@
{% extends "withnav_template.html" %}
{% from "components/banner.html" import banner_wrapper %}
{% from "components/browse-list.html" import browse_list %}
{% from "components/table.html" import mapping_table, row, text_field, edit_field, field, boolean_field %}
{% from "components/table.html" import mapping_table, row, text_field, optional_text_field, edit_field, field, boolean_field %}
{% block service_page_title %}
Settings
@@ -90,7 +90,7 @@
{% if (current_user.has_permissions([], admin_override=True) or not can_receive_inbound) and not can_receive_inbound %}
{{ edit_field('Change', url_for('.service_set_sms_sender', service_id=current_service.id, set_inbound_sms=False)) }}
{% else %}
{{ text_field('') }}
{{ text_field('') }}
{% endif %}
{% endcall %}
@@ -110,10 +110,7 @@
{% if can_receive_inbound %}
{% call row() %}
{{ text_field('API endpoint for received text messages') }}
{{ text_field(
'None' if not inbound_api_url else inbound_api_url,
status='' if inbound_api_url else 'default'
) }}
{{ optional_text_field(inbound_api_url) }}
{{ edit_field('Change', url_for('.service_set_inbound_api', service_id=current_service.id)) }}
{% endcall %}
{% endif %}
@@ -138,8 +135,8 @@
{% if 'letter' in current_service.permissions %}
{% call row() %}
{{ text_field('Sender addresses') }}
{% call field(status='default' if default_letter_contact_block == "None" else '') %}
{{ default_letter_contact_block | string | nl2br | safe if default_letter_contact_block else 'None'}}
{% call field(status='default' if default_letter_contact_block == "Not set" else '') %}
{{ default_letter_contact_block | string | nl2br | safe if default_letter_contact_block else 'Not set'}}
{% if letter_contact_details_count > 1 %}
<div class="hint">
{{ '…and %d more' | format(letter_contact_details_count - 1) }}
@@ -191,6 +188,18 @@
field_headings_visible=False,
caption_visible=False
) %}
{% call row() %}
{{ text_field('Organisation type')}}
{{ optional_text_field(
(current_service.organisation_type or '')|title
) }}
{{ edit_field('Change', url_for('.set_organisation_type', service_id=current_service.id)) }}
{% endcall %}
{% call row() %}
{{ text_field('Free text message allowance')}}
{{ text_field('{:,}'.format(current_service.free_sms_fragment_limit)) }}
{{ edit_field('Change', url_for('.set_free_sms_allowance', service_id=current_service.id)) }}
{% endcall %}
{% call row() %}
{{ text_field('Email branding' )}}
{% call field() %}

View File

@@ -0,0 +1,21 @@
{% extends "withnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% block service_page_title %}
Emails
{% endblock %}
{% block maincolumn_content %}
<form method="post">
<h1 class="heading-large">Free text message allowance</h1>
{{ textbox(form.free_sms_allowance) }}
{{ page_footer(
'Save',
back_link=url_for('.service_settings', service_id=current_service.id),
back_link_text='Back to settings'
) }}
</form>
{% endblock %}

View File

@@ -0,0 +1,22 @@
{% extends "withnav_template.html" %}
{% from "components/radios.html" import radios, branding_radios %}
{% from "components/page-footer.html" import page_footer %}
{% block service_page_title %}
Set branding and organisation
{% endblock %}
{% block maincolumn_content %}
<h1 class="heading-large">Set organisation type</h1>
<form method="post">
{{ radios(form.organisation_type) }}
{{ page_footer(
'Save',
back_link=url_for('.service_settings', service_id=current_service.id),
back_link_text='Back to settings'
) }}
</form>
</div>
{% endblock %}