def build_fhir_vaccination_protocol(cls, vaccination): # TODO Better vaccine coding/info seq = vaccination.dose authority = vaccination.institution disease = safe_attrgetter(vaccination, "vaccine.indications") # DEBUG description = vaccination.observations if seq: vp = {"doseSequence": seq, "description": description} ref = { "display": safe_attrgetter(authority, "name.rec_name"), # "reference": "".join(["Institution/", str(authority.id)]), } target = {"text": disease} # Unclear if equivalent concept in Health status = {"text": "Counts"} # coding = Coding(code='count', # display='Counts') # status.coding = [coding] # vp["doseStatus"] = status vp["authority"] = ref vp["targetDisease"] = [target] return [vp]
def build_fhir_performer(cls, procedure): actors = [] surgeon = procedure.name.surgeon if surgeon: ref = cls.build_fhir_reference_from_adapter_and_object( Practitioner, surgeon ) role = cls.build_codeable_concept( "304292004", "urn:oid:2.16.840.1.113883.4.642.2.420", "Surgeon" ) actors.append({"actor": ref, "role": role}) anesthetist = procedure.name.anesthetist if anesthetist: ref = cls.build_fhir_reference_from_adapter_and_object( Practitioner, anesthetist ) role = cls.build_codeable_concept( "158970007", "urn:oid:2.16.840.1.113883.4.642.2.420", "Anesthetist" ) actors.append({"actor": ref, "role": role}) for m in procedure.name.surgery_team: ref = cls.build_fhir_reference_from_adapter_and_object(Practitioner, m) if m.role: code, name = safe_attrgetter( m, "role.specialty.code", "role.specialty.name" ) role = cls.build_codeable_concept(code=code, text=name) actors.append({"actor": ref, "role": role}) else: actors.append({"actor": ref}) return actors
def build_fhir_performed_period(cls, procedure): start, end = safe_attrgetter( procedure, "name.surgery_date", "name.surgery_end_date" ) if start is not None: period = {"start": instance(start).to_iso8601_string()} if end is not None: period["end"] = instance(end).to_iso8601_string() return period
def build_fhir_summary(cls, impression): # Shove Objective in here - evaluation_summary # Shove HPI in here - present_illness + chief_complaint # Shove Plan in here - directions return "CC: {}\n\nHPI: {}\n\nObjective: {}\n\nPlan: {}".format( *safe_attrgetter( impression, "chief_complaint", "present_illness", "evaluation_summary", "directions", default="", ))
def build_fhir_address(cls, patient): # Only one currently du = patient.name.du if du: ad = {} ad["use"] = "home" ad["type"] = "physical" # TODO Check for this ad["text"] = patient.name.du_address line = [] number, street, zip_, city, state, country = safe_attrgetter( du, "address_street_number", "address_street", "address_zip", "address_city", "address_subdivision.name", "address_country.name", ) if number: line.append(str(number)) if street: line.append(street) if line: ad["line"] = [" ".join(line)] if city: ad["city"] = city if state: ad["state"] = state if zip_: ad["postalCode"] = zip_ if country: ad["country"] = country return [ad]
def build_fhir_expiration_date(cls, vaccination): date = safe_attrgetter(vaccination, "lot.expiration_date") if date: return instance(date).to_iso8601_string()
def build_fhir_lot_number(cls, vaccination): number = safe_attrgetter(vaccination, "lot.number") if number: return str(number)
def build_fhir_dosage(cls, med): # TODO Can always add more information! # TODO make into converter / config code_conv = { "seconds": "s", "minutes": "min", "hours": "h", "days": "d", "months": "mo", "years": "a", } dose = {} # Amount (this should be listed, but could be patient reported) if med.dose: dose["doseQuantity"] = { "value": med.dose, "unit": med.dose_unit.name } # Route # TODO Standard route values route = med.route if route: cc = {} c = {} cc["text"] = c["display"] = route.name c["code"] = route.code cc["coding"] = [c] dose["route"] = cc # PRN if med.frequency_prn or (safe_attrgetter( med, "common_dosage.abbreviation") == "prn"): dose["asNeededBoolean"] = True else: dose["asNeededBoolean"] = False # TODO # Site and Method # timing # BID | TID | QID | AM | PM | QD | QOD | Q4H | Q6H +. timing = {} if med.frequency: # prefer specific information rep = {} if med.duration_period != "indefinite": rep["duration"] = med.duration rep["durationUnits"] = code_conv.get(med.duration_period) # Health stores timing as 1 per X s/min/hr rep["frequency"] = "1" rep["period"] = med.frequency rep["periodUnits"] = code_conv.get(med.frequency_unit) timing["repeat"] = rep elif med.common_dosage: c = { "display": med.common_dosage.abbreviation, "system": "http://snomed.info/sct", "code": med.common_dosage.code, } timing["code"] = {"text": med.common_dosage.name, "coding": [c]} else: # No dosage information (either unknown or incomplete) timing = None if timing: dose["timing"] = timing # Rate - rateRatio # Only if an infusion -- always mL/hr (I think?) if med.infusion: num = {"value": med.infusion_rate, "unit": "mL"} den = {"value": 1, "unit": "hr"} dose["rateRatio"] = {"numerator": num, "denominator": den} return [dose]