Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions delta_backend/src/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,33 @@ def __init__(self, fhir_data, action_flag = ActionFlag.UPDATE, report_unexpected
self.error_records = []
self.action_flag = action_flag
self.report_unexpected_exception = report_unexpected_exception

try:
if not fhir_data:
raise ValueError("FHIR data is required for initialization.")

self.extractor = Extractor(fhir_data, self.report_unexpected_exception)
self.conversion_layout = ConversionLayout(self.extractor)
self.conversion_layout = ConversionLayout(self.extractor)
except Exception as e:
if report_unexpected_exception:
self._log_error(f"Initialization failed: [{e.__class__.__name__}] {e}")
self._log_error(None, None, f"Initialization failed: [{e.__class__.__name__}] {e}")
raise

def run_conversion(self):
conversions = self.conversion_layout.get_conversion_layout()

for conversion in conversions:
self._convert_data(conversion)

self.error_records.extend(self.extractor.get_error_records())

# Add CONVERSION_ERRORS as the 35th field
self.converted["CONVERSION_ERRORS"] = self.error_records
return self.converted

def _convert_data(self, conversion: ConversionField):
flat_field = conversion.field_name_flat
try:
flat_field = conversion.field_name_flat

if flat_field == "ACTION_FLAG":
self.converted[flat_field] = self.action_flag
else:
Expand All @@ -47,17 +46,24 @@ def _convert_data(self, conversion: ConversionField):
self.converted[flat_field] = converted

except Exception as e:
self._log_error(f"Conversion error [{e.__class__.__name__}]: {e}", code=exception_messages.PARSING_ERROR)
self._log_error(
flat_field,
None,
f"Conversion error [{e.__class__.__name__}]: {e}",
code=exception_messages.PARSING_ERROR
)
self.converted[flat_field] = ""

def _log_error(self,e,code=exception_messages.UNEXPECTED_EXCEPTION):
def _log_error(self, field_name, field_value, e, code=exception_messages.UNEXPECTED_EXCEPTION):
error_obj = {
"code": code,
"field": field_name,
"value": field_value,
"message": str(e)
}

if self.report_unexpected_exception:
self.error_records.append(error_obj)

def get_error_records(self):
return self.error_records
return self.error_records
44 changes: 24 additions & 20 deletions delta_backend/src/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,18 @@ def _get_patient(self):
return next((c for c in contained if isinstance(c, dict) and c.get("resourceType") == "Patient"), "")

def _get_valid_names(self, names, occurrence_time):

official_names = [n for n in names if n.get("use") == "official" and self._is_current_period(n, occurrence_time)]
if official_names:
return official_names[0]

valid_names = [n for n in names if self._is_current_period(n, occurrence_time) and n.get("use") != "old"]
if valid_names:
return valid_names[0]

return names[0]


return names[0]

def _get_person_names(self):
occurrence_time = self._get_occurance_date_time()
occurrence_time = self._get_occurrence_date_time()
patient = self._get_patient()
names = patient.get("name", [])
names = [n for n in names if "given" in n and "family" in n]
Expand All @@ -56,12 +53,12 @@ def _get_person_names(self):

if person_forename and person_surname:
return person_forename, person_surname

return "", ""

def _get_practitioner_names(self):
contained = self.fhir_json_data.get("contained", [])
occurrence_time = self._get_occurance_date_time()
occurrence_time = self._get_occurrence_date_time()
practitioner = next((c for c in contained if isinstance(c, dict) and c.get("resourceType") == "Practitioner"), None)
if not practitioner or "name" not in practitioner:
return "", ""
Expand All @@ -77,7 +74,6 @@ def _get_practitioner_names(self):

return performing_professional_forename, performing_professional_surname


def _is_current_period(self, name, occurrence_time):
period = name.get("period")
if not isinstance(period, dict):
Expand All @@ -94,18 +90,26 @@ def _is_current_period(self, name, occurrence_time):

return (not start or start <= occurrence_time) and (not end or occurrence_time <= end)

def _get_occurance_date_time(self) -> str:
def _get_occurrence_date_time(self) -> datetime:
occurrence_datetime_str = self.fhir_json_data.get("occurrenceDateTime", "")

try:
occurrence_time = datetime.fromisoformat(self.fhir_json_data.get("occurrenceDateTime", ""))
if occurrence_time and occurrence_time.tzinfo is None:
occurrence_time = occurrence_time.replace(tzinfo=timezone.utc)
return occurrence_time
return occurrence_time
occurrence_datetime = datetime.fromisoformat(occurrence_datetime_str)

if occurrence_datetime and occurrence_datetime.tzinfo is None:
occurrence_datetime = occurrence_datetime.replace(tzinfo=timezone.utc)

return occurrence_datetime

except Exception as e:
message = "DateTime conversion error [%s]: %s" % (e.__class__.__name__, e)
error = self._log_error(ConversionFieldName.DATE_AND_TIME, message, e, code=exception_messages.UNEXPECTED_EXCEPTION)
return error
self._log_error(
ConversionFieldName.DATE_AND_TIME,
occurrence_datetime_str,
message,
code=exception_messages.UNEXPECTED_EXCEPTION
)
raise

def _get_first_snomed_code(self, coding_container: dict) -> str:
codings = coding_container.get("coding", [])
Expand Down Expand Up @@ -255,7 +259,7 @@ def normalize(self, value):
return value.lower() if isinstance(value, str) else value

def extract_valid_address(self):
occurrence_time = self._get_occurance_date_time()
occurrence_time = self._get_occurrence_date_time()
patient = self._get_patient()

addresses = patient.get("address", [])
Expand All @@ -279,8 +283,8 @@ def extract_valid_address(self):
)

return selected_address.get("postalCode") or self.DEFAULT_POSTCODE
def extract_date_time(self) -> str:

def extract_date_time(self) -> str:
date = self.fhir_json_data.get("occurrenceDateTime","")
if date:
return self._convert_date_to_safe_format(ConversionFieldName.DATE_AND_TIME, date)
Expand Down
Loading