Skip to content

Commit 1f4abec

Browse files
committed
Add customisations to Notifier::Patient
This adds two new options when sending clinic invitations for a patient that allows users of this method to decide how the invitations should be sent. In particular, we'll be using this in a follow up commit to enable sending bulk invitations, but only for programmes that have not already received an invitation, using the new `include_already_invited_programmes` parameter. Jira-Issue: MAV-3886
1 parent ab61229 commit 1f4abec

4 files changed

Lines changed: 237 additions & 22 deletions

File tree

app/controllers/patients_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def invite_to_clinic
7575
end
7676

7777
@patient.notifier.send_clinic_invitation(
78-
programme_types: current_team.programme_types,
78+
current_team.programmes,
7979
team: current_team,
8080
academic_year:,
8181
sent_by: current_user

app/controllers/sessions/invite_to_clinic_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def update
1717

1818
@patients_to_invite.each do |patient|
1919
patient.notifier.send_clinic_invitation(
20-
programme_types: @session.programmes_for(patient:).map(&:type),
20+
@session.programmes_for(patient:),
2121
team: @session.team,
2222
academic_year: @session.academic_year,
2323
sent_by: current_user

app/lib/notifier/patient.rb

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,41 @@ def initialize(patient)
77
@patient = patient
88
end
99

10-
def send_clinic_invitation(programme_types:, team:, academic_year:, sent_by:)
10+
##
11+
# Send a clinic initiation email and SMS to the parents of this patient.
12+
#
13+
# This determines the correct type of invitation to use (either an initial
14+
# invitation or a subsequent invitation) based on the previous invitations
15+
# which have been sent:
16+
#
17+
# +include_vaccinated_programmes+ allows for the sending of invitations for
18+
# programmes where the patient has already been vaccinated.
19+
#
20+
# +include_already_invited_programmes+ allows for the sending of invitations
21+
# for programmes where the patient has already been invited for in the past.
22+
#
23+
def send_clinic_invitation(
24+
programmes,
25+
team:,
26+
academic_year:,
27+
sent_by:,
28+
include_vaccinated_programmes: false,
29+
include_already_invited_programmes: true
30+
)
1131
return unless send_notification?(team:)
1232

13-
programme_types.reject! do |programme_type|
14-
patient.programme_status(
15-
Programme.find(programme_type),
16-
academic_year:
17-
).vaccinated_fully?
18-
end
33+
programme_types =
34+
programme_types_to_send_for(
35+
programmes,
36+
team:,
37+
academic_year:,
38+
include_vaccinated_programmes:,
39+
include_already_invited_programmes:
40+
)
1941

2042
return if programme_types.empty?
2143

22-
already_sent =
23-
patient.clinic_notifications.any? do
24-
it.team_id == team.id && it.academic_year == academic_year &&
25-
(programme_types - it.programme_types).empty? # is subset
26-
end
27-
28-
type = already_sent ? :subsequent_invitation : :initial_invitation
44+
type = clinic_invitation_type(programme_types, team:, academic_year:)
2945

3046
# We create a record in the database first to avoid sending duplicate emails/texts.
3147
# If a problem occurs while the emails/texts are sent, they will be in the job
@@ -41,7 +57,7 @@ def send_clinic_invitation(programme_types:, team:, academic_year:, sent_by:)
4157
sent_by:
4258
)
4359

44-
template_name = determine_template_name(type, team:)
60+
template_name = find_template_name(type, team:)
4561

4662
params = { academic_year:, patient:, programme_types:, sent_by:, team: }
4763

@@ -64,7 +80,56 @@ def parents
6480
@parents ||= patient.parents.select(&:contactable?).uniq
6581
end
6682

67-
def determine_template_name(type, team:)
83+
def programme_types_to_send_for(
84+
programmes,
85+
team:,
86+
academic_year:,
87+
include_vaccinated_programmes: false,
88+
include_already_invited_programmes: true
89+
)
90+
programmes_to_send_for =
91+
programmes.select do |programme|
92+
unless include_vaccinated_programmes
93+
is_vaccinated =
94+
patient.programme_status(programme, academic_year:).vaccinated?
95+
96+
next false if is_vaccinated
97+
end
98+
99+
unless include_already_invited_programmes
100+
already_invited =
101+
patient.clinic_notifications.any? do
102+
it.team_id == team.id && it.academic_year == academic_year &&
103+
it.programme_types.include?(programme.type)
104+
end
105+
106+
next false if already_invited
107+
end
108+
109+
true
110+
end
111+
112+
programmes_to_send_for.map(&:type)
113+
end
114+
115+
def clinic_invitation_type(programme_types, team:, academic_year:)
116+
already_sent_initial_invitation_to_all_programmes =
117+
programme_types.all? do |programme_type|
118+
patient.clinic_notifications.any? do
119+
it.team_id == team.id && it.academic_year == academic_year &&
120+
it.initial_invitation? &&
121+
it.programme_types.include?(programme_type)
122+
end
123+
end
124+
125+
if already_sent_initial_invitation_to_all_programmes
126+
:subsequent_invitation
127+
else
128+
:initial_invitation
129+
end
130+
end
131+
132+
def find_template_name(type, team:)
68133
template_names = [
69134
:"clinic_#{type}_#{team.organisation.ods_code.downcase}",
70135
:"clinic_#{type}"

spec/lib/notifier/patient_spec.rb

Lines changed: 154 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
subject(:send_clinic_invitation) do
1010
travel_to(today) do
1111
notifier.send_clinic_invitation(
12-
programme_types:,
12+
programmes,
1313
team:,
1414
academic_year:,
15-
sent_by:
15+
sent_by:,
16+
include_vaccinated_programmes:,
17+
include_already_invited_programmes:
1618
)
1719
end
1820
end
@@ -21,12 +23,13 @@
2123

2224
let(:parents) { create_list(:parent, 2) }
2325
let(:patient) { create(:patient, parents:, year_group: 10) }
24-
let(:programme) { Programme.td_ipv }
25-
let(:programmes) { [programme] }
26+
let(:programmes) { [Programme.td_ipv] }
2627
let(:programme_types) { programmes.map(&:type) }
2728
let(:team) { create(:team, programmes:) }
2829
let(:location) { create(:school, team:) }
2930
let(:academic_year) { AcademicYear.current }
31+
let(:include_vaccinated_programmes) { false }
32+
let(:include_already_invited_programmes) { true }
3033

3134
context "without an invitation already" do
3235
it "creates a record" do
@@ -281,5 +284,152 @@
281284
end
282285
end
283286
end
287+
288+
context "when already invited to one of two possible programmes" do
289+
let(:programmes) { [Programme.flu, Programme.hpv] }
290+
291+
before do
292+
create(
293+
:clinic_notification,
294+
:initial_invitation,
295+
patient:,
296+
team:,
297+
academic_year:,
298+
programmes: [Programme.flu]
299+
)
300+
end
301+
302+
it "creates a record" do
303+
expect { send_clinic_invitation }.to change(
304+
ClinicNotification,
305+
:count
306+
).by(1)
307+
308+
clinic_notification = ClinicNotification.last
309+
expect(clinic_notification).to be_initial_invitation
310+
expect(clinic_notification.team).to eq(team)
311+
expect(clinic_notification.patient).to eq(patient)
312+
expect(clinic_notification.sent_at).to eq(today)
313+
end
314+
315+
it "enqueues an email per parent" do
316+
expect { send_clinic_invitation }.to have_delivered_email(
317+
:clinic_initial_invitation
318+
).with(
319+
parent: parents.first,
320+
patient:,
321+
programme_types:,
322+
team:,
323+
academic_year:,
324+
sent_by:
325+
).and have_delivered_email(:clinic_initial_invitation).with(
326+
parent: parents.second,
327+
patient:,
328+
programme_types:,
329+
team:,
330+
academic_year:,
331+
sent_by:
332+
)
333+
end
334+
335+
it "enqueues a text per parent" do
336+
expect { send_clinic_invitation }.to have_delivered_sms(
337+
:clinic_initial_invitation
338+
).with(
339+
parent: parents.first,
340+
patient:,
341+
programme_types:,
342+
team:,
343+
academic_year:,
344+
sent_by:
345+
).and have_delivered_sms(:clinic_initial_invitation).with(
346+
parent: parents.second,
347+
patient:,
348+
programme_types:,
349+
team:,
350+
academic_year:,
351+
sent_by:
352+
)
353+
end
354+
355+
context "when parent doesn't want to receive updates by text" do
356+
let(:parent) { parents.first }
357+
358+
before { parent.update!(phone_receive_updates: false) }
359+
360+
it "still enqueues a text" do
361+
expect { send_clinic_invitation }.to have_delivered_sms(
362+
:clinic_initial_invitation
363+
).with(
364+
parent:,
365+
patient:,
366+
programme_types:,
367+
team:,
368+
academic_year:,
369+
sent_by:
370+
)
371+
end
372+
end
373+
374+
context "and not including already invited programmes" do
375+
let(:include_already_invited_programmes) { false }
376+
377+
it "creates a record" do
378+
expect { send_clinic_invitation }.to change(
379+
ClinicNotification,
380+
:count
381+
).by(1)
382+
383+
clinic_notification = ClinicNotification.last
384+
expect(clinic_notification).to be_initial_invitation
385+
expect(clinic_notification.team).to eq(team)
386+
expect(clinic_notification.patient).to eq(patient)
387+
expect(clinic_notification.sent_at).to eq(today)
388+
expect(clinic_notification.programmes).to contain_exactly(
389+
Programme.hpv
390+
)
391+
end
392+
393+
it "enqueues an email per parent" do
394+
expect { send_clinic_invitation }.to have_delivered_email(
395+
:clinic_initial_invitation
396+
).with(
397+
parent: parents.first,
398+
patient:,
399+
programme_types: %w[hpv],
400+
team:,
401+
academic_year:,
402+
sent_by:
403+
).and have_delivered_email(:clinic_initial_invitation).with(
404+
parent: parents.second,
405+
patient:,
406+
programme_types: %w[hpv],
407+
team:,
408+
academic_year:,
409+
sent_by:
410+
)
411+
end
412+
413+
it "enqueues a text per parent" do
414+
expect { send_clinic_invitation }.to have_delivered_sms(
415+
:clinic_initial_invitation
416+
).with(
417+
parent: parents.first,
418+
patient:,
419+
programme_types: %w[hpv],
420+
team:,
421+
academic_year:,
422+
sent_by:
423+
).and have_delivered_sms(:clinic_initial_invitation).with(
424+
parent: parents.second,
425+
patient:,
426+
programme_types: %w[hpv],
427+
team:,
428+
academic_year:,
429+
sent_by:
430+
)
431+
end
432+
end
433+
end
284434
end
285435
end

0 commit comments

Comments
 (0)