This topic contains 15 replies, has 3 voices, and was last updated by  tony.manivong 7 years, 1 month ago.

Parse multiple OBR segments into seperate messages

  • Hello. I’ve tested batch processing using batch.lua, but not the result I need due to the message structure. Batch.lua is looking for multiple MSH segments. The messages I am working contains multiple OBR with a single MSH segment.

    INBOUND
    MSH|^~\&|SMral|SMeCal|RapidRad|Imaging|20160331173829||ORM^O01|201603311738996|T|2.3
    PID|1|731dad0c-0029-4283|||Arthur^King||19520801|M|||1660 A St^^Lakewood^CO^80215
    PV1|1|O|CO00013^15^^Allison Care Center&CO00013
    ORC|NW|2016012700004|||||||20160128000339|2015097-001|||||20160128000000
    OBR|1|2016012700004||76977^BONEDENSITY|||201601280000||||||||||||||||||||^^^^^R||||
    DG1|1|||Pain in Foot
    OBR|2|2016012700004||93308^ECHO2D LIM|||201601280000||||||||||||||||||||^^^^^R||||
    DG1|1|||Pain in Foot

    Result Output:
    OUTBOUND
    MSH|^~\&|SMral|SMeCal|RapidRad|Imaging|20160331173829||ORM^O01|201603311738996|T|2.3
    PID|1|731dad0c-0029-4283|||Arthur^King||19520801|M|||1660 A St^^Lakewood^CO^80215
    PV1|1|O|CO00013^15^^Allison Care Center&CO00013
    ORC|NW|2016012700004|||||||20160128000339|2015097-001|||||20160128000000
    OBR|1|2016012700004||76977^BONEDENSITY|||201601280000||||||||||||||||||||^^^^^R||||
    DG1|1|||Pain in Foot

    MSH|^~\&|SMral|SMeCal|RapidRad|Imaging|20160331173829||ORM^O01|201603311738996|T|2.3
    PID|1|731dad0c-0029-4283|||Arthur^King||19520801|M|||1660 A St^^Lakewood^CO^80215
    PV1|1|O|CO00013^15^^Allison Care Center&CO00013
    OBR|2|2016012700004||93308^ECHO2D LIM|||201601280000||||||||||||||||||||^^^^^R||||
    DG1|1|||Pain in Foot

    you’re using wrong example. your message is not HL7 batch message. your message is *single* HL7 message with multiple observations. it is *not* HL7 batch message, nor it is a batch of HL7 messages. in this case use simple loop; to loop on repetitions of observation segments group.

    Hi Tony,

    Here’s a bit of additional detail…

    Assuming you’ve built an inbound message structure with VMStudio that accommodates the repeating nature of the OBR/DG1 segments (see the attaached jpg for the grammar used with the code below), you’ll first need to populate an outbound message with all of the elements that remain the same (the MSH/PID/PV1/ORC segments), then loop through the repeating OBR/DG1 group to populate each message’s OBR and DG1 segments. The last instructions in the loop will be to call queue.push() to send each resulting message to the downstream system and clear the OBR/DG1 group structure in preparation for the next pass through the loop.

    function main(Data)
       local msgIn,msgType = hl7.parse{vmd="TestOrder.vmd",data=Data}
       local msgOut = hl7.message{vmd="TestOrder.vmd",name="Order"}
       msgOut.MSH:mapTree(msgIn.MSH)
       msgOut.PID:mapTree(msgIn.PID)
       msgOut.PV1:mapTree(msgIn.PV1)
       msgOut.ORC:mapTree(msgIn.ORC)
       for i=1,#msgIn.ObrGrp do
          msgOut.ObrGrp[1].OBR:mapTree(msgIn.ObrGrp[i].OBR)
          -- DG1 segments may repeat, so loop through them
          for j=1,#msgIn.ObrGrp[i].DG1 do
             msgOut.ObrGrp[1].DG1[j]:mapTree(msgIn.ObrGrp[i].DG1[j])
          end
          queue.push{data=msgOut:S()}
          msgOut:remove("ObrGrp") -- reset the structure for the next iteration
       end
    end
    

    The code above is very basic and doesn’t do some of the other things you’ll likely need to do (such as make the MSH-10 value unique so the receiving system doesn’t think it’s getting duplicate messages), but it does demonstrate how you would replicate a repeating group of segments into distinct outbound messages.

    Attachments:
    You must be logged in to view attached files.

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    Thanks, Jeff.

    I’m getting this error message:
    ‘OBR’ member does not exist. Named members are SET ID -OBR, Placer Order Number,…………..

    Attachments:
    You must be logged in to view attached files.

    If the .jpg you attached shows the grammar used for the incoming message, one issue you have is that ObrGrp is not configured as a repeating group (it would have either <> or {} symbols around its name; the former for optional, the latter for required).

    You can use the same VMD for the outbound message, but you’ll only be populating the first group. That’s why you see references to outMsg.ObrGrp[1]… in the code I posted.

    If fixing the VMD doesn’t help, post the Lua code from your translator and we may be able to figure this out.

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    Tony, I recommend to open Support ticket with support@interfaceware.com. This could be a more efficient channel for helping detailed coding questions for specific project.

    Hey Jeff,

    I updated it to repeating group. I will set up the outbound vmd here in a minute and let you know. Appreciate the help!

    Looks like no additional changes are required. Output as expected!

    Really appreciate the help,Jeff! Thanks, again.

    My pleasure, Tony.

    I got to thinking about the solution I posted and came to the conclusion that old habits die really, really hard. I work with multiple integration engines, and some of them enforce patterns that aren’t necessarily as efficient with Iguana. The code I posted above could be shortened pretty dramatically to the following:

    function main(Data)
       local msgIn,msgType = hl7.parse{vmd="TestOrder.vmd",data=Data}
       local msgOut = hl7.message{vmd="TestOrder.vmd",name="Order"}
       msgOut:mapTree(msgIn) -- map the entire message
       for i=1,#msgIn.ObrGrp do -- loop through repeating group
          msgOut:remove("ObrGrp") -- clear all OBR groups in the target message
          msgOut.ObrGrp[1]:mapTree(msgIn.ObrGrp[i]) -- copy each to target 1st iter.
          queue.push{data=msgOut:S()} -- send the message on
       end
    end
    

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    Hey Jeff,

    I’m getting an error message, “attempt to index global ‘out’ (a nil value)”. I am trying to add an IN1 segment that doesn’t exist in the original message and also change PV1.4.

    function main(Data)
    local msgIn,msgType = hl7.parse{vmd=”Test2.vmd”,data=Data}
    local msgOut = hl7.message{vmd=”Test2.vmd”,name=”ORM”}
    –local MSH = orig.MSH[3]:nodeValue()
    msgOut:mapTree(msgIn) — map the entire message
    –out.IN1[3]=’PrimaryPayer’
    out.IN1[16][1]=Orig.PID[5][1]
    out.IN1[16][2]=Orig.PID[5][2]
    out.IN1[16][3]=Orig.PID[5][3]
    out.IN1[18]=Orig.PID[5][1]
    out.IN1[36]=”
    out.IN1[43][1]=Orig.PID[7]
    msgOut.ORC:mapTree(msgIn.ORC)
    out.PV1[4]=’Division1′

    for i=1,#msgIn.ObrGrp do
    msgOut.ObrGrp[1].OBR:mapTree(msgIn.ObrGrp[i].OBR)
    — DG1 segments may repeat, so loop through them
    for j=1,#msgIn.ObrGrp[i].DG1 do
    msgOut.ObrGrp[1].DG1[j]:mapTree(msgIn.ObrGrp[i].DG1[j])
    end
    queue.push{data=msgOut:S()}
    msgOut:remove(“ObrGrp”) — reset the structure for the next iteration
    end
    end

    Hi Tony,

    You need to add the IN1 segment to the OUTBOUND message structure in VMDStudio, and reference it as msgOut.IN1 rather than out.IN1.

    Apologies for the brevity, I’m composing this on a smartphone 🙂

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    IN1 segment was added in VMDStudio and updated in Iguana Translator.

    function main(Data)
    local msgIn,msgType = hl7.parse{vmd=”Test.vmd”,data=Data}
    local msgOut = hl7.message{vmd=”Test.vmd”,name=”ORM”}
    –local MSH = orig.MSH[3]:nodeValue()
    msgOut:mapTree(msgIn) — map the entire message
    –out.IN1[3]=’Payer1′
    msgOut.IN1[16][1]=Orig.PID[5][1]
    msgOut.IN1[16][2]=Orig.PID[5][2]
    msgOut.IN1[16][3]=Orig.PID[5][3]
    msgOut.IN1[18]=Orig.PID[5][1]
    msgOut.IN1[36]=”
    msgOut.IN1[43][1]=Orig.PID[7]
    msgOut.ORC:mapTree(msgIn.ORC)
    msgOut.PV1[4]=’Division1′
    for i=1,#msgIn.ObrGrp do
    msgOut.ObrGrp[1].OBR:mapTree(msgIn.ObrGrp[i].OBR)
    — DG1 segments may repeat, so loop through them
    for j=1,#msgIn.ObrGrp[i].DG1 do
    msgOut.ObrGrp[1].DG1[j]:mapTree(msgIn.ObrGrp[i].DG1[j])
    end
    queue.push{data=msgOut:S()}
    msgOut:remove(“ObrGrp”) — reset the structure for the next iteration
    end
    end

    Attachments:
    You must be logged in to view attached files.

    Can I assume everything is working ok now? 🙂

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    I wish. The IN1 segment was already in the OUTBOUND message structure in VMDStudio when I got the error message.

    I’m pretty sure you’re not getting the exact same error message you were getting before; can you share what you’re seeing now?

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    Hey Jeff,

    Sorry, I’ve been traveling and haven’t had a chance to get back on this project until this morning. The previous issues are now resolved. Again, I truly appreciate the help.

    The only issue I’m running into now is the NTE segment. This segment may not be present in every message and if it is present, may contain more than 1 NTE within the ObrGrp. The NTE segment is included in the vmd as an optional repeating segment under the group ‘ObrGrp’.

    2 Issues with it:
    1. If there is no NTE segment, the message is ignored
    2. The message translates if the NTE segment is present, but if there is more than one NTE – the first message includes all the segments and OBR|1 and leaves out NTE|2. The second outbound message, it leaves out OBR|2 and NTE|1. Basically a repeat of 1 and 2 in messages 3 and 4, except it is for OBR|2 and NTE|2.

    Example for issue 2:
    Inbound:
    MSH|^~\&|TESTSYSTEM|TESTSYSTEM|TOTESTSYSTEM|Imaging|20160415203730||ORM^O01|201604152037462|T|2.3
    PID|1|d7980233-39f6|||Duck^Daffy||19420402|M|||52 West Unit Drive^^Sneads^FL^32460-4165|||||||123456789
    PV1|1|O|FL0XX1^55^^APAL&FL00001
    ORC|NW|2016041501001|||||||20160416023631|Electronic||1891929857^ABANO^JOHN||^^^^^^8507180577|20160416000000
    OBR|1|2016041501001||3117^FOOT LT 3V*|R||201604160000|||||||||1891929857^ABANO^JOHN|||||||||||||||^Non-Ambulatory – Fall Risk/Fell|||||||||||||73630
    NTE|1||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER.
    NTE|2||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER TEST TEST TEST.
    DG1|1|||Pain in Ankle
    DG1|2|||Pain in Foot
    OBR|2|2016041501001||3063^ANKLE LT 3V*|R||201604160000|||||||||1891929857^ABANO^JOHN|||||||||||||||^Non-Ambulatory – Fall Risk/Fell|||||||||||||73610
    NTE|1||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER.
    NTE|2||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER TEST TEST TEST.
    DG1|1|||Pain in Ankle
    DG1|2|||Pain in Foot

    Outbound:
    Mesage 1:
    MSH|^~\&|TESTSYSTEM|TESTSYSTEM|TOTESTSYSTEM|Imaging|20160415203730||ORM^O01|201604152037462|T|2.3|
    PID|1|d7980233-39f6|||Duck^Daffy||19420402|M|||52 West Unit Drive^^Sneads^FL^32460-4165|
    PV1|1|O|FL0XX1^55^^APAL&FL00001|Schryver Medical FL Corrections|
    IN1|1||CENTURION MASTER|||||||||||||Duck~Daffy~||19420402||||||||||||||||||DIRECT BILL|
    ORC|NW|2016041501001|||||||20160416023631|Electronic||1891929857^ABANO^JOHN||^^^^^^8507180577|20160416000000|
    OBR|1|2016041501001||3117^FOOT LT 3V*|R||201604160000|||||||||1891929857^ABANO^JOHN|||||||||||||||^Non-Ambulatory – Fall Risk/Fell|||||||||||||73630|
    NTE|1||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER.|
    DG1|1|||Pain in Ankle|
    DG1|2|||Pain in Foot|

    Mesage 2:
    MSH|^~\&|TESTSYSTEM|TESTSYSTEM|TOTESTSYSTEM|Imaging|20160415203730||ORM^O01|201604152037462|T|2.3|
    PID|1|d7980233-39f6|||Duck^Daffy||19420402|M|||52 West Unit Drive^^Sneads^FL^32460-4165|
    PV1|1|O|FL0XX1^55^^APAL&FL00001|Schryver Medical FL Corrections|
    IN1|1||CENTURION MASTER|||||||||||||Duck~Daffy~||19420402||||||||||||||||||DIRECT BILL|
    ORC|NW|2016041501001|||||||20160416023631|Electronic||1891929857^ABANO^JOHN||^^^^^^8507180577|20160416000000|
    NTE|2||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER TEST TEST TEST.|
    DG1|1|||Pain in Ankle|
    DG1|2|||Pain in Foot|

    Message 3:
    MSH|^~\&|TESTSYSTEM|TESTSYSTEM|TOTESTSYSTEM|Imaging|20160415203730||ORM^O01|201604152037462|T|2.3|
    PID|1|d7980233-39f6|||Duck^Daffy||19420402|M|||52 West Unit Drive^^Sneads^FL^32460-4165|
    PV1|1|O|FL0XX1^55^^APAL&FL00001|Schryver Medical FL Corrections|
    IN1|1||CENTURION MASTER|||||||||||||Duck~Daffy~||19420402||||||||||||||||||DIRECT BILL|
    ORC|NW|2016041501001|||||||20160416023631|Electronic||1891929857^ABANO^JOHN||^^^^^^8507180577|20160416000000|
    OBR|2|2016041501001||3063^ANKLE LT 3V*|R||201604160000|||||||||1891929857^ABANO^JOHN|||||||||||||||^Non-Ambulatory – Fall Risk/Fell|||||||||||||73610|
    NTE|1||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER.|
    DG1|1|||Pain in Ankle|
    DG1|2|||Pain in Foot|

    Message 4:
    MSH|^~\&|TESTSYSTEM|TESTSYSTEM|TOTESTSYSTEM|Imaging|20160415203730||ORM^O01|201604152037462|T|2.3|
    PID|1|d7980233-39f6|||Duck^Daffy||19420402|M|||52 West Unit Drive^^Sneads^FL^32460-4165|
    PV1|1|O|FL0XX1^55^^APAL&FL00001|Schryver Medical FL Corrections|
    IN1|1||CENTURION MASTER|||||||||||||Duck~Daffy~||19420402||||||||||||||||||DIRECT BILL|
    ORC|NW|2016041501001|||||||20160416023631|Electronic||1891929857^ABANO^JOHN||^^^^^^8507180577|20160416000000|
    NTE|2||THIS IS A TEST ORDER.\X0A\THIS IS A TEST ORDER TEST TEST TEST.|
    DG1|1|||Pain in Ankle|
    DG1|2|||Pain in Foot|

You must be logged in to reply to this topic.