@@ -103,7 +103,6 @@ def initialize(data:, team:, type:)
103103 @type = type &.to_sym
104104 end
105105
106- # Convenience predicate helpers mirroring the enum on ImmunisationImport
107106 def point_of_care? = type == :point_of_care
108107
109108 def national_reporting_flu? = national_reporting? && programme &.flu?
@@ -119,80 +118,13 @@ def national_reporting_not_administered?
119118 def to_vaccination_record
120119 return if invalid? || national_reporting_not_administered? || patient . nil?
121120
122- outcome = ( administered ? "administered" : reason_not_administered_value )
123- source =
124- if imms_api_record?
125- "nhs_immunisations_api"
126- elsif offline_recording?
127- "service"
128- elsif point_of_care?
129- "historical_upload"
130- else
131- "national_reporting"
132- end
133-
134- attributes = {
135- disease_types :,
136- dose_sequence : dose_sequence_value ,
137- full_dose : true ,
138- outcome :,
139- patient :,
140- performed_at_date :,
141- performed_by_user :,
142- performed_ods_code : performed_ods_code &.to_s ,
143- programme_type : programme &.type ,
144- protocol :,
145- session :,
146- supplied_by :
147- }
148-
149- attributes . merge! ( location :, location_name :) unless imms_api_record?
150- attributes . merge! ( notify_parents : true ) if session
151-
152- if performed_by_user . nil? &&
153- ( performed_by_family_name . present? || performed_by_given_name . present? )
154- attributes . merge! (
155- performed_by_family_name : performed_by_family_name &.to_s ,
156- performed_by_given_name : performed_by_given_name &.to_s
157- )
158- end
159-
160- if national_reporting?
161- attributes . merge! (
162- local_patient_id : local_patient_id &.to_s ,
163- local_patient_id_uri : local_patient_id_uri &.to_s
164- )
165- end
166-
167- attributes_to_stage_if_already_exists = {
168- batch_number : batch_name &.to_s ,
169- batch_expiry : batch_expiry &.to_date ,
170- discarded_at : nil ,
171- notes : notes &.to_s ,
172- performed_at_time :,
173- source :,
174- vaccine_id : vaccine &.id
175- }
176-
177- delivery_attributes = {
178- delivery_method : delivery_method_value ,
179- delivery_site : delivery_site_value
180- }
181-
182121 vaccination_record =
183- if national_reporting?
184- VaccinationRecord . find_or_initialize_by (
185- attributes . merge (
186- attributes_to_stage_if_already_exists ,
187- delivery_attributes
188- )
189- )
190- elsif uuid . present?
122+ if uuid . present?
191123 VaccinationRecord
192124 . find_by! ( uuid : uuid . to_s )
193125 . tap { it . stage_changes ( attributes ) }
194126 else
195- VaccinationRecord . find_or_initialize_by ( attributes )
127+ VaccinationRecord . find_or_initialize_by ( deduplication_attributes )
196128 end
197129
198130 if vaccination_record . persisted?
@@ -240,11 +172,94 @@ def to_archive_reason
240172 end
241173
242174 def set_patient ( candidates : nil )
175+ # Invalidate the memoised `@attributes`, which might reference the old value of `@patient` (likely to be `nil`)
176+ @attributes = nil
177+
243178 @patient =
244179 existing_patients ( candidates :) &.first ||
245180 Patient . new ( new_patient_attributes )
246181 end
247182
183+ def attributes
184+ @attributes ||=
185+ begin
186+ outcome =
187+ ( administered ? "administered" : reason_not_administered_value )
188+
189+ attributes = {
190+ disease_types :,
191+ dose_sequence : dose_sequence_value ,
192+ full_dose : true ,
193+ outcome :,
194+ patient :,
195+ performed_at_date :,
196+ performed_by_user :,
197+ performed_ods_code : performed_ods_code &.to_s ,
198+ programme_type : programme &.type ,
199+ protocol :,
200+ session :,
201+ supplied_by :
202+ }
203+
204+ attributes . merge! ( location :, location_name :) unless imms_api_record?
205+ attributes . merge! ( notify_parents : true ) if session
206+
207+ if performed_by_user . nil? &&
208+ (
209+ performed_by_family_name . present? ||
210+ performed_by_given_name . present?
211+ )
212+ attributes . merge! (
213+ performed_by_family_name : performed_by_family_name &.to_s ,
214+ performed_by_given_name : performed_by_given_name &.to_s
215+ )
216+ end
217+
218+ if national_reporting?
219+ attributes . merge! (
220+ local_patient_id : local_patient_id &.to_s ,
221+ local_patient_id_uri : local_patient_id_uri &.to_s
222+ )
223+ end
224+
225+ attributes
226+ end
227+ end
228+
229+ def attributes_to_stage_if_already_exists
230+ @attributes_to_stage_if_already_exists ||= {
231+ batch_number : batch_name &.to_s ,
232+ batch_expiry : batch_expiry &.to_date ,
233+ discarded_at : nil ,
234+ notes : notes &.to_s ,
235+ performed_at_time :,
236+ source :,
237+ vaccine_id : vaccine &.id
238+ }
239+ end
240+
241+ def delivery_attributes
242+ @delivery_attributes ||= {
243+ delivery_method : delivery_method_value ,
244+ delivery_site : delivery_site_value
245+ }
246+ end
247+
248+ def deduplication_attributes
249+ if national_reporting?
250+ attributes . merge (
251+ attributes_to_stage_if_already_exists ,
252+ delivery_attributes
253+ )
254+ else
255+ attributes
256+ end
257+ end
258+
259+ def full_row_deduplication_attributes
260+ deduplication_attributes . merge ( new_patient_attributes )
261+ end
262+
248263 def batch_expiry = @data [ :batch_expiry_date ]
249264
250265 def batch_name = @data [ :batch_number ] || @data [ :vaccination_batch_number ]
@@ -340,7 +355,7 @@ def location_name
340355 end
341356 end
342357
343- def performed_at_date = date_of_vaccination . to_date
358+ def performed_at_date = date_of_vaccination & .to_date
344359
345360 def performed_at_time = time_of_vaccination &.to_time
346361
@@ -399,6 +414,18 @@ def session
399414 end
400415 end
401416
417+ def source
418+ if imms_api_record?
419+ "nhs_immunisations_api"
420+ elsif offline_recording?
421+ "service"
422+ elsif point_of_care?
423+ "historical_upload"
424+ else
425+ "national_reporting"
426+ end
427+ end
428+
402429 def protocol
403430 if imms_api_record?
404431 nil
@@ -450,7 +477,10 @@ def programmes_by_name
450477 end
451478 end
452479
453- delegate :default_dose_sequence , :maximum_dose_sequence , to : :programme
480+ delegate :default_dose_sequence ,
481+ :maximum_dose_sequence ,
482+ to : :programme ,
483+ allow_nil : true
454484
455485 def offline_recording? = session_id . present?
456486
@@ -546,7 +576,7 @@ def delivery_method_value
546576 end
547577 end
548578
549- def disease_types = vaccine &.disease_types || programme . disease_types
579+ def disease_types = vaccine &.disease_types || programme & .disease_types
550580
551581 def dose_sequence_value
552582 value =
0 commit comments