WHO Immunization Implementation Guide
0.2.0 - ci-build

WHO Immunization Implementation Guide, published by WHO. This guide is not an authorized publication; it is the continuous build for version 0.2.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/WorldHealthOrganization/smart-immunizations/ and changes regularly. See the Directory of published versions

StructureMap: IMMZ.Helpers

Official URL: http://smart.who.int/immunizations/StructureMap/IMMZ.Helpers Version: 0.2.0
Draft as of 2025-09-10 Computable Name: IMMZ.Helpers

Immunization - Transform QuestionnaireResponse to Logical Model Helper groups

map "http://smart.who.int/immunizations/StructureMap/IMMZ.Helpers" = "IMMZ.Helpers"

// Immunization - Transform QuestionnaireResponse to Logical Model Helper groups

uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QResp as source
uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias Bundle as target

group ItemToValue(source item, target field) {
  item.answer first as answer then {
    answer.value as content -> field.value = content "SetValue";
  } "FirstAnswer";
}

group ItemToCode(source item, target field) {
  item.answer first as answer then {
    answer.value as coding then {
      coding.code as content -> field.value = content "SetCode";
    } "Coding";
  } "FirstAnswer";
}

group ItemToCoding(source item, target field) {
  item.answer first as answer then {
    answer.value as coding then {
      coding.code as code -> field.code = code "SetCode";
      coding.system as system -> field.system = system "SetSystem";
      coding.display as display -> field.display = display "SetDisplay";
    } "Coding";
  } "FirstAnswer";
}

group D1andD13Questions(source qr : QResp, target immz) {
  qr.item as item where linkId = 'birthDose' -> immz.birthDose as field then ItemToValue(item, field) "birthDose";
  qr.item as item where linkId = 'typeOfDose' -> immz.typeOfDose as field then ItemToCoding(item, field) "typeOfDose";
  qr.item as item where linkId = 'completedThePrimaryVaccinationSeries' -> immz.completedThePrimaryVaccinationSeries as field then ItemToValue(item, field) "completedThePrimaryVaccinationSeries";
  qr.item as item where linkId = 'completedTheBoosterSeries' -> immz.completedTheBoosterSeries as field then ItemToValue(item, field) "completedTheBoosterSeries";
  qr.item as item where linkId = 'dateWhenPrimaryVaccinationSeriesWasCompleted' -> immz.dateWhenPrimaryVaccinationSeriesWasCompleted as field then ItemToValue(item, field) "dateWhenPrimaryVaccinationSeriesWasCompleted";
  qr.item as item where linkId = 'hivStatus' -> immz.hivStatus as field then ItemToCoding(item, field) "hivStatus";
  qr.item as item where linkId = 'typeOfPoliovirusDose' -> immz.typeOfPoliovirusDose as field then ItemToCoding(item, field) "typeOfPoliovirusDose";
  qr.item as item where linkId = 'typeOfJeDose' -> immz.typeOfJeDose as field then ItemToCoding(item, field) "typeOfJeDose";
  qr.item as item where linkId = 'typeOfTbeDose' -> immz.typeOfTbeDose as field then ItemToCoding(item, field) "typeOfTbeDose";
  qr.item as item where linkId = 'typeOfTyphoidDose' -> immz.typeOfTyphoidDose as field then ItemToCoding(item, field) "typeOfTyphoidDose";
  qr.item as item where linkId = 'typeOfCholeraDose' -> immz.typeOfCholeraDose as field then ItemToCoding(item, field) "typeOfCholeraDose";
  qr.item as item where linkId = 'typeOfMeningococcalDose' -> immz.typeOfMeningococcalDose as field then ItemToCoding(item, field) "typeOfMeningococcalDose";
  qr.item as item where linkId = 'typeOfHepatitisADose' -> immz.typeOfHepatitisADose as field then ItemToCoding(item, field) "typeOfHepatitisADose";
  qr.item as item where linkId = 'typeOfHepatitisBDose' -> immz.typeOfHepatitisBDose as field then ItemToCoding(item, field) "typeOfHepatitisBDose";
  qr.item as item where linkId = 'vaccineType' -> immz.vaccineType as field then ItemToCoding(item, field) "vaccineType";
  qr.item as item where linkId = 'dateAndTimeOfVaccination' -> immz.dateAndTimeOfVaccination as field then ItemToValue(item, field) "dateAndTimeOfVaccination";
  qr.item as item where linkId = 'contactDate' -> immz.contactDate as field then ItemToValue(item, field) "contactDate";
  qr.item as item where linkId = 'ancContactNumber' -> immz.ancContactNumber as field then ItemToValue(item, field) "ancContactNumber";
  qr.item as item where linkId = 'doseNumber' -> immz.doseNumber as field then ItemToValue(item, field) "doseNumber";
}

