Narratif généré : StructureMap Q2FSL #xD; map "https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureMap/Q2FSL" = "Q2FSL"#xD; #xD; // Transforms QuestionnaireResponse based on Questionnaire Usage Variables socles into FHIR resources conforming to DM profiles#xD; #xD; uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source#xD; uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias Bundle as target#xD; #xD; // Main entry point: Transform QuestionnaireResponse to Bundle#xD; group QuestionnaireResponseToBundle(source src : QuestionnaireResponse, target bundle : Bundle) {#xD; // Initialize Bundle#xD; src -> bundle.id = uuid() "bundleid";#xD; src -> bundle.type = 'collection' "bundletype";#xD; src -> bundle.timestamp = (now()) "setTimestamp";#xD; // Create Patient resource#xD; src -> bundle.entry as patientEntry then {#xD; src -> patientEntry.resource = create('Patient') as patient then {#xD; src then CreatePatient(src, patient) "createpatient";#xD; src -> patient.id as patientId, patientEntry.fullUrl = append('urn:uuid:', patientId) "setfullUrl";#xD; // Create Locations from geocoding data#xD; // src then CreateLocations(src, patient, bundle) "create-locations";#xD; // Create Encounters from PMSI data#xD; src then CreateEncounters(src, patient, bundle) "createencounters";#xD; // Create Laboratory Observations#xD; src then CreateLaboratoryObservations(src, patient, bundle) "createlabobservations";#xD; // Create Medication Requests#xD; src then CreateMedicationRequests(src, patient, bundle) "createmedicationrequests";#xD; // Create Medication Administrations#xD; src then CreateMedicationAdministrations(src, patient, bundle) "createmedicationadministrations";#xD; // Create Vital Sign Observations#xD; src then CreateVitalSignObservations(src, patient, bundle) "createvitalsigns";#xD; } "createpatientresource";#xD; } "patiententry";#xD; }#xD; #xD; // Group: Create Patient from QuestionnaireResponse#xD; group CreatePatient(source src : QuestionnaireResponse, target patient : Patient) {#xD; src -> patient.id = uuid() "patientid";#xD; src -> patient.meta = create('Meta') as meta then {#xD; src -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-patient' "patientprofile";#xD; } "patientmeta";#xD; // Extract patient identity data from linkId 4647259356106 > 2958000860428#xD; src.item as socioDemo where (linkId = '4647259356106') then {#xD; socioDemo.item as identity where (linkId = '2958000860428') then {#xD; // Patient name (linkId 8605698058770 = family, 6214879623503 = given)#xD; identity -> patient.name = create('HumanName') as name then {#xD; identity.item as familyItem where (linkId = '8605698058770') then {#xD; familyItem.answer as ans -> name.family = (%ans.valueString) "setfamily";#xD; } "extractfamily";#xD; identity.item as givenItem where (linkId = '6214879623503') then {#xD; givenItem.answer as ans -> name.given = (%ans.valueString) "setgiven";#xD; } "extractgiven";#xD; } "setname";#xD; // NIR identifier (linkId 5711960356160)#xD; identity.item as nirItem where (linkId = '5711960356160') then {#xD; nirItem.answer as ans -> patient.identifier = create('Identifier') as nir then {#xD; ans -> nir.system = 'urn:oid:1.2.250.1.213.1.4.8' "nirsystem";#xD; ans -> nir.value = (%ans.valueString) "nirvalue";#xD; ans -> nir.type = cc('http://interopsante.org/fhir/CodeSystem/fr-v2-0203', 'NIR') "nirtype";#xD; } "setnir";#xD; } "extractnir";#xD; // INS identifier (linkId 3764723550987)#xD; identity.item as insItem where (linkId = '3764723550987') then {#xD; insItem.answer as ans -> patient.identifier = create('Identifier') as ins then {#xD; ans -> ins.system = 'urn:oid:1.2.250.1.213.1.4.10' "inssystem";#xD; ans -> ins.value = (%ans.valueString) "insvalue";#xD; ans -> ins.type = cc('http://interopsante.org/fhir/CodeSystem/fr-v2-0203', 'INS-C') "instype";#xD; } "setins";#xD; } "extractins";#xD; // Birth date (linkId 5036133558154)#xD; identity.item as birthItem where (linkId = '5036133558154') then {#xD; birthItem.answer as ans -> patient.birthDate = (%ans.valueDate) "setbirthdate";#xD; } "extractbirthdate";#xD; // Death date (linkId 5633552097315)#xD; identity.item as deathItem where (linkId = '5633552097315') then {#xD; deathItem.answer as ans -> patient.deceased = (%ans.valueDate) "setdeceaseddate";#xD; // Death source (linkId 9098810065693)#xD; deathItem.item as deathSource where (linkId = '9098810065693') then {#xD; deathSource.answer as sourceAns -> patient.extension = create('Extension') as ext then {#xD; sourceAns -> ext.url = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-death-source' "deathsourceurl";#xD; sourceAns -> ext.value = (%sourceAns.valueCoding) "deathsourcevalue";#xD; } "setdeathsourceext";#xD; } "extractdeathsource";#xD; } "extractdeath";#xD; // Multiple birth rank (linkId 6931296968515)#xD; identity.item as multipleItem where (linkId = '6931296968515') then {#xD; multipleItem.answer as ans -> patient.multipleBirth = (%ans.valueInteger) "setmultiplebirth";#xD; } "extractmultiplebirth";#xD; } "processidentity";#xD; // Gender from PMSI data (linkId 3894630481120 within 2825244231605)#xD; src.item as pmsiGroup where (linkId = '2825244231605') then {#xD; pmsiGroup.item as sexItem where (linkId = '3894630481120') then {#xD; sexItem.answer as ans then {#xD; ans.valueString as female where ($this = 'f') -> patient.gender = 'female' "setGenderF";#xD; ans.valueString as female where ($this = 'm') -> patient.gender = 'male' "setGenderM";#xD; } "valueCoding";#xD; } "extractgender";#xD; // Address from code géographique (linkId 2446369196222)#xD; pmsiGroup.item as codeGeoItem where (linkId = '2446369196222') then {#xD; codeGeoItem.answer as ans -> patient.address = create('Address') as addr then {#xD; ans -> addr.extension = create('Extension') as ext then {#xD; ans -> ext.url = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-pmsi-code-geo' "codegeourl";#xD; ans.value as val -> ext.value = cast(val, 'code') "codegeovalue";#xD; } "setcodegeoext";#xD; // Environnement#xD; socioDemo.item as environnementItem where (linkId = '5491974639955') then {#xD; // geolocation#xD; environnementItem.item as geocodageItem where (linkId = '3816475533472') -> addr.extension = create('Extension') as geolocationExt then {#xD; geocodageItem.item as latItem where (linkId = '3709843054556') -> geolocationExt.url = 'http://hl7.org/fhir/StructureDefinition/geolocation', geolocationExt.extension = create('Extension') as latExt then {#xD; latItem.answer as lat -> latExt.url = 'latitude', latExt.value = (%lat.valueDecimal) then {#xD; geocodageItem.item as longItem where (linkId = '7651448032665') -> geolocationExt.extension = create('Extension') as longExt then {#xD; longItem.answer as long -> longExt.url = 'longitude', longExt.value = (%long.valueDecimal) "setLong";#xD; } "createLongExt";#xD; } "setLat";#xD; } "createLatExt";#xD; } "createGeolocExt";#xD; // IRIS#xD; environnementItem.item as irisItem where (linkId = '7621032273792') -> addr.line as addrLine, addrLine.extension = create('Extension') as irisExt then {#xD; irisItem.answer as ans -> irisExt.url = 'http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-censusTract', irisExt.valueString = (%ans.valueString) "setIrisExt";#xD; } "navIrisItem";#xD; } "navEnv";#xD; } "setaddress";#xD; } "extractcodegeo";#xD; } "extractpmsidemographics";#xD; } "processsociodemographics";#xD; }#xD; #xD; // Group: Create Locations from geocoding and IRIS data#xD; group CreateLocations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) {#xD; // Extract geocoding data from linkId 4647259356106 > 5491974639955 > 3816475533472#xD; src.item as socioDemo where (linkId = '4647259356106') then {#xD; socioDemo.item as environment where (linkId = '5491974639955') then {#xD; // Geocoding locations (repeating group 3816475533472)#xD; environment.item as geocodingItem where (linkId = '3816475533472') -> bundle.entry as locationEntry then {#xD; geocodingItem -> locationEntry.resource = create('Location') as location then {#xD; geocodingItem -> location.id = uuid() "locationid";#xD; geocodingItem -> location.meta = create('Meta') as meta then {#xD; geocodingItem -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-location' "locationprofile";#xD; } "locationmeta";#xD; // Position with latitude and longitude#xD; geocodingItem -> location.position = create('LocationPosition') as pos then {#xD; // Latitude (linkId 3709843054556)#xD; geocodingItem.item as latItem where (linkId = '3709843054556') then {#xD; latItem.answer as ans -> pos.latitude = (%ans.valueDecimal) "setlatitude";#xD; } "extractlatitude";#xD; // Longitude (linkId 7651448032665)#xD; geocodingItem.item as longItem where (linkId = '7651448032665') then {#xD; longItem.answer as ans -> pos.longitude = (%ans.valueDecimal) "setlongitude";#xD; } "extractlongitude";#xD; } "setposition";#xD; // Extension for collection date (linkId 1185653257776)#xD; // geocodingItem.item as dateItem where (linkId = '1185653257776') then { dateItem.answer as ans -> location.extension = create('Extension') as ext then { ans -> ext.url = 'http://hl7.org/fhir/StructureDefinition/data-collection-date' "date-url"; ans -> ext.value = (%ans.valueDate) "date-value"; } "set-collection-date"; } "extract-collection-date";#xD; location -> locationEntry.request as request then {#xD; location -> request.method = 'POST' "setmethod";#xD; location -> request.url = 'Location' "seturl";#xD; } "setrequest";#xD; location.id as locId -> locationEntry.fullUrl = append('urn:uuid:', locId) "setfullUrl";#xD; } "createlocation";#xD; } "geocodinglocationentry";#xD; // IRIS locations (repeating item 7621032273792)#xD; environment.item as irisItem where (linkId = '7621032273792') then {#xD; irisItem.answer as irisAnswer -> bundle.entry as locationEntry then {#xD; irisAnswer -> locationEntry.resource = create('Location') as location then {#xD; irisAnswer -> location.id = uuid() "locationid";#xD; irisAnswer -> location.meta = create('Meta') as meta then {#xD; irisAnswer -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-location' "locationprofile";#xD; } "locationmeta";#xD; // IRIS code as identifier#xD; irisAnswer -> location.identifier = create('Identifier') as identifier then {#xD; irisAnswer -> identifier.system = 'urn:oid:2.16.840.1.113883.2.8.1.5.5' "irissystem";#xD; irisAnswer -> identifier.value = (%irisAnswer.valueCoding.code) "irisvalue";#xD; } "setirisidentifier";#xD; // Collection date from nested item (linkId 4999580038872)#xD; // irisAnswer.item as dateItem where (linkId = '4999580038872') then { dateItem.answer as ans -> location.extension = create('Extension') as ext then { ans -> ext.url = 'http://hl7.org/fhir/StructureDefinition/data-collection-date' "date-url"; ans -> ext.value = (%ans.valueDate) "date-value"; } "set-collection-date"; } "extract-iris-date";#xD; location -> locationEntry.request as request then {#xD; location -> request.method = 'POST' "setmethod";#xD; location -> request.url = 'Location' "seturl";#xD; } "setrequest";#xD; location.id as locId -> locationEntry.fullUrl = append('urn:uuid:', locId) "setfullUrl";#xD; } "createirislocation";#xD; } "irislocationentry";#xD; } "processiris";#xD; } "processenvironment";#xD; } "processsociodemographicslocation";#xD; }#xD; #xD; // Group: Create Encounters from PMSI data#xD; group CreateEncounters(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) {#xD; // PMSI data group (linkId 2825244231605) - Note: This can repeat in the structure#xD; src.item as pmsiItem where (linkId = '2825244231605') -> bundle.entry as encounterEntry then {#xD; pmsiItem -> encounterEntry.resource = create('Encounter') as encounter then {#xD; pmsiItem -> encounter.id = uuid() "encounterid";#xD; pmsiItem -> encounter.meta = create('Meta') as meta then {#xD; pmsiItem -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-encounter' "encounterprofile";#xD; } "encountermeta";#xD; // status#xD; src -> encounter.status = 'finished' "setStatus";#xD; // class#xD; src -> encounter.class = c('http://terminology.hl7.org/CodeSystem/v3-ActCode', 'IMP') "setClass";#xD; // Link to patient#xD; src -> encounter.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Encounter period (start: 5991443718282, end: 6114780320846)#xD; pmsiItem -> encounter.period = create('Period') as period then {#xD; pmsiItem.item as startItem where (linkId = '5991443718282') then {#xD; startItem.answer as ans -> period.start = (%ans.valueDate) "setstart";#xD; } "extractstart";#xD; pmsiItem.item as endItem where (linkId = '6114780320846') then {#xD; endItem.answer as ans -> period.end = (%ans.valueDate) "setend";#xD; } "extractend";#xD; } "setperiod";#xD; // Mode d'entrée (linkId 6172398101212)#xD; pmsiItem.item as modeInItem where (linkId = '6172398101212') then {#xD; modeInItem.answer as ans then {#xD; ans.valueString as valueString -> encounter.hospitalization as hosp, hosp.admitSource as admitSource, admitSource.coding as admitSourceCoding, admitSourceCoding.code = valueString "setadmitsource";#xD; } "navValue";#xD; } "extractmodein";#xD; // Mode de sortie (linkId 3354867075704)#xD; pmsiItem.item as modeOutItem where (linkId = '3354867075704') then {#xD; modeOutItem.answer as ans then {#xD; ans.valueString as valueString -> encounter.hospitalization as hosp, hosp.dischargeDisposition as dischargeDisposition, dischargeDisposition.coding as dischargeDispositionCoding, dischargeDispositionCoding.code = valueString "setdischargedisposition";#xD; } "navValue";#xD; } "extractmodeout";#xD; src -> encounter.id as encId, encounterEntry.fullUrl = append('urn:uuid:', encId) "setfullUrl";#xD; // Create nested Conditions and Procedures#xD; pmsiItem then CreateConditions(pmsiItem, patient, encounter, bundle) "createconditions";#xD; pmsiItem then CreateProcedures(pmsiItem, patient, encounter, bundle) "createprocedures";#xD; } "createencounter";#xD; } "encounterentry";#xD; }#xD; #xD; // Group: Create Conditions from nested diagnostics#xD; group CreateConditions(source pmsiItem, target patient : Patient, target encounter : Encounter, target bundle : Bundle) {#xD; // Diagnostics group (linkId 9391816419630) - can repeat#xD; pmsiItem.item as diagGroup where (linkId = '9391816419630') -> bundle.entry as conditionEntry then {#xD; diagGroup -> conditionEntry.resource = create('Condition') as condition then {#xD; diagGroup -> condition.id = uuid() "conditionid";#xD; diagGroup -> condition.meta = create('Meta') as meta then {#xD; diagGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-condition' "conditionprofile";#xD; } "conditionmeta";#xD; // Link to patient#xD; diagGroup -> condition.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Link to encounter#xD; diagGroup -> encounter.id as encId, condition.encounter = create('Reference') as ref, ref.reference = append('Encounter/', encId) "setencounter";#xD; // Diagnostic code (linkId 5505101189372) - CIM-10#xD; diagGroup.item as diagCodeItem where (linkId = '5505101189372') then {#xD; diagCodeItem.answer as ans -> condition.code = create('CodeableConcept') as code then {#xD; ans -> code.coding as coding, coding.code = (%ans.valueString) "setcoding";#xD; } "setcode";#xD; } "extractdiagcode";#xD; // Type de diagnostic (linkId 6427586743735) - DP/DAS/DR#xD; diagGroup.item as diagTypeItem where (linkId = '6427586743735') then {#xD; diagTypeItem.answer as ans -> condition.category = create('CodeableConcept') as category then {#xD; ans -> category.coding = create('Coding') as coding then {#xD; ans -> coding.system = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/CodeSystem/pmsi-mco-diag-type' "diagtypesystem";#xD; ans -> coding.code = (%ans.valueString) "diagtypecode";#xD; } "setcategorycoding";#xD; } "setcategory";#xD; } "extractdiagtype";#xD; // Recorded date (linkId 7114466839467)#xD; diagGroup.item as dateItem where (linkId = '7114466839467') then {#xD; dateItem.answer as ans -> condition.recordedDate = (%ans.valueDate) "setrecordeddate";#xD; } "extractrecordeddate";#xD; // fullurl#xD; pmsiItem -> condition.id as condId, conditionEntry.fullUrl = append('urn:uuid:', condId) "setfullUrl";#xD; } "createcondition";#xD; } "conditionentry";#xD; }#xD; #xD; // Group: Create Procedures from nested actes#xD; group CreateProcedures(source pmsiItem, target patient : Patient, target encounter : Encounter, target bundle : Bundle) {#xD; // Actes group (linkId 591926901726) - can repeat#xD; pmsiItem.item as acteGroup where (linkId = '591926901726') -> bundle.entry as procedureEntry then {#xD; acteGroup -> procedureEntry.resource = create('Procedure') as procedure then {#xD; acteGroup -> procedure.id = uuid() "procedureid";#xD; acteGroup -> procedure.meta = create('Meta') as meta then {#xD; acteGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-procedure' "procedureprofile";#xD; } "proceduremeta";#xD; // status#xD; acteGroup -> procedure.status = 'completed' "setStatus";#xD; // Link to patient#xD; acteGroup -> procedure.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Link to encounter#xD; acteGroup -> encounter.id as encId, procedure.encounter = create('Reference') as ref, ref.reference = append('Encounter/', encId) "setencounter";#xD; // Acte code (linkId 7758110033600) - CCAM#xD; acteGroup.item as acteCodeItem where (linkId = '7758110033600') then {#xD; acteCodeItem.answer as ans -> procedure.code = create('CodeableConcept') as code then {#xD; ans -> code.coding as coding, coding.code = (%ans.valueString) "setcoding";#xD; } "setcode";#xD; } "extractactecode";#xD; // Date de l'acte (linkId 5066866286682)#xD; acteGroup.item as dateItem where (linkId = '5066866286682') then {#xD; dateItem.answer as ans -> procedure.performed = (%ans.valueDateTime) "setperformed";#xD; } "extractperformeddate";#xD; // fullurl#xD; pmsiItem -> procedure.id as procId, procedureEntry.fullUrl = append('urn:uuid:', procId) "setfullUrl";#xD; } "createprocedure";#xD; } "procedureentry";#xD; }#xD; #xD; // Group: Create Medication Requests#xD; group CreateMedicationRequests(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) {#xD; // Exposition médicamenteuse (linkId 817801935685)#xD; src.item as medExpoGroup where (linkId = '817801935685') then {#xD; // Médicament prescrit (linkId 156631794800) - repeating#xD; medExpoGroup.item as prescribedGroup where (linkId = '156631794800') -> bundle.entry as medReqEntry then {#xD; prescribedGroup -> medReqEntry.resource = create('MedicationRequest') as medReq then {#xD; prescribedGroup -> medReq.id = uuid() "medreqid";#xD; // fullurl#xD; src -> medReq.id as medReqId, medReqEntry.fullUrl = append('urn:uuid:', medReqId) "setfullUrl";#xD; prescribedGroup -> medReq.meta = create('Meta') as meta then {#xD; prescribedGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-medication-request' "medreqprofile";#xD; } "medreqmeta";#xD; // Link to patient#xD; prescribedGroup -> medReq.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Status and intent#xD; prescribedGroup -> medReq.status = 'active' "setstatus";#xD; prescribedGroup -> medReq.intent = 'order' "setintent";#xD; // MedicationCodeableConcept#xD; prescribedGroup.answer as prescribedMedication then {#xD; prescribedMedication.item as atcItem where (linkId = '1923143398283') then {#xD; atcItem.answer as ans -> medReq.medication = create('CodeableConcept') as medReqCC, medReqCC.coding as medReqC, medReqC.code = (%ans.valueString), medReqC.display = (%prescribedMedication.valueString) "setAtcCoding";#xD; } "navAtcItem";#xD; } "navPrescribedMedication";#xD; // Create Medication resource and reference#xD; // prescribedGroup -> bundle.entry as medEntry then { prescribedGroup -> medEntry.resource = create('Medication') as medication then { prescribedGroup -> medication.id = uuid() "med-id"; // ATC code from nested items prescribedGroup.item as atcItem where (linkId.contains('ATC')) then { atcItem.answer as ans -> medication.code = create('CodeableConcept') as code then { ans -> code.coding = (%ans.valueCoding) "set-atc-coding"; } "set-med-code"; } "extract-atc"; prescribedGroup -> medication.id as medId, medEntry.fullUrl = append('urn:uuid:', medId) "set-fullUrl"; // Link MedicationRequest to Medication prescribedGroup -> medication.id as medId, medReq.medication = create('Reference') as ref, ref.reference = append('Medication/', medId) "set-medication-reference"; } "create-medication"; } "medication-entry";#xD; // Dosage instructions#xD; prescribedGroup -> medReq.dosageInstruction = create('Dosage') as dosage then {#xD; // Route#xD; prescribedGroup.answer as prescribedMedication then {#xD; prescribedMedication.item as routeItem where (linkId = '387026794874') then {#xD; routeItem.answer as ans -> dosage.route as route then {#xD; ans -> route.coding as routeCoding, routeCoding.code = (%ans.valueString) "setroutecoding";#xD; } "setroute";#xD; } "navRouteItem";#xD; } "navPrescribedMedication";#xD; // Timing#xD; medExpoGroup.item as posoGroup where (linkId = '6348237104421') -> dosage.timing as timing, timing.repeat as timingRepeat, timingRepeat.boundsPeriod as timingPeriod then {#xD; posoGroup.item as DateDebItem where (linkId = '316347573327') then {#xD; DateDebItem.answer as ans -> timingPeriod.start = (%ans.valueDate) "setDateDeb";#xD; } "navDateDeb";#xD; posoGroup.item as DateFinItem where (linkId = '429570775935') then {#xD; DateFinItem.answer as ans -> timingPeriod.end = (%ans.valueDate) "setDateFin";#xD; } "navDateFin";#xD; } "navPoso";#xD; } "setdosage";#xD; } "createmedreq";#xD; } "medreqentry";#xD; } "processmedexpo";#xD; }#xD; #xD; // Group: Create Medication Administrations#xD; group CreateMedicationAdministrations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) {#xD; // Exposition médicamenteuse (linkId 817801935685)#xD; src.item as medExpoGroup where (linkId = '817801935685') then {#xD; // Médicament administré (linkId 266852453304) - repeating#xD; medExpoGroup.item as adminGroup where (linkId = '266852453304') -> bundle.entry as medAdminEntry then {#xD; adminGroup -> medAdminEntry.resource = create('MedicationAdministration') as medAdmin then {#xD; adminGroup -> medAdmin.id = uuid() "medadminid";#xD; // fullurl#xD; src -> medAdmin.id as medAdminId, medAdminEntry.fullUrl = append('urn:uuid:', medAdminId) "setfullUrl";#xD; adminGroup -> medAdmin.meta = create('Meta') as meta then {#xD; adminGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-medication-administration' "medadminprofile";#xD; } "medadminmeta";#xD; // Link to patient#xD; adminGroup -> medAdmin.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Status#xD; adminGroup -> medAdmin.status = 'completed' "setstatus";#xD; // MedicationCodeableConcept#xD; adminGroup.answer as administeredMedication then {#xD; administeredMedication.item as atcItem where (linkId = '631972144976') then {#xD; atcItem.answer as ans -> medAdmin.medication = create('CodeableConcept') as medAdminCC, medAdminCC.coding as medAdminC, medAdminC.code = (%ans.valueString), medAdminC.display = (%administeredMedication.valueString) "setAtcCoding";#xD; } "navAtcItem";#xD; } "navadministeredMedication";#xD; // Create Medication resource and reference#xD; // adminGroup -> bundle.entry as medEntry then { adminGroup -> medEntry.resource = create('Medication') as medication then { adminGroup -> medication.id = uuid() "med-id"; // ATC code from nested items adminGroup.item as atcItem where (linkId.contains('ATC')) then { atcItem.answer as ans -> medication.code = create('CodeableConcept') as code then { ans -> code.coding = (%ans.valueCoding) "set-atc-coding"; } "set-med-code"; } "extract-atc"; adminGroup -> medication.id as medId, medEntry.fullUrl = append('Medication/', medId) "set-fullUrl"; // Link MedicationAdministration to Medication adminGroup -> medication.id as medId, medAdmin.medication = create('Reference') as ref, ref.reference = append('urn:uuid:', medId) "set-medication-reference"; } "create-medication"; } "medication-entry";#xD; // Dosage (FHIR)#xD; adminGroup -> medAdmin.dosage as dosage then {#xD; // Route#xD; adminGroup.answer as administeredMedication then {#xD; administeredMedication.item as routeItem where (linkId = '811931484859') then {#xD; routeItem.answer as ans -> dosage.route = create('CodeableConcept') as route then {#xD; ans -> route.coding as routeCoding, routeCoding.code = (%ans.valueString) "setroutecoding";#xD; } "setroute";#xD; } "navRoute";#xD; } "navadministeredMedication";#xD; // Dosage (QR)#xD; medExpoGroup.item as doseGroup where (linkId = '5720103839343') then {#xD; // Dose#xD; doseGroup.item as quantityItem where (linkId = '4765772671997') then {#xD; quantityItem.answer as ans -> dosage.dose = (%ans.valueQuantity) "setDose";#xD; } "navquantity";#xD; // Effective period#xD; doseGroup.item as startItem where (linkId = '1443558617577') then {#xD; startItem.answer as startAns then {#xD; doseGroup.item as endItem where (linkId = '780829110731') then {#xD; endItem.answer as endAns -> medAdmin.effectivePeriod as adminPeriod, adminPeriod.start = (%startAns.value), adminPeriod.end = (%endAns.value) "setAdminPeriod";#xD; } "navEnd";#xD; } "navStartAns";#xD; } "navStart";#xD; } "navDosage";#xD; } "setdosage";#xD; } "createmedadmin";#xD; } "medadminentry";#xD; } "processmedexpoadmin";#xD; }#xD; #xD; // Group: Create Vital Sign Observations#xD; group CreateVitalSignObservations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) {#xD; // Examen clinique (linkId 214880328197)#xD; src.item as examGroup where (linkId = '214880328197') then {#xD; // Dossier de soins (linkId 305831246173) - repeating#xD; examGroup.item as dossierGroup where (linkId = '305831246173') then {#xD; // Height (linkId 4846902346416)#xD; dossierGroup.item as heightItem where (linkId = '4846902346416') then {#xD; heightItem.answer as ans -> bundle.entry as obsEntry then {#xD; ans -> obsEntry.resource = create('Observation') as obs then {#xD; ans -> obs.id = uuid() "obsid";#xD; ans -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl";#xD; ans -> obs.meta = create('Meta') as meta then {#xD; ans -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-observation-body-height' "obsprofile";#xD; } "obsmeta";#xD; ans -> obs.status = 'final' "obsstatus";#xD; ans -> obs.category = cc('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs') "obscategory";#xD; ans -> obs.code = cc('http://loinc.org', '8302-2', 'Body height') "obscode";#xD; // Link to patient#xD; ans -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Value#xD; ans -> obs.value = (%ans.valueQuantity) as tgtObsVal, tgtObsVal.code = (%ans.valueQuantity.unit), tgtObsVal.system = 'http://unitsofmeasure.org' "setvalue";#xD; // Effective date from nested item#xD; ans.item as dateItem where (linkId = '941821315470') then {#xD; dateItem.answer as dateAns then {#xD; dateAns.value as val -> obs.effective = cast(val, 'dateTime') "seteffective";#xD; } "navDateAns";#xD; } "extracteffective";#xD; } "createheightobs";#xD; } "heightobsentry";#xD; } "extractheight";#xD; // Weight (linkId 451513217936)#xD; dossierGroup.item as weightItem where (linkId = '451513217936') then {#xD; weightItem.answer as ans -> bundle.entry as obsEntry then {#xD; ans -> obsEntry.resource = create('Observation') as obs then {#xD; ans -> obs.id = uuid() "obsid";#xD; ans -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl";#xD; ans -> obs.meta = create('Meta') as meta then {#xD; ans -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-observation-body-weight' "obsprofile";#xD; } "obsmeta";#xD; ans -> obs.status = 'final' "obsstatus";#xD; ans -> obs.category = cc('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs') "obscategory";#xD; ans -> obs.code = cc('http://loinc.org', '29463-7', 'Body weight') "obscode";#xD; // Link to patient#xD; ans -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Value#xD; ans -> obs.value = (%ans.valueQuantity) as tgtObsVal, tgtObsVal.code = (%ans.valueQuantity.unit), tgtObsVal.system = 'http://unitsofmeasure.org' "setvalue";#xD; // Effective date from nested item#xD; ans.item as dateItem where (linkId = '151269044052') then {#xD; dateItem.answer as dateAns then {#xD; dateAns.value as val -> obs.effective = cast(val, 'dateTime') "seteffective";#xD; } "navDateAns";#xD; } "extracteffective";#xD; } "createweightobs";#xD; } "weightobsentry";#xD; } "extractweight";#xD; // Blood Pressure - need both systolic and diastolic#xD; dossierGroup.item as sysItem where (linkId = '4160905247955') then {#xD; sysItem.answer as sysAns then {#xD; dossierGroup.item as diaItem where (linkId = '848797127998') then {#xD; diaItem.answer as diaAns -> bundle.entry as obsEntry then {#xD; sysAns -> obsEntry.resource = create('Observation') as obs then {#xD; sysAns -> obs.id = uuid() "obsid";#xD; sysAns -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl";#xD; sysAns -> obs.meta = create('Meta') as meta then {#xD; sysAns -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-observation-blood-pressure' "obsprofile";#xD; } "obsmeta";#xD; sysAns -> obs.status = 'final' "obsstatus";#xD; sysAns -> obs.category = cc('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs') "obscategory";#xD; sysAns -> obs.code = cc('http://loinc.org', '85354-9', 'Blood pressure panel') "obscode";#xD; // Link to patient#xD; sysAns -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Systolic component#xD; sysAns -> obs.component as sysComp then {#xD; sysAns -> sysComp.code = cc('http://loinc.org', '8480-6', 'Systolic blood pressure') "syscode";#xD; sysAns -> sysComp.value = (%sysAns.valueQuantity) as sysVal, sysVal.code = (%sysAns.valueQuantity.unit), sysVal.system = 'http://unitsofmeasure.org' "sysvalue";#xD; } "setsystolic";#xD; // Diastolic component#xD; diaAns -> obs.component as diaComp then {#xD; diaAns -> diaComp.code = cc('http://loinc.org', '8462-4', 'Diastolic blood pressure') "diacode";#xD; diaAns -> diaComp.value = (%diaAns.valueQuantity) as diaVal, diaVal.code = (%diaAns.valueQuantity.unit), diaVal.system = 'http://unitsofmeasure.org' "diavalue";#xD; } "setdiastolic";#xD; // Effective date from nested item#xD; sysAns.item as sysDateItem where (linkId = '987654638442') then {#xD; sysDateItem.answer as dateAns then {#xD; dateAns.value as val -> obs.effective = cast(val, 'dateTime') "seteffective";#xD; } "navDateAns";#xD; } "navDate";#xD; } "createbpobs";#xD; } "bpobsentr";#xD; } "extractdiastolic";#xD; } "processsystolic";#xD; } "extractbloodpressure";#xD; } "processdossier";#xD; } "processexam";#xD; }#xD; #xD; // Group: Create Laboratory Observations#xD; group CreateLaboratoryObservations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) {#xD; // Biologie group (linkId 7702944131447)#xD; src.item as bioGroup where (linkId = '7702944131447') then {#xD; // Fonction rénale (linkId 5241323453538)#xD; bioGroup.item as renalGroup where (linkId = '5241323453538') then {#xD; // Urée (linkId 7169026818760)#xD; renalGroup.item as ureaItem where (linkId = '7169026818760') then {#xD; ureaItem.answer as ans -> bundle then CreateLabObservation(ans, ureaItem, patient, bundle) "createureaobs";#xD; } "extracturea";#xD; // Créatininémie (linkId 500408205043)#xD; renalGroup.item as creatItem where (linkId = '500408205043') then {#xD; creatItem.answer as ans -> bundle then CreateLabObservation(ans, creatItem, patient, bundle) "createcreatobs";#xD; } "extractcreat";#xD; // DFG (linkId 786621340679)#xD; renalGroup.item as dfgItem where (linkId = '786621340679') then {#xD; dfgItem.answer as ans -> bundle then CreateLabObservation(ans, dfgItem, patient, bundle) "createdfgobs";#xD; } "extractdfg";#xD; } "processrenal";#xD; // Hémogramme (linkId 419282985970)#xD; bioGroup.item as hemoGroup where (linkId = '419282985970') then {#xD; // Leucocytes (linkId 210077225604)#xD; hemoGroup.item as leukoItem where (linkId = '210077225604') then {#xD; leukoItem.answer as ans -> bundle then CreateLabObservation(ans, leukoItem, patient, bundle) "createleukoobs";#xD; } "extractleuko";#xD; // Hémoglobine (linkId 304159088493)#xD; hemoGroup.item as hemoItem where (linkId = '304159088493') then {#xD; hemoItem.answer as ans -> bundle then CreateLabObservation(ans, hemoItem, patient, bundle) "createhemoobs";#xD; } "extracthemo";#xD; // Hématocrite (linkId 813863316705)#xD; hemoGroup.item as hematItem where (linkId = '813863316705') then {#xD; hematItem.answer as ans -> bundle then CreateLabObservation(ans, hematItem, patient, bundle) "createhematobs";#xD; } "extracthemat";#xD; // Erythrocytes (linkId 459731866614)#xD; hemoGroup.item as eryItem where (linkId = '459731866614') then {#xD; eryItem.answer as ans -> bundle then CreateLabObservation(ans, eryItem, patient, bundle) "createeryobs";#xD; } "extractery";#xD; // VGM (linkId 163624088831)#xD; hemoGroup.item as vgmItem where (linkId = '163624088831') then {#xD; vgmItem.answer as ans -> bundle then CreateLabObservation(ans, vgmItem, patient, bundle) "createvgmobs";#xD; } "extractvgm";#xD; // Plaquettes (linkId 794156787471)#xD; hemoGroup.item as platItem where (linkId = '794156787471') then {#xD; platItem.answer as ans -> bundle then CreateLabObservation(ans, platItem, patient, bundle) "createplatobs";#xD; } "extractplat";#xD; // Neutrophiles (linkId 961905168477)#xD; hemoGroup.item as neutItem where (linkId = '961905168477') then {#xD; neutItem.answer as ans -> bundle then CreateLabObservation(ans, neutItem, patient, bundle) "createneutobs";#xD; } "extractneut";#xD; // Lymphocytes (linkId 695150914696)#xD; hemoGroup.item as lymphItem where (linkId = '695150914696') then {#xD; lymphItem.answer as ans -> bundle then CreateLabObservation(ans, lymphItem, patient, bundle) "createlymphobs";#xD; } "extractlymph";#xD; // Eosinophiles (linkId 700490326748)#xD; hemoGroup.item as eosiItem where (linkId = '700490326748') then {#xD; eosiItem.answer as ans -> bundle then CreateLabObservation(ans, eosiItem, patient, bundle) "createeosiobs";#xD; } "extracteosi";#xD; // Monocytes (linkId 168661900522)#xD; hemoGroup.item as monoItem where (linkId = '168661900522') then {#xD; monoItem.answer as ans -> bundle then CreateLabObservation(ans, monoItem, patient, bundle) "createmonoobs";#xD; } "extractmono";#xD; // TP (linkId 658898841893)#xD; hemoGroup.item as tpItem where (linkId = '658898841893') then {#xD; tpItem.answer as ans -> bundle then CreateLabObservation(ans, tpItem, patient, bundle) "createtpobs";#xD; } "extracttp";#xD; // TCA (linkId 795145096241)#xD; hemoGroup.item as tcaItem where (linkId = '795145096241') then {#xD; tcaItem.answer as ans -> bundle then CreateLabObservation(ans, tcaItem, patient, bundle) "createtcaobs";#xD; } "extracttca";#xD; } "processhemo";#xD; // Bilan hépatique (linkId 796308115381)#xD; bioGroup.item as liverGroup where (linkId = '796308115381') then {#xD; // ASAT (linkId 715226319725)#xD; liverGroup.item as asatItem where (linkId = '715226319725') then {#xD; asatItem.answer as ans -> bundle then CreateLabObservation(ans, asatItem, patient, bundle) "createasatobs";#xD; } "extractasat";#xD; // ALAT (linkId 876439410327)#xD; liverGroup.item as alatItem where (linkId = '876439410327') then {#xD; alatItem.answer as ans -> bundle then CreateLabObservation(ans, alatItem, patient, bundle) "createalatobs";#xD; } "extractalat";#xD; // GGT (linkId 287545455976)#xD; liverGroup.item as ggtItem where (linkId = '287545455976') then {#xD; ggtItem.answer as ans -> bundle then CreateLabObservation(ans, ggtItem, patient, bundle) "createggtobs";#xD; } "extractggt";#xD; // PAL (linkId 508269571594)#xD; liverGroup.item as palItem where (linkId = '508269571594') then {#xD; palItem.answer as ans -> bundle then CreateLabObservation(ans, palItem, patient, bundle) "createpalobs";#xD; } "extractpal";#xD; // Bilirubine totale (linkId 927344090061)#xD; liverGroup.item as bilTotItem where (linkId = '927344090061') then {#xD; bilTotItem.answer as ans -> bundle then CreateLabObservation(ans, bilTotItem, patient, bundle) "createbiltotobs";#xD; } "extractbiltot";#xD; // Bilirubine conjuguée (linkId 208196328453)#xD; liverGroup.item as bilConjItem where (linkId = '208196328453') then {#xD; bilConjItem.answer as ans -> bundle then CreateLabObservation(ans, bilConjItem, patient, bundle) "createbilconjobs";#xD; } "extractbilconj";#xD; } "processliver";#xD; // Métabolisme glucidique (linkId 334039497382)#xD; bioGroup.item as glucoseGroup where (linkId = '334039497382') then {#xD; // Glycémie à jeun (linkId 273778921448)#xD; glucoseGroup.item as glycItem where (linkId = '273778921448') then {#xD; glycItem.answer as ans -> bundle then CreateLabObservation(ans, glycItem, patient, bundle) "createglycobs";#xD; } "extractglyc";#xD; // HbA1c (linkId 632894677152)#xD; glucoseGroup.item as hba1cItem where (linkId = '632894677152') then {#xD; hba1cItem.answer as ans -> bundle then CreateLabObservation(ans, hba1cItem, patient, bundle) "createhba1cobs";#xD; } "extracthba1c";#xD; } "processglucose";#xD; } "processbiology";#xD; }#xD; #xD; // Helper: Create a single Laboratory Observation#xD; group CreateLabObservation(source ans, source parentItem, target patient : Patient, target bundle : Bundle) {#xD; ans -> bundle.entry as obsEntry then {#xD; ans -> obsEntry.resource = create('Observation') as obs then {#xD; ans -> obs.id = uuid() "obsid";#xD; ans -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl";#xD; ans -> obs.meta = create('Meta') as meta then {#xD; ans -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/dm-observation-laboratory-generic' "obsprofile";#xD; } "obsmeta";#xD; // Status#xD; ans -> obs.status = 'final' "obsstatus";#xD; // Category#xD; ans -> obs.category = create('CodeableConcept') as cat then {#xD; ans -> cat.coding = create('Coding') as coding then {#xD; ans -> coding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catsystem";#xD; ans -> coding.code = 'laboratory' "catcode";#xD; } "setcategorycoding";#xD; } "setcategory";#xD; // Link to patient#xD; ans -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject";#xD; // Value as Quantity#xD; ans -> obs.value = (%ans.valueQuantity) as tgtObsVal, tgtObsVal.code = (%ans.valueQuantity.unit), tgtObsVal.system = 'http://unitsofmeasure.org' "setvalue";#xD; // Extract nested items - LOINC code, effective date, status, reference ranges#xD; // LOINC code#xD; ans.item as loincItem where (text.contains('code loinc')) then {#xD; loincItem.answer as loincAns -> obs.code as code, code.coding as coding, coding.code = (%loincAns.valueString) "setloinccoding";#xD; } "extractloinc";#xD; // effectiveDateTime#xD; ans.item as dateItem where (text.contains('Date et heure du prélèvement')) then {#xD; dateItem.answer as dateAns -> obs.effective = (%dateAns.valueDateTime) "seteffective";#xD; } "extracteffective";#xD; // parentItem.item as statusItem where (linkId.contains('Statut de validation')) then { statusItem.answer as statusAns -> obs.extension = create('Extension') as ext then { statusAns -> ext.url = 'http://hl7.org/fhir/StructureDefinition/observation-status' "status-url"; statusAns -> ext.value = (%statusAns.valueString) "status-value"; } "set-status-ext"; } "extract-validation-status";#xD; // Reference ranges (low and high)#xD; ans -> obs.referenceRange as refRange then {#xD; ans.item as lowItem where (text.contains('Borne inférieure')) then {#xD; lowItem.answer as lowAns -> refRange.low = (%lowAns.valueQuantity) as tgtLow, tgtLow.code = (%ans.valueQuantity.unit), tgtLow.system = 'http://unitsofmeasure.org' "setlow";#xD; } "extractlow";#xD; ans.item as highItem where (text.contains('Borne supérieure')) then {#xD; highItem.answer as highAns -> refRange.high = (%highAns.valueQuantity) as tgtHigh, tgtHigh.code = (%ans.valueQuantity.unit), tgtHigh.system = 'http://unitsofmeasure.org' "sethigh";#xD; } "extracthigh";#xD; } "setrefrange";#xD; } "createobs";#xD; } "obsentry";#xD; }#xD; #xD;
Transforms QuestionnaireResponse based on Questionnaire Usage Variables socles into FHIR resources conforming to DM profiles
Main entry point: Transform QuestionnaireResponse to Bundle
Group: Create Patient from QuestionnaireResponse
Group: Create Locations from geocoding and IRIS data
Group: Create Conditions from nested diagnostics
Group: Create Procedures from nested actes
Group: Create Medication Administrations
Helper: Create a single Laboratory Observation
(text.contains('Date et heure du prélèvement'))