From de9759b99a72b8f79ac469c1011c48a7e776d5b0 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Tue, 18 Sep 2018 08:59:23 +0100 Subject: [PATCH 1/8] 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', From c125e244323665fbf44c81b53c589c9f60b7ba31 Mon Sep 17 00:00:00 2001 From: karlchillmaid Date: Tue, 18 Sep 2018 11:05:33 +0100 Subject: [PATCH 2/8] Updated postage content Updated postage content --- .../views/service-settings/set-letter-class.html | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/templates/views/service-settings/set-letter-class.html b/app/templates/views/service-settings/set-letter-class.html index b94a2373b..26174a331 100644 --- a/app/templates/views/service-settings/set-letter-class.html +++ b/app/templates/views/service-settings/set-letter-class.html @@ -10,18 +10,22 @@
-

Postage classes

+

Postage

+

You can send letters by first or second class post.

- Letters sent before 5:30pm will be printed and despatched the following business day. + See a list of postage prices. +

+

Delivery times

+

+ Letters sent before 5:30pm are dispatched the next working day (Monday to Friday).

- 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. + First class letters are delivered one day after they're dispatched. Second class letters are delivered 2 days after they're dispatched.

- See pricing for the list - of rates. + Royal Mail delivers from Monday to Saturday, excluding bank holidays.

+

Choose your postage

