/******************************************************************************
# $RCSfile:
hl7_boom.sc,v $
#******************************************************************************
#
This is a component of Axon, the Real-Time HL7 Interface System
#
developed at the University of Washington Academic Medical Centers
# by
the HL7 Interface Team.
#
# Author: J. Martin, from Boom Specs by T. Rozmyn et
al...
#
# Purpose: Container for functions used to support
hl7_boom processing.
#
# Functions:
# ---------
# msg_list_t
* hl7_boom(msg_list_t *);
#
int
get_BOOM_person_no(msg_list_t *);
#
int
get_BOOM_pat_id();
#
msg_list_t * create_BOOM_list(msg_list_t *);
#
#******************************************************************************
#
# $Source:
/homes/hit/interfac/packages/rtif/common/src/RCS/hl7_boom.sc,v $
#
#******************************************************************************
# $Log: hl7_boom.sc,v
$
# Revision 1.6
2000/06/08 03:13:27 martinj
# added calls to get_bb_times
#
# Revision 1.5
2000/03/14 02:06:20 jalex
# added call to comma_del_remove to delete current patient
# from list of pat_no's to boom.
#
# Revision 1.4
2000/03/07 18:40:33 interfac
# *** empty log message ***
#
# Revision 1.1
2000/01/05 18:42:10 feattest
# Initial revision
#
# Revision 1.3
1999/11/09 16:53:54 jalex
# *** empty log message ***
#
# Revision 1.2
1999/11/02 00:44:07 jalex
# added functionality to create ZP2 and populate it when
# a non-patient person update (in NK1) occurs
#
# Revision 1.1
1999/10/18 17:21:36 martinj
# Initial revision
#
#******************************************************************************/
static char rcsid[] = "$Id: hl7_boom.sc,v 1.6
2000/06/08 03:13:27 martinj Exp $";
EXEC
SQL INCLUDE SQLCA;
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <strings.h>
#include <ctype.h>
#include "event.h"
#include "hl7_snd.h"
#include "error_stdout.h"
#include "safe_strcat.h"
#include "del_seg.h"
char *strPersonList;
/* list of person_no's */
char *strPatIDList; /* list of pat id's */
/* set in get_BOOM_person_no */
char
*strPID_patient_id[64];
char errmsg[128];
extern int verbose_level;
extern evn_desc_t
*pEvn;
/* objects for hl7_getset
*/
extern spec_t EVN_event_code;
extern spec_t EVN_timestamp;
extern spec_t EVN_operator_id;
extern spec_t MSA_ack_code;
extern spec_t MSA_control_id;
extern spec_t MSH_send_app;
extern spec_t MSH_send_facility;
extern spec_t MSH_dest_app;
extern spec_t MSH_dest_facility;
extern spec_t MSH_msg_timestamp;
extern spec_t MSH_msg_type;
extern spec_t MSH_msg_event;
extern spec_t MSH_sequence_id;
extern spec_t MSH_hl7_version;
extern spec_t PID_set_id;
extern spec_t PID_patient_id;
extern spec_t PID_alt_pat_id;
extern spec_t PID_alt_id_type;
extern spec_t PID_name_last;
extern spec_t PID_name_first;
extern spec_t PID_name_middle;
extern spec_t PID_name_suffix;
extern spec_t PID_ssn;
extern spec_t ZVN_upd_by;
extern spec_t ZVN_upd_area;
extern spec_t ZVN_screen_id;
extern spec_t ZVN_netsec_updby;
/* objects to support BOOM person_no rules */
extern spec_t ZP2_person_no;
spec_t
ZN2_person_no = {
"ZN2", 3, 0, 0 };
spec_t
NK1_set_id = { "NK1", 1, 0, 0 };
spec_t
GT1_guar_no = {
"GT1", 2, 0, 0 };
spec_t
ZI2_person_no = {
"ZI2", 33, 0, 0 };
extern spec_t ZMG_merge_type;
/*****************************************************************************
* function:
get_BOOM_person_no
* args:
msg_list_t *
* returns:
int (0=failure, 1=found a person_no/pat_id, 2=perform no Booming)
* usage info:
*
* accepts a msg_list_t pointer to a discrete event and
* extracts all the person_no's from the message using extraction
* rules given in boom_process.doc (T. Rozmyn). Each person_no is
* concated into a string, suitable for input into Jay Alexander's
* process_bb.comma_del_sort_u function.
*
* HISTORY:
* --------
* Programmer:
* Date:
* Mod:
*
* Programmer: J.
Alexander
* Date:
16-Nov-1999
* Mod: got rid of
A28/A31 ZN2_person_no hack.
* now using
validate_syntax / hl7_set_by_grp.
*
* Programmer: Jeff
Martin
* Date:
28-Oct-1999
* Mod:
implemented v2.1 person_no rules.
*
* Programmer: Jeff
Martin
* Date:
18-Oct-1999
* Mod: started.
*
******************************************************************************/
int
get_BOOM_person_no(msg_list_t
*REGlist)
{
hl7_union_t
*vs_result, *msgReg; /* message in
hl7_get format
*/
char *c, *sub_c;
/* generic string pointers
for hl7_get */
char evn_code[4];
/* evn_code from REG
event
*/
int handledEvent = 0; /* set if event code is BOOM
eligible */
int shutdownEnable =
1; /* used to further gate return(0) */
segment_t *pSeg_t;
char
*strWorking[MAX_HL7_MESSAGE_SIZE];
extern evn_desc_t *pEvn;
evn_desc_t
*pTrav;
char
evn_grammar[1025];
/***** code section
**************************************************/
evn_grammar[0]=(char)'\0';
if( verbose_level >= 100)
log_bb_times("get_BOOM_person_no: start");
/* convert message to storage format */
if((msgReg = (hl7_union_t
*)str2mesg(REGlist->msg)) == NULL) {
sprintf(errmsg,
"REG event %d failed str2msg",
REGlist->seq_no );
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_FATAL);
return(0);
}
/* get the REG event code */
c =
(char *)
hl7_get(msgReg, &EVN_event_code, 1, 0, NULL, 0, 0);
if (c == NULL) {
sprintf(errmsg,
"BOOM can't get EVENT CODE for REG event %d",
REGlist->seq_no );
error_notify(__FILE__, __LINE__,errmsg,
NOTIFY_FATAL);
freemesg(msgReg);
return(0);
}
strcpy(evn_code,
c);
sprintf(errmsg,
"BOOM got
event code %s.",evn_code);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
for(pTrav = pEvn; pTrav; pTrav
= pTrav->next){
if(!strcmp(pTrav->event_code, evn_code)) break;
}
if(!pTrav) {
sprintf(errmsg, "No HL7 grammar
defined for message %s", evn_code);
error_notify(__FILE__, __LINE__, errmsg,
NOTIFY_FATAL);
freemesg(msgReg);
return(0);
} else {
safe_strcat(evn_grammar,
pTrav->event_desc,1025);
if(safe_strcat_err) {
freemesg(msgReg);
return(0);
}
if(strlen(evn_grammar) == 0) {
sprintf(errmsg, "No
message grammar defined for event %s",
evn_code);
error_notify(__FILE__,
__LINE__, errmsg, NOTIFY_FATAL);
freemesg(msgReg);
return(0);
} else {
hl7_union_t *vs_result;
vs_result =
(hl7_union_t*)validate_syntax(evn_grammar, msgReg);
if(!vs_result) {
sprintf(errmsg,
"Message failed syntax validation");
error_notify(__FILE__, __LINE__, errmsg, NOTIFY_SERIOUS);
printmesg(msgReg);
sprintf(errmsg,
"Validate_syntax: Error:
syntax must match %s",
evn_grammar);
error_notify(__FILE__, __LINE__, errmsg, NOTIFY_FATAL);
freemesg(msgReg);
return(0);
}
msgReg = vs_result;
}
}
evn_grammar[0]=(char)'\0';
sprintf(errmsg,
"Finished
validate_syntax.");
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
/* allocate some storage for strPersonList */
strPersonList
= (char *) calloc(512, sizeof(char));
if(strPersonList == NULL) {
error_notify(__FILE__, __LINE__,
"Can't calloc for
strPersonList",
NOTIFY_FATAL);
freemesg(msgReg);
return NULL;
}
/* implement BOOM person_no rules. See boom_process.doc */
if (strcmp(evn_code,"A04")
== 0) {
handledEvent = 1;
c = (char *) hl7_get(msgReg, &ZP2_person_no, 1,
0, NULL, 0, 0);
if (c != NULL) {
if (verbose_level >=
10000)
printf("\t\t\tgot A04 ZP2_person_no: %s\n",c);
strcat(strPersonList, c);
strcat(strPersonList,",");
}
} /* A04 */
if
(strcmp(evn_code,"A08") == 0) {
handledEvent = 1;
c = (char *) hl7_get(msgReg, &ZP2_person_no, 1,
0, NULL, 0, 0);
if (c != NULL) {
if (verbose_level >= 10000)
printf("\t\t\tgot A08 ZP2_person_no: %s\n",c);
strcat(strPersonList, c);
strcat(strPersonList,",");
}
c = (char *) hl7_get(msgReg, &ZN2_person_no, 1,
0, NULL, 0, 0);
/* strWorking is a hack at a big stump in the
field I've
decided to plow around */
sprintf(strWorking,"%s",c?c:"<null>");
if (c != NULL) {
sub_c = (char *)
hl7_get(msgReg, &NK1_set_id, 1, 0, NULL, 0, 0);
if (sub_c != NULL ) {
if (
strcmp(sub_c,"PTN")==0 || strcmp(sub_c,"LNOK")==0 ) {
if
(verbose_level >= 10000)
printf("\t\t\tgot A08 ZN2_person_no: %s\n",strWorking);
strcat(strPersonList, strWorking);
strcat(strPersonList,",");