-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #66 from kairos-fhir/ctcue-questionnaires
added two example scripts for export of LaborMethods as Questionnaire…
- Loading branch information
Showing
3 changed files
with
237 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package projects.cxx.ctcue | ||
|
||
import de.kairos.fhir.centraxx.metamodel.CrfTemplateField | ||
import de.kairos.fhir.centraxx.metamodel.CrfTemplateSection | ||
import de.kairos.fhir.centraxx.metamodel.LaborValue | ||
import de.kairos.fhir.centraxx.metamodel.MultilingualEntry | ||
import de.kairos.fhir.centraxx.metamodel.enums.LaborValueDType | ||
import org.hl7.fhir.r4.model.Questionnaire | ||
|
||
import static de.kairos.fhir.centraxx.metamodel.RootEntities.laborMethod | ||
|
||
/** | ||
* transforms a CXX LaborMethod to a Questionnaire. | ||
*/ | ||
questionnaire { | ||
|
||
id = "Questionnaire/" + context.source[laborMethod().id()] | ||
|
||
identifier { | ||
value = context.source[laborMethod().code()] | ||
} | ||
|
||
// using first section only | ||
final def firstSection = context.source[laborMethod().crfTemplate().sections()].find() | ||
|
||
firstSection[CrfTemplateSection.FIELDS].each { final def field -> | ||
item { | ||
setLinkId(field[CrfTemplateField.LABOR_VALUE][LaborValue.CODE] as String) | ||
|
||
// assuming the question is stored as description | ||
setText(field[CrfTemplateField.LABOR_VALUE][LaborValue.DESC_MULTILINGUAL_ENTRIES].find { it[MultilingualEntry.LANG] == "en" }[MultilingualEntry.VALUE] as String) | ||
setType(mapToType(field[CrfTemplateField.LABOR_VALUE][LaborValue.D_TYPE] as LaborValueDType)) | ||
} | ||
} | ||
|
||
} | ||
|
||
// more possible, focusing on main types | ||
static mapToType(final LaborValueDType laborValueDType) { | ||
switch (laborValueDType) { | ||
case LaborValueDType.BOOLEAN: | ||
return Questionnaire.QuestionnaireItemType.BOOLEAN | ||
case LaborValueDType.INTEGER: | ||
return Questionnaire.QuestionnaireItemType.INTEGER | ||
case LaborValueDType.DECIMAL: | ||
return Questionnaire.QuestionnaireItemType.QUANTITY | ||
case LaborValueDType.DATE || LaborValueDType.LONGDATE: | ||
return Questionnaire.QuestionnaireItemType.DATETIME | ||
case LaborValueDType.TIME: | ||
return Questionnaire.QuestionnaireItemType.TIME | ||
case LaborValueDType.CATALOG: | ||
return Questionnaire.QuestionnaireItemType.CHOICE | ||
case LaborValueDType.STRING || LaborValueDType.LONGSTRING: | ||
return Questionnaire.QuestionnaireItemType.TEXT | ||
} | ||
} |
180 changes: 180 additions & 0 deletions
180
src/main/groovy/projects/cxx/ctcue/questionnaireResponse.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
package projects.cxx.ctcue | ||
|
||
import de.kairos.fhir.centraxx.metamodel.AbstractCatalog | ||
import de.kairos.fhir.centraxx.metamodel.CatalogEntry | ||
import de.kairos.fhir.centraxx.metamodel.CrfTemplateField | ||
import de.kairos.fhir.centraxx.metamodel.IcdEntry | ||
import de.kairos.fhir.centraxx.metamodel.LaborFindingLaborValue | ||
import de.kairos.fhir.centraxx.metamodel.LaborValue | ||
import de.kairos.fhir.centraxx.metamodel.LaborValueNumeric | ||
import de.kairos.fhir.centraxx.metamodel.PrecisionDate | ||
import de.kairos.fhir.centraxx.metamodel.enums.LaborValueDType | ||
import org.hl7.fhir.r4.model.QuestionnaireResponse | ||
|
||
import static de.kairos.fhir.centraxx.metamodel.AbstractCode.CODE | ||
import static de.kairos.fhir.centraxx.metamodel.AbstractCodeName.NAME_MULTILINGUAL_ENTRIES | ||
import static de.kairos.fhir.centraxx.metamodel.MultilingualEntry.LANG | ||
import static de.kairos.fhir.centraxx.metamodel.MultilingualEntry.VALUE | ||
import static de.kairos.fhir.centraxx.metamodel.RootEntities.laborMapping | ||
|
||
questionnaireResponse { | ||
id = "QuestionnaireResponse/" + context.source[laborMapping().laborFinding().id()] | ||
|
||
identifier { | ||
value = context.source[laborMapping().laborFinding().shortName()] | ||
} | ||
|
||
setQuestionnaire("Questionnaire/" + context.source[laborMapping().laborFinding().laborMethod().id()]) | ||
|
||
// static, could be mapped as a param within the LaborFinding | ||
status = QuestionnaireResponse.QuestionnaireResponseStatus.INPROGRESS | ||
|
||
subject { | ||
reference = "Patient/" + context.source[laborMapping().relatedPatient().id()] | ||
} | ||
|
||
setAuthored(context.source[laborMapping().laborFinding().findingDate()]) | ||
|
||
// author (OrgUnit or Practitioner) has to be coded within the LaborFinding | ||
|
||
context.source[laborMapping().laborFinding().laborFindingLaborValues()].each { final def lflv -> | ||
|
||
final def laborValue = lflv[LaborFindingLaborValue.CRF_TEMPLATE_FIELD][CrfTemplateField.LABOR_VALUE] | ||
item { | ||
setLinkId(laborValue[CODE] as String) | ||
|
||
// assuming the question is stored as description | ||
setText(laborValue[LaborValue.DESC_MULTILINGUAL_ENTRIES].find { it[LANG] == "en" }[VALUE] as String) | ||
|
||
if (isNumeric(laborValue)) { | ||
answer { | ||
valueQuantity { | ||
value = lflv[LaborFindingLaborValue.NUMERIC_VALUE] | ||
unit = laborValue?.getAt(LaborValueNumeric.UNIT)?.getAt(CODE) as String | ||
} | ||
} | ||
} else if (isBoolean(laborValue)) { | ||
answer { | ||
setValueBoolean(lflv[LaborFindingLaborValue.BOOLEAN_VALUE] as Boolean) | ||
} | ||
} else if (isDate(laborValue)) { | ||
answer { | ||
valueDateTime { | ||
date = lflv[LaborFindingLaborValue.DATE_VALUE]?.getAt(PrecisionDate.DATE) | ||
} | ||
} | ||
} else if (isTime(laborValue)) { | ||
answer { | ||
setValueTime(lflv[LaborFindingLaborValue.TIME_VALUE] as String) | ||
} | ||
} else if (isString(laborValue)) { | ||
answer { | ||
setValueString(lflv[LaborFindingLaborValue.STRING_VALUE] as String) | ||
} | ||
} else if (isEnumeration(laborValue)) { | ||
valueCodeableConcept { | ||
lflv[LaborFindingLaborValue.MULTI_VALUE].each { final entry -> | ||
answer { | ||
valueCoding { | ||
system = "urn:centraxx:CodeSystem/UsageEntry" | ||
code = entry[CODE] as String | ||
display = entry[NAME_MULTILINGUAL_ENTRIES]?.find { it[LANG] == "en" }?.getAt(VALUE) as String | ||
} | ||
} | ||
} | ||
lflv[LaborFindingLaborValue.CATALOG_ENTRY_VALUE].each { final entry -> | ||
answer { | ||
valueCoding { | ||
system = "urn:centraxx:CodeSystem/ValueList-" + entry[CatalogEntry.CATALOG]?.getAt(AbstractCatalog.ID) | ||
code = entry[CODE] as String | ||
display = entry[NAME_MULTILINGUAL_ENTRIES]?.find { it[LANG] == "en" }?.getAt(VALUE) as String | ||
} | ||
} | ||
} | ||
} | ||
} else if (isOptionGroup(laborValue)) { | ||
valueCodeableConcept { | ||
lflv[LaborFindingLaborValue.MULTI_VALUE].each { final entry -> | ||
answer { | ||
valueCoding { | ||
system = "urn:centraxx:CodeSystem/UsageEntry" | ||
code = entry[CODE] as String | ||
display = entry[NAME_MULTILINGUAL_ENTRIES]?.find { it[LANG] == "en" }?.getAt(VALUE) as String | ||
} | ||
} | ||
} | ||
lflv[LaborFindingLaborValue.CATALOG_ENTRY_VALUE].each { final entry -> | ||
answer { | ||
valueCoding { | ||
system = "urn:centraxx:CodeSystem/ValueList-" + entry[CatalogEntry.CATALOG]?.getAt(AbstractCatalog.ID) | ||
code = entry[CODE] as String | ||
display = entry[NAME_MULTILINGUAL_ENTRIES]?.find { it[LANG] == "en" }?.getAt(VALUE) as String | ||
} | ||
} | ||
} | ||
} | ||
} else if (isCatalog(laborValue)) { | ||
valueCodeableConcept { | ||
lflv[LaborFindingLaborValue.CATALOG_ENTRY_VALUE].each { final entry -> | ||
answer { | ||
valueCoding { | ||
system = "urn:centraxx:CodeSystem/ValueList-" + entry[CatalogEntry.CATALOG]?.getAt(AbstractCatalog.ID) | ||
code = entry[CODE] as String | ||
display = entry[NAME_MULTILINGUAL_ENTRIES]?.find { it[LANG] == "en" }?.getAt(VALUE) as String | ||
} | ||
} | ||
} | ||
lflv[LaborFindingLaborValue.ICD_ENTRY_VALUE].each { final entry -> | ||
answer { | ||
valueCoding { | ||
system = "urn:centraxx:CodeSystem/IcdCatalog-" + entry[IcdEntry.CATALOGUE]?.getAt(AbstractCatalog.ID) | ||
code = entry[CODE] as String | ||
display = entry[IcdEntry.PREFERRED_LONG] as String | ||
} | ||
} | ||
} | ||
} | ||
} else { | ||
final String msg = laborValue?.getAt(LaborValue.D_TYPE) + " not implemented yet." | ||
System.out.println(msg) | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
static boolean isDTypeOf(final Object laborValue, final List<LaborValueDType> types) { | ||
return types.contains(laborValue?.getAt(LaborValue.D_TYPE) as LaborValueDType) | ||
} | ||
|
||
static boolean isBoolean(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.BOOLEAN]) | ||
} | ||
|
||
static boolean isNumeric(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.INTEGER, LaborValueDType.DECIMAL, LaborValueDType.SLIDER]) | ||
} | ||
|
||
static boolean isDate(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.DATE, LaborValueDType.LONGDATE]) | ||
} | ||
|
||
static boolean isTime(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.TIME]) | ||
} | ||
|
||
static boolean isEnumeration(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.ENUMERATION]) | ||
} | ||
|
||
static boolean isString(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.STRING, LaborValueDType.LONGSTRING]) | ||
} | ||
|
||
static boolean isCatalog(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.CATALOG]) | ||
} | ||
|
||
static boolean isOptionGroup(final Object laborValue) { | ||
return isDTypeOf(laborValue, [LaborValueDType.OPTIONGROUP]) | ||
} |