-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpatient.py
156 lines (133 loc) · 5.71 KB
/
patient.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
from importlib.resources import Resource
from typing import Dict, List
from fhir.resources.meta import Meta
from fhir.resources.patient import Patient
from linuxforhealth.csvtofhir.fhirutils import csv_utils, fhir_constants, fhir_identifier_utils, fhir_utils
from linuxforhealth.csvtofhir.fhirutils.fhir_constants import ExtensionUrl
from linuxforhealth.csvtofhir.model.csv.patient import PatientCsv
from linuxforhealth.csvtofhir.support import get_logger
logger = get_logger(__name__)
def convert_record(
group_by_key: str, record: Dict, resource_meta: Meta = None
) -> List[Resource]:
resources: list = []
pat_name = csv_utils.get_human_name(record)
patient_name = [pat_name] if pat_name else None
incoming_patient: PatientCsv = PatientCsv.parse_obj(record)
if not incoming_patient.contains_patient_data():
return resources
identifiers = fhir_identifier_utils.create_identifier_list(incoming_patient.dict())
patient_id = (
fhir_utils.format_id_datatype(incoming_patient.patientInternalId)
if incoming_patient.patientInternalId
else fhir_utils.format_id_datatype(group_by_key)
)
# Use local copy of resource_meta so changes do not affect other resources
resource_meta_copy = fhir_utils.add_source_record_id_return_meta_copy(
incoming_patient.patientSourceRecordId, resource_meta)
fhir_patient: Patient = Patient.construct(
id=fhir_utils.get_resource_id(patient_id),
name=patient_name,
identifier=identifiers,
meta=resource_meta_copy
)
fhir_patient.gender = incoming_patient.gender
fhir_patient.telecom = fhir_utils.get_contact_point_phone(incoming_patient.telecomPhone)
address = fhir_utils.get_address(
incoming_patient.address1,
incoming_patient.address2,
incoming_patient.city,
incoming_patient.state,
incoming_patient.postalCode,
incoming_patient.country,
incoming_patient.addressText
)
if address:
fhir_patient.address = [address]
if incoming_patient.birthDate:
fhir_patient.birthDate = csv_utils.format_date(incoming_patient.birthDate)
try:
if incoming_patient.deceasedDateTime:
fhir_patient.deceasedDateTime = csv_utils.format_date(incoming_patient.deceasedDateTime)
# if we didn't set it above, try boolean value
if not fhir_patient.deceasedDateTime and incoming_patient.deceasedBoolean:
deceased = fhir_utils.get_boolean_value(incoming_patient.deceasedBoolean)
if deceased is not None:
fhir_patient.deceasedBoolean = deceased
except Exception:
logger.warning("An exception occurred evaluating Patient resource deceased")
raise
try:
if incoming_patient.multipleBirthBoolean:
multiple_births = bool(incoming_patient.multipleBirthBoolean)
fhir_patient.multipleBirthBoolean = multiple_births
if (
not fhir_patient.multipleBirthBoolean
and incoming_patient.multipleBirthInteger
):
fhir_patient.multipleBirthInteger = int(
incoming_patient.multipleBirthInteger
)
except Exception:
logger.warning("An exception occurred evaluating Patient resource multipleBirth")
raise
# extensions
_add_race_ethnic_extensions(incoming_patient, fhir_patient)
_add_age_extensions(incoming_patient, fhir_patient)
resources.append(fhir_patient)
return resources
def _add_race_ethnic_extensions(incoming_patient: PatientCsv, fhir_patient: Patient):
"""
Adds race, enthnicity extensions to the patient.
"""
extension = fhir_utils.get_extension_with_codeable_concept(
ExtensionUrl.RACE_EXTENSION_SYSTEM,
incoming_patient.race,
incoming_patient.raceSystem,
fhir_constants.PatientResource.race_display.get(incoming_patient.race, None),
incoming_patient.raceText
)
if extension:
# Add extension to the Patient resource
if not fhir_patient.extension:
fhir_patient.extension = []
fhir_patient.extension.append(extension)
extension = fhir_utils.get_extension_with_codeable_concept(
ExtensionUrl.ETHNICITY_EXTENSION_SYSTEM,
incoming_patient.ethnicity,
incoming_patient.ethnicitySystem,
fhir_constants.PatientResource.ethnicity_display.get(incoming_patient.ethnicity, None),
incoming_patient.ethnicityText
)
if extension:
if not fhir_patient.extension:
fhir_patient.extension = []
fhir_patient.extension.append(extension)
def _add_age_extensions(incoming_patient: PatientCsv, fhir_patient: Patient):
"""
Adds age in months and weeks extensions to the patient.
"""
# Add patient_age_in_weeks if present
if (incoming_patient.ageInWeeksForAgeUnder2Years):
integer_weeks = int(incoming_patient.ageInWeeksForAgeUnder2Years)
extension = fhir_utils.get_extension(
ExtensionUrl.PATIENT_AGE_IN_WEEKS_EXTENSION_URL,
"valueUnsignedInt",
integer_weeks
)
if extension:
if not fhir_patient.extension:
fhir_patient.extension = []
fhir_patient.extension.append(extension)
# Add patient_age_in_months if present
if (incoming_patient.ageInMonthsForAgeUnder8Years):
integer_months = int(incoming_patient.ageInMonthsForAgeUnder8Years)
extension = fhir_utils.get_extension(
ExtensionUrl.PATIENT_AGE_IN_MONTHS_EXTENSION_URL,
"valueUnsignedInt",
integer_months
)
if extension:
if not fhir_patient.extension:
fhir_patient.extension = []
fhir_patient.extension.append(extension)