@@ -172,41 +172,61 @@ def self.match_existing(
172
172
end
173
173
174
174
scope =
175
- Patient
176
- . where (
177
- "given_name ILIKE ? AND family_name ILIKE ?" ,
178
- given_name ,
179
- family_name
180
- )
181
- . where ( date_of_birth :)
182
- . or (
183
- Patient . where (
184
- "given_name ILIKE ? AND family_name ILIKE ?" ,
185
- given_name ,
186
- family_name
187
- ) . where ( address_postcode :)
188
- )
189
- . or (
190
- Patient . where ( "given_name ILIKE ?" , given_name ) . where (
191
- date_of_birth :,
192
- address_postcode :
175
+ Patient . where (
176
+ "given_name ILIKE ? AND family_name ILIKE ?" ,
177
+ given_name ,
178
+ family_name
179
+ ) . where ( date_of_birth :)
180
+
181
+ if address_postcode . present?
182
+ scope =
183
+ scope
184
+ . or (
185
+ Patient . where (
186
+ "given_name ILIKE ? AND family_name ILIKE ?" ,
187
+ given_name ,
188
+ family_name
189
+ ) . where ( address_postcode :)
193
190
)
194
- )
195
- . or (
196
- Patient . where ( "family_name ILIKE ?" , family_name ) . where (
197
- date_of_birth :,
198
- address_postcode :
191
+ . or (
192
+ Patient . where ( "given_name ILIKE ?" , given_name ) . where (
193
+ date_of_birth :,
194
+ address_postcode :
195
+ )
196
+ )
197
+ . or (
198
+ Patient . where ( "family_name ILIKE ?" , family_name ) . where (
199
+ date_of_birth :,
200
+ address_postcode :
201
+ )
199
202
)
200
- )
203
+ end
201
204
202
- if nhs_number . blank?
203
- scope . to_a
204
- else
205
- # This prevents us from finding a patient that happens to have at least
206
- # three of the other fields the same, but with a different NHS number,
207
- # and therefore cannot be a match.
208
- Patient . where ( nhs_number : nil ) . merge ( scope ) . to_a
205
+ results =
206
+ if nhs_number . blank?
207
+ scope . to_a
208
+ else
209
+ # This prevents us from finding a patient that happens to have at least
210
+ # three of the other fields the same, but with a different NHS number,
211
+ # and therefore cannot be a match.
212
+ Patient . where ( nhs_number : nil ) . merge ( scope ) . to_a
213
+ end
214
+
215
+ if address_postcode . present?
216
+ # Check for an exact match of all four datapoints, we do this in memory
217
+ # to avoid an extra query to the database for each record.
218
+ exact_results =
219
+ results . select do
220
+ _1 . given_name . downcase == given_name . downcase &&
221
+ _1 . family_name . downcase == family_name . downcase &&
222
+ _1 . date_of_birth == date_of_birth &&
223
+ _1 . address_postcode == UKPostcode . parse ( address_postcode ) . to_s
224
+ end
225
+
226
+ return exact_results if exact_results . length == 1
209
227
end
228
+
229
+ results
210
230
end
211
231
212
232
def relationship_to ( parent :)
0 commit comments