<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.