group D1Questions(source qr : QResp, target immz) {
  qr.item as item where linkId = 'pretermBirth' -> immz.pretermBirth as field then ItemToValue(item, field) "pretermBirth";
  qr.item as item where linkId = 'immunocompromised' -> immz.immunocompromised as field then ItemToValue(item, field) "immunocompromised";
  qr.item as item where linkId = 'currentlyOnArt' -> immz.currentlyOnArt as field then ItemToValue(item, field) "currentlyOnArt";
  qr.item as item where linkId = 'currentlyOnArt' -> immz.currentlyOnArt as field then ItemToValue(item, field) "currentlyOnArt";
  qr.item as item where linkId = 'typeOfTbInfectionTestPerformed' -> immz.typeOfTbInfectionTestPerformed as field then ItemToCoding(item, field) "typeOfTbInfectionTestPerformed";
  qr.item as item where linkId = 'tbInfectionTestResult' -> immz.tbInfectionTestResult as field then ItemToCoding(item, field) "tbInfectionTestResult";
  qr.item as item where linkId = 'immunologicallyStable' -> immz.immunologicallyStable as field then ItemToValue(item, field) "immunologicallyStable";
  qr.item as item where linkId = 'clinicallyWell' -> immz.clinicallyWell as field then ItemToValue(item, field) "clinicallyWell";
  qr.item as item where linkId = 'birthWeightInGrams' -> immz.birthWeightInGrams as field then ItemToValue(item, field) "birthWeightInGrams";
  qr.item as item where linkId = 'artStartDate' -> immz.artStartDate as field then ItemToValue(item, field) "artStartDate";
  qr.item as item where linkId = 'highRiskOfPneumococcalInfection' -> immz.highRiskOfPneumococcalInfection as field then ItemToValue(item, field) "highRiskOfPneumococcalInfection";
  qr.item as item where linkId = 'ageInMonthsWhenClientReceivedFirstMeningococcalDose' -> immz.ageInMonthsWhenClientReceivedFirstMeningococcalDose as field then ItemToValue(item, field) "ageInMonthsWhenClientReceivedFirstMeningococcalDose";
  qr.item as item where linkId = 'vnaLevel' -> immz.vnaLevel as field then ItemToValue(item, field) "vnaLevel";
  qr.item as item where linkId = 'riskOfOccupationalExposureToRabiesVirus' -> immz.riskOfOccupationalExposureToRabiesVirus as field then ItemToValue(item, field) "riskOfOccupationalExposureToRabiesVirus";
  qr.item as item where linkId = 'dengueSerostatus' -> immz.dengueSerostatus as field then ItemToCoding(item, field) "dengueSerostatus";
}

group D13Questions(source qr : QResp, target immz) {
  qr.item as item where linkId = 'immunizationEventStatus' -> immz.immunizationEventStatus as field then ItemToCoding(item, field) "immunizationEventStatus";
  qr.item as item where linkId = 'reasonVaccineWasNotAdministered' -> immz.reasonVaccineWasNotAdministered as field then ItemToCoding(item, field) "reasonVaccineWasNotAdministered";
  qr.item as item where linkId = 'vaccineBrand' -> immz.vaccineBrand as field then ItemToCoding(item, field) "vaccineBrand";
  qr.item as item where linkId = 'liveVaccine' -> immz.liveVaccine as field then ItemToValue(item, field) "liveVaccine";
  qr.item as item where linkId = 'countryOfVaccination' -> immz.countryOfVaccination as field then ItemToCoding(item, field) "countryOfVaccination";
  qr.item as item where linkId = 'administrativeArea' -> immz.administrativeArea as field then ItemToCoding(item, field) "administrativeArea";
  qr.item as item where linkId = 'vaccineManufacturer' -> immz.vaccineManufacturer as field then ItemToCoding(item, field) "vaccineManufacturer";
  qr.item as item where linkId = 'vaccineBatchNumber' -> immz.vaccineBatchNumber as field then ItemToValue(item, field) "vaccineBatchNumber";
  qr.item as item where linkId = 'vaccineMarketAuthorizationHolder' -> immz.vaccineMarketAuthorizationHolder as field then ItemToCoding(item, field) "vaccineMarketAuthorizationHolder";
  qr.item as item where linkId = 'expirationDate' -> immz.expirationDate as field then ItemToValue(item, field) "expirationDate";
  qr.item as item where linkId = 'doseQuantity' -> immz.doseQuantity as field then ItemToValue(item, field) "doseQuantity";
  qr.item as item where linkId = 'healthWorkerIdentifier' -> immz.healthWorkerIdentifier as field then ItemToValue(item, field) "healthWorkerIdentifier";
  qr.item as item where linkId = 'totalDosesInSeries' -> immz.totalDosesInSeries as field then ItemToValue(item, field) "totalDosesInSeries";
  qr.item as item where linkId = 'diseaseTargeted' -> immz.diseaseTargeted as field then ItemToCoding(item, field) "diseaseTargeted";
  qr.item as item where linkId = 'dueDateOfNextDose' -> immz.dueDateOfNextDose as field then ItemToValue(item, field) "dueDateOfNextDose";
}

