Example #1
0
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
Example #2
0
    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
Example #3
0
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)
Example #4
0
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
Example #5
0
def prepare_variables(item):
    variables = {}
    for var in item.get("variable", []):
        variables[var["name"]] = fhirpath({}, var["expression"])
    return variables
Example #6
0
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 == []