/******************************************************************************
# $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,",");
}
}
}
c = (char *) hl7_get(msgReg, >1_guar_no, 1,
0, NULL, 0, 0);
if (c != NULL) {
if (verbose_level >=
10000)
printf("\t\t\tgot A08 GT1_guar_no: %s\n",c);
strcat(strPersonList, c);
strcat(strPersonList,",");
}
c = (char *) hl7_get(msgReg, &ZI2_person_no, 1,
0, NULL, 0, 0);
if (c != NULL) {
if (verbose_level >=
10000)
printf("\t\t\tgot A08 ZI2_person_no: %s\n",c);
strcat(strPersonList, c);
strcat(strPersonList,",");
}
} /* A08 */
if
(strcmp(evn_code,"A28") == 0 || strcmp(evn_code,"A31") ==
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\tA28/A31 handler got ZP2_person_no: %s\n",c);
strcat(strPersonList,c);
strcat(strPersonList,",");
}
else {
/* no ZP2, try to get ZN2 */
c = (char *)
hl7_get(msgReg, &ZN2_person_no, 1, 0, NULL, 0, 0);
if (c != NULL )
{
if
(verbose_level >= 10000)
printf("\t\t\tA28/A31 handler got ZN2 person_no %s\n",c);
hl7_set_by_grp(msgReg,&ZP2_person_no,1,0,NULL,0,c);
pSeg_t = (segment_t *) hl7_find_seg(msgReg, "NK1",
1, 0, 0, 0, 0);
/* blank NK1 / ZN2 if they
exist */
if( pSeg_t ) {
if(
hl7_set(msgReg,&NK1_set_id,
1, 0, 0, 0, NULL)) {
sprintf(errmsg,"BOOM can't zero %s.NK1",
evn_code);
error_notify(__FILE__, __LINE__,
errmsg, NOTIFY_FATAL);
return(0);
}
}
pSeg_t = (segment_t *) hl7_find_seg(msgReg, "ZN2",
1, 0, 0, 0, 0);
if( pSeg_t ) {
if(
hl7_set(msgReg,&ZN2_person_no,
1, 0, 0, 0, NULL)) {
sprintf(errmsg,"BOOM can't zero %s.ZN2",
evn_code);
error_notify(__FILE__, __LINE__,
errmsg, NOTIFY_FATAL);
return(0);
}
}
if(strip_seg(msgReg,"NK1",1,0,0))
{
sprintf(errmsg,
"A28/A31 handler failed to strip the NK1 in event %d (%s)",
REGlist->seq_no, evn_code );
error_notify(__FILE__, __LINE__,
errmsg, NOTIFY_FATAL);
return(0);
}
if(strip_seg(msgReg,"ZN2",1,0,0))
{
sprintf(errmsg,
"A28/A31 handler failed to strip the ZN2 in event %d (%s)",
REGlist->seq_no, evn_code );
error_notify(__FILE__, __LINE__,
errmsg,
NOTIFY_FATAL);
return(0);
}
/* convert the modified msg to string,
append
person_no list */
mesg2str(msgReg,REGlist->msg);
strcat(strPersonList,c);
strcat(strPersonList,",");
/* we've modified the Boom
list head,
we should tell someone... */
if
(verbose_level >= 10000 ) {
sprintf(errmsg,
"A28/A31 handler modified ZP2,ZN2,NK1 in event %d (%s)",
REGlist->seq_no, evn_code );
error_notify(__FILE__, __LINE__,
errmsg, NOTIFY_UPDATE);
}
} /* ZN2 */
} /* ZP2 */
} /* A28/A31 */
if
(strcmp(evn_code,"A34") == 0) {
handledEvent = 1;
c = (char *) hl7_get(msgReg,
&ZP2_person_no, 1, 0, NULL, 0, 0);
strcpy(strWorking,c);
if ( c != NULL ) {
sub_c = (char *) hl7_get(msgReg,
&ZMG_merge_type, 1, 0, NULL, 0, 0);
if (sub_c != NULL) {
if
(strcmp(sub_c,"PERMNO") == 0) {
if(verbose_level
>= 10000)
printf("\t\t\tgot A34 ZP2_person_no: %s\n",
strWorking);
strcat(strPersonList, strWorking);
strcat(strPersonList,",");
}
else
/* got a ZP2_person_no,
return(2) returns
the orignial list
without Booming */
return(2);
}
}
} /* A34 */
/* filt_msg should've trapped this */
if (handledEvent == 0 ) {
if (verbose_level >= 10000 ) {
sprintf(errmsg,
"No person_no handler for event %d (%s)",
REGlist->seq_no,evn_code );
error_notify(__FILE__, __LINE__,errmsg, NOTIFY_SERIOUS);
}
freemesg(msgReg);
if( verbose_level >= 100)
log_bb_times("get_BOOM_person_no: start");
return(2);
}
if ((strPersonList ==
NULL ||
strlen(strPersonList) ==
0) &&
(shutdownEnable == 1 )) {
printmesg(msgReg);
sprintf(errmsg,
"BOOM can't find a person_no for event %d (%s)",
REGlist->seq_no, evn_code);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_FATAL);
freemesg(msgReg);
shutdown_primary();
}
/* store patient_id */
c =
(char *)
hl7_get(msgReg,
&PID_patient_id, 1, 0, NULL, 0, 0);
if( c == NULL &&
(strcmp(evn_code,"A28") && strcmp(evn_code,"A31")))
{
sprintf(errmsg,
"BOOM can't get PID_patient_id for event %d (%s)",
REGlist->seq_no, evn_code);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_FATAL);
freemesg(msgReg);
return(0);
} else if( c == NULL) {
strPID_patient_id[0]='\0';
} else {
strcpy(strPID_patient_id,c); /* get data for get_BOOM_pat_id */
}
if(msgReg)
freemesg(msgReg);
if( verbose_level >= 100)
log_bb_times("get_BOOM_person_no: end");
return(1);
}/********** end of get_BOOM_person_no
**************************************/
/*****************************************************************************
* function:
get_BOOM_pat_id
* args: none
* returns:
int, 0 if errors.
* usage info:
*
* parses a global string that contains person_no(s) from
* get_BOOM_person_no(), passes each to two SQL commands
* that return all the patient identifiers associated
* with the person_no.
The patient identifiers are
* concated into a string (strPatIDList) suitable for input
* into Jay Alexander's process_bb.comma_del_sort_u function.
*
* HISTORY:
* --------
* Programmer:
* Date:
* Mod:
*
*
* Programmer: Jeff Martin
* Date:
14-Jun-2000
* Mod:
Exclude source idrs from patient idr list for boosting.
*
* Programmer: T.
Rozmyn
* Date:
21-Feb-2000
* Mod:
Removed hosp/pat_no clauses from pat_pers_rel query; added
*
pers_syn query to get pat_nos when pat is purged.
*
* Programmer: Jeff
Martin
* Date:
20-Oct-1999
* Mod:
started.
*
******************************************************************************/
int
get_BOOM_pat_id()
{
EXEC
SQL BEGIN DECLARE SECTION;
char
hosp[2];
char
msg_hosp[2];
char
pat_no[8];
char
msg_pat_no[8];
char
pat_id[11];
int
msg_person_no;
EXEC
SQL END DECLARE SECTION;
int counter=0; /* counts char in strPatIDList */
int minor_counter=0; /* counts char in strPersonNo */
char *strPersonNo; /* extract from strPersonList */
char *strPatID[11]; /* appended to strPatIDList */
/********* code
**************************************************************/
/* init buffers */
if( verbose_level >= 100)
log_bb_times("get_BOOM_pat_id: start");
strPersonNo
= (char *)
calloc(strlen(strPersonList), sizeof(char));
if(strPersonNo == NULL) {
error_notify(__FILE__, __LINE__,
"Can't calloc for strPersonNo",
NOTIFY_SERIOUS);
return(0);
}
strPatIDList
= (char *) calloc(512, sizeof(char));
if(strPatIDList == NULL) {
error_notify(__FILE__, __LINE__,
"Can't
calloc for strPatIDList",
NOTIFY_SERIOUS);
free(strPersonNo);
return(0);
}
/* parse get_BOOM_person_no.strPID_patient_id for this list */
if(strlen(strPID_patient_id)){
sscanf(strPID_patient_id,"%c%s",msg_hosp,msg_pat_no);
sprintf(msg_hosp,"%c",strPID_patient_id[0]);
} else {
msg_hosp[0]='\0';
msg_pat_no[0]='\0';
}
/* get patient identifiers for each person_no */
for(counter=0;
counter<=strlen(strPersonList); counter++){
if (strPersonList[counter] != ',') {
/* parse strPersonList */
strPersonNo[minor_counter++] =
strPersonList[counter];
if(
minor_counter >= strlen(strPersonList) ){
error_notify(__FILE__, __LINE__,
"BOOM tried to
parse an INVALID strPersonList",
NOTIFY_SERIOUS);
free(strPersonNo);
return(0);
}
}
else {
/* do work */
strPersonNo[minor_counter++] = '\0';
minor_counter=0;
msg_person_no = atoi(strPersonNo);
if(
verbose_level >= 10 ) {
sprintf(errmsg,
"get_BOOM_pat_id:
working on person_no %d",
msg_person_no);
error_notify(__FILE__, __LINE__,errmsg,NOTIFY_UPDATE);
}
/******* get patient identifiers from PAT_PERS_REL *********/
if
(verbose_level >= 10000 ) {
printf("\nEXEC SQL REPEATED SELECT
DISTINCT hosp, pat_no\n"
"INTO
:hosp, :pat_no\n"
"FROM
pat_pers_rel\n"
"WHERE
person_no
= %d\n"
"AND
eff_thru_dt
= '31-dec-2099
23:59:59'\n"
"AND
pers_rel_to_pat_cd != 'NO'\n"
"AND
pers_rel_to_pat_cd != 'RF'\n\n",
msg_person_no, msg_pat_no, msg_hosp);
}
EXEC SQL REPEATED
SELECT DISTINCT
SQUEEZE(hosp), SQUEEZE(pat_no)
INTO
:hosp, :pat_no
FROM
pat_pers_rel
WHERE person_no
= :msg_person_no
AND
eff_thru_dt
= '31-dec-2099 23:59:59'
AND
pers_rel_to_pat_cd != 'NO'
AND
pers_rel_to_pat_cd != 'RF';
EXEC SQL BEGIN;
sprintf(strPatID,"%s%s",hosp, pat_no);
/* exclude source idr from
strPatID
*/
if(
strcmp(strPID_patient_id,strPatID) ) {
strncat(strPatIDList,strPatID,sizeof(strPatID));
strcat(strPatIDList,",");
}
if
(verbose_level >= 10000 ) {
sprintf(errmsg,"PAT_PERS_REL query returned %s",
strPatID);
error_notify(__FILE__, __LINE__,errmsg,NOTIFY_UPDATE);
}
EXEC
SQL END;
switch(sqlca.sqlcode) {
case 0:
break;
case 100:
if (verbose_level >= 10000
) {
error_notify(__FILE__,
__LINE__,
"PAT_PERS_REL query returned no
rows",
NOTIFY_UPDATE);
}
break;
default:
ingerr(__FILE__, __LINE__, sqlca.sqlcode,DEFAULT_SEQ_NO);
error_notify(__FILE__, __LINE__,
"BOOM can't select against PAT_PERS_REL",
NOTIFY_FATAL);
shutdown_primary();
} /* switch */
/******* get patient identifiers from COVERAGE *********/
/*
if(comma_del_remove(strPatIDList,strPID_patient_id)){
;
}
*/
if
(verbose_level >= 10000 ) {
printf("\nEXEC SQL REPEATED SELECT
DISTINCT hosp, pat_no\n"
"INTO
:hosp, :pat_no\n"
"FROM
coverage\n"
"WHERE
person_no
= %d\n"
"AND
eff_thru_dt
= '31-dec-2099 23:59:59'\n"
"AND
pat_no
!= '%s'\n"
"AND
hosp
!= '%s'\n\n",
msg_person_no, msg_pat_no, msg_hosp);
}
EXEC
SQL REPEATED SELECT DISTINCT
SQUEEZE(hosp), SQUEEZE(pat_no)
INTO
:hosp, :pat_no
FROM coverage
WHERE person_no
= :msg_person_no
AND
eff_thru_dt
= '31-dec-2099 23:59:59'
AND
pat_no
!= :msg_pat_no
AND
hosp
!= :msg_hosp;
EXEC
SQL BEGIN;
sprintf(strPatID,"%s%s",hosp, pat_no);
/* exclude source idr from
strPatID
*/
if(
strcmp(strPID_patient_id,strPatID) ) {
strncat(strPatIDList,strPatID,sizeof(strPatID));
strcat(strPatIDList,",");
}
if
(verbose_level >= 10000 ) {
sprintf(errmsg,"COVERAGE query returned %s",
strPatID);
error_notify(__FILE__, __LINE__,
errmsg,NOTIFY_UPDATE);
}
EXEC
SQL END;
switch(sqlca.sqlcode) {
case 0:
break;
case 100:
if
(verbose_level >= 10000 ) {
error_notify(__FILE__, __LINE__,
"COVERAGE query returned no rows",
NOTIFY_UPDATE);
}
break;
default:
ingerr(__FILE__, __LINE__, sqlca.sqlcode,DEFAULT_SEQ_NO);
error_notify(__FILE__, __LINE__,
"BOOM can't select against COVERAGE",
NOTIFY_FATAL);
shutdown_primary();
} /* switch */
/*
* get patient identifiers from PERS_SYN
using msg person_no. This is
* to catch those patients that have been
purged and do not have a
* PAT_PERS_REL 'PAT/SE' record. T. Rozmyn 2/21/2000.
*/
if
(verbose_level >= 10000 ) {
printf("\nEXEC SQL REPEATED SELECT
DISTINCT hosp, pat_no\n"
"INTO
:hosp, :pat_no\n"
"FROM
pers_syn
\n"
"WHERE
person_no
= %d\n"
"AND
hosp
!= '' \n"
"AND
pat_no
!= '' \n"
"AND
current_name
= 'Y'\n"
"AND
bypass_rs
= 'N'\n",
msg_person_no);
}
EXEC SQL REPEATED
SELECT DISTINCT
SQUEEZE(hosp), SQUEEZE(pat_no)
INTO
:hosp, :pat_no
FROM pers_syn
WHERE person_no
= :msg_person_no
AND hosp !=
''
AND
pat_no
!= ''
AND
current_name
= 'Y'
AND
bypass_rs
= 'N';
EXEC SQL BEGIN;
sprintf(strPatID,"%s%s",hosp, pat_no);
/* exclude source idr from
strPatID
*/
if(
strcmp(strPID_patient_id,strPatID) ) {
strncat(strPatIDList,strPatID,sizeof(strPatID));
strcat(strPatIDList,",");
}
if (verbose_level
>= 10000 ) {
sprintf(errmsg,"PERS_SYN query returned %s",
strPatID);
error_notify(__FILE__, __LINE__,
errmsg,NOTIFY_UPDATE);
}
EXEC
SQL END;
switch(sqlca.sqlcode) {
case 0:
break;
case 100:
if (verbose_level >= 10000
) {
error_notify(__FILE__,
__LINE__,
"PERS_SYN query returned no
rows",
NOTIFY_UPDATE);
}
break;
default:
ingerr(__FILE__, __LINE__, sqlca.sqlcode,DEFAULT_SEQ_NO);
error_notify(__FILE__, __LINE__,
"BOOM can't select against PERS_SYN",
NOTIFY_FATAL);
shutdown_primary();
} /* switch */
} /* if (strPersonList[counter] != ',') */
} /* for(counter<=strlen(strPersonList)) */
if (strPatIDList
== NULL ||
strlen(strPatIDList) == 0) {
if (verbose_level >= 10000
) {
sprintf(errmsg,
"BOOM can't find any PAT ID's for PERSON %d ",
msg_person_no);
error_notify(__FILE__, __LINE__,errmsg, NOTIFY_SERIOUS);
}
free(strPersonNo);
if( verbose_level >= 100)
log_bb_times("get_BOOM_pat_id: end");
return(0);
}
free(strPersonNo);
if( verbose_level >= 100)
log_bb_times("get_BOOM_pat_id: end");
return(1);
}/******** end of get_BOOM_pat_id
*******************************************/
/*****************************************************************************
* function:
create_BOOM_list
* args:
msg_list_t * to current REG event
* returns:
new msg_list_t * starting with current REG event
* followed
by zero or more stub A31 events.
* usage info:
*
* HISTORY:
* --------
* Programmer:
* Date:
* Mod:
*
* Programmer: Jeff
Martin
* Date:
20-Oct-1999
* Mod:
started.
*
******************************************************************************/
msg_list_t
*
create_BOOM_list(msg_list_t
* myREGlist) {
msg_list_t *pHead, *pOld, *pNew;
hl7_union_t
*msgReg;
char *c;
int intNodeCount = 0;
/* properties for A31 stubs
*/
char strDateTime[16];
int intDate;
int intTime;
char strMSH_send_app[64];
char strMSH_send_facility[64];
char strMSH_dest_app[64];
char strMSH_dest_facility[64];
char strMSH_hl7_version[64];
char strEVN_timestamp[64];
char strEVN_operator_id[64];
char strZVN_upd_by[64];
char strZVN_upd_area[64];
int counter=0;
int minor_counter=0;
char *strBoomPatID;
/* extract from
strPatIDList */
char strPersonNo[14];
/* value for hl7_set
*/
EXEC
SQL BEGIN DECLARE SECTION;
char boomee_hosp[2];
char
boomee_pat_no[8];
int
boomee_person_no;
EXEC
SQL END DECLARE SECTION;
/************ code
******************************************************/
if( verbose_level >= 100)
log_bb_times("create_BOOM_list: start");
/* init buffers
*/
strBoomPatID
= (char *)
calloc(strlen(strPatIDList), sizeof(char));
if(strBoomPatID == NULL) {
sprintf(errmsg,
"tried to calloc %d bytes for BOOM list\n%s",
strlen(strPatIDList),
strerror(errno));
error_notify(__FILE__,
__LINE__,
errmsg, NOTIFY_FATAL);
/* enable shutdown_primary */
return(NULL);
}
/* init head
*/
pNew = (msg_list_t *) calloc(1, sizeof(msg_list_t));
if
(pNew == NULL) {
sprintf(errmsg,
"tried to calloc %d bytes for BOOM list\n%s",
sizeof(msg_list_t),
strerror(errno));
error_notify(__FILE__,
__LINE__,
errmsg, NOTIFY_FATAL);
return(NULL);
}
pNew->seq_no
= myREGlist->seq_no;
strcpy(pNew->msg,myREGlist->msg);
pHead
= pNew;
pOld = pNew;
/* get stub constants
from REG message */
msgReg
= (hl7_union_t *) str2mesg(myREGlist->msg);
c =
(char *)
hl7_get(msgReg, &MSH_send_app, 1, 0, NULL, 0, 0);
strcpy(strMSH_send_app, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &MSH_send_facility, 1, 0, NULL, 0, 0);
strcpy(strMSH_send_facility, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &MSH_dest_app, 1, 0, NULL, 0, 0);
strcpy(strMSH_dest_app, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &MSH_dest_facility, 1, 0, NULL, 0, 0);
strcpy(strMSH_dest_facility, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &MSH_hl7_version, 1, 0, NULL, 0, 0);
strcpy(strMSH_hl7_version, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &EVN_timestamp, 1, 0, NULL, 0, 0);
strcpy(strEVN_timestamp, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &EVN_operator_id, 1, 0, NULL, 0, 0);
strcpy(strEVN_operator_id, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &ZVN_upd_by, 1, 0, NULL, 0, 0);
strcpy(strZVN_upd_by, ( c ? c :
"" ));
c =
(char *)
hl7_get(msgReg, &ZVN_upd_area, 1, 0, NULL, 0, 0);
strcpy(strZVN_upd_area, ( c ? c :
"" ));
if(msgReg)
freemesg(msgReg);
/* trasverse patient identifier list */
for(counter=0; counter<=strlen(strPatIDList);
counter++){
if (strPatIDList[counter] != ',') {
/* parse strPatIDList */
strBoomPatID[minor_counter++] = strPatIDList[counter];
if(
minor_counter >= strlen(strPatIDList) ){
error_notify(__FILE__, __LINE__,
"BOOM tried to parse an INVALID strPatIDList",
NOTIFY_FATAL);
return(NULL);
}
}
else {
/* play */
strBoomPatID[minor_counter++] = '\0';
minor_counter=0;
/* parse hosp, pat_no */
sscanf(strBoomPatID,"%c%s",
boomee_hosp, boomee_pat_no);
sprintf(boomee_hosp,"%c",strBoomPatID[0]);
/* populate each node with a stub
A31 */
/* Obtain the patient's person_no */
if (verbose_level >= 10000
) {
printf(
"\nEXEC SQL REPEATED SELECT DISTINCT person_no\n"
"INTO
:boomee_person_no\n"
"FROM PERS_SYN\n"
"WHERE pat_no
=
'%s'\n"
"AND hosp
= '%s'\n"
"AND
current_name
= 'Y'\n"
"AND
bypass_rs
= 'N'\n\n",
boomee_pat_no, boomee_hosp);
}
EXEC SQL REPEATED
SELECT DISTINCT person_no
INTO
:boomee_person_no
FROM PERS_SYN
WHERE pat_no
= :boomee_pat_no
AND hosp
= :boomee_hosp
AND current_name
= 'Y'
AND bypass_rs
= 'N';
switch(sqlca.sqlcode) {
case 0:
intNodeCount++;
sprintf(strPersonNo,"%d",boomee_person_no);
if (verbose_level
>= 10000 ) {
sprintf(errmsg,"PERS_SYN query returned %s",
strPersonNo);
error_notify(__FILE__, __LINE__,
errmsg,NOTIFY_UPDATE);
}
/* allocate a node for an A31 stub */
pNew = (msg_list_t *) calloc(1, sizeof(msg_list_t));
if (pNew ==
NULL) {
sprintf(errmsg,
"tried to calloc %d bytes for BOOM list\n%s",
sizeof(msg_list_t),
strerror(errno));
error_notify(__FILE__, __LINE__,
errmsg, NOTIFY_FATAL);
return(NULL);
}
/* build the A31 stub
(copied in part from
pat_xref_uwmc_hmc_batch.sc) */
/* timedate.c */
intDate = hl7_getdate();
intTime = gettime();
sprintf(strDateTime,"%d%d",intDate,intTime);
sprintf(pNew->msg,
"MSH|^~\\&|%s|%s|%s|%s|%s||ADT^A31||P|%s|%c"
"EVN|A31|%s|||%s%c"
"ZVN|%s|%s|%c"
"PID|||%s%s||%c"
"ZP2||||||||||||||||||||||||||||||||"
"||||||||||||||||||||||||||||||%d%c",
/* MSH */
strMSH_send_app,
strMSH_send_facility,
strMSH_dest_app,
strMSH_dest_facility,
strDateTime,
strMSH_hl7_version,
/* EVN */
13,
strEVN_timestamp,
strEVN_operator_id,
/* ZVN */
13,
strZVN_upd_by,
strZVN_upd_area,
/* PID */
13,
boomee_hosp,
boomee_pat_no,
/* ZP2 */
13,
boomee_person_no,13);
/* point at the next node
*/
pOld->next = pNew;
pOld
= pNew;
break;
case 100:
if
(verbose_level >= 10000 ) {
sprintf(errmsg,
"BOOM can't find a PERSON in PERS_SYN for %s%s",
boomee_hosp,boomee_pat_no);
error_notify(__FILE__, __LINE__,errmsg, NOTIFY_SERIOUS);
}
break;
default:
ingerr(__FILE__, __LINE__, sqlca.sqlcode,DEFAULT_SEQ_NO);
error_notify(__FILE__, __LINE__,
"BOOM can't select against PERS_SYN",
NOTIFY_FATAL);
shutdown_primary();
} /* switch */
} /* if (strPatIDList[counter] != ',') */
} /* for(counter<=strlen(strPatIDList)) */
/* terminate the list */
pNew->next
= NULL;
if( verbose_level >= 10) {
sprintf(errmsg,"returning %d related idrs to
BOOST",intNodeCount);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
}
if( verbose_level >= 100)
log_bb_times("create_BOOM_list: end");
return(pHead);
}/**************** end of create_BOOM_list
**********************************/
/*****************************************************************************
* function:
hl7_boost
* args:
msg_list_t *
* returns:
msg_list_t *
* usage info:
*
* recieves a pointer to a discrete HL7 message in
* msg_list_t, and extracts a list of any BOOM eligible
* person_no's found in the message.
*
* For each eligible person_no found, emits a series of
* stub A31 messages for each related patient identifier.
* The series head is always the original message.
*
* If no BOOM eligible person_no's or related patient
* identifiers can be found, the original message is
* returned. Otherwise,
the list of A31 stubs is
* returned as a new msg_list_t *.
*
* HISTORY:
* --------
* Programmer:
* Date:
* Mod:
*
* Programmer: Jeff
Martin
* Date: 17-Oct-1999
* Mod: Started
*
******************************************************************************/
msg_list_t
*
hl7_boom(msg_list_t
*REGlist)
{
msg_list_t *BOOMlist;
int
intStatus;
/****** code section ************************/
/* find the person_no's for the event type */
intStatus
= get_BOOM_person_no(REGlist);
sprintf(errmsg,
"Finished
get_BOOM_person_no with status %d",
intStatus);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
if (intStatus == 0) {
if(strPersonList)
free(strPersonList);
shutdown_primary();
}
/* perform no BOOMing */
if (intStatus == 2)
return(REGlist);
if (verbose_level >= 10) {
sprintf(errmsg,
"Booming REG event %d",REGlist->seq_no);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
}
/* remove duplicates from the person_no list */
if (
comma_del_sort_u(strPersonList) != 0) {
sprintf(errmsg,
"%s %s %d \nstrPersonList: %s",
"comma_del_sort_u failed parsing",
"strPersonList for REG event",
REGlist->seq_no, strPersonList);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_FATAL);
/* the event should be BOOMed, but can't be parsed. */
shutdown_primary();
}
if( verbose_level >= 10 ) {
sprintf(errmsg,
"person_no list for patient_id %s: %s",
strPID_patient_id,
strPersonList);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
}
/* get all the patient identifiers related to each person_no */
if (get_BOOM_pat_id()==0) {
if( verbose_level >= 10 ) {
error_notify(__FILE__, __LINE__,
"No related idrs found, returning only source to BOOST",
NOTIFY_UPDATE);
}
if(strPersonList)
free(strPersonList);
if(strPatIDList)
free(strPatIDList);
return(REGlist);
}
/* remove duplicates from the patient_id list */
if (
comma_del_sort_u(strPatIDList) != 0) {
sprintf(errmsg,
"%s %s %d \nstrPatIDList: %s",
"comma_del_sort_u failed parsing",
"strPatIDList for REG event",
REGlist->seq_no, strPatIDList);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_FATAL);
/* the event should be BOOMed, but can't be parsed. */
shutdown_primary();
}
if( verbose_level >= 10 ) {
sprintf(errmsg,
"patient_idr list: %s",strPatIDList);
error_notify(__FILE__,
__LINE__,errmsg, NOTIFY_UPDATE);
}
/* create a msg_list_t of stub A31's for each patient identifiers
*/
BOOMlist
= (msg_list_t *) create_BOOM_list(REGlist);
if(strPersonList)
free(strPersonList);
if(strPatIDList)
free(strPatIDList);
return(BOOMlist);
}/********* end of hl7_boom
************************************************/