Oscar Integration with Meditech: NE LHIN
Oscar Integration with Meditech has occurred in Northern Ontario through the North East LHIN with the Physician Office Integration project
Preface
The North East LHIN has provided HL7 file output from many of the regions hospitals. A similar export is available in the North West LHIN. The HL7 files provided do not currently render properly under Oscar. This is a method to make them work.
Document Version History
- v1.0 – initial public release on oscarmanual.org – Feb 27, 2013
This document is copyright by Peter Hutten-Czapski 2013 © under the Creative Commons Attribution-Share Alike 3.0 Unported License
Contents
|
Prerequisites
It is assumed that you or the implementation person(s) will require
- some knowledge of Mirth (fairly easy)
- a good knowledge of javascript and regular expressions to parse the input
- a thorough understanding of HL7 messaging
- some understanding of how to set up the mule transport that OSCAR uses to suck up HL7 (fairly easy)
- significant time to tune to your particular output formats
HOW TO CONNECT TO MEDITECH HL7 OUTPUT
all software is open source unless identified as not
Step 1. Get a file of output
Speak to Sudbury to get authentication credentials to SFTP access to files for your group
Step 2. Install HL7 File transport on Client
Configure a "CML" channel to Oscar through instructions provided with the hl7_file_management project
NOTE it currently is a maven project. If you prefer you can download an older version that is an ant project
Step 3. Install Mirth Connect on Client.
You have in step 1 gotten access to files in POI HL7 dialect and in step 2 configured a way to receive CML type files. Mirth Connect bridges those two pieces. It does the following
- It will regularly poll the Sudbury POI sftp site for your files
- It downloads them and will transform them into CML format with a XML script that is provided below
- It will then send the transformed file to the incoming directory for CML that you configured in 2
I use Mirth currently 1.8.0.4126 with Sun Java 1.6.0_11 configured to store messages in MySQL http://www.mirthproject.org/
The following is the channel that I currently use with anything sensitive replaced with xxx
To install save the following as sudbury.xml and import into your Mirth Connect instance
<com.webreach.mirth.model.Channel> <id>06dd2dce-2745-4559-a5ab-132e30ac89ef</id> <name>Sudbury to OSCAR - LIVE</name> <description>Takes semi-valid HL7 v2 and "cleans them" for OSCAR including
 1) Drop PV1
 2) Add in ORC
 3) Changing OBX to 'NTE' so they map clean
 1000000 ms poling is about every 16 minutes
 
 Password needs to be changed every so often
 </description> <enabled>true</enabled> <version>1.8.0.4126</version> <lastModified> <time>1360195537000</time> <timezone>America/New_York</timezone> </lastModified> <revision>538</revision> <sourceConnector> <name>sourceConnector</name> <properties> <property name="binary">0</property> <property name="fileFilter">*.HL7</property> <property name="password">xxxxx</property> <property name="username">xxxx</property> <property name="moveToDirectory"></property> <property name="moveToErrorDirectory">C:/messages/errorHL7dir</property> <property name="pollingType">interval</property> <property name="charsetEncoding">DEFAULT_ENCODING</property> <property name="scheme">sftp</property> <property name="host">xxx.xxxxxxx.xx/xxxxx/xxxx/xxxx</property> <property name="pollingFrequency">1000000</property> <property name="validateConnections">1</property> <property name="DataType">File Reader</property> <property name="processBatchFiles">0</property> <property name="passive">1</property> <property name="checkFileAge">1</property> <property name="fileAge">1000</property> <property name="sortAttribute">date</property> <property name="FTPAnonymous">0</property> <property name="moveToPattern"></property> <property name="autoDelete">1</property> </properties> <transformer> <steps/> <inboundTemplate></inboundTemplate> <outboundTemplate></outboundTemplate> <inboundProtocol>HL7V2</inboundProtocol> <outboundProtocol>HL7V2</outboundProtocol> <inboundProperties> <property name="handleRepetitions">false</property> <property name="convertLFtoCR">false</property> <property name="useStrictValidation">false</property> <property name="useStrictParser">false</property> </inboundProperties> <outboundProperties> <property name="handleRepetitions">false</property> <property name="convertLFtoCR">true</property> <property name="useStrictValidation">false</property> <property name="useStrictParser">false</property> </outboundProperties> </transformer> <filter> <rules/> </filter> <transportName>File Reader</transportName> <mode>SOURCE</mode> <enabled>true</enabled> </sourceConnector> <destinationConnectors> <com.webreach.mirth.model.Connector> <name>File writer to C:/messages...</name> <properties> <property name="scheme">file</property> <property name="binary">0</property> <property name="username">anonymous</property> <property name="outputPattern">t_${COUNT}${ORIGINALNAME}</property> <property name="validateConnections">1</property> <property name="DataType">File Writer</property> <property name="FTPAnonymous">1</property> <property name="charsetEncoding">DEFAULT_ENCODING</property> <property name="password">anonymous</property> <property name="passive">1</property> <property name="template">${message.encodedData}</property> <property name="outputAppend">0</property> <property name="host">C:/messages/incomingHL7dir</property> </properties> <transformer> <steps> <com.webreach.mirth.model.Step> <sequenceNumber>0</sequenceNumber> <name>Sudbury to OSCAR</name> <script>// Copyright (c) 2011-2012 by Peter Hutten-Czapski //msg - array representing XML of the data being transformed //makework fix the input back to Su=dbury standard Processing ID msg['MSH']['MSH.11']['MSH.11.1']="T"; //end makework //OSCAR handles versions 2.5, 2.6, 2.3, 2.2 //so make HAPI happy if its 2.4 by downgrading //if (msg['MSH']['MSH.12']['MSH.12.1'].toString()=="2.4") { msg['MSH']['MSH.12']['MSH.12.1']="2.3"; //} //set some natural language locations, especially if particularly obscure if (msg['MSH']['MSH.4']['MSH.4.1'].toString()=="TEM"){ msg['MSH']['MSH.4']['MSH.4.1']="Temiskaming Hospital"; } if (msg['MSH']['MSH.4']['MSH.4.1'].toString()=="SJH"){ msg['MSH']['MSH.4']['MSH.4.1']="North Bay Regional"; } // fudge if something has passed all prior opportunities if (msg['OBX'][0]['OBX.3']['OBX.3.2'].length()<1) { msg['OBX'][0]['OBX.3']['OBX.3.2']="Report"; } var i=0; var hin=""; for (pid in msg..PID){ // populate PID.4 the Alternate Patient ID with the HIN from PID.3 so Oscar can display it msg['PID'][i]['PID.4']['PID.4.1'] = msg['PID'][i]['PID.2']['PID.2.1'].toString(); msg['PID'][i]['PID.4']['PID.4.2'] = msg['PID'][i]['PID.2']['PID.2.2'].toString(); //msg['PID'][i]['PID.4']['PID.4.3'] = msg['PID'][i]['PID.2']['PID.2.3'].toString(); i++; } //Iterate through the segments OBX observations/results // add and remove some var NTEcount = 0; // new notes start at 0 var OBRcount = 0; var OBXcount = 0; var nte = createSegment('NTE'); var noteArray=new Array(); var noteIndex=new Array(); var ptCount=0; var PV1count=0; var categorytype="REPORT"; var reporttype="NEON REPORT"; var obr42=""; var obx31=""; var x="t"; i=0; for each(segment in msg.children()){ if(segment.name() == "PID"){ var dob = segment['PID']['PID.7']['PID.7.1'].toString(); var gender = segment['PID']['PID.8']['PID.8.1'].toString(); } if(segment.name() == "PV1"){ var attdocid = msg['OBR'][ptCount]['OBR.32']['OBR.32.1'].toString() var docid = attdocid.split("&"); //var attdocid = msg['PV1'][ptCount]['PV1.17']['PV1.17.3'].toString() //var docid = attdocid.split("~"); attdocid=docid[0]||"111111"; //var attdocName=msg['PV1'][ptCount]['PV1.17']['PV1.17.2'].toString()+", "+ msg['PV1'][ptCount]['PV1.17']['PV1.17.3'].toString(); var attdocName=(docid[1]||"")+", "+(docid[2]||"") var orc=createSegment('ORC'); createSegmentAfter('ORC', msg['PV1'][ptCount]); msg['ORC'][ptCount] = orc; msg['ORC'][ptCount]['ORC.1']['ORC.1.1'] = ptCount+1; // provide UUID or Accession Number to ORC.2 msg['ORC'][ptCount]['ORC.2']['ORC.2.1'] = msg['OBR'][ptCount]['OBR.3']['OBR.3.1'].toString(); //provide order status from OBR 25.1 msg['ORC'][ptCount]['ORC.5']['ORC.5.1'] = msg['OBR'][ptCount]['OBR.25']['OBR.25.1'].toString(); //parse OBR28 looking for local doc or use PV1.52 msg['ORC'][ptCount]['ORC.12']['ORC.12.1'] = attdocid msg['ORC'][ptCount]['ORC.12']['ORC.12.2'] = attdocName //order effective time set to message time msg['ORC'][ptCount]['ORC.15']['ORC.15.1'] = msg['MSH']['MSH.7']['MSH.7.1'].toString(); delete msg['PV1'][ptCount]; ptCount = ptCount+1; //sequence incriment } if(segment.name() == "OBR"){ //for sake of argument we will call ther placer (2) to have the same order number as the filler (3) msg['OBR'][OBRcount]['OBR.2']['OBR.2.1']=msg['OBR'][OBRcount]['OBR.3']['OBR.3.1'].toString(); if (msg['OBR'][OBRcount]['OBR.4']['OBR.4.1'].toString().length>0) { //leave it } else { msg['OBR'][OBRcount]['OBR.4']['OBR.4.1']="Report"; } //fudge to change requested date with observerd date as we look to when a Xray was taken as its date not the report //if (msg['OBR']['OBR.7']['OBR.7.1'].toString().length>0) { //var tdate=msg['OBR']['OBR.7']['OBR.7.1'].toString(); //msg['OBR']['OBR.7']['OBR.7.1']=msg['OBR']['OBR.6']['OBR.6.1'].toString(); //msg['OBR']['OBR.6']['OBR.6.1']=tdate; //} //OBR 4.2 not needed and more compact output if dropped, but keep the value obr42=msg['OBR'][OBRcount]['OBR.4']['OBR.4.2'].toString(); msg['OBR'][OBRcount]['OBR.4']['OBR.4.2']=""; //if (!((msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString()=="TEDIIDIR")||(msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString()=="TEDIIMAM"))) { if (msg['OBR']['OBR.16']['OBR.16.1'].toString().length<1) { msg['OBR'][OBRcount]['OBR.16']['OBR.16.1']=attdocid; } if (msg['OBR']['OBR.16']['OBR.16.2'].toString().length<1) { msg['OBR'][OBRcount]['OBR.16']['OBR.16.2']=attdocName; } // OBR20 codes. DEPRECATED OR CONTAINS SENDING FACILITY FOR SOME OUTPUT // CAR Cardiology // DII Diagnostic Imaging // EDS Electrodiagnostic Services // HER Health Records // MEH Mental Health // RET Respiratory Therapy // THS Therapeutic Services if (msg['OBR'][OBRcount]['OBR.20']['OBR.20.1'].toString().length>0) { categorytype=msg['OBR'][OBRcount]['OBR.20']['OBR.20.1'].toString(); if (categorytype=="HER") { categorytype="Health Records"; } if (categorytype=="DII") { categorytype="Imaging"; } } if (msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString().length>0) { reporttype=msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString(); } // OBR24.1 codes // MIC Microbiology // LAB Labwork // PTH Pathology if (msg['OBR'][OBRcount]['OBR.24']['OBR.24.1'].length()>0) { categorytype=msg['OBR'][OBRcount]['OBR.24']['OBR.24.1'].toString(); } if (msg['OBR'][OBRcount]['OBR.25']['OBR.25.1'].length()==0) { //if report status NULL assume it F msg['OBR'][OBRcount]['OBR.25']['OBR.25.1']="F"; } OBRcount= OBRcount+1; } if(segment.name() == "OBX"){ obx31=msg['OBX'][OBXcount]['OBX.3']['OBX.3.1'].toString(); x=obx31; switch (obx31) { case "TSH_N": x="4025"; break; case "INRP": x="2165"; break; case "BILIC": x="26196"; break; case "BILIU": x="26194"; break; case "ALP": x="3360"; break; case "K": x="3220"; break; case "NA": x="3210"; break; case "CL": x="3230"; break; case "CREAT": x="3180"; break; case "HGB": x="2010"; break; case "WBC": x="2016"; break; case "PLTC": x="2111"; break; case "NE#": x="2191"; break; case "RBC": x="2019"; break; case "MG": x="3165"; break; case "CA": x="3280"; break; case "AST": x="3370"; break; case "ALT": x="3380"; break; case "LDH": x="3390"; break; case "CK": x="3400"; break; case "PSA": x="4190"; break; case "DIGOXIN": x="4080"; break; case "CHOL": x="3120"; break; case "LDL": x="3933"; break; case "HDL_N": x="3923"; break; case "ALB": x="28872"; break; } msg['OBX'][OBXcount]['OBX.4']['OBX.4.1']=categorytype+ '/' +reporttype; if(( categorytype != "LAB")&&( categorytype != "MIC")&&( categorytype != "CHE")&&( categorytype != "POC")&&( categorytype != "IMM")&&( categorytype != "COA")&&( categorytype != "HEM")&&( categorytype != "HCM")&&( categorytype != "BOF")&&( categorytype != "URI")){ // Reformat OBX's into NTE text output // how about discharge summery or similar msg['OBX'][OBXcount]['OBX.3']['OBX.3.2']=obr42+categorytype; createSegmentAfter('NTE', msg['OBX'][OBXcount]); //noteIndex[NTEcount]=msg['OBX'][i]['OBX.1']['OBX.1.1'].toString()-1; noteArray[NTEcount]=msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'].toString(); NTEcount++; if (OBXcount>0) { msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'] = "DNR"; //mark to delete } else { var payload=msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'].toString(); var re = /H'd4PITAL R'c9GIONAL DE /g ; msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'] = (payload).replace(re, ""); msg['OBX'][OBXcount]['OBX.3']['OBX.3.2'] = obr42+categorytype; } } else { // get the displayed lab to the specfic and not the group //if (msg['OBX'][OBXcount]['OBX.3']['OBX.3.1'].length()>0) { //msg['OBX'][OBXcount]['OBX.3']['OBX.3.2']=msg['OBX'][OBXcount]['OBX.3']['OBX.3.1']; //} msg['OBX'][OBXcount]['OBX.3']['OBX.3.1']=x; var y=msg['OBX'][OBXcount]['OBX.4']['OBX.4.1'].toString(); switch (categorytype) { case "CHE": y="CHEMISTRY"; break; case "HEM": y="HEMATOLOGY"; break; } msg['OBX'][OBXcount]['OBX.4']['OBX.4.1']=y; } if (msg['OBX'][OBXcount]['OBX.3']['OBX.3.1'].toString()=="3180") { // since The Hospital doesn't supply eGFR calculate one var cr = msg['OBX'][OBXcount]['OBX.5']['OBX.5.1']; var today = new Date(); var year=today.getFullYear(); var age=year-dob.substring(0,4); var female_sex=false; if (gender=="F") { female_sex=true; } var eGFR= Math.round(Math.min((186.0 * Math.pow((cr/88.4),-1.154) * Math.pow(age, -0.203) * (female_sex ? 0.742 : 1.0)),90)); // changes in values over (60) 90 120 are not clinically significant //OBX|2|ST|3190^eGFR|CHEMISTRY^^|71||||||F||303^1003190||70 var obx=createSegment('OBX'); createSegmentAfter('OBX', msg['OBX'][OBXcount]); msg['OBX'][OBXcount+1] = obx; msg['OBX'][OBXcount+1]['OBX.1']['OBX.1.1'] = msg['OBX'][i]['OBX.1']['OBX.1.1']-0+1; msg['OBX'][OBXcount+1]['OBX.2']['OBX.2.1'] = "ST"; msg['OBX'][OBXcount+1]['OBX.3']['OBX.3.1'] = "3190"; //id msg['OBX'][OBXcount+1]['OBX.3']['OBX.3.2'] = "eGFR"; //id msg['OBX'][OBXcount+1]['OBX.4']['OBX.4.1'] = "CHEMISTRY"; msg['OBX'][OBXcount+1]['OBX.5']['OBX.5.1'] = eGFR; // result msg['OBX'][OBXcount+1]['OBX.6'] = "ml/min"; //units msg['OBX'][OBXcount+1]['OBX.7'] = ">60"; //reference range if (eGFR<60) {msg['OBX'][OBXcount+1]['OBX.8'] = "A";} //abnormal flag msg['OBX'][OBXcount+1]['OBX.13']['OBX.13.1'] = "303"; msg['OBX'][OBXcount+1]['OBX.13']['OBX.13.2'] = "1003190"; msg['OBX'][OBXcount+1]['OBX.15']['OBX.15.1'] = "70"; msg['OBX'][OBXcount+1]['OBX.11']['OBX.11.1'] = "F"; //'F'inal i++; OBXcount++; } i++; OBXcount++; } //end OBX }// end segment //concat the payload and clean it up var payload=noteArray.join("%%"); //fix //H'd4PITAL R'c9GIONAL var re = /H'd4PITAL R'c9GIONAL DE /g ; payload = (payload).replace(re, ""); //drop multiple __ and or spaces re = /[-_\s]{3,}/gi ; payload = (payload).replace(re, " "); //formatting codes //\T\ Oscar supports and changes to & // the following are Sudbury specific and rarely used // and would require more code to support // \ZU\ underline // \ZI\ italic // \ZIU\ italic underline // \ZHI\ bold italic // \ZHIU\ bold italic underlined // \ZTAB\ tab // drop unsupported formatting tags re = /\\ZU\\/g ; payload = (payload).replace(re, ""); re = /\\ZI\\/g ; payload = (payload).replace(re, ""); re = /\\ZIU\\/g ; payload = (payload).replace(re, ""); re = /\\ZHI\\/g ; payload = (payload).replace(re, ""); re = /\\ZHIU\\/g ; payload = (payload).replace(re, ""); re = /\\ZTAB\\/g ; payload = (payload).replace(re, ""); re = /\\H\\/g ; payload = (payload).replace(re, ""); //abstract data //CC: Leary,Tara J MD; McDermott,Thomas M MD //OBR.28.1 re = /CC:\s(.*?)%%/ ; //*? non greedy if (payload.match(re)){ var match = re.exec(payload); msg['OBR'][0]['OBR.28']['OBX.28.2']=match[1]; } //Copies to: MCDERMOTT, THOMAS M
