From de9759b99a72b8f79ac469c1011c48a7e776d5b0 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Tue, 18 Sep 2018 08:59:23 +0100 Subject: [PATCH] Add letter class row to settings page, visible to platform admin Added a new row to the settings table, 'Post class', which shows the default letter class of a service and is only visible to Platform Admin. Also added a new page to enable Platform Admin users to change the default letter class for a service - this only has two options at the moment, 1st class only and 2nd class only. --- app/main/forms.py | 11 ++++++ app/main/views/service_settings.py | 14 ++++++++ app/navigation.py | 4 +++ app/notify_client/models.py | 1 + app/notify_client/service_api_client.py | 1 + app/templates/views/service-settings.html | 15 ++++++++ .../service-settings/set-letter-class.html | 36 +++++++++++++++++++ tests/__init__.py | 2 ++ tests/app/main/views/test_service_settings.py | 33 +++++++++++++++++ 9 files changed, 117 insertions(+) create mode 100644 app/templates/views/service-settings/set-letter-class.html diff --git a/app/main/forms.py b/app/main/forms.py index 06d7e5ddc..42bdaf37e 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -684,6 +684,17 @@ class ServiceSwitchLettersForm(StripWhitespaceForm): ) +class ServiceLetterClassForm(StripWhitespaceForm): + + letter_class = RadioField( + 'Postage classes', + choices=[ + ('first', '1st class only'), + ('second', '2nd class only'), + ], + ) + + class BrandingStyle(RadioField): def post_validate(self, form, validation_stopped): diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 5cf9390db..e37f61819 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -42,6 +42,7 @@ from app.main.forms import ( ServiceDataRetentionForm, ServiceEditInboundNumberForm, ServiceInboundNumberForm, + ServiceLetterClassForm, ServiceLetterContactBlockForm, ServicePreviewBranding, ServiceReplyToEmailForm, @@ -649,6 +650,19 @@ def service_set_letters(service_id): ) +@main.route("/services//service-settings/set-letter-class", methods=['GET', 'POST']) +@login_required +@user_is_platform_admin +def service_set_letter_class(service_id): + form = ServiceLetterClassForm(letter_class=current_service.letter_class) + + if form.validate_on_submit(): + service_api_client.update_service(service_id, letter_class=form.letter_class.data) + return redirect(url_for(".service_settings", service_id=service_id)) + + return render_template('views/service-settings/set-letter-class.html', form=form) + + @main.route("/services//service-settings/set-auth-type", methods=['GET']) @login_required @user_has_permissions('manage_service') diff --git a/app/navigation.py b/app/navigation.py index 1b9e556a5..929913898 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -228,6 +228,7 @@ class HeaderNavigation(Navigation): 'service_set_inbound_number', 'service_set_inbound_sms', 'service_set_international_sms', + 'service_set_letter_class', 'service_set_letter_contact_block', 'service_set_letters', 'service_set_reply_to_email', @@ -350,6 +351,7 @@ class MainNavigation(Navigation): 'service_set_inbound_number', 'service_set_inbound_sms', 'service_set_international_sms', + 'service_set_letter_class', 'service_set_letter_contact_block', 'service_set_letters', 'service_set_reply_to_email', @@ -675,6 +677,7 @@ class CaseworkNavigation(Navigation): 'service_set_inbound_number', 'service_set_inbound_sms', 'service_set_international_sms', + 'service_set_letter_class', 'service_set_letter_contact_block', 'service_set_letters', 'service_set_reply_to_email', @@ -903,6 +906,7 @@ class OrgNavigation(Navigation): 'service_set_inbound_number', 'service_set_inbound_sms', 'service_set_international_sms', + 'service_set_letter_class', 'service_set_letter_contact_block', 'service_set_letters', 'service_set_reply_to_email', diff --git a/app/notify_client/models.py b/app/notify_client/models.py index 10a5eefad..6b140b641 100644 --- a/app/notify_client/models.py +++ b/app/notify_client/models.py @@ -275,6 +275,7 @@ class Service(dict): 'email_from', 'id', 'inbound_api', + 'letter_class', 'letter_contact_block', 'message_limit', 'name', diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index 73ac7b6f3..9dfafa075 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -81,6 +81,7 @@ class ServiceAPIClient(NotifyAdminAPIClient): 'created_by', 'branding', 'email_branding', + 'letter_class', 'letter_contact_block', 'dvla_organisation', 'permissions', diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index ad6b64909..4290b6aa8 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -235,6 +235,21 @@ )}} {% endcall %} + {% if current_user.platform_admin %} + {% call row() %} + {{ text_field('Post class') }} + {% set letter_class = {'first': '1st class only', 'second': '2nd class only'} %} + {{ text_field(letter_class[current_service.letter_class]) }} + {{ edit_field( + 'Change', + url_for('.service_set_letter_class', + service_id=current_service.id), + permissions=['manage_service'] + ) + }} + {% endcall %} + {% endif %} + {% endcall %} diff --git a/app/templates/views/service-settings/set-letter-class.html b/app/templates/views/service-settings/set-letter-class.html new file mode 100644 index 000000000..b94a2373b --- /dev/null +++ b/app/templates/views/service-settings/set-letter-class.html @@ -0,0 +1,36 @@ +{% extends "withnav_template.html" %} +{% from "components/radios.html" import radios %} +{% from "components/page-footer.html" import page_footer %} + +{% block service_page_title %} + Postage classes +{% endblock %} + +{% block maincolumn_content %} + +
+
+

