Announcement

Collapse

Mirth Connect 3.12.0 Released!

Mirth Connect 3.12.0 is now available as an appliance update and on our GitHub page. This release includes database performance improvements, improves visual HL7 representation, message pruning, keystore handling, PDF generation, community contributions, and fixes several security vulnerabilities. This release also contains many improvements to commercial extensions. See the release notes for the list of fixes and updates.

Download | See What's New | Upgrade Guide | Release Notes

For discussion on this release, see this thread.
See more
See less

Adding NTE after each OBX, but other NTEs exist

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

  • Adding NTE after each OBX, but other NTEs exist

    Open Source Mirth v3.11.0

    OK. I have been searching for ever on the forum and I haven't gotten to an answer that helps with my issue.
    Here is my situation.

    I have Result ORUs coming in and they may or may not contain NTE segments. On these ORUs, if NTE segments exist on the inbound message, there will be one after the OBR and then a random number of NTE's following OBX segments.

    My objective is to add an NTE after each OBX and supply the phrase "Order Provider: <firstname> <lastname>" in NTE.3.1.

    I'm looping through the segments of the message and when I get to an OBX, I'm using the createSegmentAfter routine to generate the needed NTE. Using the index number of the OBX, I'm allowed to assign a setID and insert the phrase.

    This processes a message without error, but the output is not acceptable.
    Here is my input:
    MSH|^~\&|LAB|Hospital^0001|NEXTGEN|COM|20210910115 434||ORU^R01|8790939479|P|2.4|||||||
    PID|||123456789||TEST^Jane^J^^^||19660910|F|||123 Main Street^^HomeTown^IN^44444^^|||||W||V9876543210|||| |
    PV1|1|E|11||||PROVID^LNAME^DOCTOR^W^^^MD^PP_MASTER |||||||||||||||||||||||||||||||||||||||||||||123^D OCTOR^FNAME^^^^^ProviderNPI|
    OBR|1||90081555^LAB^0081555|CL1403^Basic Metabolic Panel^LAB^1403^Lab (Hospital)^LAB||202109101920|202109101920|||||||20 2109091932||PROVID^LNAME^DOCTOR^W^^^MD^PP_MASTER|| ||||202109091945||LAB|F||^^^^^|123^DOCTOR^FNAME^^^ ^^ProviderNPI|||||||||||^|
    NTE|1||Is Patient Fasting? N
    OBX|1|NM|CL1405^Whole Blood Sodium^LAB_C^^^LB|1.1|143|mmol/L|137-145||||F|||202109091938
    OBX|2|NM|CL1507^Whole Blood Potassium^LAB_C^^^LB|1.2|3.5|mmol/L|3.4-5.1||||F|||202109091938
    OBX|3|NM|CL1605^Whole Blood Chloride^LAB_C^^^LB|1.3|103|mmol/L|98-107||||F|||202109091938
    OBX|4|NM|CL1212^Whole Blood Ionized Calcium^LAB_C^^^LB|1.4|1.24|mmol/L|1.12-1.32||||F|||202109091938
    OBX|5|NM|CL1214^Whole Blood Carbon Dioxide^LAB_C^^^LB|1.5|24|mmol/L|22-30||||F|||202109091938
    OBX|6|NM|CL1216^Whole Blood Glucose^LAB_C^^^LB|1.6|97|mg/dL|60-110||||F|||202109091938
    NTE|2|X|Ranges listed are for Fasting Specimens
    OBX|7|NM|CL1218^Whole Blood Urea Nitrogen^LAB_C^^^LB|1.7|21.0|mg/dL|7-17|H|||F|||202109091938
    OBX|8|NM|CL1220^Whole Blood Creatinine^LAB_C^^^LB|1.8|1.0|mg/dL|0.7-1.2||||F|||202109091938
    OBX|9|NM|CL12205^Estimat Glomerular Filtration Rate^LAB_C^^^LB|1.9|58||>60||||F|||202109091938
    NTE|3|X|mL/min/1.73 square meters
    OBX|10|NM|CL1221^Whole Blood BUN/Creatinine Ratio^LAB_C^^^LB|1.10|21||8-20|H|||F|||202109091938
    OBX|11|NM|CL1222^Whole Blood Anion Gap^LAB_C^^^LB|1.11|20||6-22||||F|||202109091938

    Here is my desired output:
    MSH|^~\&|LAB|Hospital^0001|NEXTGEN|COM|20210910115 434||ORU^R01|8790939479|P|2.4|||||||
    PID|||123456789||TEST^Jane^J^^^||19660910|F|||123 Main Street^^HomeTown^IN^44444^^|||||W||V9876543210|||| |
    PV1|1|E|11||||PROVID^LNAME^DOCTOR^W^^^MD^PP_MASTER |||||||||||||||||||||||||||||||||||||||||||||123^D OCTOR^FNAME^^^^^ProviderNPI|
    OBR|1||90081555^LAB^0081555|CL1403^Basic Metabolic Panel^LAB^1403^Lab (Hospital)^LAB||202109101920|202109101920|||||||20 2109091932||PROVID^LNAME^DOCTOR^W^^^MD^PP_MASTER|| ||||202109091945||LAB|F||^^^^^|123^DOCTOR^FNAME^^^ ^^ProviderNPI|||||||||||^|
    NTE|1||Is Patient Fasting? N
    OBX|1|NM|CL1405^Whole Blood Sodium^LAB_C^^^LB|1.1|143|mmol/L|137-145||||F|||202109091938
    NTE|2||Ordering Provider: firstname lastname
    OBX|2|NM|CL1507^Whole Blood Potassium^LAB_C^^^LB|1.2|3.5|mmol/L|3.4-5.1||||F|||202109091938
    NTE|3||Ordering Provider: firstname lastname
    OBX|3|NM|CL1605^Whole Blood Chloride^LAB_C^^^LB|1.3|103|mmol/L|98-107||||F|||202109091938
    NTE|4||Ordering Provider: firstname lastname
    OBX|4|NM|CL1212^Whole Blood Ionized Calcium^LAB_C^^^LB|1.4|1.24|mmol/L|1.12-1.32||||F|||202109091938
    NTE|5||Ordering Provider: firstname lastname
    OBX|5|NM|CL1214^Whole Blood Carbon Dioxide^LAB_C^^^LB|1.5|24|mmol/L|22-30||||F|||202109091938
    NTE|6||Ordering Provider: firstname lastname
    OBX|6|NM|CL1216^Whole Blood Glucose^LAB_C^^^LB|1.6|97|mg/dL|60-110||||F|||202109091938
    NTE|7||Ordering Provider: firstname lastname
    NTE|8|X|Ranges listed are for Fasting Specimens
    OBX|7|NM|CL1218^Whole Blood Urea Nitrogen^LAB_C^^^LB|1.7|21.0|mg/dL|7-17|H|||F|||202109091938
    NTE|9||Ordering Provider: firstname lastname
    OBX|8|NM|CL1220^Whole Blood Creatinine^LAB_C^^^LB|1.8|1.0|mg/dL|0.7-1.2||||F|||202109091938
    NTE|10||Ordering Provider: firstname lastname
    OBX|9|NM|CL12205^Estimat Glomerular Filtration Rate^LAB_C^^^LB|1.9|58||>60||||F|||202109091938
    NTE|11||Ordering Provider: firstname lastname
    NTE|12|X|mL/min/1.73 square meters
    OBX|10|NM|CL1221^Whole Blood BUN/Creatinine Ratio^LAB_C^^^LB|1.10|21||8-20|H|||F|||202109091938
    NTE|13||Ordering Provider: firstname lastname
    OBX|11|NM|CL1222^Whole Blood Anion Gap^LAB_C^^^LB|1.11|20||6-22||||F|||202109091938
    NTE|14||Ordering Provider: firstname lastname




    Here is my code:
    // grab Ordering Provider LastName and FirstName for NTEs
    var provLN = msg['OBR']['OBR.16']['OBR.16.2'].toString();
    var provFN = msg['OBR']['OBR.16']['OBR.16.3'].toString();

    var OBXidx = 0;
    for each (seg in msg.children())
    {
    if (seg.name().toString() == "OBX")
    {
    createSegmentAfter('NTE',msg['OBX'][OBXidx]);
    msg['NTE'][OBXidx]['NTE.1']['NTE.1.1'] = OBXidx + 1;
    msg['NTE'][OBXidx]['NTE.2']['NTE.2.1'] = 'X';
    msg['NTE'][OBXidx]['NTE.3']['NTE.3.1'] = 'Ordering Provider: ' + provFN.trim() + ' ' + provLN.trim();
    OBXidx++;
    }
    }

    This is what the output looks like:
    MSH|^~\&|LAB|Hospital^0001|NEXTGEN|COM|20210910115 434||ORU^R01|8790939479|P|2.4|||||||
    PID|||123456789||TEST^Jane^J^^^||19660910|F|||123 Main Street^^HomeTown^IN^44444^^|||||W||V9876543210|||| |
    PV1|1|E|11||||PROVID^LNAME^DOCTOR^W^^^MD^PP_MASTER |||||||||||||||||||||||||||||||||||||||||||||123^D OCTOR^FNAME^^^^^ProviderNPI|
    OBR|1||90081555^LAB^0081555|CL1403^Basic Metabolic Panel^LAB^1403^Lab (Hospital)^LAB||202109101920|202109101920|||||||20 2109091932||PROVID^LNAME^DOCTOR^W^^^MD^PP_MASTER|| ||||202109091945||LAB|F||^^^^^|123^DOCTOR^FNAME^^^ ^^ProviderNPI|||||||||||^|
    NTE|1|X|Ordering Provider: firstname lastname
    OBX|1|NM|CL1405^Whole Blood Sodium^LAB_C^^^LB|1.1|143|mmol/L|137-145||||F|||202109091938
    NTE|2|X|Ordering Provider: firstname lastname
    OBX|2|NM|CL1507^Whole Blood Potassium^LAB_C^^^LB|1.2|3.5|mmol/L|3.4-5.1||||F|||202109091938
    NTE|3|X|Ordering Provider: firstname lastname
    OBX|3|NM|CL1605^Whole Blood Chloride^LAB_C^^^LB|1.3|103|mmol/L|98-107||||F|||202109091938
    NTE|4|X|Ordering Provider: firstname lastname
    OBX|4|NM|CL1212^Whole Blood Ionized Calcium^LAB_C^^^LB|1.4|1.24|mmol/L|1.12-1.32||||F|||202109091938
    NTE|5|X|Ordering Provider: firstname lastname
    OBX|5|NM|CL1214^Whole Blood Carbon Dioxide^LAB_C^^^LB|1.5|24|mmol/L|22-30||||F|||202109091938
    NTE|6|X|Ordering Provider: firstname lastname
    OBX|6|NM|CL1216^Whole Blood Glucose^LAB_C^^^LB|1.6|97|mg/dL|60-110||||F|||202109091938
    NTE|7|X|Ordering Provider: firstname lastname
    NTE|8|X|Ordering Provider: firstname lastname
    OBX|7|NM|CL1218^Whole Blood Urea Nitrogen^LAB_C^^^LB|1.7|21.0|mg/dL|7-17|H|||F|||202109091938
    NTE|9|X|Ordering Provider: firstname lastname
    OBX|8|NM|CL1220^Whole Blood Creatinine^LAB_C^^^LB|1.8|1.0|mg/dL|0.7-1.2||||F|||202109091938
    NTE|10|X|Ordering Provider: firstname lastname
    OBX|9|NM|CL12205^Estimat Glomerular Filtration Rate^LAB_C^^^LB|1.9|58||>60||||F|||202109091938
    NTE|11|X|Ordering Provider: firstname lastname
    NTE|3|X|mL/min/1.73 square meters
    OBX|10|NM|CL1221^Whole Blood BUN/Creatinine Ratio^LAB_C^^^LB|1.10|21||8-20|H|||F|||202109091938
    NTE|
    OBX|11|NM|CL1222^Whole Blood Anion Gap^LAB_C^^^LB|1.11|20||6-22||||F|||202109091938
    NTE|

    I don't understand exactly what the routine "createSegmentAfter" is doing except to say it is giving me a new segment. How do I access the fields of the new segment? I have tried to manipulate the index and setid values to get to my desired output and I keep getting the same errors.
    DETAILS: TypeError: Cannot read property "NTE.1" from undefined

    If anyone has any ideas, I would love to hear them. I'm now in more of a crunch to get this figured out then I desired.
    Thanks in advance.


  • #2
    Note this code throws values in the channelMap so you can understand the behavior of getSegmentsAfter (a code template you need to import. See https://github.com/nextgenhealthcare...ular%20Segment)



    PHP Code:
    var obr_index 0;
    var 
    obx_index;
    var 
    nte_inded;

    var 
    provLN msg['OBR']['OBR.16']['OBR.16.2'].toString();
    var 
    provFN msg['OBR']['OBR.16']['OBR.16.3'].toString();

    for 
    each(obr in msg..OBR) {
        
    $c('obr_' obr_index '_this_obr_entity_identifier'obr['OBR.2']['OBR.2.1'].toString())
        
    nte_index 0;
        for 
    each(nte in getSegmentsAfter(msgobr'NTE'true'OBX')) { // Collect NTEs until an OBX
            
    $c('obr_' obr_index '_nte_' nte_index '_nte_' nte_indexnte['NTE.3']['NTE.3.1'].toString())
            
    nte_index++;
        }
        
    obx_index 0;
        for 
    each(obx in getSegmentsAfter(msgobr'OBX'false'OBR')) { // Collect OBX (only one), stop at OBR
            
    $c('obr_' obr_index '_obx_' obx_indexobx['OBX.3']['OBX.3.1'].toString());
            var 
    newNTE createSegmentAfter('NTE'obx)
            
    newNTE['NTE.3']['NTE.3.1'] = 'Ordering Provider: ' provFN.trim() + ' ' provLN.trim()
            
    nte_index 0;
            for 
    each(nte in getSegmentsAfter(msgobx'NTE'true'OBR')) { // Collect NTEs until next OBR
                
    $c('obr_' obr_index '_obx_' obx_index '_nte_' nte_indexnte['NTE.3']['NTE.3.1'].toString())
                
    nte_index++;
            }
            
    obx_index++;
        }
        
    obr_index++

    Last edited by pacmano; 09-17-2021, 09:25 AM.
    Diridium Technologies, Inc.
    https://diridium.com

    Comment


    • #3
      Do check that code of course - I stop after 1 OBX when collecting them. I could see a case where you want to insert the NTE after a bunch of continuous OBXs.
      Diridium Technologies, Inc.
      https://diridium.com

      Comment


      • #4
        Eh, I am off a bit there.. will look at this later. The NTE-1.1 aren't correct.
        Diridium Technologies, Inc.
        https://diridium.com

        Comment


        • #5
          Also, the "getSegmentsAfter()" routine is not standard. Where does this come from? I'm getting an error of not defined.
          Along with that, what do the parameters on that routine represent?
          Last edited by rkMC; 09-19-2021, 12:45 PM.

          Comment


          • #6
            Read my post again. Thoroughly.
            Diridium Technologies, Inc.
            https://diridium.com

            Comment


            • #7
              Got it. Never mind on the getSegmentsAfter routine.

              Comment


              • #8
                I saw that on the NTE.1.1. I tried to add a loop to reset the NTE SetIDs, but it did not work:
                // Reset all the setIDs of the NTEs after each OBX in the message
                for each (obr in msg.OBR) {
                var nteGroup = getSegmentsAfter(msg, obr,'NTE',false,['SPM','ZBP']);
                for (var i = 0; i <= nteGroup.length-1; i++) {
                msg.children()[nteGroup[i].childIndex()]['NTE.1']['NTE.1.1'] = (i+1);
                }
                }

                Comment


                • #9
                  I have added the routine in my last post and the outcome is close to what I need:
                  MSH|^~\&|LAB|HOSPITAL^0001|NEXTGEN|XX|202109100000 00||ORU^R01|0123456789|P|2.4|||||||
                  PID|||||DOE^JANE^J^^^||19660910|F|||123 State St^^Hometown^IN^46999^^|||||W|||222722222||||
                  PV1|1|E|11||||444444^ATTEND^PROV|||||||||||||||||| |||||||||||||||||||||||||||55555^PCP^PROV|
                  OBR|1|||BMP||202109100000|202109100000|||||||20210 9090000||3333^ORDER^PROV||||||202109000000||LAB|F| |^^^^^|444444^COPYTO^PROV^|||||||||||^|
                  NTE|1||Is Patient Fasting? N
                  OBX|1|NM|CL4001405^CL4001405^CL4001405^|1.1|143|mm ol/L|137-145||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|2
                  OBX|2|NM|CL4001507^CL4001507^CL4001507^|1.2|3.5|mm ol/L|3.4-5.1||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|3
                  OBX|3|NM|CL4001605^CL4001605^CL4001605^|1.3|103|mm ol/L|98-107||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|4
                  OBX|4|NM|CL4011212^CL4011212^CL4011212^|1.4|1.24|m mol/L|1.12-1.32||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|5
                  OBX|5|NM|CL4011214^CL4011214^CL4011214^|1.5|24|mmo l/L|22-30||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|6
                  OBX|6|NM|CL4011216^CL4011216^CL4011216^|1.6|97|mg/dL|60-110||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|7
                  NTE|8|X|Ranges listed are for Fasting Specimens
                  OBX|7|NM|CL4011218^CL4011218^CL4011218^|1.7|21.0|m g/dL|7-17|H|||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|9
                  OBX|8|NM|CL4011220^CL4011220^CL4011220^|1.8|1.0|mg/dL|0.7-1.2||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|10
                  OBX|9|NM|CL40112205^CL40112205^CL40112205^|1.9|58| |>60||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|11
                  NTE|12|X|mL/min/1.73 square meters
                  OBX|10|NM|CL4011221^CL4011221^CL4011221^|1.10|21|| 8-20|H|||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|13
                  OBX|11|NM|CL4011222^CL4011222^CL4011222^|1.11|20|| 6-22||||F|||202109090000|REFLAB^REFERENCE LAB^L
                  NTE|||Ordering Provider: ORDER PROV|14

                  Only issue is that the SETID, on the new NTEs is added to the end (NTE.4.1). Even though the code is specifying the NTE.1.1 field.
                  Also, you will notice on the original NTEs (there were 3) they all got a new SETID that is correctly sequenced and the value is placed in NTE.1.1.
                  Go figure.
                  It almost seems like the routine's final assignment line is seeing "msg.children()[nteGroup[i].childIndex()['NTE.1']['NTE.1.1']" as the entire new segment and just adds the (i+1) at the end.

                  Any ideas?
                  Thanks in advance

                  Comment

                  Working...
                  X