group MakeImmzObservation(source patient : Reference, source immid, source code : Coding, source cat : Coding, source value, target bundle : Bundle) {
  value ->  uuid() as oid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', oid),  entry.request as request,  request.method = 'PUT',  request.url = append('Observation/', oid),  entry.resource = create('Observation') as obs then {
    value -> obs.id = oid "SetId";
    immid ->  obs.partOf as partOf,  partOf.reference = append('urn:uuid:', immid) "SetPartOf";
    patient -> obs.subject = patient "SetSubject";
    code -> obs.code = code "SetCode";
    value -> obs.value = value "SetValue";
    cat -> obs.category = cat "SetCategory";
  } "CreateObservation";
}

group MakeObservation(source patient : Reference, source code : Coding, source cat : Coding, source value, target bundle : Bundle) {
  value ->  uuid() as oid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', oid),  entry.request as request,  request.method = 'PUT',  request.url = append('Observation/', oid),  entry.resource = create('Observation') as obs then {
    value -> obs.id = oid "SetId";
    patient -> obs.subject = patient "SetSubject";
    code -> obs.code = code "SetCode";
    value -> obs.value = value "SetValue";
    cat -> obs.category = cat "SetCategory";
  } "CreateObservation";
}

group TypeOfVaccineDose(source typeof : Coding, target ext : Extension) {
  typeof -> ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZTypeOfDose' "SetURL";
  typeof -> ext.value = typeof "SetValue";
}

group MakeImmunization(source patient : Reference, source immid, source immz, target bundle : Bundle) {
  immz.vaccineType as vaccineCode ->  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', immid),  entry.request as request,  request.method = 'PUT',  request.url = append('Immunization/', immid),  entry.resource = create('Immunization') as imm then {
    // D1 and D13
    immid -> imm.id = immid "SetId";
    patient -> imm.patient = patient "SetPatient";
    vaccineCode -> imm.vaccineCode = vaccineCode "vaccineCode";
    immz.typeOfDose as typeOfDose -> imm.protocolApplied as pa then {
      typeOfDose.code as code -> pa.series = code "SetSeriesToCode"; // if display is missing
      typeOfDose.display as display -> pa.series = display "SetSeriesToDisplay";
      immz.doseNumber as doseNumber -> pa.doseNumber = doseNumber "SetDoseNumber";
      immz.totalDosesInSeries as totalDoses -> pa.seriesDoses = totalDoses;
      immz.diseaseTargeted as disease -> pa.targetDisease = disease;
      immz.dueDateOfNextDose as duedate ->  pa.extension as ext,  ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZDueDateOfNextDose',  ext.value = duedate;
    } "protocolApplied";
    immz.dateAndTimeOfVaccination as occurrence -> imm.occurrence = occurrence;
    immz.typeOfPoliovirusDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfJeDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfTbeDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfTyphoidDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfCholeraDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfMeningococcalDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfHepatitisADose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    immz.typeOfHepatitisBDose as typeof -> imm.extension as ext then TypeOfVaccineDose(typeof, ext);
    // D1
    immz -> imm.status = 'completed' "SetDefaultStatus";
    // D13
    immz.immunizationEventStatus as status -> imm.status = translate(status, 'http://smart.who.int/immunizations/ConceptMap/IMMZ.D.ConceptMap', 'code');
    immz.reasonVaccineWasNotAdministered as reason -> imm.statusReason = reason;
    immz.vaccineBrand as brand ->  imm.extension as ext,  ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZVaccineBrand',  ext.value = brand;
    immz.liveVaccine as live ->  imm.extension as ext,  ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZLiveVaccine',  ext.value = live;
    immz.countryOfVaccination as country ->  imm.extension as ext,  ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZCountryOfVaccination',  ext.value = country;
    immz.administrativeArea as area ->  imm.extension as ext,  ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZAdministrativeArea',  ext.value = area;
    immz.vaccineManufacturer as vman ->  imm.manufacturer as manufacturer,  manufacturer.identifier as identifier then {
      vman.system as system -> identifier.system = system "SetSystem";
      vman.code as code -> identifier.value = code "SetValue";
    };
    immz.vaccineBatchNumber as batch -> imm.lotNumber = batch;
    immz.vaccineMarketAuthorizationHolder as market ->  imm.extension as ext,  ext.url = 'http://smart.who.int/immunizations/StructureDefinition/IMMZMarketAuthorization',  ext.value = market;
    immz.expirationDate as expiration -> imm.expirationDate = expiration;
    immz.doseQuantity as dosequantity -> imm.doseQuantity = dosequantity;
    immz.healthWorkerIdentifier as hw ->  imm.performer as performer,  performer.actor as actor,  actor.identifier as identifier,  identifier.value = hw;
  } "MakeImmunization";
}

group D1andD13Observations(source patient : Reference, source immid, source immz, target bundle : Bundle) {
  immz -> c('http://terminology.hl7.org/CodeSystem/observation-category', 'survey', 'Survey') as survey then {
    immz.birthDose as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE263', 'Birth dose') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.completedThePrimaryVaccinationSeries as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE203', 'Completed the primary vaccination series') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.completedTheBoosterSeries as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE257', 'Completed the booster series') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.dateWhenPrimaryVaccinationSeriesWasCompleted as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE242', 'Date when primary vaccination series was completed') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.hivStatus as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE204', 'HIV status') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.contactDate as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE201', 'Contact date') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.ancContactNumber as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE202', 'ANC contact number') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
  } "DefineCategory";
}

group D1Observations(source patient : Reference, source immid, source immz, target bundle : Bundle) {
  immz -> c('http://terminology.hl7.org/CodeSystem/observation-category', 'survey', 'Survey') as survey then {
    immz.pretermBirth as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE208', 'Preterm birth') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.immunocompromised as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE209', 'Immunocompromised') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.currentlyOnArt as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE210', 'Currently on ART') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.typeOfTbInfectionTestPerformed as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE243', 'Type of TB infection test performed') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.tbInfectionTestResult as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE246', 'TB infection test result') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.immunologicallyStable as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE249', 'Immunologically stable') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.clinicallyWell as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE250', 'Clinically well') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.birthWeightInGrams as value ->  create('Quantity') as content,  content.system = 'http://unitsofmeasure.org',  content.code = 'g',  content.unit = 'g',  content.value = value,  c('http://loinc.org', '8339-4', 'Birth weight Measured') as bwloinc,  c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE211', 'Birth weight in grams') as bwdak,  create('CodeableConcept') as code,  code.coding = bwloinc,  code.coding = bwdak,  c('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs', 'Vital Signs') as vital then MakeImmzObservation(patient, immid, code, vital, content, bundle);
    immz.artStartDate as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE215', 'ART start date') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.highRiskOfPneumococcalInfection as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE251', 'High risk of pneumococcal infection') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.ageInMonthsWhenClientReceivedFirstMeningococcalDose as value ->  create('Quantity') as content,  content.unit = 'mo',  content.value = value,  c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE236', 'Age in months when client received first meningococcal dose') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.vnaLevel as value ->  create('Quantity') as content,  content.system = 'http://unitsofmeasure.org',  content.code = '[IU]/mL',  content.unit = '[IU]/mL',  content.value = value,  c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE240', 'VNA level') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.riskOfOccupationalExposureToRabiesVirus as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE253', 'Risk of occupational exposure to rabies virus') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
    immz.dengueSerostatus as content -> c('http://smart.who.int/immunizations/CodeSystem/IMMZ.D', 'DE241', 'Dengue serostatus') as code then MakeImmzObservation(patient, immid, code, survey, content, bundle);
  } "DefineCategory";
}