mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-06-01 03:50:26 -04:00
Users who go to edit the contact details for a letter from the template page get very confused when they click save and are dumped on the settings page. It doesn’t match the way editing other parts of letter works, and you can’t see an accurate preview of the changes from the settings page. So this commit changes the flow to go from the _edit contact details_ page back to the _view template_ page when the user has got there by clicking the blue _Edit_ button on the _view template_ page.
331 lines
12 KiB
Python
331 lines
12 KiB
Python
import requests
|
||
from flask import (
|
||
render_template,
|
||
redirect,
|
||
request,
|
||
url_for,
|
||
session,
|
||
flash,
|
||
abort,
|
||
current_app
|
||
)
|
||
|
||
from flask_login import (
|
||
login_required,
|
||
current_user
|
||
)
|
||
from notifications_python_client.errors import HTTPError
|
||
|
||
from app import service_api_client
|
||
from app.main import main
|
||
from app.utils import user_has_permissions, email_safe
|
||
from app.main.forms import (
|
||
ConfirmPasswordForm,
|
||
ServiceNameForm,
|
||
RequestToGoLiveForm,
|
||
ServiceReplyToEmailFrom,
|
||
ServiceSmsSender,
|
||
ServiceLetterContactBlock,
|
||
ServiceBrandingOrg
|
||
)
|
||
from app import user_api_client, current_service, organisations_client
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings")
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_settings(service_id):
|
||
if current_service['organisation']:
|
||
organisation = organisations_client.get_organisation(current_service['organisation'])['organisation']
|
||
else:
|
||
organisation = None
|
||
return render_template(
|
||
'views/service-settings.html',
|
||
organisation=organisation
|
||
)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/name", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_name_change(service_id):
|
||
form = ServiceNameForm(service_api_client.find_all_service_email_from)
|
||
|
||
if request.method == 'GET':
|
||
form.name.data = current_service.get('name')
|
||
|
||
if form.validate_on_submit():
|
||
session['service_name_change'] = form.name.data
|
||
return redirect(url_for('.service_name_change_confirm', service_id=service_id))
|
||
|
||
return render_template(
|
||
'views/service-settings/name.html',
|
||
form=form)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/name/confirm", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_name_change_confirm(service_id):
|
||
# Validate password for form
|
||
def _check_password(pwd):
|
||
return user_api_client.verify_password(current_user.id, pwd)
|
||
|
||
form = ConfirmPasswordForm(_check_password)
|
||
|
||
if form.validate_on_submit():
|
||
try:
|
||
service_api_client.update_service(
|
||
current_service['id'],
|
||
name=session['service_name_change'],
|
||
email_from=email_safe(session['service_name_change'])
|
||
)
|
||
except HTTPError as e:
|
||
error_msg = "Duplicate service name '{}'".format(session['service_name_change'])
|
||
if e.status_code == 400 and error_msg in e.message['name']:
|
||
# Redirect the user back to the change service name screen
|
||
flash('This service name is already in use', 'error')
|
||
return redirect(url_for('main.service_name_change', service_id=service_id))
|
||
else:
|
||
raise e
|
||
else:
|
||
session.pop('service_name_change')
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
return render_template(
|
||
'views/service-settings/confirm.html',
|
||
heading='Change your service name',
|
||
form=form)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/request-to-go-live", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_request_to_go_live(service_id):
|
||
form = RequestToGoLiveForm()
|
||
|
||
if form.validate_on_submit():
|
||
|
||
data = {
|
||
'person_email': current_user.email_address,
|
||
'person_name': current_user.name,
|
||
'department_id': current_app.config.get('DESKPRO_DEPT_ID'),
|
||
'agent_team_id': current_app.config.get('DESKPRO_ASSIGNED_AGENT_TEAM_ID'),
|
||
'subject': 'Request to go live - {}'.format(current_service['name']),
|
||
'message': (
|
||
'On behalf of {} ({})\n\nExpected usage\n---'
|
||
'\nMOU in place: {}'
|
||
'\nChannel: {}\nStart date: {}\nStart volume: {}'
|
||
'\nPeak volume: {}\nUpload or API: {}'
|
||
).format(
|
||
current_service['name'],
|
||
url_for('main.service_dashboard', service_id=current_service['id'], _external=True),
|
||
form.mou.data,
|
||
form.channel.data,
|
||
form.start_date.data,
|
||
form.start_volume.data,
|
||
form.peak_volume.data,
|
||
form.upload_or_api.data
|
||
|
||
)
|
||
}
|
||
headers = {
|
||
"X-DeskPRO-API-Key": current_app.config.get('DESKPRO_API_KEY'),
|
||
'Content-Type': "application/x-www-form-urlencoded"
|
||
}
|
||
resp = requests.post(
|
||
current_app.config.get('DESKPRO_API_HOST') + '/api/tickets',
|
||
data=data,
|
||
headers=headers
|
||
)
|
||
if resp.status_code != 201:
|
||
current_app.logger.error(
|
||
"Deskpro create ticket request failed with {} '{}'".format(
|
||
resp.status_code,
|
||
resp.json())
|
||
)
|
||
abort(500, "Request to go live submission failed")
|
||
|
||
flash('We’ve received your request to go live', 'default')
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
|
||
return render_template('views/service-settings/request-to-go-live.html', form=form)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/switch-live")
|
||
@login_required
|
||
@user_has_permissions(admin_override=True)
|
||
def service_switch_live(service_id):
|
||
service_api_client.update_service(
|
||
current_service['id'],
|
||
# TODO This limit should be set depending on the agreement signed by
|
||
# with Notify.
|
||
message_limit=250000 if current_service['restricted'] else 50,
|
||
restricted=(not current_service['restricted'])
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/research-mode")
|
||
@login_required
|
||
@user_has_permissions(admin_override=True)
|
||
def service_switch_research_mode(service_id):
|
||
service_api_client.update_service_with_properties(
|
||
service_id,
|
||
{"research_mode": not current_service['research_mode']}
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/can-send-letters")
|
||
@login_required
|
||
@user_has_permissions(admin_override=True)
|
||
def service_switch_can_send_letters(service_id):
|
||
service_api_client.update_service_with_properties(
|
||
service_id,
|
||
{"can_send_letters": not current_service['can_send_letters']}
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/archive", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def archive_service(service_id):
|
||
if request.method == 'POST':
|
||
service_api_client.archive_service(service_id)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
else:
|
||
flash('There\'s no way to reverse this! Are you sure you want to archive this service?', 'delete')
|
||
return service_settings(service_id)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/suspend", methods=["GET", "POST"])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def suspend_service(service_id):
|
||
if request.method == 'POST':
|
||
service_api_client.suspend_service(service_id)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
else:
|
||
flash("This will suspend the service and revoke all api keys. Are you sure you want to suspend this service?",
|
||
'suspend')
|
||
return service_settings(service_id)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/resume", methods=["GET", "POST"])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def resume_service(service_id):
|
||
if request.method == 'POST':
|
||
service_api_client.resume_service(service_id)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
else:
|
||
flash("This will resume the service. New api key are required for this service to use the API.", 'resume')
|
||
return service_settings(service_id)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/set-reply-to-email", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_set_reply_to_email(service_id):
|
||
form = ServiceReplyToEmailFrom()
|
||
if request.method == 'GET':
|
||
form.email_address.data = current_service.get('reply_to_email_address')
|
||
if form.validate_on_submit():
|
||
service_api_client.update_service(
|
||
current_service['id'],
|
||
reply_to_email_address=form.email_address.data
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
|
||
return render_template(
|
||
'views/service-settings/set-reply-to-email.html',
|
||
form=form)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/set-sms-sender", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_set_sms_sender(service_id):
|
||
form = ServiceSmsSender()
|
||
if request.method == 'GET':
|
||
form.sms_sender.data = current_service.get('sms_sender')
|
||
if form.validate_on_submit():
|
||
service_api_client.update_service(
|
||
current_service['id'],
|
||
sms_sender=form.sms_sender.data or None
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
return render_template(
|
||
'views/service-settings/set-sms-sender.html',
|
||
form=form)
|
||
|
||
|
||
@main.route("/services/<service_id>/service-settings/set-letter-contact-block", methods=['GET', 'POST'])
|
||
@login_required
|
||
@user_has_permissions('manage_settings', admin_override=True)
|
||
def service_set_letter_contact_block(service_id):
|
||
|
||
if not current_service['can_send_letters']:
|
||
abort(403)
|
||
|
||
form = ServiceLetterContactBlock(letter_contact_block=current_service['letter_contact_block'])
|
||
if form.validate_on_submit():
|
||
service_api_client.update_service(
|
||
current_service['id'],
|
||
letter_contact_block=form.letter_contact_block.data.replace('\r', '') or None
|
||
)
|
||
if request.args.get('from_template'):
|
||
return redirect(
|
||
url_for('.view_template', service_id=service_id, template_id=request.args.get('from_template'))
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
return render_template(
|
||
'views/service-settings/set-letter-contact-block.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)
|
||
def service_set_branding_and_org(service_id):
|
||
organisations = organisations_client.get_organisations()
|
||
|
||
form = ServiceBrandingOrg(branding_type=current_service.get('branding'))
|
||
# dynamically create org choices, including the null option
|
||
form.organisation.choices = [('None', 'None')] + get_branding_as_value_and_label(organisations)
|
||
|
||
if form.validate_on_submit():
|
||
organisation = None if form.organisation.data == 'None' else form.organisation.data
|
||
service_api_client.update_service(
|
||
service_id,
|
||
branding=form.branding_type.data,
|
||
organisation=organisation
|
||
)
|
||
return redirect(url_for('.service_settings', service_id=service_id))
|
||
|
||
form.organisation.data = current_service['organisation'] or 'None'
|
||
|
||
return render_template(
|
||
'views/service-settings/set-branding-and-org.html',
|
||
form=form,
|
||
branding_dict=get_branding_as_dict(organisations)
|
||
)
|
||
|
||
|
||
def get_branding_as_value_and_label(organisations):
|
||
return [
|
||
(organisation['id'], organisation['name'])
|
||
for organisation in organisations
|
||
]
|
||
|
||
|
||
def get_branding_as_dict(organisations):
|
||
return {
|
||
organisation['id']: {
|
||
'logo': '/static/images/email-template/crests/{}'.format(organisation['logo']),
|
||
'colour': organisation['colour']
|
||
} for organisation in organisations
|
||
}
|