<strong>Test</strong>: Final Code Tweaks
Contents
So in the vmd file the OBR.18 field was defined as a string – i.e. a ST composite type. There was a fragment of python script that appended ^NHCCVIS to the value.
Effectively this made the OBR.18.2 set to this value.
The difference showed up when comparing the strings directly. The other little difference is the the original interface appended \r to the last segment whereas the Translator interface did not.
This was easy to resolve by tweaking the vmd file and the editing the script. I also modified the script to tell me if the generated message was identical or not. The other trivial difference was a trailing \r at the end of the message. I made it so that test code will only run within the editor in test mode.
So here’s the final code. The CVISOutbound.vmd vmd file and the filter module:
require 'dateparse' require 'node' require 'dbfill' require 'diff' local conn = db.connect{ api=db.SQLITE, name='test', live=true } local function trace(a,b,c,d) return end function main(Data) local R = conn:query{ live=true, sql="SELECT * FROM NHCCVISREPORT WHERE MESSAGE_ID = "..Data } local Msg = hl7.message{vmd='CVISOutbound.vmd', name='NHCCVIS'} if #R == 0 then print("Odd - unable to find message matching this one.") return end MapMSH(Msg.MSH, R[1]) MapPID(Msg.PID, R[1]) MapPV1(Msg.PV1, R[1]) MapOBR(Msg.OBR, R[1]) MapOBX(Msg.OBX, R[1]) if iguana.isTest() then Compare(Msg) end queue.push{data=Msg:S()} end function Compare(Msg) local Out = Msg:S() local Orig, Different = dbfill.CompareMessage(Out) if Different then local R = diff.Compare(Orig, Msg) trace('There were '..#R..' differences.') else trace('Messages match!') end end function MapMSH(MSH, T) MSH[9][1]='ORU' MSH[9][2]='R01' MSH[3][1] = 'NHCCVIS' MSH[4][1] = 'NHC' MSH[5][1] = 'PCS' MSH[6][1] = 'EMR' MSH[12] = '2.3' MSH[10] = T.MSHMessageControlID MSH[7] = T.MSHDateTimeofMessage:HT() MSH[11][1] = 'T' return MSH end function node.HD(N) return os.date('%Y%m%d', dateparse.parse(N:S())) end function node.HT(N) return os.date('%Y%m%d%H%M%S', dateparse.parse(N:S())) end function MapPID(PID, T) PID[2][1] = T.PIDPatientIDExternalIDID PID[2][3] = '11' PID[2][4][1] = 'EMI Primary' PID[3][1] = T.PIDPatientIDInternalIDID PID[3][2] = T.PIDPatientIDInternalIDCheckDigit PID[3][3] = '11' PID[3][4][1] = 'MRN' PID[5][1] = T.PIDPatientNameFamilyName PID[5][2] = T.PIDPatientNameGivenName PID[7] = T.PIDDateTimeofBirth:HD() PID[8] = T.PIDSex PID[18][1] = T.PIDPatientAccountNumberID PID[18][4][1] = "Visit" return PID end function MapPV1(PV1, T) PV1[2] = 'OUTPATIENT' PV1[3][1] = 'NHCCVIS Assign' PV1[3][4][1] = 'NHC' PV1[18] = 'NA' PV1[19][1] = T.PVVisitNumberID PV1[19][4][1] = 'Visit' PV1[44] = T.PVAdmitDateTime:HT() end function MapOBR(OBR, T) OBR[2][2] = 'PCS' OBR[3][1] = T.OBRFillerOrderNumberEntityIdentifier OBR[3][2] = 'NHCCVIS' OBR[4][1] = T.OBRUniversalServiceIDIdentifier OBR[4][2] = T.OBRUniversalServiceIDText OBR[4][3] = 'NHCCVIS' OBR[7] = T.OBRObservationDateTime:HT() OBR[18][1] = T.OBRPlacerField OBR[18][2] = 'NHCCVIS' OBR[25] = 'F' OBR[27][6] = 'ROUTINE' return OBR end function MapOBX(OBX, T) OBX[1][1] = '1' OBX[1][2] = 'FT' OBX[1][3][1] = T.OBXObservationIdentifierIdentifier OBX[1][3][3] = 'NHCCVIS' OBX[1][5][1] = T.OBXObservationValue OBX[1][11] = 'F' OBX[2][1] = '2' OBX[2][2] = 'RP' OBX[2][5][1] = T.OBXObservationValue1 OBX[2][3][1] = T.OBXObservationIdentifierIdentifier1 OBX[2][3][3] = 'NHCCVIS' OBX[2][11] = 'F' OBX[3][1] = '3' OBX[3][2] = 'FT' OBX[3][3][1] = T.OBXObservationIdentifierIdentifier2 OBX[3][3][2] = T.OBXObservationIdentifierText2 OBX[3][3][3] = 'NHCCVIS' OBX[3][5][1] = T.OBXObservationValue2 OBX[3][11] = 'F' end
The dbfill module:
dbfill = {} local function trace(a,b,c,d) return end local function RandomDate(Modifier) local T = 40700 - Modifier trace(T) return os.ts.date("%Y-%m-%dT%H:%M:%S", T) end local function RandomString(V, RowIndex) return V:nodeName()..RowIndex end local function FillValue(R, i, RowIndex) local T = R[i]:nodeType() if T == 'datetime' then R[i] = RandomDate(RowIndex*i) elseif T == 'string' then R[i] = RandomString(R[i], RowIndex) else error('Need to handle integers and doubles') end end local function MakeRow(T,RowIndex) for i =1,#T do FillValue(T, i, RowIndex) end return T end local function makeDummyDatabase(Vmd, Name) local T = db.tables{vmd=Vmd, name=Name} for i =1,20 do MakeRow(T.NHCCVISReport[i], i) end return T end local function ColumnList(Row) local L = '' for i =1, #Row-1 do L = L..Row[i]:nodeName()..',n' end L = L..Row[#Row]:nodeName() return L end local function generateSql(T, DB) for TableIndex=1,#T do local C = ColumnList(T[TableIndex][1]) ..", MESSAGE_ID, PARENT_ID" for RowIndex = 1, #T[TableIndex] do local Row = T[TableIndex][RowIndex] local S = 'REPLACE INTO '..T[TableIndex]:nodeName() ..'('..C..')n VALUES(' for ColumnIndex =1,#Row-1 do S = S..'"'..Row[ColumnIndex]..'",n' end S = S..'"'..Row[#Row]..'"n' S = S..',"'..RowIndex..'"n' S = S..',"'..RowIndex..'")' trace(S) DB:execute{sql=S, live=true} end end end local function InsertMessageRow(Count, MessageName, DB) for i=1, Count do local S = 'REPLACE INTO '..MessageName..'(MESSAGE_ID, STATUS)'..' VALUES('..i..",'W')" DB:execute{sql=S, live=true} end end function dbfill.generateDummySourceData(Vmd, MessageName, D) local T = makeDummyDatabase(Vmd, MessageName) generateSql(T, D) InsertMessageRow(#T.NHCCVISReport, MessageName, D) end function dbfill.SaveMessage(Base, Msg, Data) local FileName = 'D:temp'..Base ..Msg.MSH[10]..'.txt' trace(FileName) local F = io.open(FileName, "w") F:write(Data) F:close() end function dbfill.LoadMessage(Base, Msg) local FileName = 'D:temp'..Base ..Msg.MSH[10]..'.txt' trace(FileName) local F = io.open(FileName, "r") return F:read("*a") end -- gets equivalent old message -- the name is a blind... function dbfill.CompareMessage(Data) local Out = hl7.parse{vmd='CVISOutbound.vmd', data=Data} local Orig = dbfill.LoadMessage('orig', Out) return hl7.parse{vmd='CVISOutbound.vmd', data=Orig} end
Here’s the source code for the diff module.
And the code for the “From Translator” channel:
require('dbfill') --dbfill.generateDummySourceData('CVISOutbound.vmd', 'NHCCVIS',D)
And the code for the “To Translator” channel we used to record the original messages from the old interface:
require 'dbfill' local conn = db.connect{ api=db.SQLITE, name='test', live=true } function main() --dbfill.generateDummySourceData('CVISOutbound.vmd', 'NHCCVIS',D) local R = conn:query( "SELECT MESSAGE_ID FROM NHCCVIS WHERE STATUS = 'W'" ) for i=1, #R do PushId(R[i].MESSAGE_ID:nodeValue()) conn:execute( "UPDATE NHCCVIS SET STATUS='R' WHERE MESSAGE_ID = " ..R[i].MESSAGE_ID ) end end function PushId(Id) queue.push{data=Id} end
Next Step?
Now we have completed the regression test it only remains to review what we learned and consider the next steps.