Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions databaseData/db.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

{
"clients": [],
"logs": [],
Expand Down
9 changes: 6 additions & 3 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export default class App extends Component {
this.setState({ questionnaire: artifacts.questionnaire });
this.setState({ deviceRequest: deviceRequest });
this.setState({ isAdaptiveFormWithoutExtension: artifacts.questionnaire.meta && artifacts.questionnaire.meta.profile && artifacts.questionnaire.meta.profile.includes("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-adapt") && (artifacts.questionnaire.extension === undefined || !artifacts.questionnaire.extension.includes(e => e.url === "http://hl7.org/fhir/StructureDefinition/cqf-library")) });

this.setState({ });
// execute for each main library
return Promise.all(
artifacts.mainLibraryElms.map(mainLibraryElm => {
Expand Down Expand Up @@ -157,7 +157,7 @@ export default class App extends Component {
const executionInputs = {
elm: mainLibraryElm,
// look at main library elms to determine dependent elms to include
elmDependencies: mainLibraryElm.library.includes.def.map(
elmDependencies: mainLibraryElm.library.includes ? mainLibraryElm.library.includes.def.map(
includeStatement => {
let foundLibrary = artifacts.dependentElms.find(elm => {
return (
Expand All @@ -172,7 +172,7 @@ export default class App extends Component {
this.consoleLog(`Could not find library ${includeStatement.path}. Check if it is referenced in FHIR Library (${mainLibraryElm.library.identifier.id}) properly.`, `errorClass`)
}
}
),
) : undefined,
valueSetDB: {},
parameters: parameterObj,
mainLibraryMaps: artifacts.mainLibraryMaps
Expand Down Expand Up @@ -263,6 +263,9 @@ export default class App extends Component {

// fill the valueSetDB in executionInputs with the required valuesets from their artifact source
fillValueSetDB(executionInputs, artifacts) {
if (!executionInputs.elmDependencies) {
return;
}
// create list of all ELMs that will be used
let allElms = executionInputs.elmDependencies.slice();
allElms.push(executionInputs.elm);
Expand Down
36 changes: 22 additions & 14 deletions src/components/QuestionnaireForm/QuestionnaireForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ export default class QuestionnaireForm extends Component {
getLibraryPrepopulationResult(item, cqlResults) {
let prepopulationResult;
item.extension.forEach(e => {
let value;
let value, valueExpression;
if (
e.url ===
"http://hl7.org/fhir/StructureDefinition/cqif-calculatedValue"
Expand All @@ -464,26 +464,34 @@ export default class QuestionnaireForm extends Component {
) {
// r4
value = findValueByPrefix(e, "value");
value = value.expression;
valueExpression = value.expression;
} else {
// not a cql statement reference
return;
}

// split library designator from statement
const valueComponents = value.split(".");
let libraryName;
let statementName;
if (valueComponents.length > 1) {
libraryName = valueComponents[0].substring(
1,
valueComponents[0].length - 1
);
statementName = valueComponents[1];
} else {
// if there is not library name grab the first library name
statementName = value;
libraryName = Object.keys(cqlResults)[0];
// this is embedded CQL in Questionnaire
if(value.language === "application/elm+json") {
libraryName = "LibraryLinkId" + item.linkId;
statementName = "LinkId." + item.linkId;
}
else {
// split library designator from statement
const valueComponents = valueExpression.split(".");

if (valueComponents.length > 1) {
libraryName = valueComponents[0].substring(
1,
valueComponents[0].length - 1
);
statementName = valueComponents[1];
} else {
// if there is not library name grab the first library name
statementName = valueExpression;
libraryName = Object.keys(cqlResults)[0];
}
}

if (cqlResults[libraryName] != null) {
Expand Down
5 changes: 5 additions & 0 deletions src/elmExecutor/buildPopulatedResourceBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ function buildPopulatedResourceBundle(
}
};

// at least grab patient
if(!neededResources) {
neededResources = [];
neededResources.push("Patient");
}
readResources(neededResources.slice(), () => {
const bundle = {
resourceType: "Bundle",
Expand Down
15 changes: 12 additions & 3 deletions src/elmExecutor/executeElm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import cql from "cql-execution";
import cqlfhir from "cql-exec-fhir";
// import fhirhelpersElm from "./FHIRHelpers.json";
import extractFhirResourcesThatNeedFetching from "./extractFhirResourcesThatNeedFetching";
import buildPopulatedResourceBundle from "./buildPopulatedResourceBundle";

Expand Down Expand Up @@ -56,8 +55,18 @@ function findDifference(array1, array2) {

function executeElmAgainstPatientSource(executionInputs, patientSource) {
// executionInputs.elmDependencies = [ fhirhelpersElm ]
const repository = new cql.Repository(executionInputs.elmDependencies);
const lib = new cql.Library(executionInputs.elm, repository);
let repository = undefined;
if(executionInputs.elmDependencies) {
repository = new cql.Repository(executionInputs.elmDependencies);
}

let lib = undefined;
if(repository) {
lib = new cql.Library(executionInputs.elm, repository);
} else {
lib = new cql.Library(executionInputs.elm);
}

const codeService = new cql.CodeService(executionInputs.valueSetDB);
const executor = new cql.Executor(lib, codeService, executionInputs.parameters);
const results = executor.exec(patientSource);
Expand Down
33 changes: 33 additions & 0 deletions src/util/fetchArtifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,35 @@ function fetchArtifacts(fhirPrefix, filePrefix, questionnaireReference, fhirVers
else reject("Failed to fetch all artifacts.");
}

function findQuestionnaireEmbeddedCql(inputItems) {
if(!inputItems) {
return;
}
inputItems.forEach(item => {
const itemExtensions = item.extension;
if(item.extension) {
let findEmbeddedCql = item.extension.find(ext =>
ext.url === "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression"
&& ext.valueExpression && ext.valueExpression.language === "application/elm+json");

if(findEmbeddedCql) {
const itemLibrary = JSON.parse(findEmbeddedCql.valueExpression.expression);
itemLibrary.library.identifier= {
id: "LibraryLinkId" + item.linkId,
version: "0.0.1"
};
elmLibraryMaps[itemLibrary.library.identifier.id] = itemLibrary;
retVal.mainLibraryMaps = elmLibraryMaps;
retVal.mainLibraryElms.push(itemLibrary);
}
}

if(item.item !== undefined && item.item.length > 0) {
findQuestionnaireEmbeddedCql(item.item);
}
});
}

pendingFetches += 1;
consoleLog("fetching questionnaire and elms", "infoClass");
consoleLog(questionnaireReference, "infoClass");
Expand All @@ -46,6 +75,8 @@ function fetchArtifacts(fhirPrefix, filePrefix, questionnaireReference, fhirVers

fetchedUrls.add(questionnaireReference);

findQuestionnaireEmbeddedCql(questionnaire.item);

if (questionnaire.extension !== undefined) {
// grab all main elm urls
// R4 resources use cqf library.
Expand Down Expand Up @@ -81,6 +112,8 @@ function fetchArtifacts(fhirPrefix, filePrefix, questionnaireReference, fhirVers

//fetchedUrls.add(questionnaireReference);

findQuestionnaireEmbeddedCql(questionnaire.item);

if (questionnaire.extension !== undefined) {
// grab all main elm urls
// R4 resources use cqf library.
Expand Down