@@ -20,19 +20,23 @@ def perform(patient_id)
2020
2121 return unless feature_flags_enabled
2222
23- existing_vaccination_records . find_each do |vaccination_record |
23+ existing_vaccination_records . each do |vaccination_record |
2424 incoming_vaccination_record =
2525 incoming_vaccination_records . find do
2626 it . nhs_immunisations_api_id ==
2727 vaccination_record . nhs_immunisations_api_id
2828 end
2929
3030 if incoming_vaccination_record
31- vaccination_record . update! (
31+ vaccination_record . assign_attributes (
3232 incoming_vaccination_record
3333 . attributes
3434 . except ( "id" , "uuid" , "created_at" )
35- . merge ( updated_at : Time . current )
35+ . merge (
36+ duplicate_of_vaccination_record :
37+ incoming_vaccination_record . duplicate_of_vaccination_record ,
38+ updated_at : Time . current
39+ )
3640 )
3741
3842 incoming_vaccination_records . delete ( incoming_vaccination_record )
@@ -41,10 +45,12 @@ def perform(patient_id)
4145 end
4246 end
4347
44- # Remaining incoming_vaccination_records are new.
4548 # Save non-discarded records first so they have IDs before discarded
4649 # duplicates reference them via duplicate_of_vaccination_record_id.
47- incoming_vaccination_records . sort_by { it . discarded? ? 1 : 0 } . each ( &:save! )
50+ (
51+ existing_vaccination_records . reject ( &:destroyed? ) +
52+ incoming_vaccination_records
53+ ) . sort_by { it . discarded? ? 1 : 0 } . each ( &:save! )
4854
4955 update_vaccination_search_timestamps if patient . nhs_number . present?
5056
@@ -104,6 +110,7 @@ def existing_vaccination_records
104110 @existing_vaccination_records ||=
105111 patient
106112 . vaccination_records
113+ . with_discarded
107114 . includes ( :identity_check )
108115 . sourced_from_nhs_immunisations_api
109116 . for_programmes ( programmes )
@@ -150,8 +157,23 @@ def deduplicate_vaccination_records(incoming_vaccination_records)
150157 end
151158 elsif records . any? ( &:nhs_immunisations_api_primary_source )
152159 # If some records have `primarySource: true`, set `discarded_at` for all `primarySource: false` records,
153- # pointing each at the first `primarySource: true` record
154- canonical = records . find ( &:nhs_immunisations_api_primary_source )
160+ # pointing each at the first `primarySource: true` record.
161+
162+ canonical_incoming =
163+ records . find ( &:nhs_immunisations_api_primary_source )
164+ canonical_existing =
165+ patient
166+ . vaccination_records
167+ . sourced_from_nhs_immunisations_api
168+ . with_discarded
169+ . find_by (
170+ nhs_immunisations_api_id :
171+ canonical_incoming . nhs_immunisations_api_id
172+ )
173+
174+ # Prefer the persisted DB record (if it already exists from a previous run) so that
175+ # `duplicate_of_vaccination_record_id` is non-nil when the non-primary record is saved.
176+ canonical = canonical_existing || canonical_incoming
155177 records
156178 . select ( &:sourced_from_nhs_immunisations_api? )
157179 . reject ( &:nhs_immunisations_api_primary_source )
0 commit comments