› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › KILL $mh help
I want a message killed if a certain set of criteria are met. From what I’ve gathered returning KILL $mh is the way to do this. So I have a couple questions in regards to this.
1. Can this command be used in a TCL fragment inside the XLATE itself, or does it need to be in a TCLPROC?
2. Does KILL $mh need to be placed in the message itself? if so is one location better than another.
Thanks for any input.
Keith
Use KILL $mh in TPS scripts. The best location is your inbound TPS so that the message doesn’t get to the xlate. If possible always filter your unwanted messages as early as possible in the message flow.
You wouldn’t use KILL $mh in an xlate.
Regards
Garry
You can filter messages within the Xlate – however many of us (myself included) do not believe it is the best place (if you want to have a more in depth discussion about that, email me).
You can place your Tps type Tcl proc at the inbound Tps UPoC – however that means that filtering is effective for EVERY receiving system. That may be OK but, in my experience, much of the message filtering is specific to the destination.
So you can move down stream to the TrxId UPoC and apply your filter there. That gives more tactical control over the effect of the filter.
You can also place your filtering proc at the pre (xlate, raw) message routing UPoC. This is my preference because now I can have the greatest granularity of control and yet remove messages before too much engine work is done.
Jim Kosloskey
email: jim.kosloskey@jim-kosloskey.com 29+ years Cloverleaf, 59 years IT - old fart.
You mention trxid as a possible place to kill a message – I thought message data in a trxid was immutable?
Regards
Garry
What you do is change the Transaction ID to something like ‘Del_filt1″; then in the Route, do a tpsmsgkill on the route for messages with that TrxID.
Jim Kosloskey
email: jim.kosloskey@jim-kosloskey.com 29+ years Cloverleaf, 59 years IT - old fart.
I too have found using a trxID proc for identifying messages to be killed to be more flexible, consice, and maintainable.
As pointed out already the trxID proc only returns a trxID which in turn can be set to something usefull like trxId_KILL to identify messages to be killed in the route via hcitpsmsgkill.
Here is an example of a trxID proc I did for our pharmacy system and some screen shots showing how to use it:
trxid_SIU_rxtfc.tcl
# Begin Module Header ==========================================================
#
# —–
# Name:
# —–
#
# trxid_SIU_rxtfc.tcl
#
# ——–
# Purpose:
# ——–
#
# Set the trxId to the message type in MSH-9 as the default case first.
#
# Set the trxId for SIU_S15 messages to one of the following:
#
# – SIU_S15_==arrival
# which means that ZSD-2 == “SC165”
#
# – SIU_S15_!=arrival
# which means that ZSD-2 != “SC165”
#
# For SIU* messages set the trxId to “trxId_KILL” if one of the following SIU filtering conditions are met:
#
# – trxId_KILL if the message does not have a MRN, which means:
# PID-3.1 is empty
#
# – trxId_KILL if the message does not have a patient account/visit number, which means:
# PID-18.1 is empty
#
# – trxId_KILL if the message has an undesirable location, which means:
# AIL-3.1 does NOT match an entry in lookup table rxtfc_desirable_locations_for_all_SIU
#
# – trxId_KILL if the message account/visit number starts with “20”, which means:
# PID-18.1 first 2 characters = “20”
#
# – trxId_KILL if the message account/visit number starts with “90” and patient type is “O”, which means:
# PID-18.1 first 2 characters = “90”
# and
# PV1-2 = “O”
#
# – trxId_KILL if the message account/visit number starts with “90” and has an undesired location, which means:
# PID-18.1 fist 2 characters = “90”
# and
# AIL-3.1 does NOT match an entry in lookup table rxtfc_desirable_locations_for_90_SIU
#
# – trxId_KILL if the message is too old, which means:
# AIL-6 is a valid date/time in a ts format
# and
# AIL-6 is older than -6 hours
#
# ——-
# Inputs:
# ——-
#
# msgId – message handle
#
# ——–
# Outputs:
# ——–
#
# trxId – transaction ID
#
# ——
# Notes:
# ——
#
# Manually hardcode the variable debug to “Y” to turn on debug echo statements
#
# Manually hardcode the variable debug to “N” to turn off debug echo statements
#
# ——–
# History:
# ——–
#
# 2004.09.16 Russ Ross
# – wrote initial version
#
# 2005.01.03 Russ Ross
# – trxId_KILL if the message account/visit number starts with “20”, which means:
# PID-18.1 first 2 characters = “20”
#
# End Module Header ============================================================
proc trxid_SIU_rxtfc { msgId } {
global HciConnName
set module “trxid_SIU_rxtfc”
set debug “N”
#——————————————————————————–
# Set the trxId to the message type in the MSH segment as the default case first.
#——————————————————————————–
set msg [msgget $msgId]
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: ………………………………………..”
echo “$HciConnName $module: msgId ($msgId) points to the following message:”
echo “”
echo $msg
echo “”
echo “$HciConnName $module: ………………………………………..”
echo “”
}
set field_separator [csubstr $msg 3 1]
set subfield_separator [csubstr $msg 4 1]
set segment_list [split $msg “r”]
set MSH_index [lsearch -regexp $segment_list “^MSH”]
set MSH_segment [lindex $segment_list $MSH_index]
set MSH_field_list [split $MSH_segment $field_separator]
set MSH_9 [lindex $MSH_field_list 8]
set trxId [join [split $MSH_9 $subfield_separator] “_”]
#————————————————————
# Set the trxId for SIU_S15 messages to one of the following:
#
# – SIU_S15_==arrival
# which means that ZSD-2 == “SC165”
#
# – SIU_S15_!=arrival
# which means that ZSD-2 != “SC165”
#————————————————————
if { [cequal “$trxId” “SIU_S15″] } {
set ZSD_index [lsearch -regexp $segment_list “^ZSD”]
set ZSD_segment [lindex $segment_list $ZSD_index]
set ZSD_field_list [split $ZSD_segment $field_separator]
set ZSD_2 [split [lindex $ZSD_field_list 2] $subfield_separator]
if { [cequal “$ZSD_2” “SC165″] } {
set trxId “SIU_S15_==arrival”
} else {
set trxId “SIU_S15_!=arrival”
}
}
#———————————————————————————-
# At this point the trxId has been determined unless the message needs to be killed
#———————————————————————————-
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: …………………….”
echo “$HciConnName $module: setting trxId to ($trxId)”
echo “$HciConnName $module: …………………….”
echo “”
}
switch -glob — $trxId {
SIU* {
#—————————————————–
# Then for SIU* messages set the trxId to “trxId_KILL”
# if one of the SIU filtering conditions are met.
#—————————————————–
set in_loop 1
while {$in_loop} { # dummy loop to be able to use the break command
set PID_index [lsearch -regexp $segment_list “^PID”]
set PV1_index [lsearch -regexp $segment_list “^PV1″]
set AIL_index [lsearch -regexp $segment_list “^AIL”]
set PID_segment [lindex $segment_list $PID_index]
set PV1_segment [lindex $segment_list $PV1_index]
set AIL_segment [lindex $segment_list $AIL_index]
set PID_field_list [split $PID_segment $field_separator]
set PV1_field_list [split $PV1_segment $field_separator]
set AIL_field_list [split $AIL_segment $field_separator]
set PID_3_1 [lindex [split [lindex $PID_field_list 3] $subfield_separator] 0]
set PID_18_1 [lindex [split [lindex $PID_field_list 18] $subfield_separator] 0]
set PV1_2 [split [lindex $PV1_field_list 2] $subfield_separator]
set AIL_3_1 [lindex [split [lindex $AIL_field_list 3] $subfield_separator] 0]
set AIL_6 [split [lindex $AIL_field_list 6] $subfield_separator]
if { [cequal “$debug” “Y”] } {
echo “”
echo “…………………………………………..”
echo “checking to see if SIU* message needs to be KILLed”
echo “MSH-9 ($MSH_9)”
echo “trxId ($trxId)”
echo “PID-3.1 ($PID_3_1)”
echo “PID-18.1 ($PID_18_1)”
echo “PV1-2 ($PV1_2)”
echo “AIL-3.1 ($AIL_3_1)”
echo “AIL-6 ($AIL_6)”
echo “…………………………………………..”
echo “”
}
#————————————————————
# trxId_KILL if the message does not have a MRN, which means:
#
# PID-3.1 is empty
#————————————————————
if { [cequal “$PID_3_1” “”] } {
set trxId “trxId_KILL”
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: …………………………………………….”
echo “$HciConnName $module: setting trxId to $trxId”
echo “$HciConnName $module: because the message does not have a MRN, which means”
echo “$HciConnName $module: PID-3.1 is empty”
echo “$HciConnName $module: …………………………………………….”
echo “”
}
break
}
#————————————————————————————-
# trxId_KILL if the message does not have a patient account/visit number, which means:
#
# PID-18.1 is empty
#————————————————————————————-
if { [cequal “$PID_18_1” “”] } {
set trxId “trxId_KILL”
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: …………………………………………………………………..”
echo “$HciConnName $module: setting trxId to $trxId”
echo “$HciConnName $module: because the message does not have a patient account/visit number, which means”
echo “$HciConnName $module: PID-18.1 is empty”
echo “$HciConnName $module: …………………………………………………………………..”
echo “”
}
break
}
#————————————————————————————–
# trxId_KILL if the message has an undesirable location, which means:
#
# AIL-3.1 does NOT match an entry in lookup table rxtfc_desirable_locations_for_all_SIU
#————————————————————————————–
set table_name “rxtfc_desirable_locations_for_all_SIU”
if {[catch {set desirable_location [tbllookup $table_name $AIL_3_1]} cerr]} {
echo “”
echo “$HciConnName $module: ………………………………”
echo “$HciConnName $module: leaving trxId ($trxId) alone because”
echo “$HciConnName $module: ERROR while trying to lookup table ($table_name) got ($cerr)”
echo “$HciConnName $module: ………………………………”
echo “”
break
}
if { [cequal “$desirable_location” “N”] } {
set trxId “trxId_KILL”
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: ………………………………………………………………”
echo “$HciConnName $module: setting trxId to ($trxId)”
echo “$HciConnName $module: because the message has an undesirable location, which means”
echo “$HciConnName $module: AIL-3.1 ($AIL_3_1) does NOT match an entry in lookup table ($table_name)”
echo “$HciConnName $module: ………………………………………………………………”
echo “”
}
break
}
#——————————————————————————
# trxId_KILL if the message account/visit number starts with “20”, which means:
#
# PID-18.1 first 2 characters = “20”
#——————————————————————————
set PID_18_1_first_2_chars [csubstr $PID_18_1 0 2]
if { [cequal “$PID_18_1_first_2_chars” “20”] } {
set trxId “trxId_KILL”
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: …………………………………………………………………………..”
echo “$HciConnName $module: setting trxId to ($trxId)”
echo “$HciConnName $module: because the account/visit number starts with (20), which means”
echo “$HciConnName $module: PID-18.1 first 2 characters = ($PID_18_1_first_2_chars)”
echo “$HciConnName $module: …………………………………………………………………………..”
echo “”
}
break
}
#——————————————————————————————————
# trxId_KILL if the message account/visit number starts with “90” and patient type is “O”, which means:
#
# PID-18.1 first 2 characters = “90”
# and
# PV1-2 = “O”
#——————————————————————————————————
set PID_18_1_first_2_chars [csubstr $PID_18_1 0 2]
if { [cequal “$PID_18_1_first_2_chars” “90”] && [cequal “$PV1_2” “O”] } {
set trxId “trxId_KILL”
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: …………………………………………………………………………..”
echo “$HciConnName $module: setting trxId to ($trxId)”
echo “$HciConnName $module: because the account/visit number starts with (90) and patient type is (O), which means”
echo “$HciConnName $module: PID-18.1 first 2 characters = ($PID_18_1_first_2_chars)”
echo “$HciConnName $module: and”
echo “$HciConnName $module: PV1-2 = ($PV1_2)”
echo “$HciConnName $module: …………………………………………………………………………..”
echo “”
}
break
}
#————————————————————————————————————
# trxId_KILL if the message account/visit number starts with “90” and has an undesired location, which means:
#
# PID-18.1 fist 2 characters = “90”
# and
# AIL-3.1 does NOT match an entry in lookup table rxtfc_desirable_locations_for_90_SIU
#————————————————————————————————————
if { [cequal “$PID_18_1_first_2_chars” “90”] } {
set table_name “rxtfc_desirable_locations_for_90_SIU”
if {[catch {set desirable_location [tbllookup $table_name $AIL_3_1]} cerr]} {
echo “”
echo “$HciConnName $module: ………………………………”
echo “$HciConnName $module: leaving trxId ($trxId) alone because”
echo “$HciConnName $module: ERROR while trying to lookup table ($table_name) got ($cerr)”
echo “$HciConnName $module: ………………………………”
echo “”
break
}
if { [cequal “$desirable_location” “N”] } {
set trxId “trxId_KILL”
if { [cequal “$debug” “Y”] } {
echo “”
echo “$HciConnName $module: ………………………………………………………………”
echo “$HciConnName $module: setting trxId to ($trxId)”
echo “$HciConnName $module: because the message has an undesirable location, which means”
echo “$HciConnName $module: PID-18.1 ($PID_18_1) fist 2 characters = ’90′”
echo “$HciConnName $module: and”
echo “$HciConnName $module: AIL-3.1 ($AIL_3_1) does NOT match an entry in lookup table ($table_name)”
echo “$HciConnName $module: ………………………………………………………………”
echo “”
}
break
}
}
#—————————————————
# trxId_KILL if the message is too old, which means:
#
# AIL-6 is a valid date/time in a ts format
# and
# AIL-6 is older than -6 hours
#—————————————————
if {![catch {set formatted_date [convert_date ts $AIL_6 fd 10]} catch_error]} {
set ghd “”
set fhd “”
set sav_msgval $AIL_6
keylset arg4tcl DATA_TYPE “ts”
keylset arg4tcl OPERAND “<"
keylset arg4tcl TIME_NUMB "-6"
keylset arg4tcl TIME_UNIT "Hours"
keylset arg4tcl DEBUG "$debug"
# uncomment this and hardcode a desired date for controlled testing of oth_chk_time_span
# keylset arg4tcl 2NDDATE "01/01/1970 00:00:01"
set old_SIU [oth_chk_time_span]
if { [cequal "$old_SIU" "Y"] } {
set trxId "trxId_KILL"
if { [cequal "$debug" "Y"] } {
echo ""
echo "$HciConnName $module: .................................................."
echo "$HciConnName $module: setting trxId to ($trxId)"
echo "$HciConnName $module: because message is too old, which means:"
echo "$HciConnName $module: AIL-6 ($AIL_6) is a valid date/time in a ts format"
echo "$HciConnName $module: and is older than [keylget arg4tcl TIME_NUMB] [keylget arg4tcl TIME_UNIT]"
echo "$HciConnName $module: .................................................."
echo ""
}
break
}
} else {
if { [cequal "$debug" "Y"] } {
echo ""
echo "$HciConnName $module: .................................................."
echo "$HciConnName $module: skipping check for AIL_6 ($AIL_6)"
echo "$HciConnName $module: because NOT a valid date/time in a ts format"
echo "$HciConnName $module: wich prodcued the following catch_error:"
echo "$catch_error"
echo "$HciConnName $module: .................................................."
echo ""
}
}
#--------------------------------------------------------------------------------------------------------
# Any new trxId_KILL logic for SIU* will most likely need to be inserted here.
# Note: This proc has been coded in such a way that the break command will break out of the SIU* switch.
#--------------------------------------------------------------------------------------------------------
break
} ; # end of dummy loop for SIU* switch }
default {
#------------------------------------------------------------------------------
# default case is to pass along any trxId that has not been set to "trxId_KILL"
#------------------------------------------------------------------------------
if { [cequal "$debug" "Y"] } {
echo ""
echo "$HciConnName $module: ............................................"
echo "$HciConnName $module: switch default case - passing trxId ($trxId)"
echo "$HciConnName $module: ............................................"
echo ""
}
}
}
#-----------------
# return the trxID
#-----------------
if { [cequal "$debug" "Y"] } {
echo ""
echo "$HciConnName $module: ............................................"
echo "$HciConnName $module: returning trxId ($trxId)"
echo "$HciConnName $module: ............................................"
echo ""
}
return $trxId
}
Russ Ross
RussRoss318@gmail.com
Never thought about doing it that way. I usually just have a KILL TPS that I add in to my inbound TPS routines.
This makes sense and I will look into adopting it in future builds.
Thanks
Garry