@@ -7,6 +7,32 @@ def initialize(patient)
77 @patient = patient
88 end
99
10+ ##
11+ # Send a consent request email and SMS to the parents of this patient.
12+ def send_consent_request ( programmes , session :, sent_by :)
13+ send_consent_notification ( programmes , type : :request , session :, sent_by :)
14+ end
15+
16+ ##
17+ # Send a consent reminder email and SMS to the parents of this patient.
18+ #
19+ # This determines whether to send the initial reminder or subsequent
20+ # reminder based on what has already been sent to this patient.
21+ def send_consent_reminder ( programmes , session :, sent_by :)
22+ already_sent_initial_reminder =
23+ programmes . all? do |programme |
24+ patient
25+ . consent_notifications
26+ . select { it . programmes . include? ( programme ) }
27+ . any? ( &:initial_reminder? )
28+ end
29+
30+ type =
31+ already_sent_initial_reminder ? :subsequent_reminder : :initial_reminder
32+
33+ send_consent_notification ( programmes , type :, session :, sent_by :)
34+ end
35+
1036 ##
1137 # Send a clinic initiation email and SMS to the parents of this patient.
1238 #
@@ -31,7 +57,7 @@ def send_clinic_invitation(
3157 return unless send_notification? ( team :)
3258
3359 programme_types =
34- programme_types_to_send_for (
60+ programme_types_to_send_clinic_invitation_for (
3561 programmes ,
3662 team :,
3763 academic_year :,
@@ -43,10 +69,6 @@ def send_clinic_invitation(
4369
4470 type = clinic_invitation_type ( programme_types , team :, academic_year :)
4571
46- # We create a record in the database first to avoid sending duplicate emails/texts.
47- # If a problem occurs while the emails/texts are sent, they will be in the job
48- # queue and restarted at a later date.
49-
5072 ClinicNotification . create! (
5173 patient :,
5274 programme_types :,
@@ -57,7 +79,7 @@ def send_clinic_invitation(
5779 sent_by :
5880 )
5981
60- template_name = find_template_name ( type , team :)
82+ template_name = find_clinic_template_name ( type , team :)
6183
6284 params = { academic_year :, patient :, programme_types :, sent_by :, team : }
6385
@@ -72,15 +94,128 @@ def send_clinic_invitation(
7294 attr_reader :patient
7395
7496 def send_notification? ( team :)
75- patient . send_notifications? ( team :, send_to_archived : true ) &&
76- parents . present?
97+ patient . send_notifications? ( team :) && parents . present?
7798 end
7899
79100 def parents
80101 @parents ||= patient . parents . select ( &:contactable? ) . uniq
81102 end
82103
83- def programme_types_to_send_for (
104+ def send_consent_notification ( programmes , type :, session :, sent_by :)
105+ return unless send_notification? ( team : session . team )
106+
107+ ConsentNotification . create! (
108+ programmes :,
109+ patient :,
110+ session :,
111+ type :,
112+ sent_at : Time . current ,
113+ sent_by :
114+ )
115+
116+ email_template , sms_template =
117+ generate_consent_templates ( programmes :, patient :, session :, type :)
118+
119+ programme_types = programmes . map ( &:type )
120+ disease_types = programmes . flat_map ( &:disease_types ) . presence
121+
122+ parents . each do |parent |
123+ EmailDeliveryJob . perform_later (
124+ email_template ,
125+ disease_types :,
126+ parent :,
127+ patient :,
128+ programme_types :,
129+ session :,
130+ sent_by :
131+ )
132+
133+ SMSDeliveryJob . perform_later (
134+ sms_template ,
135+ disease_types :,
136+ parent :,
137+ patient :,
138+ programme_types :,
139+ session :,
140+ sent_by :
141+ )
142+ end
143+ end
144+
145+ def generate_consent_templates ( programmes :, patient :, session :, type :)
146+ is_school = session . location . school?
147+ base_template = :"consent_#{ is_school ? "school" : "clinic" } _#{ type } "
148+
149+ # We can only handle a single programme group or variant in the template.
150+ group = ProgrammeGrouper . call ( programmes ) . keys . sole
151+ variant =
152+ if programmes . count == 1
153+ programmes . sole . variant_for ( patient :) . variant_type
154+ end
155+
156+ email_template =
157+ if is_school
158+ template =
159+ resolve_consent_template (
160+ base_template :,
161+ group :,
162+ variant :,
163+ session :,
164+ channel : :email
165+ )
166+ if template . blank?
167+ raise (
168+ "Missing email template for consent notification: #{ base_template } " \
169+ "with group=#{ group . inspect } variant=#{ variant . inspect } " \
170+ "outbreak=#{ is_outbreak . inspect } "
171+ )
172+ end
173+ template
174+ else
175+ base_template
176+ end
177+
178+ sms_template =
179+ if type == :request
180+ template =
181+ resolve_consent_template (
182+ base_template :,
183+ group :,
184+ variant :,
185+ session :,
186+ channel : :sms
187+ )
188+ template || base_template
189+ elsif is_school
190+ :consent_school_reminder
191+ end
192+
193+ [ email_template , sms_template ]
194+ end
195+
196+ def resolve_consent_template (
197+ base_template :,
198+ group :,
199+ variant :,
200+ session :,
201+ channel :
202+ )
203+ renderer = NotifyTemplateRenderer . for ( channel )
204+ is_outbreak = session . outbreak
205+
206+ combinations = [ ( [ group , :outbreak ] if is_outbreak ) , [ group ] ]
207+ if variant . present? && variant != group
208+ combinations . prepend ( ( [ variant , :outbreak ] if is_outbreak ) , [ variant ] )
209+ end
210+ combinations . compact!
211+
212+ combinations
213+ . lazy
214+ . map { |parts | :"#{ base_template } _#{ parts . join ( "_" ) } " }
215+ . detect { renderer . template_exists? ( it , source : :any ) }
216+ end
217+
218+ def programme_types_to_send_clinic_invitation_for (
84219 programmes ,
85220 team :,
86221 academic_year :,
@@ -129,7 +264,7 @@ def clinic_invitation_type(programme_types, team:, academic_year:)
129264 end
130265 end
131266
132- def find_template_name ( type , team :)
267+ def find_clinic_template_name ( type , team :)
133268 template_names = [
134269 :"clinic_#{ type } _#{ team . organisation . ods_code . downcase } " ,
135270 :"clinic_#{ type } "
0 commit comments