// RAHN, RAYMOND J //the following captures both at this point re = /Copies to:\s(.*?)<br>/ ; //*? non greedy ,?\s?[A-Z]*\s*?[A-Z]? if (payload.match(re)){ var match = re.exec(payload); msg['OBR'][0]['OBR.28']['OBR.28.2']=match[1]; } if ( msg['OBR'][0]['OBR.3']['OBR.3.1'].toString().length >0 ) { msg['ORC'][0]['ORC.2']['ORC.2.1']=msg['OBR'][0]['OBR.3']['OBR.3.1'].toString(); msg['OBR'][0]['OBR.2']['OBR.2.1']=msg['OBR'][0]['OBR.3']['OBR.3.1'].toString(); } else { //Report #: 2107-007 re = /Report\s*?#:\s(.*?)\s/ ; //*? non greedy if (payload.match(re)){ var match = re.exec(payload); //ORC.2 OBR.2 msg['ORC'][0]['ORC.2']['ORC.2.1']=match[1]; msg['OBR'][0]['OBR.2']['OBR.2.1']=match[1]; } } //label consults as such // note this will potentially overcall so let it be overwritten // with more specific terms if appropriate by // putting this check first re = /Consultation Note|Consultation Report/i ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Consult"; } //label h&p as such re = /HISTORY\s*PHYSICAL/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="History"; } //label discharge summaries as such re = /Discharge Date:.*Date of Admission:|DISCHARGE SUMMARY/i ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Discharge Summary"; } //label operative summaries as such re = /OPERATION|OPERATIVE REPORT/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Operative Report"; } // Radiology reports non greedy! re = /PROCEDURES: Radiology Chest/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="CXR"; } //re = /PROCEDURES:\s*Radiology\s*([A-Z]\D*\b)\s?[\d\.]/ ; //label cancer clinic summaries as such re = /Regional Cancer Program/i ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Cancer Clinic"; } //label progress notes as such re = /PROGRESS NOTE|Progress Note/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Progress Note"; } //label respiratory notes as such re = /RESPIRATORY THERAPY REPORT/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Respiratory"; } //label letters as such re = /LETTER/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Letter"; } //label outpatient notes as such re = /OUTPATIENT CLINIC NOTE|OUTPATIENT NOTE|Ambulatory Care Unit Note/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Clinics"; } // ### CLEANUP THE OUTPUT ### // drop pagation headers as Oscar pagation is different // remove the footer and header in multipage reports //myRe = /[%\s]*\w*\s\w*\sCont.*?Page\s\d\sof\s\d[%\s]*/g; // better handling of two page HISTORY & PHYSICAL //myRe = /[%\s]*\w*(\s&)?\s\w*\sCont.*?Page\s\d\sof\s\d[%\s]*/g; // works ish myRe = /[%\s]*(TEMISKAMING|OUTPATIENT CLINIC NOTE Contd)[\w\W]*?[%\s]*Page\s\d\sof\s\d[%\s]*/g; re = /[%\s]*TEMISKAMING[\w\s%-:#]*?[%\s]*Page\s\d\sof\s\d[%\s]*/g; if (payload.match(re)) { payload=payload.replace(re,"%%"); } else { // for New Liskeard Echo //[%\s]*?Page\s\d\sof\s\d.*?%% re = /[%\s]*?Page\s\d\sof\s\d.*?%%/g; if (payload.match(re)) { payload=payload.replace(re,"%%"); } else { // for North Bay header re = /NORTH BAY REGIONAL HEALTH CENTRE.{190,290}\(continued\)\s?%{2,}\s?/ ; if (payload.match(re)) { payload = (payload).replace(re, " "); } } } // To keep HAPI happpy do not give it more than one ## re = /#{2,}\s*/gi ; payload = (payload).replace(re, "#"); // four or more %% is an intentional paragraph break re = /\s?%{4,}\s*/gi ; payload = (payload).replace(re, "<br><br>"); // A capitalised heading followed by %% is an intentional paragraph break re = /([A-Z]\s*:)\s?%{2,}\s*/g ; payload = (payload).replace(re, "$1<br><br>"); // a period followed by %% is an intentional paragraph break // EXCEPT when it is an abbreviation such as Dr. re = /Dr\.\s*?%{2,}\s*/gi ; payload = (payload).replace(re, "Dr. "); // a period followed by %% is an intentional paragraph break re = /\.\s*?%{2,}\s*/gi ; payload = (payload).replace(re, ".<br><br>"); // for Cancer Clinic --108 is an intentional paragraph break re = /--108\s*/gi ; payload = (payload).replace(re, "<br><br>"); // Patient: HUTTEN,PETER re = /(Patient:\s\s[A-Z]{3,})/ ; payload = (payload).replace(re, "<br>$1"); // Unit#: SH00590986 re = /(Unit#:\s\s[A-Z]{2})/ ; payload = (payload).replace(re, "<br>$1"); // DOB - Age re = /(DOB\s-\sAge)/ ; payload = (payload).replace(re, "<br>$1"); // Account#: SC196219/12 re = /(Account#:\s\s[A-Z])/ ; payload = (payload).replace(re, "<br>$1"); // Patient Location: SRM CLIDIA re = /(Patient\sLocation:\s[A-Z]{3,})/ ; payload = (payload).replace(re, "<br>$1"); // drop single line breaks as they mess up the output re = /\s?%{2,}\s?/gi ; payload = (payload).replace(re, " "); re = /&/gi ; payload = (payload).replace(re, " and "); //word wrap the output //payload=payload+" "; //wordwrap(payload,100,'<br>'); //reform the array noteArray=payload.split("<br><br>"); //populate the notes var j=0; for(var i=0;i<msg['NTE'].length();i++ ){ if (j<noteArray.length) { msg['NTE'][i]['NTE.2']['NTE.2.1'] = "L"; //source of comment if (msg['NTE'][i]['NTE.3']['NTE.3.1'].toString().length<1){ //if (noteArray[j].toString().length<1){ j++;} if ((noteArray[j].toString().length>0)&&((noteArray[j].toString()).lastIndexOf('.',noteArray[j].toString().length)<(noteArray[j].length-1))) {noteArray[j]=noteArray[j].toString()+' '} msg['NTE'][i]['NTE.3']['NTE.3.1'] = wordwrap(noteArray[j].toString(),100,'<br>'); j++; } } } // delete unwanted results marked as DNR do not report. // note that deleting the node resets the index so we have to do i-- for(var i=0;i<msg['OBX'].length();i++ ){ if (msg['OBX'][i]['OBX.5']['OBX.5.1'].toString() == "DNR") { delete msg['OBX'][i]; i--; } } // clean up OBX for(var i=0;i<msg['OBX'].length();i++ ){ var re = /\s*\\H\\\s/ ; msg['OBX'][i]['OBX.5']['OBX.5.1']= msg['OBX'][i]['OBX.5']['OBX.5.1'].toString().replace(re,""); } // delete unwanted results marked as DNR do not report. // note that deleting the node resets the index so we have to do i-- for(var i=0;i<msg['NTE'].length();i++ ){ if (msg['NTE'][i]['NTE.3']['NTE.3.1'].toString() == "") { delete msg['NTE'][i]; i--; } } //OSCAR will allow <br> to format both screen and pdf output function wordwrap( str, width, brk ) { brk = brk || '\n'; width = width || 80; if (!str) { return str; } // doesnt work var myRe = new RegExp('(.{1,'+width+'}[\\s|.|$])','g'); var myRe = /(.{1,100}[\s|.|$])/g; //***test for match first*** if (str.match(myRe)) { /*Success!*/ return str.match( myRe ).join( brk ); } else { // there is no match for lines between paragraphs return str; } } //end</script> <type>JavaScript</type> <data class="map"> <entry> <string>Script</string> <string>// Copyright (c) 2011-2012 by Peter Hutten-Czapski //msg - array representing XML of the data being transformed //makework fix the input back to Su=dbury standard Processing ID msg['MSH']['MSH.11']['MSH.11.1']="T"; //end makework //OSCAR handles versions 2.5, 2.6, 2.3, 2.2 //so make HAPI happy if its 2.4 by downgrading //if (msg['MSH']['MSH.12']['MSH.12.1'].toString()=="2.4") { msg['MSH']['MSH.12']['MSH.12.1']="2.3"; //} //set some natural language locations, especially if particularly obscure if (msg['MSH']['MSH.4']['MSH.4.1'].toString()=="TEM"){ msg['MSH']['MSH.4']['MSH.4.1']="Temiskaming Hospital"; } if (msg['MSH']['MSH.4']['MSH.4.1'].toString()=="SJH"){ msg['MSH']['MSH.4']['MSH.4.1']="North Bay Regional"; } // fudge if something has passed all prior opportunities if (msg['OBX'][0]['OBX.3']['OBX.3.2'].length()<1) { msg['OBX'][0]['OBX.3']['OBX.3.2']="Report"; } var i=0; var hin=""; for (pid in msg..PID){ // populate PID.4 the Alternate Patient ID with the HIN from PID.3 so Oscar can display it msg['PID'][i]['PID.4']['PID.4.1'] = msg['PID'][i]['PID.2']['PID.2.1'].toString(); msg['PID'][i]['PID.4']['PID.4.2'] = msg['PID'][i]['PID.2']['PID.2.2'].toString(); //msg['PID'][i]['PID.4']['PID.4.3'] = msg['PID'][i]['PID.2']['PID.2.3'].toString(); i++; } //Iterate through the segments OBX observations/results // add and remove some var NTEcount = 0; // new notes start at 0 var OBRcount = 0; var OBXcount = 0; var nte = createSegment('NTE'); var noteArray=new Array(); var noteIndex=new Array(); var ptCount=0; var PV1count=0; var categorytype="REPORT"; var reporttype="NEON REPORT"; var obr42=""; var obx31=""; var x="t"; i=0; for each(segment in msg.children()){ if(segment.name() == "PID"){ var dob = segment['PID']['PID.7']['PID.7.1'].toString(); var gender = segment['PID']['PID.8']['PID.8.1'].toString(); } if(segment.name() == "PV1"){ var attdocid = msg['OBR'][ptCount]['OBR.32']['OBR.32.1'].toString() var docid = attdocid.split("&"); //var attdocid = msg['PV1'][ptCount]['PV1.17']['PV1.17.3'].toString() //var docid = attdocid.split("~"); attdocid=docid[0]||"111111"; //var attdocName=msg['PV1'][ptCount]['PV1.17']['PV1.17.2'].toString()+", "+ msg['PV1'][ptCount]['PV1.17']['PV1.17.3'].toString(); var attdocName=(docid[1]||"")+", "+(docid[2]||"") var orc=createSegment('ORC'); createSegmentAfter('ORC', msg['PV1'][ptCount]); msg['ORC'][ptCount] = orc; msg['ORC'][ptCount]['ORC.1']['ORC.1.1'] = ptCount+1; // provide UUID or Accession Number to ORC.2 msg['ORC'][ptCount]['ORC.2']['ORC.2.1'] = msg['OBR'][ptCount]['OBR.3']['OBR.3.1'].toString(); //provide order status from OBR 25.1 msg['ORC'][ptCount]['ORC.5']['ORC.5.1'] = msg['OBR'][ptCount]['OBR.25']['OBR.25.1'].toString(); //parse OBR28 looking for local doc or use PV1.52 msg['ORC'][ptCount]['ORC.12']['ORC.12.1'] = attdocid msg['ORC'][ptCount]['ORC.12']['ORC.12.2'] = attdocName //order effective time set to message time msg['ORC'][ptCount]['ORC.15']['ORC.15.1'] = msg['MSH']['MSH.7']['MSH.7.1'].toString(); delete msg['PV1'][ptCount]; ptCount = ptCount+1; //sequence incriment } if(segment.name() == "OBR"){ //for sake of argument we will call ther placer (2) to have the same order number as the filler (3) msg['OBR'][OBRcount]['OBR.2']['OBR.2.1']=msg['OBR'][OBRcount]['OBR.3']['OBR.3.1'].toString(); if (msg['OBR'][OBRcount]['OBR.4']['OBR.4.1'].toString().length>0) { //leave it } else { msg['OBR'][OBRcount]['OBR.4']['OBR.4.1']="Report"; } //fudge to change requested date with observerd date as we look to when a Xray was taken as its date not the report //if (msg['OBR']['OBR.7']['OBR.7.1'].toString().length>0) { //var tdate=msg['OBR']['OBR.7']['OBR.7.1'].toString(); //msg['OBR']['OBR.7']['OBR.7.1']=msg['OBR']['OBR.6']['OBR.6.1'].toString(); //msg['OBR']['OBR.6']['OBR.6.1']=tdate; //} //OBR 4.2 not needed and more compact output if dropped, but keep the value obr42=msg['OBR'][OBRcount]['OBR.4']['OBR.4.2'].toString(); msg['OBR'][OBRcount]['OBR.4']['OBR.4.2']=""; //if (!((msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString()=="TEDIIDIR")||(msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString()=="TEDIIMAM"))) { if (msg['OBR']['OBR.16']['OBR.16.1'].toString().length<1) { msg['OBR'][OBRcount]['OBR.16']['OBR.16.1']=attdocid; } if (msg['OBR']['OBR.16']['OBR.16.2'].toString().length<1) { msg['OBR'][OBRcount]['OBR.16']['OBR.16.2']=attdocName; } // OBR20 codes. DEPRECATED OR CONTAINS SENDING FACILITY FOR SOME OUTPUT // CAR Cardiology // DII Diagnostic Imaging // EDS Electrodiagnostic Services // HER Health Records // MEH Mental Health // RET Respiratory Therapy // THS Therapeutic Services if (msg['OBR'][OBRcount]['OBR.20']['OBR.20.1'].toString().length>0) { categorytype=msg['OBR'][OBRcount]['OBR.20']['OBR.20.1'].toString(); if (categorytype=="HER") { categorytype="Health Records"; } if (categorytype=="DII") { categorytype="Imaging"; } } if (msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString().length>0) { reporttype=msg['OBR'][OBRcount]['OBR.21']['OBR.21.1'].toString(); } // OBR24.1 codes // MIC Microbiology // LAB Labwork // PTH Pathology if (msg['OBR'][OBRcount]['OBR.24']['OBR.24.1'].length()>0) { categorytype=msg['OBR'][OBRcount]['OBR.24']['OBR.24.1'].toString(); } if (msg['OBR'][OBRcount]['OBR.25']['OBR.25.1'].length()==0) { //if report status NULL assume it F msg['OBR'][OBRcount]['OBR.25']['OBR.25.1']="F"; } OBRcount= OBRcount+1; } if(segment.name() == "OBX"){ obx31=msg['OBX'][OBXcount]['OBX.3']['OBX.3.1'].toString(); x=obx31; switch (obx31) { case "TSH_N": x="4025"; break; case "INRP": x="2165"; break; case "BILIC": x="26196"; break; case "BILIU": x="26194"; break; case "ALP": x="3360"; break; case "K": x="3220"; break; case "NA": x="3210"; break; case "CL": x="3230"; break; case "CREAT": x="3180"; break; case "HGB": x="2010"; break; case "WBC": x="2016"; break; case "PLTC": x="2111"; break; case "NE#": x="2191"; break; case "RBC": x="2019"; break; case "MG": x="3165"; break; case "CA": x="3280"; break; case "AST": x="3370"; break; case "ALT": x="3380"; break; case "LDH": x="3390"; break; case "CK": x="3400"; break; case "PSA": x="4190"; break; case "DIGOXIN": x="4080"; break; case "CHOL": x="3120"; break; case "LDL": x="3933"; break; case "HDL_N": x="3923"; break; case "ALB": x="28872"; break; } msg['OBX'][OBXcount]['OBX.4']['OBX.4.1']=categorytype+ '/' +reporttype; if(( categorytype != "LAB")&&( categorytype != "MIC")&&( categorytype != "CHE")&&( categorytype != "POC")&&( categorytype != "IMM")&&( categorytype != "COA")&&( categorytype != "HEM")&&( categorytype != "HCM")&&( categorytype != "BOF")&&( categorytype != "URI")){ // Reformat OBX's into NTE text output // how about discharge summery or similar msg['OBX'][OBXcount]['OBX.3']['OBX.3.2']=obr42+categorytype; createSegmentAfter('NTE', msg['OBX'][OBXcount]); //noteIndex[NTEcount]=msg['OBX'][i]['OBX.1']['OBX.1.1'].toString()-1; noteArray[NTEcount]=msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'].toString(); NTEcount++; if (OBXcount>0) { msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'] = "DNR"; //mark to delete } else { var payload=msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'].toString(); var re = /H'd4PITAL R'c9GIONAL DE /g ; msg['OBX'][OBXcount]['OBX.5']['OBX.5.1'] = (payload).replace(re, ""); msg['OBX'][OBXcount]['OBX.3']['OBX.3.2'] = obr42+categorytype; } } else { // get the displayed lab to the specfic and not the group //if (msg['OBX'][OBXcount]['OBX.3']['OBX.3.1'].length()>0) { //msg['OBX'][OBXcount]['OBX.3']['OBX.3.2']=msg['OBX'][OBXcount]['OBX.3']['OBX.3.1']; //} msg['OBX'][OBXcount]['OBX.3']['OBX.3.1']=x; var y=msg['OBX'][OBXcount]['OBX.4']['OBX.4.1'].toString(); switch (categorytype) { case "CHE": y="CHEMISTRY"; break; case "HEM": y="HEMATOLOGY"; break; } msg['OBX'][OBXcount]['OBX.4']['OBX.4.1']=y; } if (msg['OBX'][OBXcount]['OBX.3']['OBX.3.1'].toString()=="3180") { // since The Hospital doesn't supply eGFR calculate one var cr = msg['OBX'][OBXcount]['OBX.5']['OBX.5.1']; var today = new Date(); var year=today.getFullYear(); var age=year-dob.substring(0,4); var female_sex=false; if (gender=="F") { female_sex=true; } var eGFR= Math.round(Math.min((186.0 * Math.pow((cr/88.4),-1.154) * Math.pow(age, -0.203) * (female_sex ? 0.742 : 1.0)),90)); // changes in values over (60) 90 120 are not clinically significant //OBX|2|ST|3190^eGFR|CHEMISTRY^^|71||||||F||303^1003190||70 var obx=createSegment('OBX'); createSegmentAfter('OBX', msg['OBX'][OBXcount]); msg['OBX'][OBXcount+1] = obx; msg['OBX'][OBXcount+1]['OBX.1']['OBX.1.1'] = msg['OBX'][i]['OBX.1']['OBX.1.1']-0+1; msg['OBX'][OBXcount+1]['OBX.2']['OBX.2.1'] = "ST"; msg['OBX'][OBXcount+1]['OBX.3']['OBX.3.1'] = "3190"; //id msg['OBX'][OBXcount+1]['OBX.3']['OBX.3.2'] = "eGFR"; //id msg['OBX'][OBXcount+1]['OBX.4']['OBX.4.1'] = "CHEMISTRY"; msg['OBX'][OBXcount+1]['OBX.5']['OBX.5.1'] = eGFR; // result msg['OBX'][OBXcount+1]['OBX.6'] = "ml/min"; //units msg['OBX'][OBXcount+1]['OBX.7'] = ">60"; //reference range if (eGFR<60) {msg['OBX'][OBXcount+1]['OBX.8'] = "A";} //abnormal flag msg['OBX'][OBXcount+1]['OBX.13']['OBX.13.1'] = "303"; msg['OBX'][OBXcount+1]['OBX.13']['OBX.13.2'] = "1003190"; msg['OBX'][OBXcount+1]['OBX.15']['OBX.15.1'] = "70"; msg['OBX'][OBXcount+1]['OBX.11']['OBX.11.1'] = "F"; //'F'inal i++; OBXcount++; } i++; OBXcount++; } //end OBX }// end segment //concat the payload and clean it up var payload=noteArray.join("%%"); //fix //H'd4PITAL R'c9GIONAL var re = /H'd4PITAL R'c9GIONAL DE /g ; payload = (payload).replace(re, ""); //drop multiple __ and or spaces re = /[-_\s]{3,}/gi ; payload = (payload).replace(re, " "); //formatting codes //\T\ Oscar supports and changes to & // the following are Sudbury specific and rarely used // and would require more code to support // \ZU\ underline // \ZI\ italic // \ZIU\ italic underline // \ZHI\ bold italic // \ZHIU\ bold italic underlined // \ZTAB\ tab // drop unsupported formatting tags re = /\\ZU\\/g ; payload = (payload).replace(re, ""); re = /\\ZI\\/g ; payload = (payload).replace(re, ""); re = /\\ZIU\\/g ; payload = (payload).replace(re, ""); re = /\\ZHI\\/g ; payload = (payload).replace(re, ""); re = /\\ZHIU\\/g ; payload = (payload).replace(re, ""); re = /\\ZTAB\\/g ; payload = (payload).replace(re, ""); re = /\\H\\/g ; payload = (payload).replace(re, ""); //abstract data //CC: Leary,Tara J MD; McDermott,Thomas M MD //OBR.28.1 re = /CC:\s(.*?)%%/ ; //*? non greedy if (payload.match(re)){ var match = re.exec(payload); msg['OBR'][0]['OBR.28']['OBX.28.2']=match[1]; } //Copies to: MCDERMOTT, THOMAS M
// RAHN, RAYMOND J //the following captures both at this point re = /Copies to:\s(.*?)<br>/ ; //*? non greedy ,?\s?[A-Z]*\s*?[A-Z]? if (payload.match(re)){ var match = re.exec(payload); msg['OBR'][0]['OBR.28']['OBR.28.2']=match[1]; } if ( msg['OBR'][0]['OBR.3']['OBR.3.1'].toString().length >0 ) { msg['ORC'][0]['ORC.2']['ORC.2.1']=msg['OBR'][0]['OBR.3']['OBR.3.1'].toString(); msg['OBR'][0]['OBR.2']['OBR.2.1']=msg['OBR'][0]['OBR.3']['OBR.3.1'].toString(); } else { //Report #: 2107-007 re = /Report\s*?#:\s(.*?)\s/ ; //*? non greedy if (payload.match(re)){ var match = re.exec(payload); //ORC.2 OBR.2 msg['ORC'][0]['ORC.2']['ORC.2.1']=match[1]; msg['OBR'][0]['OBR.2']['OBR.2.1']=match[1]; } } //label consults as such // note this will potentially overcall so let it be overwritten // with more specific terms if appropriate by // putting this check first re = /Consultation Note|Consultation Report/i ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Consult"; } //label h&p as such re = /HISTORY\s*PHYSICAL/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="History"; } //label discharge summaries as such re = /Discharge Date:.*Date of Admission:|DISCHARGE SUMMARY/i ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Discharge Summary"; } //label operative summaries as such re = /OPERATION|OPERATIVE REPORT/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Operative Report"; } // Radiology reports non greedy! re = /PROCEDURES: Radiology Chest/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="CXR"; } //re = /PROCEDURES:\s*Radiology\s*([A-Z]\D*\b)\s?[\d\.]/ ; //label cancer clinic summaries as such re = /Regional Cancer Program/i ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Cancer Clinic"; } //label progress notes as such re = /PROGRESS NOTE|Progress Note/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Progress Note"; } //label respiratory notes as such re = /RESPIRATORY THERAPY REPORT/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Respiratory"; } //label letters as such re = /LETTER/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Letter"; } //label outpatient notes as such re = /OUTPATIENT CLINIC NOTE|OUTPATIENT NOTE|Ambulatory Care Unit Note/ ; if (payload.match(re)){ msg['OBX'][0]['OBX.4']['OBX.4.1']="Clinics"; } // ### CLEANUP THE OUTPUT ### // drop pagation headers as Oscar pagation is different // remove the footer and header in multipage reports //myRe = /[%\s]*\w*\s\w*\sCont.*?Page\s\d\sof\s\d[%\s]*/g; // better handling of two page HISTORY & PHYSICAL //myRe = /[%\s]*\w*(\s&)?\s\w*\sCont.*?Page\s\d\sof\s\d[%\s]*/g; // works ish myRe = /[%\s]*(TEMISKAMING|OUTPATIENT CLINIC NOTE Contd)[\w\W]*?[%\s]*Page\s\d\sof\s\d[%\s]*/g; re = /[%\s]*TEMISKAMING[\w\s%-:#]*?[%\s]*Page\s\d\sof\s\d[%\s]*/g; if (payload.match(re)) { payload=payload.replace(re,"%%"); } else { // for New Liskeard Echo //[%\s]*?Page\s\d\sof\s\d.*?%% re = /[%\s]*?Page\s\d\sof\s\d.*?%%/g; if (payload.match(re)) { payload=payload.replace(re,"%%"); } else { // for North Bay header re = /NORTH BAY REGIONAL HEALTH CENTRE.{190,290}\(continued\)\s?%{2,}\s?/ ; if (payload.match(re)) { payload = (payload).replace(re, " "); } } } // To keep HAPI happpy do not give it more than one ## re = /#{2,}\s*/gi ; payload = (payload).replace(re, "#"); // four or more %% is an intentional paragraph break re = /\s?%{4,}\s*/gi ; payload = (payload).replace(re, "<br><br>"); // A capitalised heading followed by %% is an intentional paragraph break re = /([A-Z]\s*:)\s?%{2,}\s*/g ; payload = (payload).replace(re, "$1<br><br>"); // a period followed by %% is an intentional paragraph break // EXCEPT when it is an abbreviation such as Dr. re = /Dr\.\s*?%{2,}\s*/gi ; payload = (payload).replace(re, "Dr. "); // a period followed by %% is an intentional paragraph break re = /\.\s*?%{2,}\s*/gi ; payload = (payload).replace(re, ".<br><br>"); // for Cancer Clinic --108 is an intentional paragraph break re = /--108\s*/gi ; payload = (payload).replace(re, "<br><br>"); // Patient: HUTTEN,PETER re = /(Patient:\s\s[A-Z]{3,})/ ; payload = (payload).replace(re, "<br>$1"); // Unit#: SH00590986 re = /(Unit#:\s\s[A-Z]{2})/ ; payload = (payload).replace(re, "<br>$1"); // DOB - Age re = /(DOB\s-\sAge)/ ; payload = (payload).replace(re, "<br>$1"); // Account#: SC196219/12 re = /(Account#:\s\s[A-Z])/ ; payload = (payload).replace(re, "<br>$1"); // Patient Location: SRM CLIDIA re = /(Patient\sLocation:\s[A-Z]{3,})/ ; payload = (payload).replace(re, "<br>$1"); // drop single line breaks as they mess up the output re = /\s?%{2,}\s?/gi ; payload = (payload).replace(re, " "); re = /&/gi ; payload = (payload).replace(re, " and "); //word wrap the output //payload=payload+" "; //wordwrap(payload,100,'<br>'); //reform the array noteArray=payload.split("<br><br>"); //populate the notes var j=0; for(var i=0;i<msg['NTE'].length();i++ ){ if (j<noteArray.length) { msg['NTE'][i]['NTE.2']['NTE.2.1'] = "L"; //source of comment if (msg['NTE'][i]['NTE.3']['NTE.3.1'].toString().length<1){ //if (noteArray[j].toString().length<1){ j++;} if ((noteArray[j].toString().length>0)&&((noteArray[j].toString()).lastIndexOf('.',noteArray[j].toString().length)<(noteArray[j].length-1))) {noteArray[j]=noteArray[j].toString()+' '} msg['NTE'][i]['NTE.3']['NTE.3.1'] = wordwrap(noteArray[j].toString(),100,'<br>'); j++; } } } // delete unwanted results marked as DNR do not report. // note that deleting the node resets the index so we have to do i-- for(var i=0;i<msg['OBX'].length();i++ ){ if (msg['OBX'][i]['OBX.5']['OBX.5.1'].toString() == "DNR") { delete msg['OBX'][i]; i--; } } // clean up OBX for(var i=0;i<msg['OBX'].length();i++ ){ var re = /\s*\\H\\\s/ ; msg['OBX'][i]['OBX.5']['OBX.5.1']= msg['OBX'][i]['OBX.5']['OBX.5.1'].toString().replace(re,""); } // delete unwanted results marked as DNR do not report. // note that deleting the node resets the index so we have to do i-- for(var i=0;i<msg['NTE'].length();i++ ){ if (msg['NTE'][i]['NTE.3']['NTE.3.1'].toString() == "") { delete msg['NTE'][i]; i--; } } //OSCAR will allow <br> to format both screen and pdf output function wordwrap( str, width, brk ) { brk = brk || '\n'; width = width || 80; if (!str) { return str; } // doesnt work var myRe = new RegExp('(.{1,'+width+'}[\\s|.|$])','g'); var myRe = /(.{1,100}[\s|.|$])/g; //***test for match first*** if (str.match(myRe)) { /*Success!*/ return str.match( myRe ).join( brk ); } else { // there is no match for lines between paragraphs return str; } } //end</string> </entry> </data> </com.webreach.mirth.model.Step> </steps> <inboundTemplate>MSH|^~\&|ITS|SRH|||20110629134750||ORU^R01|15A0-4E0B6546DF|T|2.3
PID|1|9792463243^LX^ON^0641002|9792463243^LX^ON||TEST^JENNA||19850731|F|||12 TEST LANE^^SUDBURY^ON^P3A 1J8|||||||SI000150/11|1111111116 ORC|NW|0101-0042|||F|||||||247486^OrderingMD|||20101129
PV1|1|I|SRHSPED3^SRH3110^2|L|||TST.FISCO^Fisher^Cory^IT Tech^^^^PRV~56789^^^^^^^PPN|TST.KULAN^Kulyski^Andrea^IT Tech^^^^PRV~25874^^^^^^^PPN|TST.BRORE^BROOKIE^BECKS^^^^^PRV~98745^^^^^^^PPN|PEME||||04|||TST.KULAN^Kulyski^Andrea^IT Tech^^^^PRV~25874^^^^^^^PPN|IN||01|||||||||||||||||||SRH||ADM|||201009281023||||||||TST.KULAN^Kulyski^Andrea^^^^^PRV~25874^^^^^^^PPN~HUTTE.PE01^Hutten-Czapski^Peter^^^^^PRV~57283^^^^^^^PPN
OBR|1||1102:H00280R^SRH|HER^HER|||201106291319|201106291319||||||||173948^DR MCDERMOTT||||HER|SRFN|201106291322|||P|||TST.ROSDA^Ross^Dan^ITS^^^^PRV~12345^^^^^^^PPN~TST.FISCO^Fisher^Cory^IT Tech^^^^PRV~56789^^^^^^^PPN~DSUDHER^Serv.^HRSRH^Health Information^^^^PRV~^^^^^^^PPN||||HUTTE.PE01&Hutten-Czapski&Peter&A&&&MD&PRV|||ROSDA01&&&&&&&PRV~&&&&&&&NPI
OBX|1|TX|ITS^ITS REPORT|| \H\ Sudbury Regional Hospital ||||||P
OBX|2|TX|ITS^ITS REPORT|| Health Records||||||P
OBX|3|TX|ITS^ITS REPORT|| HRSRH Laurentian Site||||||P
OBX|4|TX|ITS^ITS REPORT|| ______________________________________________________________________________________________________||||||P
OBX|5|TX|ITS^ITS REPORT|| Patient: TEST,JENNA Unit#: SH00001057||||||P
OBX|6|TX|ITS^ITS REPORT|| DOB - Age- Sex: 31/07/1985 - 25 - F Account#: SI000150/11||||||P
OBX|7|TX|ITS^ITS REPORT|| Dictating Doctor:: Hutten-Czapski,Peter A MD ||||||P
OBX|8|TX|ITS^ITS REPORT|| Patient Location: SRHSPED3 ||||||P
OBX|9|TX|ITS^ITS REPORT|| SRH3110-2||||||P
OBX|10|TX|ITS^ITS REPORT|| Discharge Date: ||||||P
OBX|11|TX|ITS^ITS REPORT||||||||P
OBX|12|TX|ITS^ITS REPORT||||||||P
OBX|13|TX|ITS^ITS REPORT||||||||P
OBX|14|TX|ITS^ITS REPORT||||||||P
OBX|15|TX|ITS^ITS REPORT|| Test||||||P
OBX|16|TX|ITS^ITS REPORT||||||||P
OBX|17|TX|ITS^ITS REPORT||||||||P
OBX|18|TX|ITS^ITS REPORT||||||||P
OBX|19|TX|ITS^ITS REPORT||||||||P
OBX|20|TX|ITS^ITS REPORT||||||||P
OBX|21|TX|ITS^ITS REPORT||||||||P
OBX|22|TX|ITS^ITS REPORT|| CC: Fisher,Cory IT Tech; HRSRH Health Information Serv.; Hutten-Czapski,Peter A MD; Kulyski,Andrea IT Tech; Ross,Dan ITS ||||||P
OBX|23|TX|ITS^ITS REPORT|| Report #: 2906-0002 ||||||P
OBX|24|TX|ITS^ITS REPORT|| Transcribed Date/Time : 29/06/11 1319 Transcribed By : ROSDA01||||||P
OBX|25|TX|ITS^ITS REPORT||||||||P
OBX|26|TX|ITS^ITS REPORT||||||||P
OBX|27|TX|ITS^ITS REPORT||||||||P
</inboundTemplate> <outboundTemplate></outboundTemplate> <inboundProtocol>HL7V2</inboundProtocol> <outboundProtocol>HL7V2</outboundProtocol> <inboundProperties> <property name="handleRepetitions">false</property> <property name="convertLFtoCR">true</property> <property name="useStrictValidation">false</property> <property name="useStrictParser">false</property> </inboundProperties> <outboundProperties> <property name="handleRepetitions">false</property> <property name="convertLFtoCR">false</property> <property name="useStrictValidation">false</property> <property name="useStrictParser">false</property> </outboundProperties> </transformer> <filter> <rules/> </filter> <transportName>File Writer</transportName> <mode>DESTINATION</mode> <enabled>true</enabled> </com.webreach.mirth.model.Connector> <com.webreach.mirth.model.Connector> <name>email notification to PHC</name> <properties> <property name="fromAddress">phuttenczapski@haileyburyfht.org</property> <property name="attachmentNames"><list/></property> <property name="emailSecure">none</property> <property name="attachmentContents"><list/></property> <property name="username"></property> <property name="DataType">Email Sender</property> <property name="body">This is an automated notification that the HICL channel that transforms HICL data has just processed a file attributed to you ${ORIGINALNAME}</property> <property name="subject">You have Labwork ${ORIGINALNAME}</property> <property name="hostname">smtp.localhost.ca</property> <property name="smtpPort">25</property> <property name="toAddresses">phuttenczapski@gmail.com</property> <property name="contentType">text/plain</property> <property name="password"></property> <property name="attachmentTypes"><list/></property> </properties> <transformer> <steps/> <inboundTemplate></inboundTemplate> <outboundTemplate></outboundTemplate> <inboundProtocol>HL7V2</inboundProtocol> <outboundProtocol>HL7V2</outboundProtocol> <inboundProperties> <property name="handleRepetitions">false</property> <property name="convertLFtoCR">true</property> <property name="useStrictValidation">false</property> <property name="useStrictParser">false</property> </inboundProperties> <outboundProperties/> </transformer> <filter> <rules> <com.webreach.mirth.model.Rule> <sequenceNumber>0</sequenceNumber> <name>New Rule</name> <data class="map"> <entry> <string>Script</string> <string>return true;</string> </entry> </data> <type>JavaScript</type> <script>return true;</script> <operator>NONE</operator> </com.webreach.mirth.model.Rule> </rules> </filter> <transportName>Email Sender</transportName> <mode>DESTINATION</mode> <enabled>false</enabled> </com.webreach.mirth.model.Connector> </destinationConnectors> <properties> <property name="synchronous">true</property> <property name="removeNamespace">true</property> <property name="transactional">false</property> <property name="initialState">started</property> <property name="dont_store_filtered">false</property> <property name="error_messages_only">false</property> <property name="max_message_age">60</property> <property name="store_messages">true</property> <property name="encryptData">true</property> </properties> <preprocessingScript>// Modify the message variable below to pre process data
 return message;</preprocessingScript> <postprocessingScript>// This script executes once after a message has been processed return;</postprocessingScript> <deployScript>// This script executes once when the mule engine is started // You only have access to the globalMap here to persist data return;</deployScript> <shutdownScript>// This script executes once when the mule engine is stopped // You only have access to the globalMap here to persist data return;</shutdownScript> </com.webreach.mirth.model.Channel>