Announcement

Collapse
No announcement yet.

HOw to implement Dispatch Pattern based on incoming Message contents (X12 source)?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • HOw to implement Dispatch Pattern based on incoming Message contents (X12 source)?

    Hello fellow MirthConnected folks,

    I am still new to the platform and the whole Medical Message based integration field and working on a new project that requires both and have the following questions, please:

    Basically, I need to verify Insurance eligibility using different "backend" API providers depending on payer data (DELTA, CIGNA etc). ONe API is SOAP 1.1 based and basically accepts X12 EDI text wrapped in SOAP envelope, the other - RESTFul WS API that accepts HTTP requests with query strings

    QUESTION 1:

    We need to come up with implementation of "Dispatcher pattern" in Mirth that would direct Insurance Eigibility verification requests to various APIs - RESTful for some payers and SOAP for others, based on payer code passed in X12 payload, like shown below for SOAP request sample:

    <Process837 xmlns="https://www.realtimeclaims.com/">
    <Input837>ISA*00* *00* *30*521301729 *20*0135WCH00 *100126*1731*U*00401*000000001*1*T*:~GS*HC*5213017 29*0135WCH00*20100126*0531*1001*X*004010X097A1~ST* 837*0001~BHT*0019*00*1*20100126*0531*CH~REF*87*004 010X097A1~NM1*41*2*WORKS INC*****46*999999999~PER*IC*SERVICES*TE*4107851470 ~NM1*40*2*ABC*****46*0135WCH00~HL*1**20*1~NM1*85*1 *AUSTIN*KEITH****XX*999999999~N3*3718 OLD ROAD~N4*LYNCHBURG*NY*11111~REF*G5*0000~REF*EI*9999 99999~REF*1B*005927~REF*1D*0012287~REF*LU*43438560 00~REF*G2*0401005610~NM1*87*2*DR KEITH AUSTIN*****24*54-9999999~HL*2*1*22*1~SBR*P*18*9141*CBS PERSONNEL SERVICES**6***ZZ~NM1*IL*1*STONE*SHARON*W***MI*9999 99999~N3*1911 SMITH DR~N4*LYNCHBURG*NY*11111~DMG*D8*19620202*F~NM1*PR* 2*DELTA/MI*****PI*DELTA~N3*PO BOX 9085~N4*FARMINGTON HILL*MI*48333~HL*2*1*23*0~PAT*19~NM1*QC*1*SMITH*JO AN*H~N3*1911 SMITH DR~N4*LYNCHBURG*NY*11111~DMG*D8*19921223*F~CLM*000 7969010075152P*238***11::1*Y*A*Y*Y~REF*D9*00934100 0075152~NTE*ADD*3718 OLD ROAD\\LYNCHBURG\NY\11111~NM1*82*1*AUSTIN*KEITH**** XX*999999999~PRV*PE*ZZ*122300000X~REF*TJ*541146835 ~REF*1E*5610~LX*1~SV3*AD0120*39****1~DTP*472*D8*20091203~LX*2~SV3*AD1110*64****1~DTP*472*D8*20091203~LX*3~SV3*AD2160*135****1~TOO*JP*31*D:O:B~DTP*472*D8*20091203~ SE*50*0001~GE*1*1001~IEA*1*000000001~
    </Input837>
    <OutputEOB />
    <Output997 />


    The RESTful request would look like:

    "https://gds.eligibleapi.com/v1.3/coverage/all.json?test=true&api_key=81ef98e5-4584-19fb-0d8c-6e987b95d695&payer_id=
    00001&provider_last_name=Doe&provider_first_name=J ohn&provider_npi=0123456789&member_id=ZZZ445554301 &member_first_name=IDA&member_last_name=FRANKLIN&m ember_dob=1701-12-12&service_type=30"


    Could you advise how that can be implemented please with one channel accepting X12 data and dispatching to either one for further processing based on Payer data: extract code for Payer (DELTA or CIGNA etc) from X12 and then based on that code value (how to implement decision point?) would call other channels passing either whole X12 payload for SOAP wrapped Requests or portions of it for lightweight RESTful request?

    Have you implemented something like that before - if so, a sample would be very helpful.

    QUESTION 2: In case of SOAP response returned and containing X12 data again what would be the best way to parse for the values?

    1. The code for getting values from SOAP response to be placed on Channel map should be placed in the Transformer section of a Response Destination (Web Services call) and will use MSG..<node_name> syntax to start iterating in, correct:

    [I]var tdata = new Array();
    for each (node in msg..eligibility_verification) { //are there TWO dots in MSG..ELIGIBILITY VERFICIATION?

    var i = 0;
    for each (child in node) {

    var nodename = child.name.toString();
    tdata[i] = child.toString();

    channelMap.put(nodename + i,tdata); //this will write values to the channel Map.
    i++;

    } //for loop
    }


    (the sample SOAP response message looks like this - really an X12 EDIt text wrapped into SOAP Envelope format)

    <Process837Response xmlns="https://www.realtimeclaims.com/">
    <Process837Result>0</Process837Result>
    <OutputEOB>--------------------------------------
    CLAIM SUBMISSION RESULTS
    DELTA USA
    ---------------------------------------
    SUBSCRIBER NAME: SHARON STONE
    PATIENT NAME: JOAN SMITH
    IDENTIFICATIN NO: 229065379
    RECEIVE DATE: 04/07/2010
    SERVICE DATE: 12/03/2009
    PROVIDER(NUMBER) : 999999999
    PROVIDER: KEITH AUSTIN
    CLAIM #: 999999999999
    ---------------------------------------
    CODE-TOOTH # PROCEDURE DESCRIPTION
    CHARGE ALLOW SUBSCRIBER N-CHARGE PAID EX
    ---------------------------------------
    D0120 ADA PROC CODE DESC
    39.00 39.00 0.00 0.00 39.00
    D1110 ADA PROC CODE DESC
    64.00 64.00 0.00 0.00 64.00
    D2160 ADA PROC CODE DESC
    135.00 135.00 0.00 0.00 13
    ...
    </OutputEOB>
    <Output997>ISA*00* *00* *20*0135WCH00 *30*521301729 *100126*1731*U*00401*000000001*1*T*:~
    GS*FA*0135WCH00*521301729*20100126*0531*1001*X*004 010X097A1~
    ST*997*0001~
    AK1*HC*1001~
    AK2*837*0001~
    AK5*A~
    AK9*A*1*1*1~
    SE*6*0001~
    GE*1*1001~
    IEA*1*000000001~
    </Output997>


    And how would I go about processing JSON response form RESTfuil Web Services?

    Sorry for too many questions and appreciate partial responses as well.

    thanks,
    Dan

  • #2
    Well Dan,

    I hope I can shed some light for you but to be honest I do not have much experience with restful api and soap (not yet).

    Question 1:

    My Idea would be 1 channel accepting soap messages and extract the X12 data at the source connector. using something like this:
    Code:
    SerializerFactory.getX12Serializer(inferDelimiters).toXML(message);
    default xml namespace = new Namespace('urn:mirthproject-org:x12:xml');
    (Mirth Connect 2.x)

    then send the parsed X12 message to the destinations
    where a filtering per destination on the Payer data occurs

    Question 2:

    every response will be placed in the responseMap variable so you can traverse through this. the javascript example you are seeing is calles E4x (ecmascript for xml)

    the code snippet will not work on the response this is a code snippet for a transformerstep in the source or destination connector.

    do you use MirthConnect 3.0.1? then there is a response transformer.
    JSON is native javascript so you can use JSON.stringify and JSON.Parse


    I hope this helps you on your way.
    with kind regards
    Stefan Scholte
    Stefan

    Mirth Certified|Epic Bridges Certified|Cloverleaf Level 2 Certified

    Comment


    • #3
      Hi Stefan,

      Thanks a lot for your response. I am also new to Mirth 9as mentioned before and still am struggling with questions "Where to put certain JScript code to obtain data from SOAP/RESTful Web Service call response"?

      I am running Mirth 3.0.1 BTW. So, the script you suggested for extracting X12 payload form SOAP message:

      Code:
      SerializerFactory.getX12Serializer(inferDelimiters).toXML(message);
      default xml namespace = new Namespace('urn:mirthproject-org:x12:xml');
      would still work in 3.0.1? Will I place this code into the "source" section of the channel? Actually, I am thinking for development purposes I can even read the X12 payload form a text file.

      The main question I am still unclear about is once I retrieve a X12 payload like:

      ISA*00* *00* *12*ABCCOM *01*999999999 *120117*1719*U*00400*000006768*0*P*>
      GS*HS*4405197800*999999999*20120117*1719*1421*X*00 4010VICS
      ST*270*1234
      BHT*0022*13*1*20010820*1330
      HL*1**20*1
      NM1*PR*2******PI*123456789
      HL*2*1*21*1
      NM1*1P*2******SV*987654321
      HL*3*2*22*0
      NM1*IL*1*DOE*JANE****MI*345678901
      EQ*30**FAM
      SE*10*1234
      GE*1*1421
      IEA*1*000006768


      And place it into "Raw" format - how then to implement a dispatch logic that would call either different Destinations or external Channels depending on value of Insurance payer contained in that payload? How that "conditional workflow" logic can be implemented in Mirth?

      thanks again,
      Dan Zilberman

      Comment


      • #4
        Do you have the channel working so that you can accept a soap message?

        If you do please post your channel together with an example message so I can help you further.
        Stefan

        Mirth Certified|Epic Bridges Certified|Cloverleaf Level 2 Certified

        Comment


        • #5
          Hi Stefan,

          I don't have an input channel with Web Service source reader - and may not need one as the input data may be red from a shared file system from a X12 text file like the one attached.

          From the 270 standard, we have:

          "The 270 document typically includes the following:

          Details of the sender of the inquiry (name and contact information of the information receiver)
          Name of the recipient of the inquiry (the information source)
          Details of the plan subscriber about to the inquiry is referring (patient)
          Description of eligibility or benefit information requested"

          Then once we have the Raw XML version of the input X12 message in the Source map - can we make a "decision point" that dispatches that data either wrapped in a SOAP call to Channel1 or mapped to HTTP Get RESTful WS call with parsed out parameters passed in a URL query string?

          That's that part I am actually looking for, Stefan. I can post a simple receiver channel that reads the above data as inbound Web Service call ("Reader") later tonight if that is still needed.

          Thanks
          Dan
          Attached Files

          Comment


          • #6
            Could anybody please respond with an answer on whether/how one can implement a dispatch pattern using ONE inbound channel that routes messages further based on values of one or more fields in their PAYLOADS, please? Thanks!

            Comment


            • #7
              If you only have two destinations then you could set up a channel with two destinations and just filter each. So you could have one destination with an HTTP Sender and one destination with a Web Service Sender. The filter logic would determine which messages get through to each.

              You could also work out the logic and route the messages to a new channel if you want to separate the two destinations.

              Comment


              • #8
                Originally posted by eduardoa View Post
                If you only have two destinations then you could set up a channel with two destinations and just filter each. So you could have one destination with an HTTP Sender and one destination with a Web Service Sender. The filter logic would determine which messages get through to each.

                You could also work out the logic and route the messages to a new channel if you want to separate the two destinations.
                Thanks for responding Eduardo, I would very much appreciate an example of such Filter code that routes to different channels - I am new to Mirth. Thanks, Dan

                Comment


                • #9
                  Originally posted by dzilberman View Post
                  Thanks for responding Eduardo, I would very much appreciate an example of such Filter code that routes to different channels - I am new to Mirth. Thanks, Dan
                  Have you tried it out?

                  Edit your destination filter, and add a new Rule Builder step. Paste a sample inbound X12 message into the inbound message template, then drag over the field you want to test into the Rule Builder step. Then choose your condition (e.g. "Equals"), and add values to the table below, if necessary.
                  Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

                  Nicholas Rupley
                  Work: 949-237-6069
                  Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


                  - How do I foo?
                  - You just bar.

                  Comment


                  • #10
                    Can somebody take a look at this example and correct so dispatching to WS caller or c

                    OK, I have finally got my hands on trying to implement the Filter based routing to the channels - please see attached export. I'm struggling with how to build those Filter rules in order to make sure that values of certain variables contained in the overall inciming SOAP message payload:

                    <?xml version="1.0" encoding="utf-8"?>
                    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <soap:Body>
                    <Process837 xmlns="https://www.realtimeclaims.com/">
                    <Input837>ISA*00* *00* *30*521301729 *20*0135WCH00 *100126*1731*U*00401*000000001*1*T*:~GS*HC*5213017 29*0135WCH00*20100126*0531*1001*X*004010X097A1~ST* 837*0001~BHT*0019*00*1*20100126*0531*CH~REF*87*004 010X097A1~NM1*41*2*WORKS INC*****46*999999999~PER*IC*SERVICES*TE*4107851470 ~NM1*40*2*ABC*****46*0135WCH00~HL*1**20*1~NM1*85*1 *AUSTIN*KEITH****XX*999999999~N3*3718 OLD ROAD~N4*LYNCHBURG*NY*11111~REF*G5*0000~REF*EI*9999 99999~REF*1B*005927~REF*1D*0012287~REF*LU*43438560 00~REF*G2*0401005610~NM1*87*2*DR KEITH AUSTIN*****24*54-9999999~HL*2*1*22*1~SBR*P*18*9141*CBS PERSONNEL SERVICES**6***ZZ~NM1*IL*1*STONE*SHARON*W***MI*9999 99999~N3*1911 SMITH DR~N4*LYNCHBURG*NY*11111~DMG*D8*19620202*F~NM1*PR* 2*DELTA/MI*****PI*DELTA~N3*PO BOX 9085~N4*FARMINGTON HILL*MI*48333~HL*2*1*23*0~PAT*19~NM1*QC*1*SMITH*JO AN*H~N3*1911 SMITH DR~N4*LYNCHBURG*NY*11111~DMG*D8*19921223*F~CLM*000 7969010075152P*238***11::1*Y*A*Y*Y~REF*D9*00934100 0075152~NTE*ADD*3718 OLD ROAD\\LYNCHBURG\NY\11111~NM1*82*1*AUSTIN*KEITH**** XX*999999999~PRV*PE*ZZ*122300000X~REF*TJ*541146835 ~REF*1E*5610~LX*1~SV3*AD0120*39****1~DTP*472*D8*20091203~LX*2~SV3*AD1110*64****1~DTP*472*D8*20091203~LX*3~SV3*AD2160*135****1~TOO*JP*31*D:O:B~DTP*472*D8*20091203~ SE*50*0001~GE*1*1001~IEA*1*000000001~
                    </Input837>
                    <OutputEOB />
                    <Output997 />
                    <UserId>userid</UserId>
                    <UserPassword>xxxx</UserPassword>
                    </Process837>
                    </soap:Body>
                    </soap:Envelope>
                    will have one value or another "Abcd1234" or "CDEF4321" just for example in the attached.
                    Could somebody take a look and correct pls? I'm actually looking for different values in the included X12 formatted payload in this segment: ISA*00* *00* *30*521301729 *20*0135WCH00 , so I guess I have to first parse SOAP request into X12 message, then extract that segment int a variable and then use it in filter expressions - no idea how to do that.

                    thanks,
                    Dan Z
                    Attached Files

                    Comment


                    • #11
                      Depending on whether you would like to just use the X12 as your message you could do this a couple of ways. If you just want to serialize the X12 and put it in the channel map, that works too.

                      You could do the following to serialize the X12 to XML and put it in the channel map:

                      var x12Message = SerializerFactory.getSerializer('EDI/X12').toXML(msg.*::Body.*::Process837.*::Input837. toString());
                      channelMap.put('x12Message', x12Message);

                      Then you could do this in another destination's filter:

                      if(new XML(channelMap.get('x12Message'))['ISA']['ISA.05']['ISA.05.1'] == "Abcd1234"){
                      logger.info('Containted value Abcd1234');
                      return true;
                      }

                      I'll attach a sample using your channel. Worked for this message:
                      ISA*00* *00* *Abcd1234*521301729 *20*0135WCH00 *100126
                      Attached Files

                      Comment


                      • #12
                        Here's the slightly improved version of my attempt to implement a dispatch pattern for your review, narupley.
                        I still can't figure out the logic of properly building filter expressions based on message fields' values (which need to be extracted form bulk X12 payload first - how) ... Could you please take a look and let me know what could be updated so in the first scenario the SOAP Web Servcies destination will be called and in the second - RESTull HTTP GET request with parameters passed in "query string"?

                        many thanks!
                        Dan Z
                        Attached Files

                        Comment


                        • #13
                          X12 ==&gt; XML transformer fails

                          Many thanks Eduardo - but I couldn't import your sample b/c it was created in the newer version of Mirth. Mine is Mirth Connect Server 3.0.0.6931. Any chance you could "back port" your sample to that version? I really like your idea of putting the whole X12 message object into the channel Map and then construct an XML form it and look for specific element's value, right:

                          if(new XML(channelMap.get('x12Message'))['ISA']['ISA.05']['ISA.05.1'] == "Abcd1234"){
                          logger.info('Containted value Abcd1234');
                          return true;
                          }
                          I have followed your example and created a filter with pretty much same code (see attached) but it always fails with this exception:

                          Transformer error
                          ERROR MESSAGE: Error evaluating transformer
                          com.mirth.connect.server.MirthJavascriptTransforme rException:
                          CHANNEL: Test WS Dispatcher 1
                          CONNECTOR: Destination 1
                          SCRIPT SOURCE:
                          SOURCE CODE:
                          21: }
                          22: }
                          23: function doScript() {
                          24: msg = new XML(connectorMessage.getTransformedData());
                          25: if (msg.namespace('') != undefined) { default xml namespace = msg.namespace(''); } else { default xml namespace = ''; }
                          26: tmp = new XML(template);
                          27: function doFilter() { phase[0] = 'filter'; return true; }function doTransform() { phase[0] = 'transformer'; logger = Packages.org.apache.log4j.Logger.getLogger(phase[0]);
                          28:
                          29:
                          30: //from the Mirth forum sample:
                          LINE NUMBER: 26
                          DETAILS: TypeError: The prefix "soap" for element "soap:Envelope" is not bound.
                          at 63307e0e-6d59-4d65-bd7d-64299ee801d7:26 (doScript)
                          at 63307e0e-6d59-4d65-bd7d-64299ee801d7:54
                          at com.mirth.connect.server.transformers.JavaScriptFi lterTransformer$FilterTransformerTask.call(JavaScr iptFilterTransformer.java:134)
                          at com.mirth.connect.server.transformers.JavaScriptFi lterTransformer$FilterTransformerTask.call(JavaScr iptFilterTransformer.java:100)
                          at java.util.concurrent.FutureTask$Sync.innerRun(Futu reTask.java:334)
                          at java.util.concurrent.FutureTask.run(FutureTask.jav a:166)
                          at java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1110)
                          at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:603)
                          at java.lang.Thread.run(Thread.java:722)
                          ----------------------------------------------------
                          I am not sure where soap prefix comes form - maybe from the template?

                          Could you please review the attached channel, correct it for 3.0.0 and share?

                          many thanks,
                          Dan Z
                          Attached Files

                          Comment


                          • #14
                            You are seeing that error because you are stripping the namespaces. You can choose the option to not strip namespaces in the Summary tab-> Set Data Types.

                            I'll upload the way you can do it if you wanted to put the message in the channelmap. It is probably best if you just change the data type to be X12 after the source connector. That way you can just use the transformed message and check values in the x12 from msg. If you needed anymore values from the envelope then you could put those in the channel map.

                            I'll include an example of both.
                            Attached Files
                            Last edited by eduardoa; 02-05-2014, 03:16 PM.

                            Comment


                            • #15
                              Thanks a ton, Eduardo - will try these soon!
                              Could you comment when IT DOES MAKE SENSE to strip out XML namespaces?

                              Dan Z

                              Comment

                              Working...
                              X