Skip to content

Commit 24b2648

Browse files
committed
Ensure we don't duplicate counts of overlapping cascades
1 parent 4181047 commit 24b2648

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

manage_breast_screening/notifications/queries/aggregate.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ AND msg_fld.status = 'failed'
2525
LEFT OUTER JOIN notifications_channelstatus nhsapp_read ON nhsapp_read.message_id = msg_snt.id
2626
AND nhsapp_read.channel = 'nhsapp'
2727
AND nhsapp_read.status = 'read'
28+
AND (nhsapp_read.status_updated_at::date - msg_snt.sent_at::date) <= 1
2829
LEFT OUTER JOIN notifications_channelstatus sms_dlv ON sms_dlv.message_id = msg_snt.id
2930
AND sms_dlv.channel = 'sms'
3031
AND sms_dlv.status = 'delivered'
32+
AND (sms_dlv.status_updated_at::date - msg_snt.sent_at::date) <= 4
3133
LEFT OUTER JOIN notifications_channelstatus ltr_sent ON ltr_sent.message_id = msg_snt.id
3234
AND ltr_sent.channel = 'letter'
3335
AND ltr_sent.status = 'received'

manage_breast_screening/notifications/tests/queries/test_aggregate_query.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,19 @@ def create_appointment_set(
3030
starts_at=date,
3131
episode_type=episode_type,
3232
)
33-
message = MessageFactory(appointment=appt, status=message_status)
34-
MessageStatusFactory(message=message, status=message_status)
33+
message = MessageFactory(
34+
appointment=appt, status=message_status, sent_at=datetime.now()
35+
)
36+
MessageStatusFactory(
37+
message=message, status=message_status, status_updated_at=datetime.now()
38+
)
3539
for channel, status in channel_statuses.items():
36-
ChannelStatusFactory(message=message, channel=channel, status=status)
40+
ChannelStatusFactory(
41+
message=message,
42+
channel=channel,
43+
status=status,
44+
status_updated_at=datetime.now(),
45+
)
3746
return appt
3847

3948
def test_query_aggregates_appointments_and_cascade_counts(self):
@@ -127,6 +136,74 @@ def test_aggregate_uses_date_range(self):
127136

128137
assert len(results) == 1
129138

139+
def test_aggregate_cascade_overlaps_are_counted_once(self):
140+
appt_date = datetime.now() - timedelta(days=20)
141+
message_sent_at = datetime.now() - timedelta(days=6)
142+
appt = AppointmentFactory(
143+
clinic=ClinicFactory(code="BU006", bso_code="BSO6", name="BSU 6"),
144+
starts_at=appt_date,
145+
episode_type="S",
146+
)
147+
message = MessageFactory(
148+
appointment=appt, status="delivered", sent_at=message_sent_at
149+
)
150+
MessageStatusFactory(message=message, status="delivered")
151+
ChannelStatusFactory(
152+
message=message,
153+
channel="nhsapp",
154+
status="read",
155+
status_updated_at=(message_sent_at + timedelta(days=2)),
156+
)
157+
sms_status = ChannelStatusFactory(
158+
message=message,
159+
channel="sms",
160+
status="delivered",
161+
status_updated_at=(message_sent_at + timedelta(days=4)),
162+
)
163+
164+
with connection.cursor() as cursor:
165+
cursor.execute(AggregateQuery.sql(), ("1 month",))
166+
results = cursor.fetchall()
167+
168+
assert list(results[0]) == [
169+
appt_date.strftime("%Y-%m-%d"),
170+
"BSO6",
171+
"BU006",
172+
"BSU 6",
173+
"Self referral",
174+
1,
175+
0,
176+
1,
177+
0,
178+
0,
179+
]
180+
181+
sms_status.status_updated_at = message_sent_at + timedelta(days=5)
182+
sms_status.save()
183+
ChannelStatusFactory(
184+
message=message,
185+
channel="letter",
186+
status="received",
187+
status_updated_at=(message_sent_at + timedelta(days=5)),
188+
)
189+
190+
with connection.cursor() as cursor:
191+
cursor.execute(AggregateQuery.sql(), ("1 month",))
192+
results = cursor.fetchall()
193+
194+
assert list(results[0]) == [
195+
appt_date.strftime("%Y-%m-%d"),
196+
"BSO6",
197+
"BU006",
198+
"BSU 6",
199+
"Self referral",
200+
1,
201+
0,
202+
0,
203+
1,
204+
0,
205+
]
206+
130207
def test_aggregate_columns(self):
131208
assert AggregateQuery.columns() == [
132209
"Appointment date",

0 commit comments

Comments
 (0)