{{ radios(form.letter_class) }} {{ page_footer( From a2a8496d521d7e10a0888ca9a997d03e6187ba93 Mon Sep 17 00:00:00 2001 From: karlchillmaid Date: Tue, 18 Sep 2018 11:12:12 +0100 Subject: [PATCH 3/8] Updated postage radio labels Updated postage radio labels --- app/main/forms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 42bdaf37e..737a5b003 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -687,10 +687,10 @@ class ServiceSwitchLettersForm(StripWhitespaceForm): class ServiceLetterClassForm(StripWhitespaceForm): letter_class = RadioField( - 'Postage classes', + 'Choose your postage', choices=[ - ('first', '1st class only'), - ('second', '2nd class only'), + ('first', 'First class only'), + ('second', 'Second class only'), ], ) From 02ad9ed0a3a979502e9bab3702fc053bdddd313d Mon Sep 17 00:00:00 2001 From: karlchillmaid Date: Tue, 18 Sep 2018 11:13:32 +0100 Subject: [PATCH 4/8] Updated postage labels Updated postage labels --- app/templates/views/service-settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index 4290b6aa8..7cf86de11 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -237,8 +237,8 @@ {% if current_user.platform_admin %} {% call row() %} - {{ text_field('Post class') }} - {% set letter_class = {'first': '1st class only', 'second': '2nd class only'} %} + {{ text_field('Postage') }} + {% set letter_class = {'first': 'First class only', 'second': 'Second class only'} %} {{ text_field(letter_class[current_service.letter_class]) }} {{ edit_field( 'Change', From eb9768c91b6ea199e2fffc48afffe527ae08c6fc Mon Sep 17 00:00:00 2001 From: karlchillmaid Date: Tue, 18 Sep 2018 11:14:11 +0100 Subject: [PATCH 5/8] Removed heading above radios Removed heading above radios --- app/templates/views/service-settings/set-letter-class.html | 1 - 1 file changed, 1 deletion(-) diff --git a/app/templates/views/service-settings/set-letter-class.html b/app/templates/views/service-settings/set-letter-class.html index 26174a331..6336ddf59 100644 --- a/app/templates/views/service-settings/set-letter-class.html +++ b/app/templates/views/service-settings/set-letter-class.html @@ -25,7 +25,6 @@

Royal Mail delivers from Monday to Saturday, excluding bank holidays.

-

Choose your postage

{{ radios(form.letter_class) }} {{ page_footer( From 3390cfaaa2669ce8fe37a59a69cde47bb2a2299b Mon Sep 17 00:00:00 2001 From: karlchillmaid Date: Tue, 18 Sep 2018 11:21:31 +0100 Subject: [PATCH 6/8] Updated postage labels --- tests/app/main/views/test_service_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index ce2c30250..4369a8c4d 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -89,7 +89,7 @@ def mock_get_service_settings_page_common( 'Label Value Action', 'Send letters Off Change', - 'Post class 2nd class only Change', + 'Postage Second class only Change', 'Label Value Action', 'Organisation Org 1 Change', From 9660f372f3d261ad69034d1293a93f41c9672069 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 19 Sep 2018 09:20:09 +0100 Subject: [PATCH 7/8] Change naming in code to use 'postage' Renamed everything that was previously called 'letter class' or 'postage class' to 'postage', which is the new name we have decided to use. --- app/main/forms.py | 4 ++-- app/main/views/service_settings.py | 12 ++++++------ app/navigation.py | 8 ++++---- app/notify_client/models.py | 2 +- app/notify_client/service_api_client.py | 2 +- app/templates/views/service-settings.html | 6 +++--- .../{set-letter-class.html => set-postage.html} | 2 +- tests/__init__.py | 4 ++-- tests/app/main/views/test_service_settings.py | 16 ++++++++-------- 9 files changed, 28 insertions(+), 28 deletions(-) rename app/templates/views/service-settings/{set-letter-class.html => set-postage.html} (96%) diff --git a/app/main/forms.py b/app/main/forms.py index 737a5b003..79353ff11 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -684,9 +684,9 @@ class ServiceSwitchLettersForm(StripWhitespaceForm): ) -class ServiceLetterClassForm(StripWhitespaceForm): +class ServicePostageForm(StripWhitespaceForm): - letter_class = RadioField( + postage = RadioField( 'Choose your postage', choices=[ ('first', 'First class only'), diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index e37f61819..d25160b6d 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -42,8 +42,8 @@ from app.main.forms import ( ServiceDataRetentionForm, ServiceEditInboundNumberForm, ServiceInboundNumberForm, - ServiceLetterClassForm, ServiceLetterContactBlockForm, + ServicePostageForm, ServicePreviewBranding, ServiceReplyToEmailForm, ServiceSetBranding, @@ -650,17 +650,17 @@ def service_set_letters(service_id): ) -@main.route("/services//service-settings/set-letter-class", methods=['GET', 'POST']) +@main.route("/services//service-settings/set-postage", methods=['GET', 'POST']) @login_required @user_is_platform_admin -def service_set_letter_class(service_id): - form = ServiceLetterClassForm(letter_class=current_service.letter_class) +def service_set_postage(service_id): + form = ServicePostageForm(postage=current_service.postage) if form.validate_on_submit(): - service_api_client.update_service(service_id, letter_class=form.letter_class.data) + service_api_client.update_service(service_id, postage=form.postage.data) return redirect(url_for(".service_settings", service_id=service_id)) - return render_template('views/service-settings/set-letter-class.html', form=form) + return render_template('views/service-settings/set-postage.html', form=form) @main.route("/services//service-settings/set-auth-type", methods=['GET']) diff --git a/app/navigation.py b/app/navigation.py index 929913898..36a126478 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -228,9 +228,9 @@ 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_postage', 'service_set_reply_to_email', 'service_set_sms', 'service_set_sms_prefix', @@ -351,9 +351,9 @@ 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_postage', 'service_set_reply_to_email', 'service_set_sms', 'service_set_sms_prefix', @@ -677,9 +677,9 @@ 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_postage', 'service_set_reply_to_email', 'service_set_sms', 'service_set_sms_prefix', @@ -906,9 +906,9 @@ 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_postage', 'service_set_reply_to_email', 'service_set_sms', 'service_set_sms_prefix', diff --git a/app/notify_client/models.py b/app/notify_client/models.py index 6b140b641..03a97851c 100644 --- a/app/notify_client/models.py +++ b/app/notify_client/models.py @@ -275,12 +275,12 @@ class Service(dict): 'email_from', 'id', 'inbound_api', - 'letter_class', 'letter_contact_block', 'message_limit', 'name', 'organisation_type', 'permissions', + 'postage', 'prefix_sms', 'research_mode', 'service_callback_api', diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index 9dfafa075..26a1fe79f 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -81,7 +81,6 @@ class ServiceAPIClient(NotifyAdminAPIClient): 'created_by', 'branding', 'email_branding', - 'letter_class', 'letter_contact_block', 'dvla_organisation', 'permissions', @@ -89,6 +88,7 @@ class ServiceAPIClient(NotifyAdminAPIClient): 'free_sms_fragment_limit', 'prefix_sms', 'contact_link', + 'postage', } if disallowed_attributes: raise TypeError('Not allowed to update service attributes: {}'.format( diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index 7cf86de11..0314769af 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -238,11 +238,11 @@ {% if current_user.platform_admin %} {% call row() %} {{ text_field('Postage') }} - {% set letter_class = {'first': 'First class only', 'second': 'Second class only'} %} - {{ text_field(letter_class[current_service.letter_class]) }} + {% set postage = {'first': 'First class only', 'second': 'Second class only'} %} + {{ text_field(postage[current_service.postage]) }} {{ edit_field( 'Change', - url_for('.service_set_letter_class', + url_for('.service_set_postage', service_id=current_service.id), permissions=['manage_service'] ) diff --git a/app/templates/views/service-settings/set-letter-class.html b/app/templates/views/service-settings/set-postage.html similarity index 96% rename from app/templates/views/service-settings/set-letter-class.html rename to app/templates/views/service-settings/set-postage.html index 6336ddf59..7da5fc34d 100644 --- a/app/templates/views/service-settings/set-letter-class.html +++ b/app/templates/views/service-settings/set-postage.html @@ -26,7 +26,7 @@ Royal Mail delivers from Monday to Saturday, excluding bank holidays.

- {{ radios(form.letter_class) }} + {{ radios(form.postage) }} {{ page_footer( 'Save', back_link=url_for('.service_settings', service_id=current_service.id), diff --git a/tests/__init__.py b/tests/__init__.py index e7738bf4a..6f412363e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -139,7 +139,6 @@ 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, @@ -147,6 +146,7 @@ def service_json( organisation_type='central', prefix_sms=True, contact_link=None, + postage='second', ): if users is None: users = [] @@ -169,13 +169,13 @@ 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, 'inbound_api': inbound_api, 'service_callback_api': service_callback_api, 'prefix_sms': prefix_sms, + 'postage': postage, } diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index 4369a8c4d..cab7f38e8 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -1850,36 +1850,36 @@ 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( +def test_set_postage_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)) + response = logged_in_client.get(url_for('main.service_set_postage', service_id=SERVICE_ONE_ID)) assert response.status_code == 403 -def test_set_letter_class_prepopulates( +def test_set_postage_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)) + response = logged_in_platform_admin_client.get(url_for('main.service_set_postage', 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( +def test_set_postage_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'} + url_for('main.service_set_postage', service_id=SERVICE_ONE_ID), + data={'postage': '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') + mock_update_service.assert_called_once_with(SERVICE_ONE_ID, postage='first') @pytest.mark.parametrize('current_branding, expected_values, expected_labels', [ From 2726467fc7296536240e2932207acf281a8ad5bf Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 19 Sep 2018 16:53:31 +0100 Subject: [PATCH 8/8] Minor quote and heading fixes --- app/templates/views/service-settings/set-postage.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/templates/views/service-settings/set-postage.html b/app/templates/views/service-settings/set-postage.html index 7da5fc34d..995b1fc3b 100644 --- a/app/templates/views/service-settings/set-postage.html +++ b/app/templates/views/service-settings/set-postage.html @@ -3,7 +3,7 @@ {% from "components/page-footer.html" import page_footer %} {% block service_page_title %} - Postage classes + Postage {% endblock %} {% block maincolumn_content %} @@ -13,14 +13,14 @@

Postage

You can send letters by first or second class post.

- See a list of postage prices. + See a list of postage prices.

Delivery times

Letters sent before 5:30pm are dispatched the next working day (Monday to Friday).

- First class letters are delivered one day after they're dispatched. Second class letters are delivered 2 days after they're dispatched. + First class letters are delivered one day after they’re dispatched. Second class letters are delivered 2 days after they’re dispatched.

Royal Mail delivers from Monday to Saturday, excluding bank holidays.