A Developer's Guide to the ORUR01 Message
Given below is a detailed OURR01 message which maps between OpenMRS data and the relevant hl7 segments.
This message contains an Obs group with seven observations.
<ORU_R01 xmlns="urn:hl7-org:v2xml">
<MSH>
<MSH.1>|</MSH.1> <!-- This is the field seperator. It is a constant. The user should NOT be allowed to change it-->
<MSH.2>^~\&</MSH.2> <!-- Thease are the encoding characcters. The user should NOT be allowed to change it-->
<MSH.4>
<HD.1>hl7source.name</HD.1> <!--The hl7source specified here must exist in the receivers hl7source table--> <!-- use a module setting/gp for this -->
</MSH.4>
<MSH.6>
<HD.1>Sending Faculty</HD.1> <!-- The Sending faculty. This is implementation specific. it represents the implementation site. use a module setting/gp for this -->
</MSH.6>
<MSH.7>
<TS.1>new Date()</TS.1> <!--A time stamp representing when this message was created -->
</MSH.7>
<MSH.9>
<MSG.1>ORU</MSG.1> <!-- The Message type. It is a constant for this type of message-->
<MSG.2>R01</MSG.2> <!-- The message event. It is a constant for this type of message -->
<MSG.3>ORU_R01</MSG.3> <!-- The message structure. It is a constant for this type of message -->
</MSH.9>
<MSH.10>UUID.randomUUID().toString()</MSH.10> <!-- The message control ID-->
<MSH.11>
<PT.1>D</PT.1> <!-- Processing Id. It is a constant/hardcoded -->
<PT.2>C</PT.2> <!-- Processing mode. It is a constant/hardcoded-->
</MSH.11>
<MSH.12>
<VID.1>2.5</VID.1> <!-- The hl7 version im using. It is a constant. I DONT think the user should be allowed to change this, because it may affect the message structure -->
<VID.2>
<CE.1>RWA</CE.1> <!-- The internationalization code. For jembi purposes, this is a fixed constant of RWA, what to use for a generic one? -->
</VID.2>
</MSH.12>
<MSH.21>
<EI.1>CLSM_V0.83</EI.1> <!-- The Message profile identifier : A constant, as proposed by Grahame. Who determines this? -->
</MSH.21>
</MSH>
<ORU_R01.PATIENT_RESULT>
<ORU_R01.PATIENT>
<PID>
<PID.1>1</PID.1> <!--Set ID - PID. It is a hardcoded -->
<PID.3> <!-- PID.3 segments represent patient identifier and identifier type pairs. They can be repeated -->
<CX.1>patient.patientIdentifier.identifier</CX.1> <!-- displays the id number -->
<CX.5>patient.patientIdentifierType.name</CX.5> <!-- displays the name of the identifier type -->
</PID.3>
<PID.5> <!-- PID.3 segments represent several names that a patient may have. They can be repeated -->
<XPN.1>
<FN.1>patient.getFamilyName()</FN.1>
</XPN.1>
<XPN.2>patient.getGivenName()</XPN.2>
</PID.5>
</PID>
<!-- Note: The PID segment should also include the patient's address (Repeatable), sex, race, country code and telephone numbers. Jembi are not using these segments. However, they may be of use to others -->
<ORU_R01.VISIT>
<PV1>
<PV1.2>0</PV1.2> <!-- The patient class. It is a hardcoded -->
<PV1.3>
<PL.1>encounter.getLocation().getUuid()</PL.1>
<PL.4>
<HD.1>encounter.getLocation().getName()</HD.1>
</PL.4>
</PV1.3>
<PV1.4>encounter.getEncounterType().getName()</PV1.4>
<PV1.7>
<XCN.1>encounter.getProvider().getUuid()</XCN.1>
<XCN.2>
<FN.1>encounter.getProvider().getFamilyName()</FN.1>
</XCN.2>
<XCN.3>encounter.getProvider().getGivenName()</XCN.3>
<XCN.13>NID</XCN.13> <!-- This is the identifier type name of the identifier we will use to identify the provider. The user will be allowed to set it -->
</PV1.7>
<PV1.44>
<TS.1>encounter.getEncounterDatetime()</TS.1> <!-- The date the visit took place -->
</PV1.44>
</PV1>
</ORU_R01.VISIT>
</ORU_R01.PATIENT>
<ORU_R01.ORDER_OBSERVATION>
<OBR> <!-- The First OBR segment will represent the encounter. There will be one of these per each message -->
<OBR.1>0</OBR.1>
<OBR.3>
<EI.1>encounter.getUuid()</EI.1>
</OBR.3>
<OBR.4>
<CE.2>encounter.getEncounterType().getName()</CE.2> <!-- The encounter type -->
</OBR.4>
<OBR.7>
<TS.1>encounter.getEncounterDatetime()</TS.1>
</OBR.7>
<OBR.16>
<XCN.1>encounter.getProvider().getUuid()</XCN.1> <!-- Question. Which ID type should we use here ? -->
<XCN.2>
<FN.1>encounter.getProvider().getFamilyName()</FN.1>
</XCN.2>
<XCN.3>encounter.getProvider().getGivenName()</XCN.3>
</OBR.16>
<OBR.20>encounter.getLocation().getUuid()</OBR.20>
<OBR.21>encounter.getLocation().getName()</OBR.21>
</OBR>
</ORU_R01.ORDER_OBSERVATION>
<ORU_R01.ORDER_OBSERVATION>
<OBR> <!-- Additional OBR segments will be used to represent each Obs group -->
<OBR.1>1</OBR.1>
<OBR.4> <!-- This is the concept source id, the concept name and the concept source name of the obs grouper -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBR.4>
<OBR.18>0</OBR.18>
<OBR.29>
<EIP.2>
<EI.3>encounter.getUuid()</EI.3>
</EIP.2>
</OBR.29>
</OBR>
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>0</OBX.1> <!-- This is the 1st Observation comming under this encounter -->
<OBX.2>HL7Constants.HL7_NUMERIC</OBX.2> <!-- This is a constant from the core HL7Constants.java class. Here, since the concept type is numeric, it's value is 'NM'-->
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<OBX.5>obs.getValueNumeric()</OBX.5>
<OBX.6>
<CE.1>conceptNumeric.getUnits()</CE.1> <!-- Since the concept type is numeric, we get to do this -->
<CE.3>UCUM</CE.3> <!-- Unit coding system. It is a constant. The user should NOT be allowed to change it-->
</OBX.6>
<OBX.14>
<TS.1>obs.getDateCreated()</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>1</OBX.1> <!-- This is the 2nd Observation comming under this encounter -->
<OBX.2>NM</OBX.2>
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<OBX.3>
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<OBX.5>34.0</OBX.5>
<OBX.6>
<CE.1>conceptNumeric.getUnits()</CE.1>
<CE.3>UCUM</CE.3>
</OBX.6>
<OBX.14>
<TS.1>20120712114812</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>2</OBX.1> <!-- This is the 3rd Observation comming under this encounter -->
<OBX.2>NM</OBX.2>
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<OBX.5>34.0</OBX.5>
<OBX.6>
<CE.1>conceptNumeric.getUnits()</CE.1>
<CE.3>UCUM</CE.3>
</OBX.6>
<OBX.14>
<TS.1>20120712114812</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
<!-- Lets see what an Observation with A coded concept looks like -->
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>3</OBX.1> <!-- This is the 4th Observation comming under this encounter -->
<OBX.2>CE</OBX.2>
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<!--OBX.5 stores the value of the Observation. In this case, it is a Concept. Therefore, we are storing the concept name, Concept source code and the source name-->
<OBX.5>
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.5>
<OBX.14>
<TS.1>20120712114812</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>4</OBX.1> <!-- This is the 5th Observation comming under this encounter -->
<OBX.2>NM</OBX.2>
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<OBX.5>34.0</OBX.5>
<OBX.6>
<CE.1>conceptNumeric.getUnits()</CE.1>
<CE.3>UCUM</CE.3>
</OBX.6>
<OBX.14>
<TS.1>20120712114812</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>5</OBX.1> <!-- This is the 6th Observation comming under this encounter -->
<OBX.2>NM</OBX.2>
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<OBX.5>34.0</OBX.5>
<OBX.6>
<CE.1>conceptNumeric.getUnits()</CE.1>
<CE.3>UCUM</CE.3>
</OBX.6>
<OBX.14>
<TS.1>20120712114812</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
<ORU_R01.OBSERVATION>
<OBX>
<OBX.1>6</OBX.1> <!-- This is the 7th Observation comming under this encounter -->
<OBX.2>NM</OBX.2>
<OBX.3> <!-- OBX.3 segments are used to share the concept name, mapping and ID. There can be only one OBX.3 segment per OBX -->
<!-- So assume we do this :
Collection<ConceptMap> conceptMappings = ob.getConcept().getConceptMappings();
Iterator<ConceptMap> itr = conceptMappings.iterator();
ConceptMap map = itr.next();
Then, -->
<CE.1>map.getSourceCode()</CE.1>
<CE.2>obs.getConcept().getName().toString()</CE.2>
<CE.3>map.getSource().getName()</CE.3>
</OBX.3>
<OBX.5>34.0</OBX.5>
<OBX.6>
<CE.1>conceptNumeric.getUnits()</CE.1>
<CE.3>UCUM</CE.3>
</OBX.6>
<OBX.14>
<TS.1>20120712114812</TS.1>
</OBX.14>
</OBX>
</ORU_R01.OBSERVATION>
</ORU_R01.ORDER_OBSERVATION>
</ORU_R01.PATIENT_RESULT>
</ORU_R01>