Postage classes

+

+ Letters sent before 5:30pm will be printed and despatched the following business day. +

+

+ 1st class letters will be delivered the day after they are despatched (Monday to Saturday). + 2nd class letters will be delivered 2 days after they are despatched. +

+

+ See pricing for the list + of rates. +

+
+ {{ radios(form.letter_class) }} + {{ page_footer( + 'Save', + back_link=url_for('.service_settings', service_id=current_service.id), + back_link_text='Back to settings' + ) }} +
+
+
+ +{% endblock %} diff --git a/tests/__init__.py b/tests/__init__.py index 1d626d4cb..e7738bf4a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -139,6 +139,7 @@ def service_json( email_branding=None, branding='govuk', created_at=None, + letter_class='second', letter_contact_block=None, inbound_api=None, service_callback_api=None, @@ -168,6 +169,7 @@ def service_json( 'email_branding': email_branding, 'branding': branding, 'created_at': created_at or str(datetime.utcnow()), + 'letter_class': letter_class, 'letter_contact_block': letter_contact_block, 'dvla_organisation': '001', 'permissions': permissions, diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index abace066a..ce2c30250 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -89,6 +89,7 @@ def mock_get_service_settings_page_common( 'Label Value Action', 'Send letters Off Change', + 'Post class 2nd class only Change', 'Label Value Action', 'Organisation Org 1 Change', @@ -1849,6 +1850,38 @@ def test_set_letter_branding_saves( mock_update_service.assert_called_once_with(service_one['id'], dvla_organisation='500') +def test_set_letter_class_platform_admin_only( + logged_in_client, + service_one, +): + response = logged_in_client.get(url_for('main.service_set_letter_class', service_id=SERVICE_ONE_ID)) + assert response.status_code == 403 + + +def test_set_letter_class_prepopulates( + logged_in_platform_admin_client, + service_one, +): + response = logged_in_platform_admin_client.get(url_for('main.service_set_letter_class', service_id=SERVICE_ONE_ID)) + assert response.status_code == 200 + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + assert page.select('input[checked]')[0]['value'] == 'second' + + +def test_set_letter_class_saves( + logged_in_platform_admin_client, + service_one, + mock_update_service, +): + response = logged_in_platform_admin_client.post( + url_for('main.service_set_letter_class', service_id=SERVICE_ONE_ID), + data={'letter_class': 'first'} + ) + assert response.status_code == 302 + assert response.location == url_for('main.service_settings', service_id=SERVICE_ONE_ID, _external=True) + mock_update_service.assert_called_once_with(SERVICE_ONE_ID, letter_class='first') + + @pytest.mark.parametrize('current_branding, expected_values, expected_labels', [ (None, [ 'None', '1', '2', '3', '4', '5',