Skip to content

Instantly share code, notes, and snippets.

@MichaelLeeHobbs
Last active April 20, 2021 18:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MichaelLeeHobbs/bbcb51fdd82e3b9041b0e1fe409215f9 to your computer and use it in GitHub Desktop.
Save MichaelLeeHobbs/bbcb51fdd82e3b9041b0e1fe409215f9 to your computer and use it in GitHub Desktop.
A new way to write Mirth Connect Messages
function getReportDataFromPacsORU(json) {
const pacsDT_HL7DT = (val) => (val || '').replace(/[: -]]/g, '').split('.')[0]
const pacsDate_HL7D = (val) => (val || '').replace(/-/g, '').split(' ')[0]
const $data = json.V_ALLDATA
const msgDT = $data['V_MESSAGEHEADER']['MSGDATETIME'].slice(0,-5)
const msgID = $data['V_MESSAGEHEADER']['MSGCONTROLID']
const {ACCESSIONNUMBER, INSTITUTIONNAME, REQUESTEDPROCEDUREID, STUDYDESCRIPTION, STUDYINSTANCEUID, STUDYDATETIME, MODALITY, PRIORITY} = $data['V_STUDYINFO']
const {PATIENTID, LASTNAME, FIRSTNAME, MIDDLENAME, SEX, BIRTHDATE} = $data['V_PATIENTGENERAL']
const VISITDATETIME = pacsDT_HL7DT($data.V_PATIENTVISIT.VISITDATETIME)
const dob = pacsDate_HL7D(BIRTHDATE)
const {REFPHY_NPI, REFPHY_LASTNAME, REFPHY_FIRSTNAME} = $data['V_STUDYPLAYERS']
const {OBSERVER_NPI, OBSERVER_LASTNAME, OBSERVER_FIRSTNAME, OBSERVER_MIDDLENAME, OBSERVER_SUFFIX: OBSERVER_DEGREE, OBSERVER_DATETIME, BUFFERCONTENT, BUFFERCONTENT_PDF, DOCUMENT_TITLE, DOCUMENT_FILEKIND} = $data['V_OBSERVATIONREPORT']
var BUFFERCONTENT_TXT = $data.V_OBSERVATIONREPORT.BUFFERCONTENT_TXT
if (!BUFFERCONTENT_TXT && DOCUMENT_FILEKIND === 'TXT') BUFFERCONTENT_TXT = BUFFERCONTENT
const studyDT = pacsDT_HL7DT(STUDYDATETIME)
const reportURL = ''
return {
MSGDATETIME: msgDT, MSGCONTROLID: msgID,
ACCESSIONNUMBER: ACCESSIONNUMBER, INSTITUTIONNAME: INSTITUTIONNAME, REQUESTEDPROCEDUREID: REQUESTEDPROCEDUREID, STUDYDESCRIPTION: STUDYDESCRIPTION, STUDYINSTANCEUID: STUDYINSTANCEUID, STUDYDATETIME: studyDT, MODALITY: MODALITY,
PATIENTID: PATIENTID, LASTNAME: LASTNAME, FIRSTNAME: FIRSTNAME, MIDDLENAME: MIDDLENAME, SEX: SEX, BIRTHDATE: dob,
VISITDATETIME: VISITDATETIME, PRIORITY: PRIORITY,
REFPHY_NPI: REFPHY_NPI, REFPHY_LASTNAME: REFPHY_LASTNAME, REFPHY_FIRSTNAME: REFPHY_FIRSTNAME,
OBSERVER_NPI: OBSERVER_NPI, OBSERVER_LASTNAME: OBSERVER_LASTNAME, OBSERVER_FIRSTNAME: OBSERVER_FIRSTNAME, OBSERVER_MIDDLENAME: OBSERVER_MIDDLENAME, OBSERVER_DEGREE: OBSERVER_DEGREE,
OBSERVER_DATETIME: OBSERVER_DATETIME, BUFFERCONTENT: BUFFERCONTENT, BUFFERCONTENT_PDF: BUFFERCONTENT_PDF, BUFFERCONTENT_TXT: BUFFERCONTENT_TXT, DOCUMENT_TITLE: DOCUMENT_TITLE
}
}
function JaneDoeMemorialORU(pacsORU) {
const reportURL = ''
const {
MSGDATETIME, MSGCONTROLID, ACCESSIONNUMBER, INSTITUTIONNAME, REQUESTEDPROCEDUREID, STUDYDESCRIPTION, STUDYINSTANCEUID, STUDYDATETIME, MODALITY,
PATIENTID, LASTNAME, FIRSTNAME, MIDDLENAME, SEX, BIRTHDATE,
REFPHY_NPI, REFPHY_LASTNAME, REFPHY_FIRSTNAME, OBSERVER_NPI, OBSERVER_LASTNAME, OBSERVER_FIRSTNAME, OBSERVER_MIDDLENAME, OBSERVER_SUFFIX, OBSERVER_DATETIME, BUFFERCONTENT, BUFFERCONTENT_PDF,
} = getReportDataFromPacsORU(pacsORU)
const xml =
<>
MSH|^~\&amp;|JANEDOEMEMORIAL|MIRTH|{INSTITUTIONNAME}|PACS|{MSGDATETIME}||ORU^R01^ORU_R01|{MSGCONTROLID}||2.5.1|||AL||||
EVN|A01|{OBSERVER_DATETIME}||||||||||
PID|1|{PATIENTID}|{PATIENTID}||{LASTNAME}^{FIRSTNAME}^{MIDDLENAME}^^||{BIRTHDATE}|{SEX}|||^^^^|||||||{PATIENTID}||||||||||||||
PV1|1|O||^^ROMF|||^^^^^|{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}^^^{REFPHY_NPI}|||||||||{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}^^^{REFPHY_NPI}|{INSTITUTIONNAME}||||||{STUDYDATETIME}|
ORC|RE|{STUDYINSTANCEUID}|{ACCESSIONNUMBER}||{REQUESTEDPROCEDUREID}^{STUDYDESCRIPTION}|||||||{REFPHY_NPI}|{MODALITY}|{INSTITUTIONNAME}||{OBSERVER_DATETIME}||
OBR|1|{STUDYINSTANCEUID}|{ACCESSIONNUMBER}|^{REQUESTEDPROCEDUREID}^{STUDYDESCRIPTION}||{MODALITY}||{OBSERVER_DATETIME}|{OBSERVER_NPI}^{OBSERVER_LASTNAME}^{OBSERVER_FIRSTNAME}^{OBSERVER_MIDDLENAME}^^||||||{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}^^^{REFPHY_NPI}|{REFPHY_NPI}|||{reportURL}|||{REQUESTEDPROCEDUREID}^{STUDYDESCRIPTION}|||{REQUESTEDPROCEDUREID}^{STUDYDESCRIPTION}||{OBSERVER_DATETIME}||||||||||{OBSERVER_DATETIME}|
OBX|1|TX|R^REPORT^L||^^PDF^Base64^{BUFFERCONTENT_PDF}||||||F|||{OBSERVER_DATETIME}||
</>
return xmlStringToHL7(xml)
}
// JaneDoeMemorialORUDestinationTransformer.js
// Jane Doe Memorial
// inbound msg is from pacs
msg = JaneDoeMemorialORU(msg)
function JohnDoeMemorialORU(pacsORU) {
const reportURL = ''
const {
MSGDATETIME, MSGCONTROLID, ACCESSIONNUMBER, INSTITUTIONNAME, REQUESTEDPROCEDUREID, STUDYDESCRIPTION, STUDYINSTANCEUID, STUDYDATETIME, MODALITY, PRIORITY,
PATIENTID, LASTNAME, FIRSTNAME, MIDDLENAME, SEX, BIRTHDATE, VISITDATETIME,
REFPHY_NPI, REFPHY_LASTNAME, REFPHY_FIRSTNAME, OBSERVER_NPI,
OBSERVER_LASTNAME, OBSERVER_FIRSTNAME, OBSERVER_MIDDLENAME, OBSERVER_SUFFIX, OBSERVER_DATETIME, BUFFERCONTENT_TXT, BUFFERCONTENT_PDF,
DOCUMENT_TITLE
} = getReportDataFromPacsORU(pacsORU)
// getReportDataFromPacsORU - is pacs specific function to pull data out of the pacs oru message in a reusable way to DRY up ORU message generators
const reportType = DOCUMENT_TITLE.slice(0, 1)
const reportArr = BUFFERCONTENT_TXT.split('\\.br\\')
var xml =
<>
MSH|^~\&amp;|JOHNDOEMEMORIAL|MIRTH|{INSTITUTIONNAME}|MIRTH|{MSGDATETIME}||ORU^R01|{MSGCONTROLID}|P|2.3|||||||
PID|1|{PATIENTID}|{PATIENTID}||{LASTNAME}^{FIRSTNAME}^{MIDDLENAME}^^||{BIRTHDATE}|{SEX}||0
PV1|1|O|||||{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}|{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}|{OBSERVER_NPI}^{OBSERVER_LASTNAME}^{OBSERVER_FIRSTNAME}^{OBSERVER_MIDDLENAME}||||||||||{ACCESSIONNUMBER}|||||||||||||||||||||||||{VISITDATETIME}
ORC|RE|{ACCESSIONNUMBER}|{ACCESSIONNUMBER}||||^^^{STUDYDATETIME}|||||{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}|||||{INSTITUTIONNAME}|{MODALITY}|||{INSTITUTIONNAME}|
OBR|1|{ACCESSIONNUMBER}|{ACCESSIONNUMBER}|{REQUESTEDPROCEDUREID}^{STUDYDESCRIPTION}|{PRIORITY}||{OBSERVER_DATETIME}|^^^{STUDYDATETIME}||||||||{REFPHY_NPI}^{REFPHY_LASTNAME}^{REFPHY_FIRSTNAME}||||{OBSERVER_DATETIME}|||{MODALITY}|{reportType}||^^^{OBSERVER_DATETIME}|||||{OBSERVER_NPI}^{OBSERVER_LASTNAME}^{OBSERVER_FIRSTNAME}^{OBSERVER_MIDDLENAME}^^^^^^^^^{OBSERVER_DATETIME}^{OBSERVER_DATETIME}|{OBSERVER_NPI}^{OBSERVER_LASTNAME}^{OBSERVER_FIRSTNAME}^{OBSERVER_MIDDLENAME}||^^^
</>
// this is how you handle segments that repeat
reportArr.forEach((line, i) => xml += <>OBX|{(i + 1)}|FT|{STUDYDESCRIPTION}||{line}||||||{reportType}|||{OBSERVER_DATETIME}</> + '\r\n');
return xmlStringToHL7(xml)
}
// JohnDoeMemorialORUDestinationTransformer.js
// John Doe Memorial
// inbound msg is from pacs
msg = JohnDoeMemorialORU(msg)
// source Transformer
const FACILITY_NAME = tryIt(()=>msg.V_ALLDATA.V_IMAGINGFACILITY.FACILITYNAME, msg.V_ALLDATA.V_STUDYINFO.INSTITUTIONNAME)
const isPDF = tryIt(()=>msg.V_ALLDATA.V_OBSERVATIONREPORT.DOCUMENT_FILEKIND === 'PDF', false)
// Filter: John Doe Memorial
if (isPDF || FACILITY_NAME !== "John Doe Memorial") destinationSet.remove(["John Doe Memorial"])
// Filter: Jane Doe Memorial
if (!isPDF || FACILITY_NAME !== "Jane Doe Memorial") destinationSet.remove(["Jane Doe Memorial"])
function tryIt(fn, defaultValue) {
const runIt = (fn, args) => (typeof fn === 'function') ? fn(args) : fn
var result = undefined
try {
if (Array.isArray(fn)) fn.some(func=>(result = tryIt(func)) !== undefined)
else result = runIt(fn)
return result !== undefined ? result : runIt(defaultValue)
} catch (e) {
return runIt(defaultValue, e)
}
}
function xmlStringToHL7(xmlStr) {
return SerializerFactory.getSerializer('HL7V2').toXML(
String(xmlStr)
.replace(/^ +/gm, '')
.replace(/null/g, '')
.replace(/undefined/g, '')
.replace(/[^\r\n\x20-\x7E]/g, ' ')
.trim()
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment