SGHI FHIR Profile Implementation Guide
0.1.0 - ci-build
SGHI FHIR Profile Implementation Guide, published by Kathurima Kimathi. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/savannahghi/sil_fhir_profile_ig/ and changes regularly. See the Directory of published versions
| Official URL: https://fhir.slade360.co.ke/fhir/StructureMap/ExtractMOH510ImmunisationRegister | Version: 0.1.0 | |||
| Active as of 2026-09-14 | Computable Name: ExtractMOH510ImmunisationRegister | |||
Extracts a transaction Bundle from a QuestionnaireResponse to the Kenya MOH 510 Immunisation Permanent Register: guardian RelatedPersons, growth-monitoring Observations, one Immunization per antigen dose for sections L-Y/AA-AB/AD, Vitamin A MedicationAdministrations for section Z, danger-signs and education Observations, and an Appointment for the next scheduled visit. It creates no Patient, Encounter or EpisodeOfCare – the register is launched from inside a visit the EMR has already opened, so all three arrive as context on the QuestionnaireResponse and are referenced rather than minted. QuestionnaireResponse.subject and .encounter are therefore both required.
/// url = 'https://fhir.slade360.co.ke/fhir/StructureMap/ExtractMOH510ImmunisationRegister' /// name = 'ExtractMOH510ImmunisationRegister' /// title = 'MOH 510 Immunisation Permanent Register Extraction' /// status = 'active' /// description = 'Extracts a transaction Bundle from a QuestionnaireResponse to the Kenya MOH 510 Immunisation Permanent Register: guardian RelatedPersons, growth-monitoring Observations, one Immunization per antigen dose for sections L-Y/AA-AB/AD, Vitamin A MedicationAdministrations for section Z, danger-signs and education Observations, and an Appointment for the next scheduled visit. It creates no Patient, Encounter or EpisodeOfCare -- the register is launched from inside a visit the EMR has already opened, so all three arrive as context on the QuestionnaireResponse and are referenced rather than minted. QuestionnaireResponse.subject and .encounter are therefore both required.' /// experimental = true uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QR as source uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias Bundle as target uses "http://hl7.org/fhir/StructureDefinition/RelatedPerson" alias RelatedPerson as target uses "http://hl7.org/fhir/StructureDefinition/Observation" alias Observation as target uses "http://hl7.org/fhir/StructureDefinition/Immunization" alias Immunization as target uses "http://hl7.org/fhir/StructureDefinition/MedicationAdministration" alias MedicationAdministration as target uses "http://hl7.org/fhir/StructureDefinition/Appointment" alias Appointment as target group ExtractMOH510ImmunisationRegister(source qr : QR, target bundle : Bundle) { qr -> bundle.type = 'transaction' "setBundleType"; // ---------------------------------------------------------------- A-K qr.item as gReg where (linkId = 'IMM-group-registration') then { // No Patient is emitted. The child is registered before the register entry // is filled, so the patient already exists and arrives as // QuestionnaireResponse.subject -- every resource below references it. // Sections C (child number), D (name), E (sex), F (date of birth) and // J (address) are the paper form transcribing demographics the EMR already // holds, so they are deliberately not extracted: creating a Patient here // would mint a duplicate record, and a blind PUT would clobber fields the // form does not carry. Reconciling them belongs in registration, not here. // This makes QuestionnaireResponse.subject mandatory for extraction -- // without it Immunization.patient (1..1) cannot be populated. gReg.item as itH where (linkId = 'IMM-RG-H-father-name') then { itH.answer first as aH then { aH -> bundle.entry as eFat, eFat.resource = create('RelatedPerson') as fat then { qr -> fat, eFat then BuildRelatedPerson(qr, itH, fat, eFat) "fatherBase"; qr -> fat.relationship as relF then { qr -> relF.coding as relFc then { qr -> relFc.system = 'http://terminology.hl7.org/CodeSystem/v3-RoleCode' "fatRelSystem"; qr -> relFc.code = 'FTH' "fatRelCode"; qr -> relFc.display = 'father' "fatRelDisplay"; } "fatherRelCoding"; } "fatherRelationship"; aH.value as v -> fat.name as nF then { v -> nF.text = v "fatherNameText"; } "fatherName"; gReg.item as itKf where (linkId = '42077-8') then { itKf.answer first as aKf then { aKf.value as v -> fat.telecom as tcF then { qr -> tcF.system = 'phone' "fatPhoneSystem"; v -> tcF.value = v "fatPhoneValue"; } "fatherTelecom"; } "fatherPhoneAnswer"; } "fatherPhoneRule"; } "fatherResource"; } "fatherAnswer"; } "fatherRule"; gReg.item as itI where (linkId = 'IMM-RG-I-mother-name') then { itI.answer first as aI then { aI -> bundle.entry as eMot, eMot.resource = create('RelatedPerson') as mot then { qr -> mot, eMot then BuildRelatedPerson(qr, itI, mot, eMot) "motherBase"; qr -> mot.relationship as relM then { qr -> relM.coding as relMc then { qr -> relMc.system = 'http://terminology.hl7.org/CodeSystem/v3-RoleCode' "motRelSystem"; qr -> relMc.code = 'MTH' "motRelCode"; qr -> relMc.display = 'mother' "motRelDisplay"; } "motherRelCoding"; } "motherRelationship"; aI.value as v -> mot.name as nM then { v -> nM.text = v "motherNameText"; } "motherName"; gReg.item as itKm where (linkId = '42077-8') then { itKm.answer first as aKm then { aKm.value as v -> mot.telecom as tcM then { qr -> tcM.system = 'phone' "motPhoneSystem"; v -> tcM.value = v "motPhoneValue"; } "motherTelecom"; } "motherPhoneAnswer"; } "motherPhoneRule"; } "motherResource"; } "motherAnswer"; } "motherRule"; } "registrationGroup"; // ------------------------------------------------------ Growth monitoring qr.item as gGrow where (linkId = 'IMM-group-growth') then { gGrow.item as itW where (linkId = 'IMM-GM-Q1-weight') then { itW.answer first as aW then { aW -> bundle.entry as eW, eW.resource = create('Observation') as obW then { qr -> obW, eW then BuildObsBase(qr, obW, eW) "weightBase"; qr -> obW then VitalSignsCategory(qr, obW) "weightCategory"; qr -> obW.code as cdW then { qr -> cdW.coding as ccW then { qr -> ccW.system = 'http://loinc.org' "wSystem"; qr -> ccW.code = '29463-7' "wCode"; qr -> ccW.display = 'Body weight' "wDisplay"; } "weightCodeCoding"; } "weightCode"; aW.value as dv -> obW.value = create('Quantity') as qW then { dv -> qW.value = dv "wQtyValue"; qr -> qW.system = 'http://unitsofmeasure.org' "wQtySystem"; qr -> qW.code = 'kg' "wQtyCode"; qr -> qW.unit = 'kilogram' "wQtyUnit"; } "weightValue"; } "weightObservation"; } "weightAnswer"; } "weightRule"; gGrow.item as itH2 where (linkId = 'IMM-GM-Q2-height') then { itH2.answer first as aH2 then { aH2 -> bundle.entry as eH2, eH2.resource = create('Observation') as obH2 then { qr -> obH2, eH2 then BuildObsBase(qr, obH2, eH2) "heightBase"; qr -> obH2 then VitalSignsCategory(qr, obH2) "heightCategory"; qr -> obH2.code as cdH2 then { qr -> cdH2.coding as ccH2 then { qr -> ccH2.system = 'http://loinc.org' "hSystem"; qr -> ccH2.code = '8302-2' "hCode"; qr -> ccH2.display = 'Body height' "hDisplay"; } "heightCodeCoding"; } "heightCode"; aH2.value as dv -> obH2.value = create('Quantity') as qH2 then { dv -> qH2.value = dv "hQtyValue"; qr -> qH2.system = 'http://unitsofmeasure.org' "hQtySystem"; qr -> qH2.code = 'cm' "hQtyCode"; qr -> qH2.unit = 'centimeter' "hQtyUnit"; } "heightValue"; } "heightObservation"; } "heightAnswer"; } "heightRule"; gGrow.item as itMu where (linkId = 'IMM-GM-Q3-muac') then { itMu.answer first as aMu then { aMu -> bundle.entry as eMu, eMu.resource = create('Observation') as obMu then { qr -> obMu, eMu then BuildObsBase(qr, obMu, eMu) "muacBase"; qr -> obMu then VitalSignsCategory(qr, obMu) "muacCategory"; qr -> obMu.code as cdMu then { qr -> cdMu.coding as ccMu then { qr -> ccMu.system = 'http://loinc.org' "muSystem"; qr -> ccMu.code = '9847-5' "muCode"; qr -> ccMu.display = 'Circumference site' "muDisplay"; } "muacCodeCoding"; } "muacCode"; qr -> obMu then SetCodedValue(itMu, obMu) "muacValue"; } "muacObservation"; } "muacAnswer"; } "muacRule"; gGrow.item as itWfa where (linkId = 'IMM-GM-Q4-weight-category') then { itWfa.answer first as aWfa then { aWfa -> bundle.entry as eWfa, eWfa.resource = create('Observation') as obWfa then { qr -> obWfa, eWfa then BuildObsBase(qr, obWfa, eWfa) "wfaBase"; qr -> obWfa then VitalSignsCategory(qr, obWfa) "wfaCategory"; qr -> obWfa.code as cdWfa then { qr -> cdWfa.coding as ccWfa then { qr -> ccWfa.system = 'http://loinc.org' "wfaSystem"; qr -> ccWfa.code = '77606-2' "wfaCode"; qr -> ccWfa.display = 'Weight-for-age percentile' "wfaDisplay"; } "wfaCodeCoding"; } "wfaCode"; qr -> obWfa then SetCodedValue(itWfa, obWfa) "wfaValue"; } "wfaObservation"; } "wfaAnswer"; } "wfaRule"; gGrow.item as itHfa where (linkId = 'IMM-GM-Q5-height-category') then { itHfa.answer first as aHfa then { aHfa -> bundle.entry as eHfa, eHfa.resource = create('Observation') as obHfa then { qr -> obHfa, eHfa then BuildObsBase(qr, obHfa, eHfa) "hfaBase"; qr -> obHfa then VitalSignsCategory(qr, obHfa) "hfaCategory"; qr -> obHfa.code as cdHfa then { qr -> cdHfa.coding as ccHfa then { qr -> ccHfa.system = 'http://loinc.org' "hfaSystem"; qr -> ccHfa.code = '59576-9' "hfaCode"; qr -> ccHfa.display = 'Height-for-age percentile' "hfaDisplay"; } "hfaCodeCoding"; } "hfaCode"; qr -> obHfa then SetCodedValue(itHfa, obHfa) "hfaValue"; } "hfaObservation"; } "hfaAnswer"; } "hfaRule"; } "growthGroup"; // ------------------------------------------------------------- L-Y vaccines qr.item as gVax where (linkId = 'IMM-group-vaccines') then { gVax.item as itL where (linkId = 'IMM-VAX-L-bcg') then { itL.answer first as aL then { aL -> bundle.entry as eL, eL.resource = create('Immunization') as imL then { qr -> imL, eL then BuildImm(qr, itL, aL, imL, eL) "bcgBase"; qr -> imL.vaccineCode as vcL then { qr -> vcL.coding as vccL then { qr -> vccL.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "bcgSystem"; qr -> vccL.code = 'bcg' "bcgCode"; qr -> vccL.display = 'BCG' "bcgDisplay"; } "bcgCoding"; qr -> vcL.text = 'BCG' "bcgText"; } "bcgVaccineCode"; qr -> imL.protocolApplied as paL then { qr -> paL.series = 'BCG' "bcgSeries"; qr -> paL.doseNumber = '1' "bcgDose"; } "bcgProtocol"; } "bcgImmunization"; } "bcgAnswer"; } "bcgRule"; gVax.item as itM where (linkId = 'IMM-VAX-M-polio-birth') then { itM.answer first as aM then { aM -> bundle.entry as eM, eM.resource = create('Immunization') as imM then { qr -> imM, eM then BuildImm(qr, itM, aM, imM, eM) "opv0Base"; qr -> imM.vaccineCode as vcM then { qr -> vcM.coding as vccM then { qr -> vccM.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "opv0System"; qr -> vccM.code = 'bopv' "opv0Code"; qr -> vccM.display = 'Bivalent oral poliovirus vaccine' "opv0Display"; } "opv0Coding"; qr -> vcM.text = 'Polio birth dose (bOPV)' "opv0Text"; } "opv0VaccineCode"; qr -> imM.protocolApplied as paM then { qr -> paM.series = 'Polio (bOPV)' "opv0Series"; qr -> paM.doseNumber = '0' "opv0Dose"; } "opv0Protocol"; } "opv0Immunization"; } "opv0Answer"; } "opv0Rule"; gVax.item as itN where (linkId = 'IMM-VAX-N-opv1') then { itN.answer first as aN then { aN -> bundle.entry as eN, eN.resource = create('Immunization') as imN then { qr -> imN, eN then BuildImm(qr, itN, aN, imN, eN) "opv1Base"; qr -> imN.vaccineCode as vcN then { qr -> vcN.coding as vccN then { qr -> vccN.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "opv1System"; qr -> vccN.code = 'bopv' "opv1Code"; qr -> vccN.display = 'Bivalent oral poliovirus vaccine' "opv1Display"; } "opv1Coding"; qr -> vcN.text = 'OPV 1' "opv1Text"; } "opv1VaccineCode"; qr -> imN.protocolApplied as paN then { qr -> paN.series = 'Polio (bOPV)' "opv1Series"; qr -> paN.doseNumber = '1' "opv1Dose"; } "opv1Protocol"; } "opv1Immunization"; } "opv1Answer"; } "opv1Rule"; gVax.item as itO where (linkId = 'IMM-VAX-O-opv2') then { itO.answer first as aO then { aO -> bundle.entry as eO, eO.resource = create('Immunization') as imO then { qr -> imO, eO then BuildImm(qr, itO, aO, imO, eO) "opv2Base"; qr -> imO.vaccineCode as vcO then { qr -> vcO.coding as vccO then { qr -> vccO.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "opv2System"; qr -> vccO.code = 'bopv' "opv2Code"; qr -> vccO.display = 'Bivalent oral poliovirus vaccine' "opv2Display"; } "opv2Coding"; qr -> vcO.text = 'OPV 2' "opv2Text"; } "opv2VaccineCode"; qr -> imO.protocolApplied as paO then { qr -> paO.series = 'Polio (bOPV)' "opv2Series"; qr -> paO.doseNumber = '2' "opv2Dose"; } "opv2Protocol"; } "opv2Immunization"; } "opv2Answer"; } "opv2Rule"; gVax.item as itP where (linkId = 'IMM-VAX-P-opv3') then { itP.answer first as aP then { aP -> bundle.entry as eP, eP.resource = create('Immunization') as imP then { qr -> imP, eP then BuildImm(qr, itP, aP, imP, eP) "opv3Base"; qr -> imP.vaccineCode as vcP then { qr -> vcP.coding as vccP then { qr -> vccP.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "opv3System"; qr -> vccP.code = 'bopv' "opv3Code"; qr -> vccP.display = 'Bivalent oral poliovirus vaccine' "opv3Display"; } "opv3Coding"; qr -> vcP.text = 'OPV 3' "opv3Text"; } "opv3VaccineCode"; qr -> imP.protocolApplied as paP then { qr -> paP.series = 'Polio (bOPV)' "opv3Series"; qr -> paP.doseNumber = '3' "opv3Dose"; } "opv3Protocol"; } "opv3Immunization"; } "opv3Answer"; } "opv3Rule"; // IPV carries its own antigen code: the questionnaire reuses the OPV LOINC // code for both, which would collapse two distinct vaccines into one. gVax.item as itQ where (linkId = 'IMM-VAX-Q-ipv') then { itQ.answer first as aQ then { aQ -> bundle.entry as eQ, eQ.resource = create('Immunization') as imQ then { qr -> imQ, eQ then BuildImm(qr, itQ, aQ, imQ, eQ) "ipvBase"; qr -> imQ.vaccineCode as vcQ then { qr -> vcQ.coding as vccQ then { qr -> vccQ.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "ipvSystem"; qr -> vccQ.code = 'ipv' "ipvCode"; qr -> vccQ.display = 'Inactivated poliovirus vaccine' "ipvDisplay"; } "ipvCoding"; qr -> vcQ.text = 'IPV' "ipvText"; } "ipvVaccineCode"; qr -> imQ.protocolApplied as paQ then { qr -> paQ.series = 'Polio (IPV)' "ipvSeries"; qr -> paQ.doseNumber = '1' "ipvDose"; } "ipvProtocol"; } "ipvImmunization"; } "ipvAnswer"; } "ipvRule"; gVax.item as itR where (linkId = 'IMM-VAX-R-penta1') then { itR.answer first as aR then { aR -> bundle.entry as eR, eR.resource = create('Immunization') as imR then { qr -> imR, eR then BuildImm(qr, itR, aR, imR, eR) "penta1Base"; qr -> imR.vaccineCode as vcR then { qr -> vcR.coding as vccR then { qr -> vccR.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "penta1System"; qr -> vccR.code = 'penta' "penta1Code"; qr -> vccR.display = 'DTP-HepB-Hib (pentavalent) vaccine' "penta1Display"; } "penta1Coding"; qr -> vcR.text = 'Pentavalent 1' "penta1Text"; } "penta1VaccineCode"; qr -> imR.protocolApplied as paR then { qr -> paR.series = 'Pentavalent' "penta1Series"; qr -> paR.doseNumber = '1' "penta1Dose"; } "penta1Protocol"; } "penta1Immunization"; } "penta1Answer"; } "penta1Rule"; gVax.item as itS where (linkId = 'IMM-VAX-S-penta2') then { itS.answer first as aS then { aS -> bundle.entry as eS, eS.resource = create('Immunization') as imS then { qr -> imS, eS then BuildImm(qr, itS, aS, imS, eS) "penta2Base"; qr -> imS.vaccineCode as vcS then { qr -> vcS.coding as vccS then { qr -> vccS.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "penta2System"; qr -> vccS.code = 'penta' "penta2Code"; qr -> vccS.display = 'DTP-HepB-Hib (pentavalent) vaccine' "penta2Display"; } "penta2Coding"; qr -> vcS.text = 'Pentavalent 2' "penta2Text"; } "penta2VaccineCode"; qr -> imS.protocolApplied as paS then { qr -> paS.series = 'Pentavalent' "penta2Series"; qr -> paS.doseNumber = '2' "penta2Dose"; } "penta2Protocol"; } "penta2Immunization"; } "penta2Answer"; } "penta2Rule"; gVax.item as itT where (linkId = 'IMM-VAX-T-penta3') then { itT.answer first as aT then { aT -> bundle.entry as eT, eT.resource = create('Immunization') as imT then { qr -> imT, eT then BuildImm(qr, itT, aT, imT, eT) "penta3Base"; qr -> imT.vaccineCode as vcT then { qr -> vcT.coding as vccT then { qr -> vccT.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "penta3System"; qr -> vccT.code = 'penta' "penta3Code"; qr -> vccT.display = 'DTP-HepB-Hib (pentavalent) vaccine' "penta3Display"; } "penta3Coding"; qr -> vcT.text = 'Pentavalent 3' "penta3Text"; } "penta3VaccineCode"; qr -> imT.protocolApplied as paT then { qr -> paT.series = 'Pentavalent' "penta3Series"; qr -> paT.doseNumber = '3' "penta3Dose"; } "penta3Protocol"; } "penta3Immunization"; } "penta3Answer"; } "penta3Rule"; gVax.item as itU where (linkId = 'IMM-VAX-U-pcv1') then { itU.answer first as aU then { aU -> bundle.entry as eU, eU.resource = create('Immunization') as imU then { qr -> imU, eU then BuildImm(qr, itU, aU, imU, eU) "pcv1Base"; qr -> imU.vaccineCode as vcU then { qr -> vcU.coding as vccU then { qr -> vccU.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "pcv1System"; qr -> vccU.code = 'pcv10' "pcv1Code"; qr -> vccU.display = 'Pneumococcal conjugate vaccine (PCV10)' "pcv1Display"; } "pcv1Coding"; qr -> vcU.text = 'PCV10 1' "pcv1Text"; } "pcv1VaccineCode"; qr -> imU.protocolApplied as paU then { qr -> paU.series = 'PCV10' "pcv1Series"; qr -> paU.doseNumber = '1' "pcv1Dose"; } "pcv1Protocol"; } "pcv1Immunization"; } "pcv1Answer"; } "pcv1Rule"; gVax.item as itV where (linkId = 'IMM-VAX-V-pcv2') then { itV.answer first as aV then { aV -> bundle.entry as eV, eV.resource = create('Immunization') as imV then { qr -> imV, eV then BuildImm(qr, itV, aV, imV, eV) "pcv2Base"; qr -> imV.vaccineCode as vcV then { qr -> vcV.coding as vccV then { qr -> vccV.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "pcv2System"; qr -> vccV.code = 'pcv10' "pcv2Code"; qr -> vccV.display = 'Pneumococcal conjugate vaccine (PCV10)' "pcv2Display"; } "pcv2Coding"; qr -> vcV.text = 'PCV10 2' "pcv2Text"; } "pcv2VaccineCode"; qr -> imV.protocolApplied as paV then { qr -> paV.series = 'PCV10' "pcv2Series"; qr -> paV.doseNumber = '2' "pcv2Dose"; } "pcv2Protocol"; } "pcv2Immunization"; } "pcv2Answer"; } "pcv2Rule"; gVax.item as itW2 where (linkId = 'IMM-VAX-W-pcv3') then { itW2.answer first as aW2 then { aW2 -> bundle.entry as eW2, eW2.resource = create('Immunization') as imW2 then { qr -> imW2, eW2 then BuildImm(qr, itW2, aW2, imW2, eW2) "pcv3Base"; qr -> imW2.vaccineCode as vcW2 then { qr -> vcW2.coding as vccW2 then { qr -> vccW2.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "pcv3System"; qr -> vccW2.code = 'pcv10' "pcv3Code"; qr -> vccW2.display = 'Pneumococcal conjugate vaccine (PCV10)' "pcv3Display"; } "pcv3Coding"; qr -> vcW2.text = 'PCV10 3' "pcv3Text"; } "pcv3VaccineCode"; qr -> imW2.protocolApplied as paW2 then { qr -> paW2.series = 'PCV10' "pcv3Series"; qr -> paW2.doseNumber = '3' "pcv3Dose"; } "pcv3Protocol"; } "pcv3Immunization"; } "pcv3Answer"; } "pcv3Rule"; gVax.item as itX where (linkId = 'IMM-VAX-X-rota1') then { itX.answer first as aX then { aX -> bundle.entry as eX, eX.resource = create('Immunization') as imX then { qr -> imX, eX then BuildImm(qr, itX, aX, imX, eX) "rota1Base"; qr -> imX.vaccineCode as vcX then { qr -> vcX.coding as vccX then { qr -> vccX.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "rota1System"; qr -> vccX.code = 'rota' "rota1Code"; qr -> vccX.display = 'Rotavirus vaccine' "rota1Display"; } "rota1Coding"; qr -> vcX.text = 'Rota 1' "rota1Text"; } "rota1VaccineCode"; qr -> imX.protocolApplied as paX then { qr -> paX.series = 'Rotavirus' "rota1Series"; qr -> paX.doseNumber = '1' "rota1Dose"; } "rota1Protocol"; } "rota1Immunization"; } "rota1Answer"; } "rota1Rule"; gVax.item as itY where (linkId = 'IMM-VAX-Y-rota2') then { itY.answer first as aY then { aY -> bundle.entry as eY, eY.resource = create('Immunization') as imY then { qr -> imY, eY then BuildImm(qr, itY, aY, imY, eY) "rota2Base"; qr -> imY.vaccineCode as vcY then { qr -> vcY.coding as vccY then { qr -> vccY.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "rota2System"; qr -> vccY.code = 'rota' "rota2Code"; qr -> vccY.display = 'Rotavirus vaccine' "rota2Display"; } "rota2Coding"; qr -> vcY.text = 'Rota 2' "rota2Text"; } "rota2VaccineCode"; qr -> imY.protocolApplied as paY then { qr -> paY.series = 'Rotavirus' "rota2Series"; qr -> paY.doseNumber = '2' "rota2Dose"; } "rota2Protocol"; } "rota2Immunization"; } "rota2Answer"; } "rota2Rule"; } "vaccineGroup"; // ------------------------------------------------- Z Vitamin A supplements qr.item as gSup where (linkId = 'IMM-group-supplementation') then { gSup.item as itZ where (linkId = '55876-9') then { itZ.answer first as aZ then { aZ -> bundle.entry as eZ, eZ.resource = create('MedicationAdministration') as maZ then { qr -> maZ, eZ then BuildMedAdmin(qr, itZ, aZ, maZ, eZ) "vitA100Base"; qr -> maZ.medication as mcrZ then { qr -> mcrZ.concept as mccZ then { qr -> mccZ.coding as mcoZ then { qr -> mcoZ.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-supplement' "vitA100System"; qr -> mcoZ.code = 'vitamin-a-100000' "vitA100Code"; qr -> mcoZ.display = 'Vitamin A 100,000 IU' "vitA100Display"; } "vitA100Coding"; qr -> mccZ.text = 'Vitamin A 100,000 IU (6-11 months)' "vitA100Text"; } "vitA100Concept"; } "vitA100Medication"; qr -> maZ.dosage as dosZ then { qr -> dosZ.dose as dqZ then { qr -> dqZ.value = 100000 "vitA100DoseValue"; qr -> dqZ.system = 'http://unitsofmeasure.org' "vitA100DoseSystem"; qr -> dqZ.code = '[IU]' "vitA100DoseCode"; qr -> dqZ.unit = 'international unit' "vitA100DoseUnit"; } "vitA100Dose"; } "vitA100Dosage"; } "vitA100Resource"; } "vitA100Answer"; } "vitA100Rule"; gSup.item as itZ2 where (linkId = '0v8mpdt') then { itZ2.answer first as aZ2 then { aZ2 -> bundle.entry as eZ2, eZ2.resource = create('MedicationAdministration') as maZ2 then { qr -> maZ2, eZ2 then BuildMedAdmin(qr, itZ2, aZ2, maZ2, eZ2) "vitA200Base"; qr -> maZ2.medication as mcrZ2 then { qr -> mcrZ2.concept as mccZ2 then { qr -> mccZ2.coding as mcoZ2 then { qr -> mcoZ2.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-supplement' "vitA200System"; qr -> mcoZ2.code = 'vitamin-a-200000' "vitA200Code"; qr -> mcoZ2.display = 'Vitamin A 200,000 IU' "vitA200Display"; } "vitA200Coding"; qr -> mccZ2.text = 'Vitamin A 200,000 IU (12 months onwards)' "vitA200Text"; } "vitA200Concept"; } "vitA200Medication"; qr -> maZ2.dosage as dosZ2 then { qr -> dosZ2.dose as dqZ2 then { qr -> dqZ2.value = 200000 "vitA200DoseValue"; qr -> dqZ2.system = 'http://unitsofmeasure.org' "vitA200DoseSystem"; qr -> dqZ2.code = '[IU]' "vitA200DoseCode"; qr -> dqZ2.unit = 'international unit' "vitA200DoseUnit"; } "vitA200Dose"; } "vitA200Dosage"; } "vitA200Resource"; } "vitA200Answer"; } "vitA200Rule"; } "supplementationGroup"; // ------------------------------------------------------ AA-AB MR1 + Yellow Fever qr.item as gMrYf where (linkId = 'IMM-group-mr-yf') then { gMrYf.item as itAa where (linkId = 'IMM-VAX-AA-mr1') then { itAa.answer first as aAa then { aAa -> bundle.entry as eAa, eAa.resource = create('Immunization') as imAa then { qr -> imAa, eAa then BuildImm(qr, itAa, aAa, imAa, eAa) "mr1Base"; qr -> imAa.vaccineCode as vcAa then { qr -> vcAa.coding as vccAa then { qr -> vccAa.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "mr1System"; qr -> vccAa.code = 'mr' "mr1Code"; qr -> vccAa.display = 'Measles-rubella vaccine' "mr1Display"; } "mr1Coding"; qr -> vcAa.text = 'MR 1' "mr1Text"; } "mr1VaccineCode"; qr -> imAa.protocolApplied as paAa then { qr -> paAa.series = 'Measles-Rubella' "mr1Series"; qr -> paAa.doseNumber = '1' "mr1Dose"; } "mr1Protocol"; } "mr1Immunization"; } "mr1Answer"; } "mr1Rule"; gMrYf.item as itAb where (linkId = 'IMM-VAX-AB-yf') then { itAb.answer first as aAb then { aAb -> bundle.entry as eAb, eAb.resource = create('Immunization') as imAb then { qr -> imAb, eAb then BuildImm(qr, itAb, aAb, imAb, eAb) "yfBase"; qr -> imAb.vaccineCode as vcAb then { qr -> vcAb.coding as vccAb then { qr -> vccAb.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "yfSystem"; qr -> vccAb.code = 'yf' "yfCode"; qr -> vccAb.display = 'Yellow fever vaccine' "yfDisplay"; } "yfCoding"; qr -> vcAb.text = 'Yellow Fever' "yfText"; } "yfVaccineCode"; qr -> imAb.protocolApplied as paAb then { qr -> paAb.series = 'Yellow Fever' "yfSeries"; qr -> paAb.doseNumber = '1' "yfDose"; } "yfProtocol"; } "yfImmunization"; } "yfAnswer"; } "yfRule"; } "mrYfGroup"; // ------------------------------------------------------------- AC FIC date qr.item as gFic where (linkId = 'IMM-group-fic') then { gFic.item as itAc where (linkId = 'IMM-FIC-AC-date') then { itAc.answer first as aAc then { aAc -> bundle.entry as eAc, eAc.resource = create('Observation') as obAc then { qr -> obAc, eAc then BuildObsBase(qr, obAc, eAc) "ficBase"; qr -> obAc then SurveyCategory(qr, obAc) "ficCategory"; qr -> obAc.code as cdAc then { qr -> cdAc.coding as ccAc then { qr -> ccAc.system = 'http://loinc.org' "ficSystem"; qr -> ccAc.code = '11369-6' "ficCode"; qr -> ccAc.display = 'Immunisation completion status' "ficDisplay"; } "ficCodeCoding"; qr -> cdAc.text = 'Fully Immunised Child (FIC) completion date' "ficCodeText"; } "ficCode"; aAc.value as dv -> obAc.value = cast(dv, 'dateTime') "ficValue"; } "ficObservation"; } "ficAnswer"; } "ficRule"; } "ficGroup"; // ------------------------------------------------------------------ AD MR2 qr.item as gMr2 where (linkId = 'IMM-group-mr2') then { gMr2.item as itAd where (linkId = 'IMM-VAX-AD-mr2') then { itAd.answer first as aAd then { aAd -> bundle.entry as eAd, eAd.resource = create('Immunization') as imAd then { qr -> imAd, eAd then BuildImm(qr, itAd, aAd, imAd, eAd) "mr2Base"; qr -> imAd.vaccineCode as vcAd then { qr -> vcAd.coding as vccAd then { qr -> vccAd.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/kepi-antigen' "mr2System"; qr -> vccAd.code = 'mr' "mr2Code"; qr -> vccAd.display = 'Measles-rubella vaccine' "mr2Display"; } "mr2Coding"; qr -> vcAd.text = 'MR 2' "mr2Text"; } "mr2VaccineCode"; qr -> imAd.protocolApplied as paAd then { qr -> paAd.series = 'Measles-Rubella' "mr2Series"; qr -> paAd.doseNumber = '2' "mr2Dose"; } "mr2Protocol"; } "mr2Immunization"; } "mr2Answer"; } "mr2Rule"; } "mr2Group"; // ------------------------------------------------------------- Danger signs qr.item as gDs where (linkId = 'IMM-group-danger-signs') then { gDs.item as itD1 where (linkId = 'IMM-DS-Q1-fever') then { itD1.answer first as aD1 then { aD1 -> bundle.entry as eD1, eD1.resource = create('Observation') as obD1 then { qr -> obD1, eD1 then BuildObsBase(qr, obD1, eD1) "feverBase"; qr -> obD1 then SurveyCategory(qr, obD1) "feverCategory"; qr -> obD1.code as cdD1 then { qr -> cdD1.coding as ccD1 then { qr -> ccD1.system = 'http://loinc.org' "feverSystem"; qr -> ccD1.code = '8310-5' "feverCode"; qr -> ccD1.display = 'Body temperature' "feverDisplay"; } "feverCodeCoding"; qr -> cdD1.text = 'Fever reported' "feverCodeText"; } "feverCode"; qr -> obD1 then SetCodedValue(itD1, obD1) "feverValue"; } "feverObservation"; } "feverAnswer"; } "feverRule"; gDs.item as itD2 where (linkId = 'IMM-DS-Q2-feeding') then { itD2.answer first as aD2 then { aD2 -> bundle.entry as eD2, eD2.resource = create('Observation') as obD2 then { qr -> obD2, eD2 then BuildObsBase(qr, obD2, eD2) "feedingBase"; qr -> obD2 then SurveyCategory(qr, obD2) "feedingCategory"; qr -> obD2.code as cdD2 then { qr -> cdD2.coding as ccD2 then { qr -> ccD2.system = 'http://loinc.org' "feedingSystem"; qr -> ccD2.code = '75890-1' "feedingCode"; qr -> ccD2.display = 'Feeding status' "feedingDisplay"; } "feedingCodeCoding"; // Polarity is inverted relative to the other danger signs: "Yes" // here is reassuring, not alarming. qr -> cdD2.text = 'Child is feeding' "feedingCodeText"; } "feedingCode"; qr -> obD2 then SetCodedValue(itD2, obD2) "feedingValue"; } "feedingObservation"; } "feedingAnswer"; } "feedingRule"; gDs.item as itD3 where (linkId = 'IMM-DS-Q3-convulsions') then { itD3.answer first as aD3 then { aD3 -> bundle.entry as eD3, eD3.resource = create('Observation') as obD3 then { qr -> obD3, eD3 then BuildObsBase(qr, obD3, eD3) "convulsionsBase"; qr -> obD3 then SurveyCategory(qr, obD3) "convulsionsCategory"; qr -> obD3.code as cdD3 then { qr -> cdD3.coding as ccD3 then { qr -> ccD3.system = 'http://loinc.org' "convulsionsSystem"; qr -> ccD3.code = '31398-4' "convulsionsCode"; qr -> ccD3.display = 'Convulsions' "convulsionsDisplay"; } "convulsionsCodeCoding"; } "convulsionsCode"; qr -> obD3 then SetCodedValue(itD3, obD3) "convulsionsValue"; } "convulsionsObservation"; } "convulsionsAnswer"; } "convulsionsRule"; gDs.item as itD4 where (linkId = 'IMM-DS-Q4-cough') then { itD4.answer first as aD4 then { aD4 -> bundle.entry as eD4, eD4.resource = create('Observation') as obD4 then { qr -> obD4, eD4 then BuildObsBase(qr, obD4, eD4) "coughBase"; qr -> obD4 then SurveyCategory(qr, obD4) "coughCategory"; qr -> obD4.code as cdD4 then { qr -> cdD4.coding as ccD4 then { qr -> ccD4.system = 'http://loinc.org' "coughSystem"; qr -> ccD4.code = '28238-4' "coughCode"; qr -> ccD4.display = 'Cough' "coughDisplay"; } "coughCodeCoding"; } "coughCode"; qr -> obD4 then SetCodedValue(itD4, obD4) "coughValue"; } "coughObservation"; } "coughAnswer"; } "coughRule"; // The questionnaire declares this SNOMED CT concept id under the LOINC // system; emitted here against the SNOMED CT system it actually belongs to. gDs.item as itD5 where (linkId = 'IMM-DS-Q5-diarrhoea') then { itD5.answer first as aD5 then { aD5 -> bundle.entry as eD5, eD5.resource = create('Observation') as obD5 then { qr -> obD5, eD5 then BuildObsBase(qr, obD5, eD5) "diarrhoeaBase"; qr -> obD5 then SurveyCategory(qr, obD5) "diarrhoeaCategory"; qr -> obD5.code as cdD5 then { qr -> cdD5.coding as ccD5 then { qr -> ccD5.system = 'http://snomed.info/sct' "diarrhoeaSystem"; qr -> ccD5.code = '28229008' "diarrhoeaCode"; qr -> ccD5.display = 'Diarrhoea' "diarrhoeaDisplay"; } "diarrhoeaCodeCoding"; } "diarrhoeaCode"; qr -> obD5 then SetCodedValue(itD5, obD5) "diarrhoeaValue"; } "diarrhoeaObservation"; } "diarrhoeaAnswer"; } "diarrhoeaRule"; gDs.item as itD6 where (linkId = 'IMM-DS-Q6-vomiting') then { itD6.answer first as aD6 then { aD6 -> bundle.entry as eD6, eD6.resource = create('Observation') as obD6 then { qr -> obD6, eD6 then BuildObsBase(qr, obD6, eD6) "vomitingBase"; qr -> obD6 then SurveyCategory(qr, obD6) "vomitingCategory"; qr -> obD6.code as cdD6 then { qr -> cdD6.coding as ccD6 then { qr -> ccD6.system = 'http://snomed.info/sct' "vomitingSystem"; qr -> ccD6.code = '21522001' "vomitingCode"; qr -> ccD6.display = 'Vomiting' "vomitingDisplay"; } "vomitingCodeCoding"; } "vomitingCode"; qr -> obD6 then SetCodedValue(itD6, obD6) "vomitingValue"; } "vomitingObservation"; } "vomitingAnswer"; } "vomitingRule"; gDs.item as itD7 where (linkId = 'IMM-DS-Q7-notes') then { itD7.answer first as aD7 then { aD7 -> bundle.entry as eD7, eD7.resource = create('Observation') as obD7 then { qr -> obD7, eD7 then BuildObsBase(qr, obD7, eD7) "dsNotesBase"; qr -> obD7 then SurveyCategory(qr, obD7) "dsNotesCategory"; qr -> obD7.code as cdD7 then { qr -> cdD7.coding as ccD7 then { qr -> ccD7.system = 'http://loinc.org' "dsNotesSystem"; qr -> ccD7.code = '48767-8' "dsNotesCode"; qr -> ccD7.display = 'Annotation comment' "dsNotesDisplay"; } "dsNotesCodeCoding"; qr -> cdD7.text = 'Danger signs clinical notes' "dsNotesCodeText"; } "dsNotesCode"; aD7.value as v -> obD7.value = v "dsNotesValue"; } "dsNotesObservation"; } "dsNotesAnswer"; } "dsNotesRule"; } "dangerSignsGroup"; // ---------------------------------------------------------- Patient education qr.item as gEd where (linkId = 'IMM-group-education') then { gEd.item as itE1 where (linkId = 'IMM-ED-Q1-education-given') then { itE1.answer first as aE1 then { aE1 -> bundle.entry as eE1, eE1.resource = create('Observation') as obE1 then { qr -> obE1, eE1 then BuildObsBase(qr, obE1, eE1) "eduGivenBase"; qr -> obE1 then SurveyCategory(qr, obE1) "eduGivenCategory"; qr -> obE1.code as cdE1 then { qr -> cdE1.coding as ccE1 then { qr -> ccE1.system = 'http://loinc.org' "eduGivenSystem"; qr -> ccE1.code = '61144-2' "eduGivenCode"; qr -> ccE1.display = 'Patient education provided' "eduGivenDisplay"; } "eduGivenCodeCoding"; } "eduGivenCode"; qr -> obE1 then SetCodedValue(itE1, obE1) "eduGivenValue"; } "eduGivenObservation"; } "eduGivenAnswer"; } "eduGivenRule"; gEd.item as itE2 where (linkId = 'IMM-ED-Q2-topics') then { itE2.answer first as aE2 then { aE2 -> bundle.entry as eE2, eE2.resource = create('Observation') as obE2 then { qr -> obE2, eE2 then BuildObsBase(qr, obE2, eE2) "eduTopicsBase"; qr -> obE2 then SurveyCategory(qr, obE2) "eduTopicsCategory"; qr -> obE2.code as cdE2 then { qr -> cdE2.coding as ccE2 then { qr -> ccE2.system = 'http://loinc.org' "eduTopicsSystem"; qr -> ccE2.code = '61144-2' "eduTopicsCode"; qr -> ccE2.display = 'Education topics covered' "eduTopicsDisplay"; } "eduTopicsCodeCoding"; qr -> cdE2.text = 'Education topics covered' "eduTopicsCodeText"; } "eduTopicsCode"; aE2.value as v -> obE2.value = v "eduTopicsValue"; } "eduTopicsObservation"; } "eduTopicsAnswer"; } "eduTopicsRule"; gEd.item as itE3 where (linkId = 'IMM-ED-Q3-next-visit') then { itE3.answer first as aE3 then { aE3 -> bundle.entry as eE3, eE3.resource = create('Observation') as obE3 then { qr -> obE3, eE3 then BuildObsBase(qr, obE3, eE3) "nextVisitToldBase"; qr -> obE3 then SurveyCategory(qr, obE3) "nextVisitToldCategory"; qr -> obE3.code as cdE3 then { qr -> cdE3.coding as ccE3 then { qr -> ccE3.system = 'http://loinc.org' "nextVisitToldSystem"; qr -> ccE3.code = '57177-3' "nextVisitToldCode"; qr -> ccE3.display = 'Follow-up plan' "nextVisitToldDisplay"; } "nextVisitToldCodeCoding"; qr -> cdE3.text = 'Next visit date communicated to caregiver' "nextVisitToldCodeText"; } "nextVisitToldCode"; qr -> obE3 then SetCodedValue(itE3, obE3) "nextVisitToldValue"; } "nextVisitToldObservation"; } "nextVisitToldAnswer"; } "nextVisitToldRule"; // Appointment.start is an instant, so a date-only answer is carried on // requestedPeriod instead. gEd.item as itE4 where (linkId = 'IMM-ED-Q4-next-visit-date') then { itE4.answer first as aE4 then { aE4 -> bundle.entry as eE4, eE4.resource = create('Appointment') as appt then { // One proposed appointment per (child, requested date). aE4.value as dvAp -> appt.identifier as idAp then { qr -> idAp.system = 'https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell' "apptCellSystem"; dvAp -> idAp.value = append('IMM-ED-Q4-next-visit-date@', dvAp) "apptCellValue"; } "apptCellIdentifier"; qr.subject as subjAp then { subjAp.reference as prefAp then { aE4.value as dvAp2 -> eE4.request as rqAp then { qr -> rqAp.method = 'POST' "apptReqMethod"; qr -> rqAp.url = 'Appointment' "apptReqUrl"; qr -> rqAp.ifNoneExist = append('actor=', prefAp, '&identifier=https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell|IMM-ED-Q4-next-visit-date@', dvAp2) "apptIfNoneExist"; } "apptReq"; } "apptPatientRef"; } "apptSubject"; qr -> appt.id = uuid() "apptId"; qr -> appt.status = 'proposed' "apptStatus"; qr -> appt.description = 'Next scheduled immunisation visit (MOH 510)' "apptDescription"; qr.subject as s -> appt.subject = s "apptSubject"; qr -> appt.participant as prt then { qr -> prt.status = 'needs-action' "apptParticipantStatus"; qr.subject as s -> prt.actor = s "apptParticipantActor"; } "apptParticipant"; aE4.value as dv -> appt.requestedPeriod as rp then { dv -> rp.start = cast(dv, 'dateTime') "apptRequestedStart"; } "apptRequestedPeriod"; } "appointmentResource"; } "nextVisitDateAnswer"; } "nextVisitDateRule"; } "educationGroup"; // ---------------------------------------------------------------- AE Remarks qr.item as gRem where (linkId = 'IMM-group-remarks') then { gRem.item as itAe where (linkId = '48767-8') then { itAe.answer first as aAe then { aAe -> bundle.entry as eAe, eAe.resource = create('Observation') as obAe then { qr -> obAe, eAe then BuildObsBase(qr, obAe, eAe) "remarksBase"; qr -> obAe then SurveyCategory(qr, obAe) "remarksCategory"; qr -> obAe.code as cdAe then { qr -> cdAe.coding as ccAe then { qr -> ccAe.system = 'http://loinc.org' "remarksSystem"; qr -> ccAe.code = '48767-8' "remarksCode"; qr -> ccAe.display = 'Annotation comment' "remarksDisplay"; } "remarksCodeCoding"; qr -> cdAe.text = 'MOH 510 register remarks' "remarksCodeText"; } "remarksCode"; aAe.value as v -> obAe.value = v "remarksValue"; } "remarksObservation"; } "remarksAnswer"; } "remarksRule"; } "remarksGroup"; } // ---------------------------------------------------------------- helper groups // Plain POST, deliberately not a conditional create. These are per-visit facts, // so the key would have to be (cell, visit) -- and qr.authored carries a // "+03:00" offset that cannot go into an ifNoneExist query string unencoded. // Consequence: extracting the SAME response twice duplicates its Observations. // Populate never fills these sections, so the populate/extract loop is // unaffected; only a repeated submission of one response is. group BuildObsBase(source qr : QR, target obs : Observation, target entry) { qr -> entry.request as rq then { qr -> rq.method = 'POST' "obsReqMethod"; qr -> rq.url = 'Observation' "obsReqUrl"; } "obsReq"; qr -> obs.id = uuid() "obsId"; qr -> obs.status = 'final' "obsStatus"; qr.subject as s -> obs.subject = s "obsSubject"; qr.encounter as e -> obs.encounter = e "obsEncounter"; qr.authored as t -> obs.effective = t "obsEffective"; // qr.id is already type-qualified ("QuestionnaireResponse/1008") when the // response is read from the server, so prepending the type -- or using // reference() -- yields a doubled reference. qr.id as qid -> obs.derivedFrom = create('Reference') as dr then { qid -> dr.reference = qid "obsDerivedRef"; } "obsDerivedFrom"; } // A register cell -- (child, column) -- is the natural key for everything below. // The paper form has exactly one BCG box per child, so re-submitting a // pre-populated form must not add a second one. Each resource therefore carries // its linkId as a business identifier and is emitted as a conditional create. group BuildImm(source qr : QR, source it, source a, target imm : Immunization, target entry) { it.linkId as lk -> imm.identifier as idc then { qr -> idc.system = 'https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell' "immCellSystem"; lk -> idc.value = lk "immCellValue"; } "immCellIdentifier"; qr.subject as subjImm then { subjImm.reference as pref then { it.linkId as lk2 -> entry.request as rq then { qr -> rq.method = 'POST' "immReqMethod"; qr -> rq.url = 'Immunization' "immReqUrl"; qr -> rq.ifNoneExist = append('patient=', pref, '&identifier=https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell|', lk2) "immIfNoneExist"; } "immReq"; } "immPatientRef"; } "immSubject"; qr -> imm.id = uuid() "immId"; qr -> imm.status = 'completed' "immStatus"; // Register entries are transcribed from the child's card, so the recording // facility is not necessarily the administering one. qr -> imm.primarySource = false "immPrimarySource"; qr.subject as s -> imm.patient = s "immPatient"; qr.encounter as e -> imm.encounter = e "immEncounter"; a.value as dv -> imm.occurrence = cast(dv, 'dateTime') "immOccurrence"; } group BuildMedAdmin(source qr : QR, source it, source a, target ma : MedicationAdministration, target entry) { it.linkId as lk -> ma.identifier as idc then { qr -> idc.system = 'https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell' "maCellSystem"; lk -> idc.value = lk "maCellValue"; } "maCellIdentifier"; qr.subject as subjMa then { subjMa.reference as pref then { it.linkId as lk2 -> entry.request as rq then { qr -> rq.method = 'POST' "maReqMethod"; qr -> rq.url = 'MedicationAdministration' "maReqUrl"; qr -> rq.ifNoneExist = append('subject=', pref, '&identifier=https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell|', lk2) "maIfNoneExist"; } "maReq"; } "maPatientRef"; } "maSubject"; qr -> ma.id = uuid() "maId"; qr -> ma.status = 'completed' "maStatus"; qr.subject as s -> ma.subject = s "maSubject"; qr.encounter as e -> ma.encounter = e "maEncounter"; a.value as dv -> ma.occurence = cast(dv, 'dateTime') "maOccurence"; } group BuildRelatedPerson(source qr : QR, source it, target rp : RelatedPerson, target entry) { it.linkId as lk -> rp.identifier as idc then { qr -> idc.system = 'https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell' "rpCellSystem"; lk -> idc.value = lk "rpCellValue"; } "rpCellIdentifier"; qr.subject as subjRp then { subjRp.reference as pref then { it.linkId as lk2 -> entry.request as rq then { qr -> rq.method = 'POST' "rpReqMethod"; qr -> rq.url = 'RelatedPerson' "rpReqUrl"; qr -> rq.ifNoneExist = append('patient=', pref, '&identifier=https://fhir.slade360.co.ke/fhir/Identifier/moh510-register-cell|', lk2) "rpIfNoneExist"; } "rpReq"; } "rpPatientRef"; } "rpSubject"; qr -> rp.id = uuid() "rpId"; qr -> rp.active = true "rpActive"; qr.subject as s -> rp.patient = s "rpPatient"; } group VitalSignsCategory(source qr : QR, target obs : Observation) { qr -> obs.category as cat then { qr -> cat.coding as c then { qr -> c.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "vsCatSystem"; qr -> c.code = 'vital-signs' "vsCatCode"; qr -> c.display = 'Vital Signs' "vsCatDisplay"; } "vsCatCoding"; } "vsCat"; } group SurveyCategory(source qr : QR, target obs : Observation) { qr -> obs.category as cat then { qr -> cat.coding as c then { qr -> c.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "svCatSystem"; qr -> c.code = 'survey' "svCatCode"; qr -> c.display = 'Survey' "svCatDisplay"; } "svCatCoding"; } "svCat"; } group SetCodedValue(source it : Element, target obs : Observation) { it.answer as a -> obs.value = create('CodeableConcept') as c then { a.value as coding -> c.coding = coding as nc "copyCoding"; } "setCodedValue"; }