Skip to content

Commit

Permalink
Add pre-pop queries to value[x] items
Browse files Browse the repository at this point in the history
  • Loading branch information
fongsean committed Mar 4, 2024
1 parent 81ed01a commit 647f327
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 150 deletions.
11 changes: 11 additions & 0 deletions packages/structure-def-to-questionnaire/convertTypes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Convert structure definition type codes to appropriate questionnaire item types
def convert_to_appropriate_type(item_type):
# convert id to string
if item_type == "id":
return "string"

# convert uri to url
if item_type == "uri":
return "url"

return item_type
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
def add_required_and_repeats_attribute(element, item):
# required
if element.get("min", 0) > 0:
item["required"] = True

# repeats
if element.get("max", 0) == "*":
item["repeats"] = True

return item


def create_item(element, parent_link_id=None):
link_id = element["id"]

Expand All @@ -12,13 +24,7 @@ def create_item(element, parent_link_id=None):
"repeats": False,
}

# required
if element.get("min", 0) > 0:
item["required"] = True

# repeats
if element.get("max", 0) == "*":
item["repeats"] = True
item = add_required_and_repeats_attribute(element, item)

return item

Expand Down
11 changes: 11 additions & 0 deletions packages/structure-def-to-questionnaire/helperFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,14 @@ def add_launch_context_to_questionnaire(questionnaire, profile_resource_type):
]

return questionnaire


def get_element_name_without_resource(element, root_level=True):
if root_level:
return ".".join(element["id"].split(".")[1:])

if ":" not in element["id"]:
return element["id"]

# if element is not at root level (i.e. it was further obtained via profile resolution), only use the last part of the id
return element["id"].split(":")[1]
64 changes: 64 additions & 0 deletions packages/structure-def-to-questionnaire/initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
def add_item_initial(item, element):
if element.get("fixedUri") is not None and element.get("fixedUri") != "":
item["initial"] = [{"valueString": element["fixedUri"]}]

return item


def add_initial_expression(item, element, structure_definition_url=None):
# skip adding initial expression if item has item.initial
if item.get("initial") is not None:
return item

if item.get("extension", None) is None:
item["extension"] = []

initialExpressionString = ""
if element["path"].startswith("Extension") and structure_definition_url is not None:
preInitialExpressionExtensionString = (
item["linkId"].lower().split("extension")[0].replace(":", ".") + "extension"
)

initialExpressionString = f"%{preInitialExpressionExtensionString}.where(url='{structure_definition_url}').value"
else:
initialExpressionString = f"%{item['linkId'].lower()}"

item = add_display_instructions(item, initialExpressionString)

item["extension"].append(
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": initialExpressionString,
},
}
)

return item


def add_display_instructions(item, displayInstructionString):
if item.get("type") != "group":
item["item"] = [
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory",
"valueCodeableConcept": {
"coding": [
{
"system": "http://hl7.org/fhir/questionnaire-display-category",
"code": "instructions",
}
]
},
}
],
"linkId": f"{item['linkId']}-display-instructions",
"text": displayInstructionString,
"type": "display",
}
]

return item
5 changes: 4 additions & 1 deletion packages/structure-def-to-questionnaire/readTableElements.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ def read_table_elements(structure_definition):

# Create a dictionary of element names and URLs
a_tags_dict = {
a_tag.text.strip(): a_tag.get("href")
a_tag.text.strip(): {
"href": a_tag.get("href", None),
"title": a_tag.get("title", None),
}
for a_tag in a_tags
if a_tag.text.strip() != "" or a_tag.get("href") is not None
}
Expand Down
77 changes: 77 additions & 0 deletions packages/structure-def-to-questionnaire/resolveProfiles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import re


def get_all_profile_links(table_element):
profile_links = []
# get links with 'http' in them
for value_i in table_element.values():
for value_j in value_i.values():
if value_j is not None and "http" in value_j:
if value_j.startswith("http"):
profile_links.append(value_j)
else:
profile_links.append("http" + value_j.split("http")[-1])

# clean links that does not start with 'http'
return profile_links


def get_first_profile_link(table_element):
# retrieve links from table element
profile_links = get_all_profile_links(table_element)

# not root level, resolve via appending profie name to end of base url (hardcoded)
for link in profile_links:
if "extension" in link:
return link

if "StructureDefinition" in link:
try:
# Split the URL by "StructureDefinition-" and ".html"
re_match = re.search(
r"(?:StructureDefinition[/\-])(.*?)(?:\.html|\/|$)", link
)
if re_match:
profile_name = re_match.group(1)

return (
"https://build.fhir.org/ig/hl7au/au-fhir-base/StructureDefinition-"
+ profile_name
+ ".json"
)

print("Fail to get profile link ", link)
return None
except IndexError:
print("Fail to get profile link ", link)
return None

return None


def is_value_set_link(key, value):
if key in value and value[key] is not None and "ValueSet" in value[key]:
return True

return False


def get_all_valueset_links(table_element):
profile_links = []
for value in table_element.values():
if is_value_set_link(key="title", value=value):
profile_links.append(value["title"])
elif is_value_set_link(key="href", value=value):
profile_links.append(value["href"])

return profile_links


def get_coding_terminology_binding(table_element):
if "Coding" in table_element:
valueset_links = get_all_valueset_links(table_element)

if len(valueset_links) > 0:
return valueset_links[0]

return None
Loading

0 comments on commit 647f327

Please sign in to comment.