def handle_item(item, env, context): root = {"linkId": item["linkId"]} if "text" in item: root["text"] = item["text"] if "itemContext" in item: data = fhirpath(context, item["itemContext"]["expression"], env) context = data if (context and "initialExpression" in item and "repeats" in item and item["repeats"] is True): answers = [] root["answer"] = answers for index, _item in enumerate(context): type = get_type(item) data = fhirpath( context, "%context[{}].{}".format( index, item["initialExpression"]["expression"]), env, ) answers.append({"value": {item["type"]: data[0]}}) elif "initialExpression" in item: data = fhirpath(context, item["initialExpression"]["expression"], env) if data and len(data): type = get_type(item) if item.get("repeats") is True: root["answer"] = [{"value": {type: d}} for d in data] else: root["answer"] = [{"value": {type: data[0]}}] elif "initial" in item: root["answer"] = item["initial"] if (item["type"] == "group" and "repeats" in item and item["repeats"] is True and is_list(context)): answer = [] for c in context: q = [] for i in item["item"]: q.append(handle_item(i, env, c)) answer.append({"item": q}) root["answer"] = answer elif "item" in item: root["item"] = [] for i in item["item"]: root["item"].append(handle_item(i, env, context)) return root
def pp(i): if not isinstance(i, str): return i exprs = re_all(r"(?P<var>{{[\S\s]+}})", i) vs = {} for exp in exprs: data = fhirpath({}, exp["var"][2:-2], env) if len(data) > 0: vs[exp["var"]] = data[0] res = i for k, v in vs.items(): res = res.replace(k, v) return res
def constraint_check_for_item(errors, questionnaire_item, env): for constraint in questionnaire_item.get("constraint", []): expression = constraint["expression"]["expression"] result = fhirpath({}, expression, env) import logging logging.debug("expression %s", expression) logging.debug("result %s", result) logging.debug("env %s", env) if result == [True]: # TODO: calculate error location path errors.append(constraint) for item in questionnaire_item.get("item", []): constraint_check_for_item(errors, item, env)
def resolve_string_template(i, env, encode_result=False): if not isinstance(i, str): return i exprs = re_all(r"(?P<var>{{[\S\s]+?}})", i) vs = {} for exp in exprs: data = fhirpath({}, exp["var"][2:-2], env) if len(data) > 0: # TODO: pass comma separated values for x-fhir-query vs[exp["var"]] = quote(data[0]) if encode_result else data[0] else: vs[exp["var"]] = "" res = i for k, v in vs.items(): res = res.replace(k, v) return res
def prepare_variables(item): variables = {} for var in item.get("variable", []): variables[var["name"]] = fhirpath({}, var["expression"]) return variables
def handle_item(item, env, context): def init_item(): new_item = {"linkId": item["linkId"]} if "text" in item: new_item["text"] = item["text"] return new_item if "itemContext" in item: context = fhirpath(context, item["itemContext"]["expression"], env) if "itemPopulationContext" in item: context = fhirpath(context, item["itemPopulationContext"]["expression"], env) if (item["type"] == "group" and item.get("repeats", False) is True and is_list(context)): root_items = [] for c in context: populated_items = [] for i in item["item"]: populated_items.extend(handle_item(i, env, c)) root_item = init_item() root_item["item"] = populated_items root_items.append(root_item) return root_items root_item = init_item() if context and "initialExpression" in item and item.get("repeats", False) is True: answers = [] for index, _item in enumerate(context): data = fhirpath( context, "%context[{}].{}".format( index, item["initialExpression"]["expression"]), env, ) if data and len(data): type = get_type(item, data) answers.extend([{"value": {type: d}} for d in data]) if answers: root_item["answer"] = answers elif "initialExpression" in item: answers = [] data = fhirpath(context, item["initialExpression"]["expression"], env) if data and len(data): type = get_type(item, data) if item.get("repeats") is True: answers = [{"value": {type: d}} for d in data] else: answers = [{"value": {type: data[0]}}] if answers: root_item["answer"] = answers elif "initial" in item: root_item["answer"] = item["initial"] if "item" in item: populated_items = [] for i in item["item"]: populated_items.extend(handle_item(i, env, context)) root_item["item"] = populated_items return [root_item]
async def test_populate_nutritio_order(sdk, safe_db): """ TODO think how this kind of error may be handled Shown typo (missing bracket) causes an empty bundle response The system should check such cases an fire warnings """ q = sdk.client.resource( "Questionnaire", **{ "status": "active", "launchContext": [{"name": "LaunchPatient", "type": "Patient"}], "sourceQueries": [{"localRef": "Bundle#DietAndNutrition"}], "contained": [ { "id": "DietAndNutrition", "type": "batch", "entry": [ { "request": { # -------second bracket is missing here \/ "url": "/NutritionOrder?patient={{%LaunchPatient.id}&status=active", "method": "GET", } } ], "resourceType": "Bundle", } ], "item": [ { "text": "Diet and Nutrition", "type": "choice", "linkId": "diet", "repeats": True, "answerValueSet": "diet", "initialExpression": { "language": "text/fhirpath", "expression": "%DietAndNutrition.entry[0].resource.entry.resource.oralDiet.type.coding.where(system = 'http://snomed.info/sct')", }, } ], }, ) await q.save() assert q.id is not None launch_patient = sdk.client.resource("Patient") await launch_patient.save() assert launch_patient.id is not None n = sdk.client.resource( "NutritionOrder", **{ "intent": "plan", "status": "active", "patient": { "id": launch_patient.id, "resourceType": "Patient" }, "dateTime": "2020-01-01T00:00", "oralDiet": { "type": [{ "coding": [{ "code": "437091000124100", "system": "http://snomed.info/sct", "display": "Calcium modified diet", }] }] }, }, ) await n.save() assert n.id is not None p = await q.execute("$populate", data=create_parameters(LaunchPatient=launch_patient)) populated_answer = fhirpath( p, "QuestionnaireResponse.item.where(linkId='diet').answer.value.Coding") assert populated_answer == []