Skip to content

Commit 973c8a2

Browse files
committed
VED-755: Adding demographics logic
1 parent 001fda1 commit 973c8a2

File tree

3 files changed

+28
-74
lines changed

3 files changed

+28
-74
lines changed

lambdas/id_sync/src/ieds_db_operations.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ def extract_patient_resource_from_item(item: dict) -> dict | None:
151151
if not isinstance(patient_resource, dict):
152152
return None
153153

154-
for res in patient_resource.get("contained", []):
155-
if isinstance(res, dict) and res.get("resourceType") == "Patient":
156-
return res
154+
for response in patient_resource.get("contained", []):
155+
if isinstance(response, dict) and response.get("resourceType") == "Patient":
156+
return response
157157

158158
return None

lambdas/id_sync/src/record_processor.py

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -128,54 +128,44 @@ def extract_normalized_name_from_patient(patient: dict) -> str | None:
128128

129129

130130
def demographics_match(pds_details: dict, ieds_item: dict) -> bool:
131-
"""Compare PDS patient details to an IEDS item (FHIR Patient resource).
132-
133-
Parameters:
134-
- pds_details: dict returned by PDS (patient details)
135-
- ieds_item: dict representing a single IEDS item containing a FHIR Patient resource
136-
131+
"""Compare PDS patient details from PDS to an IEDS item (FHIR Patient resource).
137132
Returns True if name, birthDate and gender match (when present in both sources).
138133
If required fields are missing or unparsable on the IEDS side the function returns False.
139134
"""
140135
try:
141-
# extract pds values
142-
pds_name = normalize_name_from_pds(pds_details) if isinstance(pds_details, dict) else None
143-
pds_gender = pds_details.get("gender") if isinstance(pds_details, dict) else None
144-
pds_birth = pds_details.get("birthDate") if isinstance(pds_details, dict) else None
145-
136+
137+
def normalize_strings(item: Any) -> str | None:
138+
return str(item).strip().lower() if item else None
139+
140+
# Retrieve patient resource from PDS
141+
pds_name = normalize_strings(normalize_name_from_pds(pds_details))
142+
pds_gender = normalize_strings(pds_details.get("gender"))
143+
pds_birth = normalize_strings(pds_details.get("birthDate"))
144+
145+
# Retrieve patient resource from IEDS item
146146
patient = extract_patient_resource_from_item(ieds_item)
147147
if not patient:
148-
logger.debug("demographics_match: no patient resource in item")
148+
logger.debug("demographics_match: no patient resource in IEDS table item")
149149
return False
150150

151-
# normalize incoming patient name
152-
incoming_name = extract_normalized_name_from_patient(patient)
153-
154-
incoming_gender = patient.get("gender")
155-
incoming_birth = patient.get("birthDate")
151+
# normalize patient name
152+
ieds_name = extract_normalized_name_from_patient(patient)
156153

157-
def _norm_str(x):
158-
return str(x).strip().lower() if x is not None else None
154+
ieds_gender = normalize_strings(patient.get("gender"))
155+
ieds_birth = patient.get("birthDate")
159156

160-
# Compare birthDate (strict if both present)
161-
if pds_birth and incoming_birth:
162-
if str(pds_birth).strip() != str(incoming_birth).strip():
163-
logger.debug("demographics_match: birthDate mismatch %s != %s", pds_birth, incoming_birth)
164-
return False
157+
if pds_birth and ieds_birth and pds_birth != ieds_birth:
158+
logger.debug("demographics_match: birthDate mismatch %s != %s", pds_birth, ieds_birth)
159+
return False
165160

166-
# Compare gender (case-insensitive)
167-
if pds_gender and incoming_gender:
168-
if _norm_str(pds_gender) != _norm_str(incoming_gender):
169-
logger.debug("demographics_match: gender mismatch %s != %s", pds_gender, incoming_gender)
170-
return False
161+
if pds_gender and ieds_gender and pds_gender != ieds_gender:
162+
logger.debug("demographics_match: gender mismatch %s != %s", pds_gender, ieds_gender)
163+
return False
171164

172-
# Compare names if both present (normalized)
173-
if pds_name and incoming_name:
174-
if _norm_str(pds_name) != _norm_str(incoming_name):
175-
logger.debug("demographics_match: name mismatch %s != %s", pds_name, incoming_name)
176-
return False
165+
if pds_name and ieds_name and pds_name != ieds_name:
166+
logger.debug("demographics_match: name mismatch %s != %s", pds_name, ieds_name)
167+
return False
177168

178-
# If we reached here, all present fields matched (or were not present to compare)
179169
return True
180170
except Exception:
181171
logger.exception("demographics_match: comparison failed with exception")

lambdas/id_sync/tests/test_ieds_db_operations.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -673,39 +673,3 @@ def test_ieds_check_exist_limit_parameter(self):
673673
# Assert - Verify the limit parameter is correctly passed
674674
self.mock_get_items_from_patient_id.assert_called_once_with(patient_id, 1)
675675

676-
677-
678-
class TestExtractPatientResource(TestIedsDbOperations):
679-
def test_extract_patient_from_immunization_contained(self):
680-
"""Should return the contained Patient resource from an Immunization Resource"""
681-
item = {
682-
"Resource": {
683-
"resourceType": "Immunization",
684-
"contained": [
685-
{
686-
"resourceType": "Patient",
687-
"id": "Pat1",
688-
"name": [{"family": "Taylor", "given": ["Sarah"]}],
689-
"gender": "unknown",
690-
"birthDate": "1965-02-28"
691-
}
692-
]
693-
}
694-
}
695-
696-
patient = ieds_db_operations.extract_patient_resource_from_item(item)
697-
self.assertIsNotNone(patient)
698-
self.assertEqual(patient.get("resourceType"), "Patient")
699-
self.assertEqual(patient.get("id"), "Pat1")
700-
701-
def test_extract_returns_none_when_no_patient_in_contained(self):
702-
"""Should return None when contained exists but has no Patient entries"""
703-
item = {"Resource": {"resourceType": "Immunization", "contained": [{"resourceType": "Practitioner"}]}}
704-
patient = ieds_db_operations.extract_patient_resource_from_item(item)
705-
self.assertIsNone(patient)
706-
707-
def test_extract_returns_none_when_resource_not_dict(self):
708-
"""Should return None when Resource attribute is present but not a dict"""
709-
item = {"Resource": '{"not": "a dict string"}'}
710-
patient = ieds_db_operations.extract_patient_resource_from_item(item)
711-
self.assertIsNone(patient)

0 commit comments

Comments
 (0)