diff --git a/src/backend/apps/event/enums.py b/src/backend/apps/event/enums.py
index 164a530d..a85ff7ce 100644
--- a/src/backend/apps/event/enums.py
+++ b/src/backend/apps/event/enums.py
@@ -133,5 +133,14 @@ class EVENT_DISPLAY_CATEGORY:
MINOR_DELAYS = 'minorEvents'
FUTURE_DELAYS = 'futureEvents'
ROAD_CONDITION = 'roadConditions'
- HIGHWAY_CAMERAS = 'highwayCams'
CHAIN_UP = 'chainUps'
+
+
+EVENT_DISPLAY_CATEGORY_TITLE = {
+ EVENT_DISPLAY_CATEGORY.CLOSURE: "closures",
+ EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS: "major delays",
+ EVENT_DISPLAY_CATEGORY.MINOR_DELAYS: "minor delays",
+ EVENT_DISPLAY_CATEGORY.FUTURE_DELAYS: "future delays",
+ EVENT_DISPLAY_CATEGORY.ROAD_CONDITION: "road conditions",
+ EVENT_DISPLAY_CATEGORY.CHAIN_UP: "chain ups"
+}
diff --git a/src/backend/apps/event/tasks.py b/src/backend/apps/event/tasks.py
index f6be7c26..df079148 100644
--- a/src/backend/apps/event/tasks.py
+++ b/src/backend/apps/event/tasks.py
@@ -7,6 +7,7 @@
from apps.event.enums import (
EVENT_DIFF_FIELDS,
EVENT_DISPLAY_CATEGORY,
+ EVENT_DISPLAY_CATEGORY_TITLE,
EVENT_STATUS,
EVENT_TYPE,
EVENT_UPDATE_FIELDS,
@@ -240,6 +241,52 @@ def send_event_notifications(updated_event_ids, dt=None):
send_route_notifications(saved_route, updated_event_ids)
+def generate_settings_message(route):
+ msg = 'Based on your settings, you are being notified for all new and updated '
+
+ # Add event types
+ if route.notification_types and len(route.notification_types) == 4:
+ msg += 'information '
+
+ else:
+ types = [EVENT_DISPLAY_CATEGORY_TITLE[t] for t in route.notification_types]
+ if len(types) > 2:
+ msg += f'{", ".join(types[:-1])}, and {types[-1]} '
+ elif len(types) == 2:
+ msg += f'{types[0]} and {types[1]} '
+ else:
+ msg += f'{types[0]} '
+
+ msg += 'that affects your route '
+
+ # Add date/time
+ # Immediately and all the time
+ if not route.notification_start_time:
+ msg += 'at any time.'
+
+ else:
+ msg += (f'between {route.notification_start_time.strftime("%I:%M%p").lower()} '
+ f'and {route.notification_end_time.strftime("%I:%M%p").lower()} ')
+
+ # Specific date
+ if route.notification_end_date:
+ msg += (f'from {route.notification_start_date.strftime("%B %d")} '
+ f'and {route.notification_end_date.strftime("%B %d")}.')
+
+ # Date range
+ elif route.notification_start_date:
+ msg += f'on {route.notification_start_date.strftime("%B %d")}.'
+
+ # Days of the week
+ elif len(route.notification_days) == 7:
+ msg += 'every day.'
+
+ else:
+ msg += f'every {", ".join(route.notification_days)}.'
+
+ return msg
+
+
def send_route_notifications(saved_route, updated_event_ids):
# Apply a 150m buffer to the route geometry
saved_route.route.transform(3857)
@@ -262,6 +309,7 @@ def send_route_notifications(saved_route, updated_event_ids):
'display_category': event.display_category,
'display_category_title': event.display_category_title,
'fe_base_url': settings.FRONTEND_BASE_URL,
+ 'footer_message': generate_settings_message(saved_route),
}
text = render_to_string('email/event_updated.txt', context)
diff --git a/src/backend/apps/event/templates/email/event_updated.html b/src/backend/apps/event/templates/email/event_updated.html
index 2ac5d03c..1a611378 100644
--- a/src/backend/apps/event/templates/email/event_updated.html
+++ b/src/backend/apps/event/templates/email/event_updated.html
@@ -169,7 +169,7 @@
- Based on your settings, you are being notified for new and updated advisories, closures, major delays, and road conditions from 9:00 am to 10:30 am, every Monday, Tuesday, Wednesday, Thursday, Friday.
+ {{ footer_message }}
|
diff --git a/src/backend/apps/event/tests/test_event_notification.py b/src/backend/apps/event/tests/test_event_notification.py
index 8f8e0a0f..80e7a041 100644
--- a/src/backend/apps/event/tests/test_event_notification.py
+++ b/src/backend/apps/event/tests/test_event_notification.py
@@ -11,7 +11,7 @@
EVENT_TYPE,
)
from apps.event.models import Event
-from apps.event.tasks import send_event_notifications
+from apps.event.tasks import generate_settings_message, send_event_notifications
from django.contrib.gis.geos import LineString, MultiLineString, Point
from django.core import mail
from django.test import TestCase
@@ -22,7 +22,6 @@
EVENT_DISPLAY_CATEGORY.MINOR_DELAYS,
EVENT_DISPLAY_CATEGORY.FUTURE_DELAYS,
EVENT_DISPLAY_CATEGORY.ROAD_CONDITION,
- EVENT_DISPLAY_CATEGORY.HIGHWAY_CAMERAS,
EVENT_DISPLAY_CATEGORY.CHAIN_UP
]
@@ -242,3 +241,81 @@ def test_restricted_types(self):
assert 'Always Active Route' in mail.outbox[0].subject
assert 'Always Active Minor Route' in mail.outbox[1].subject
assert 'Intersecting Event Minor' in mail.outbox[1].body
+
+ def test_generate_footer_message(self):
+ # All notification types
+ route = SavedRoutes(notification_types=[
+ EVENT_DISPLAY_CATEGORY.CLOSURE,
+ EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS,
+ EVENT_DISPLAY_CATEGORY.MINOR_DELAYS,
+ EVENT_DISPLAY_CATEGORY.ROAD_CONDITION
+ ])
+ msg = generate_settings_message(route)
+ assert 'all new and updated information ' in msg
+
+ # Two notification types
+ route = SavedRoutes(notification_types=[
+ EVENT_DISPLAY_CATEGORY.CLOSURE,
+ EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS
+ ])
+ msg = generate_settings_message(route)
+ assert 'closures and major delays ' in msg
+
+ # Three notification types
+ route = SavedRoutes(notification_types=[
+ EVENT_DISPLAY_CATEGORY.CLOSURE,
+ EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS,
+ EVENT_DISPLAY_CATEGORY.MINOR_DELAYS
+ ])
+ msg = generate_settings_message(route)
+ assert 'closures, major delays, and minor delays ' in msg
+
+ # Any time
+ route = SavedRoutes(
+ notification_types=[EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS],
+ )
+ msg = generate_settings_message(route)
+ assert 'at any time.' in msg
+
+ # Specific date
+ route = SavedRoutes(
+ notification_types=[EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS],
+ notification_start_time=datetime.time(8, 0),
+ notification_end_time=datetime.time(17, 0),
+ notification_start_date=datetime.date(2023, 1, 1)
+ )
+ msg = generate_settings_message(route)
+ assert 'on January 01.' in msg
+
+ # Date range
+ route = SavedRoutes(
+ notification_types=[EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS],
+ notification_start_time=datetime.time(8, 0),
+ notification_end_time=datetime.time(17, 0),
+ notification_start_date=datetime.date(2023, 1, 1),
+ notification_end_date=datetime.date(2023, 1, 7)
+ )
+ msg = generate_settings_message(route)
+ assert 'between 08:00am and 05:00pm ' in msg
+ assert 'from January 01 and January 07.' in msg
+
+ # Days of the week
+ route = SavedRoutes(
+ notification_types=[EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS],
+ notification_start_time=datetime.time(12, 0),
+ notification_end_time=datetime.time(23, 0),
+ notification_days=['Monday', 'Wednesday', 'Friday']
+ )
+ msg = generate_settings_message(route)
+ assert 'between 12:00pm and 11:00pm ' in msg
+ assert 'every Monday, Wednesday, Friday.' in msg
+
+ # Every day
+ route = SavedRoutes(
+ notification_types=[EVENT_DISPLAY_CATEGORY.MAJOR_DELAYS],
+ notification_start_time=datetime.time(8, 0),
+ notification_end_time=datetime.time(17, 0),
+ notification_days=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
+ )
+ msg = generate_settings_message(route)
+ assert 'every day.' in msg
diff --git a/src/frontend/src/Components/routing/forms/NotificationDateTime.js b/src/frontend/src/Components/routing/forms/NotificationDateTime.js
index a8eb7989..affc09e2 100644
--- a/src/frontend/src/Components/routing/forms/NotificationDateTime.js
+++ b/src/frontend/src/Components/routing/forms/NotificationDateTime.js
@@ -24,8 +24,8 @@ const NotificationDateTime = forwardRef((props, ref) => {
const [specificDateOption, setSpecificDateOption] = useState(defaultSpecificDateOption);
// Time range
- const defaultStartTime = route.notification_start_time.split(':').slice(0, 2).join(':');
- const defaultEndTime = route.notification_end_time.split(':').slice(0, 2).join(':');
+ const defaultStartTime = route.notification_start_time ? route.notification_start_time.split(':').slice(0, 2).join(':') : null;
+ const defaultEndTime = route.notification_end_time ? route.notification_end_time.split(':').slice(0, 2).join(':') : null;
const [startTime, setStartTime] = useState(defaultStartTime);
const [endTime, setEndTime] = useState(defaultEndTime);