Structured Data Capture
4.0.0-ballot - STU 4 ballot International flag

This page is part of the Structured Data Capture FHIR IG (v4.0.0-ballot: STU 4 Ballot 1) based on FHIR (HL7® FHIR® Standard) R4. The current version which supersedes this version is 3.0.0. For a full list of available versions, see the Directory of published versions

StructureMap: QuestionnairePopulationTransform

Official URL: http://hl7.org/fhir/uv/sdc/StructureMap/QuestionnairePopulationTransform Version: 4.0.0-ballot
Standards status: Trial-use Maturity Level: 4 Computable Name: QuestionnairePopulationTransform
Other Identifiers: OID:2.16.840.1.113883.4.642.40.17.43.4
/// name = "QuestionnairePopulationTransform"
/// status = "active"
/// title = "Questionnaire Population Transform Example"
/// description = "An example of a StructureMap used to support population of a QuestionnaireResponse from a search bundle"
/// experimental = "true"

map "http://hl7.org/fhir/uv/sdc/StructureMap/QuestionnairePopulationTransform" = "QuestionnairePopulationTransform"

uses 'http://hl7.org/fhir/StructureDefinition/Bundle' as source
uses 'http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse' as target
uses 'http://hl7.org/fhir/StructureDefinition/MedicationStatement' as source

// The input bundle is a search bundle that contains search bundles for patient, condition, and medication statement resources

group main(source src : Bundle, target qr : QuestionnaireResponse) {
  src -> qr.questionnaire = 'http://hl7.org/fhir/uv/sdc/Questionnaire/questionnaire-sdc-test-fhirpath-prepop-source-query' "questionnaire";
  src -> qr.status = 'in-progress' "status";
  src -> qr.authored = (now()) "authored";
  src.entry first as patient -> qr.subject as subject, subject.reference = (%patient.resource.entry.fullUrl.toString()) "subject";

  src -> qr.item as grp, grp.linkId = 'grp' then {
    src -> grp.item as partDetails, partDetails.linkId = 'part-details' then {
      src.entry first as patient then {
        patient.resource : Bundle as patientRes -> partDetails then populatePatientGroup(patientRes, partDetails) "partBundleDetails";
      } "patientDetails";
      src.entry as conditions where (resource.link.url.contains("/Condition?")) -> partDetails.item as conditionItem, conditionItem.linkId = 'condition-count' then {
        conditions -> conditionItem.answer as conditionCountAnswer, conditionCountAnswer.value = (%conditions.resource.entry.count()) "conditionCountAnswer";
      } "conditionCount";
    } "partDetails";

    // Scan the search bundle for a medication statement bunde
    src.entry as medications where (resource.link.url.contains("/MedicationStatement?")) -> grp then {
      medications.resource : Bundle as medRes then populateMedicationsGroup(medRes, grp) "medEntry";
    } "meds";
  } "grp";
}

group populatePatientGroup(source patientRes : Bundle, target partDetails) {
  patientRes -> partDetails.item as participantId, 
                    participantId.linkId = 'participant-id',
                    participantId.answer as participantIdAnswer,
                    participantIdAnswer.value = (%patientRes.entry.resource.id.toString()) "participantIdValue";

  patientRes -> partDetails.item as familyName,
                    familyName.linkId = 'family-name',
                    familyName.answer as familyNameAnswer,
                    familyNameAnswer.value = (%patientRes.entry.resource.name.first().family) "familyNameValue";

  patientRes -> partDetails.item as givenName,
                    givenName.linkId = 'given-names',
                    givenName.answer as givenNameAnswer,
                    givenNameAnswer.value = (%patientRes.entry.resource.name.first().given.join(', ')) "givenNameValue";
  patientRes -> partDetails.item as dob, 
                    dob.linkId = 'dob',
                    dob.answer as dobAnswer,
                    dobAnswer.value = (%patientRes.entry.resource.birthDate) "dobValue";
}

group populateMedicationsGroup(source medRes : Bundle, target grp) {
  medRes.entry as med where (resource is MedicationStatement) -> grp.item as medsItem, medsItem.linkId = 'meds' then {
    med.resource : MedicationStatement as medResource -> medsItem.item as medsName, 
                    medsName.linkId = 'med-name',
                    medsName.answer as medsNameAnswer, 
                    medsNameAnswer.value = (%medResource.medication.select(iif(text.exists(), text, coding.display.first()))) "medsNameAnswer";
/* Todo handle medicationReference once resolve is supported
        iif($this is Reference, iif($this.resolve().text.exists(), $this.resolve().text, $this.resolve().coding.display.first()), iif(text, text, coding.display.first())))) "medsNameAnswer";
*/
    
    med.resource : MedicationStatement as medResource -> medsItem.item as medsStatus, medsStatus.linkId = 'med-status' then {
      medResource.status as medsMedicationStatus -> medsStatus.answer as medsStatusAnswer, medsStatusAnswer.value = c('http://hl7.org/fhir/CodeSystem/medication-status', medsMedicationStatus) "medsStatusAnswer";
    } "medsStatus";
    
    med.resource as medResource where (category.coding.where(system='http://terminology.hl7.org/CodeSystem/medicationrequest-category').exists()) -> medsItem.item as medsCategory, medsCategory.linkId = 'meds-category' then {
      medResource -> medsCategory.answer as medsCategoryAnswer, medsCategoryAnswer.value = (%medResource.category.coding.where(system='http://terminology.hl7.org/CodeSystem/medicationrequest-category').code.join(' ')) "medsCategoryAnswer";
    } "medsCategory";
  } "medItem";
}