diff --git a/fhirflat/flat2fhir.py b/fhirflat/flat2fhir.py index ee26a4f..925a4f1 100644 --- a/fhirflat/flat2fhir.py +++ b/fhirflat/flat2fhir.py @@ -17,7 +17,7 @@ def create_codeable_concept( """Re-creates a codeableConcept structure from the FHIRflat representation.""" # for reading in from ingestion pipeline - if (name + ".code" and name + ".system") in old_dict: + if name + ".code" in old_dict and name + ".system" in old_dict: code = old_dict[name + ".code"] if isinstance(code, list) and len(code) > 1: new_dict = {"coding": []} diff --git a/fhirflat/resources/extension_types.py b/fhirflat/resources/extension_types.py index 3eea251..ba077be 100644 --- a/fhirflat/resources/extension_types.py +++ b/fhirflat/resources/extension_types.py @@ -51,5 +51,9 @@ class birthSexType(AbstractType): __resource_type__ = "birthSex" +class raceType(AbstractType): + __resource_type__ = "Race" + + class dateTimeExtensionType(AbstractType): __resource_type__ = "dateTimeExtension" diff --git a/fhirflat/resources/extension_validators.py b/fhirflat/resources/extension_validators.py index 7e96460..0658ce8 100644 --- a/fhirflat/resources/extension_validators.py +++ b/fhirflat/resources/extension_validators.py @@ -65,6 +65,7 @@ def __init__(self): "Duration": (None, ".extensions"), "Age": (None, ".extensions"), "birthSex": (None, ".extensions"), + "Race": (None, ".extensions"), "dateTimeExtension": (None, ".extensions"), } @@ -230,5 +231,9 @@ def birthsex_validator(v: Union[StrBytes, dict, Path, FHIRAbstractModel]): return Validators().fhir_model_validator("birthSex", v) +def race_validator(v: Union[StrBytes, dict, Path, FHIRAbstractModel]): + return Validators().fhir_model_validator("Race", v) + + def datetimeextension_validator(v: Union[StrBytes, dict, Path, FHIRAbstractModel]): return Validators().fhir_model_validator("dateTimeExtension", v) diff --git a/fhirflat/resources/extensions.py b/fhirflat/resources/extensions.py index dad428b..006c8c5 100644 --- a/fhirflat/resources/extensions.py +++ b/fhirflat/resources/extensions.py @@ -417,6 +417,42 @@ def elements_sequence(cls): ] +class Race(_DataType): + """ + An ISARIC extension collecting data on the race of a patient. + """ + + resource_type = Field("Race", const=True) + + url = Field("race", const=True, alias="url") + + valueCodeableConcept: fhirtypes.CodeableConceptType = Field( + None, + alias="valueCodeableConcept", + title="Value of extension", + description=( + "Value of extension - must be one of a constrained set of the data " + "types (see [Extensibility](extensibility.html) for a list)." + ), + # if property is element of this resource. + element_property=True, + element_required=True, + ) + + @classmethod + def elements_sequence(cls): + """returning all elements names from + ``Extension`` according specification, + with preserving original sequence order. + """ + return [ + "id", + "extension", + "url", + "valueCodeableConcept", + ] + + # ------------------- extension types ------------------------------ diff --git a/fhirflat/resources/patient.py b/fhirflat/resources/patient.py index 4585235..ac06f5b 100644 --- a/fhirflat/resources/patient.py +++ b/fhirflat/resources/patient.py @@ -1,10 +1,7 @@ from fhir.resources.patient import Patient from .base import FHIRFlatBase -from .extension_types import ( - ageType, - birthSexType, -) -from .extensions import Age, birthSex +from .extension_types import ageType, birthSexType, raceType +from .extensions import Age, birthSex, Race import orjson from ..flat2fhir import expand_concepts @@ -16,18 +13,20 @@ class Patient(Patient, FHIRFlatBase): - extension: list[Union[ageType, birthSexType, fhirtypes.ExtensionType]] = Field( - None, - alias="extension", - title="Additional content defined by implementations", - description=( - """ + extension: list[Union[ageType, birthSexType, raceType, fhirtypes.ExtensionType]] = ( + Field( + None, + alias="extension", + title="Additional content defined by implementations", + description=( + """ Contains the G.H 'age' and 'birthSex' extensions, and allows extensions from other implementations to be included.""" - ), - # if property is element of this resource. - element_property=True, - union_mode="smart", + ), + # if property is element of this resource. + element_property=True, + union_mode="smart", + ) ) # attributes to exclude from the flat representation @@ -47,9 +46,10 @@ class Patient(Patient, FHIRFlatBase): def validate_extension_contents(cls, extensions): age_count = sum(isinstance(item, Age) for item in extensions) birthsex_count = sum(isinstance(item, birthSex) for item in extensions) + race_count = sum(isinstance(item, Race) for item in extensions) - if age_count > 1 or birthsex_count > 1: - raise ValueError("Age and birthSex can only appear once.") + if age_count > 1 or birthsex_count > 1 or race_count > 1: + raise ValueError("Age, birthSex and Race can only appear once.") return extensions