mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-09 09:09:49 -04:00
Add function to estimate letter delivery date
Letter delivery depends on: - how long it takes to print - how long it takes to post Both of these process are impacted by weekends, because people don’t work on weekends. It also depends on if you submit your letter before or after 5pm, because that’s the cut off time for getting a letter printed on a given day – ie after 5pm on Monday is effectively the same as Tuesday and so on. But I reckon all our users need to know is roughly how long it will take until the letter turns up on the user’s doorstep. So this commit adds a function to calculate this. Doesn’t surface it on the front end _yet_.
This commit is contained in:
@@ -7,7 +7,6 @@ from time import monotonic
|
|||||||
|
|
||||||
import dateutil
|
import dateutil
|
||||||
import itertools
|
import itertools
|
||||||
import pytz
|
|
||||||
import ago
|
import ago
|
||||||
from flask import (
|
from flask import (
|
||||||
Flask,
|
Flask,
|
||||||
@@ -58,6 +57,8 @@ from app.notify_client.organisations_client import OrganisationsClient
|
|||||||
from app.notify_client.models import AnonymousUser
|
from app.notify_client.models import AnonymousUser
|
||||||
from app.notify_client.letter_jobs_client import LetterJobsClient
|
from app.notify_client.letter_jobs_client import LetterJobsClient
|
||||||
|
|
||||||
|
from app.utils import gmt_timezones
|
||||||
|
|
||||||
login_manager = LoginManager()
|
login_manager = LoginManager()
|
||||||
csrf = CsrfProtect()
|
csrf = CsrfProtect()
|
||||||
|
|
||||||
@@ -215,12 +216,6 @@ def syntax_highlight_json(code):
|
|||||||
return Markup(highlight(code, JavascriptLexer(), HtmlFormatter(noclasses=True)))
|
return Markup(highlight(code, JavascriptLexer(), HtmlFormatter(noclasses=True)))
|
||||||
|
|
||||||
|
|
||||||
def gmt_timezones(date):
|
|
||||||
date = dateutil.parser.parse(date)
|
|
||||||
forced_utc = date.replace(tzinfo=pytz.utc)
|
|
||||||
return forced_utc.astimezone(pytz.timezone('Europe/London'))
|
|
||||||
|
|
||||||
|
|
||||||
def format_datetime(date):
|
def format_datetime(date):
|
||||||
return '{} at {}'.format(
|
return '{} at {}'.format(
|
||||||
format_date(date),
|
format_date(date),
|
||||||
|
|||||||
24
app/utils.py
24
app/utils.py
@@ -1,10 +1,12 @@
|
|||||||
import re
|
import re
|
||||||
import csv
|
import csv
|
||||||
|
import pytz
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from os import path
|
from os import path
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from dateutil import parser
|
||||||
|
|
||||||
import dateutil
|
import dateutil
|
||||||
import ago
|
import ago
|
||||||
@@ -324,3 +326,25 @@ def get_time_left(created_at):
|
|||||||
|
|
||||||
def email_or_sms_not_enabled(template_type, permissions):
|
def email_or_sms_not_enabled(template_type, permissions):
|
||||||
return (template_type in ['email', 'sms']) and (template_type not in permissions)
|
return (template_type in ['email', 'sms']) and (template_type not in permissions)
|
||||||
|
|
||||||
|
|
||||||
|
def get_estimated_delivery_date_for_letters(upload_time):
|
||||||
|
|
||||||
|
# shift anything after 5pm to the next day
|
||||||
|
processing_day = gmt_timezones(upload_time) + timedelta(hours=(7))
|
||||||
|
|
||||||
|
return tuple(
|
||||||
|
processing_day + timedelta(days=days)
|
||||||
|
for days in {
|
||||||
|
'Wednesday': (3, 5),
|
||||||
|
'Thursday': (4, 5),
|
||||||
|
'Friday': (5, 6),
|
||||||
|
'Saturday': (4, 5),
|
||||||
|
}.get(processing_day.strftime('%A'), (3, 4))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def gmt_timezones(date):
|
||||||
|
date = dateutil.parser.parse(date)
|
||||||
|
forced_utc = date.replace(tzinfo=pytz.utc)
|
||||||
|
return forced_utc.astimezone(pytz.timezone('Europe/London'))
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ from app.utils import (
|
|||||||
generate_notifications_csv,
|
generate_notifications_csv,
|
||||||
generate_previous_dict,
|
generate_previous_dict,
|
||||||
generate_next_dict,
|
generate_next_dict,
|
||||||
Spreadsheet
|
Spreadsheet,
|
||||||
|
get_estimated_delivery_date_for_letters,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests import notification_json, single_notification_json
|
from tests import notification_json, single_notification_json
|
||||||
@@ -154,3 +155,45 @@ def test_generate_notifications_csv_calls_twice_if_next_link(mocker):
|
|||||||
# mock_calls[0][2] is the kwargs from first call
|
# mock_calls[0][2] is the kwargs from first call
|
||||||
assert mock_get_notifications.mock_calls[0][2]['page'] == 1
|
assert mock_get_notifications.mock_calls[0][2]['page'] == 1
|
||||||
assert mock_get_notifications.mock_calls[1][2]['page'] == 2
|
assert mock_get_notifications.mock_calls[1][2]['page'] == 2
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('upload_time, expected_estimate', [
|
||||||
|
|
||||||
|
# BST
|
||||||
|
# ==================================================================
|
||||||
|
# First thing Monday
|
||||||
|
('2017-07-10 00:00:01', ('Thursday', 'Friday')),
|
||||||
|
# Monday at 16:59 BST
|
||||||
|
('2017-07-10 15:59:59', ('Thursday', 'Friday')),
|
||||||
|
# Monday at 17:00 BST
|
||||||
|
('2017-07-10 16:00:01', ('Friday', 'Saturday')),
|
||||||
|
# Tuesday before 17:00 BST
|
||||||
|
('2017-07-11 12:00:00', ('Friday', 'Saturday')),
|
||||||
|
# Wednesday before 17:00 BST
|
||||||
|
('2017-07-12 12:00:00', ('Saturday', 'Monday')),
|
||||||
|
# Thursday before 17:00 BST
|
||||||
|
('2017-07-13 12:00:00', ('Monday', 'Tuesday')),
|
||||||
|
# Friday anytime
|
||||||
|
('2017-07-14 00:00:00', ('Wednesday', 'Thursday')),
|
||||||
|
('2017-07-14 12:00:00', ('Wednesday', 'Thursday')),
|
||||||
|
('2017-07-14 22:00:00', ('Wednesday', 'Thursday')),
|
||||||
|
# Saturday anytime
|
||||||
|
('2017-07-14 12:00:00', ('Wednesday', 'Thursday')),
|
||||||
|
# Sunday before 1700 BST
|
||||||
|
('2017-07-15 15:59:59', ('Wednesday', 'Thursday')),
|
||||||
|
# Sunday after 17:00 BST
|
||||||
|
('2017-07-16 16:00:01', ('Thursday', 'Friday')),
|
||||||
|
|
||||||
|
# GMT
|
||||||
|
# ==================================================================
|
||||||
|
# Monday at 16:59 GMT
|
||||||
|
('2017-01-02 16:59:59', ('Thursday', 'Friday')),
|
||||||
|
# Monday at 17:00 GMT
|
||||||
|
('2017-01-02 17:00:01', ('Friday', 'Saturday')),
|
||||||
|
|
||||||
|
])
|
||||||
|
def test_get_estimated_delivery_date_for_letter(upload_time, expected_estimate):
|
||||||
|
assert tuple(
|
||||||
|
day.strftime('%A')
|
||||||
|
for day in get_estimated_delivery_date_for_letters(upload_time)
|
||||||
|
) == expected_estimate
|
||||||
|
|||||||
Reference in New Issue
Block a user