Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: KMPCSMRT

KMPCSMRT.m

Go to the documentation of this file.
KMPCSMRT ;SP/JML - Coversheet Timing Data ;11/1/2023
 ;;4.0;CAPACITY MANAGEMENT;**1,2,3,4**;3/1/2018;Build 36
 ;
 ; Reference to $$WORKDAY^XUWORKDY in ICR #10046
 ; Reference to $$HTFM^XLFDT in ICR #10103
 ; Reference to $$HDIFF^XLFDT in ICR #10103
 ; Reference to GETENV^%ZOSV, EC^%ZOSV and LGR^%ZOSV in ICR #10097 
 ; Reference to $ESTACK, $ETRAP, ^%ZTER and UNWIND^%ZTER in ICR #1621
 ;
RUN ;
 N $ESTACK,$ETRAP S $ETRAP="D ^%ZTER Q"
 I $$GETVAL^KMPVCCFG("VCSM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VCSM DRIVER")
 N KMPDFGBG,KMPDLN,KMPINST,KMPMAP,KMPNDTYP,KMPON,KMPPARMS,KMPSC,KMPVCHKH,KMPFMDAY,KMPVH,KMPVHANG,KMPVNODE,KMPVSINF,KMPVSINT
 N KMPVSITE,KMPVSLOT,KMPVSTOP,KMPWORK,KMPVTEST,B,U,ZTDESC,ZTDTH,ZTRTN,ZTSAVE,Y,%
 ; ALWAYS - verify data is not building past configured number of days - if so for any reason, delete it
 D PURGEDLY^KMPVCBG("VCSM")
 ; Quit if monitor is not turned on
 I $$GETVAL^KMPVCCFG("VCSM","ONOFF",8969)'="ON" D  Q
 .I $$GETVAL^KMPVCCFG("VCSM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VCSM DRIVER END")
 ; Environment Check
 ;   if TEST system - quit if system is a front end OR allow test=no
 ;   if PROD system - quit if system is a front end AND allow test=no
 S KMPVTEST=$$GETVAL^KMPVCCFG("VCSM","ALLOW TEST SYSTEM",8969,"I")
 D GETENV^%ZOSV S KMPVNODE=$P(Y,U,3)_":"_$P($P(Y,U,4),":",2) ;supported by ICR #10097
 I $$PROD^KMPVCCFG'="prod",$$GETVAL^KMPVCCFG("VTCM","ALLOW TEST SYSTEM",8969,"I")'=1 Q
 ;
 S KMPFMDAY=+$$HTFM^XLFDT($H,1) ;supported by ICR #10103
 S KMPWORK=$$WORKDAY^XUWORKDY(KMPFMDAY) ;supported by ICR #10046
 S KMPINST=$P(KMPVNODE,":",2),KMPNDTYP=$$NODETYPE^KMPUTLW(KMPINST)
 ; quit if on front end and ^KMPTMP is mapped to the back end
 S KMPMAP=$P(##Class(%SYS.Namespace).GetGlobalDest($ZDEFNSP,"KMPTMP",""),"^",2)
 S KMPMAP=$SYSTEM.SQL.UPPER(KMPMAP)
 I KMPMAP["SHARE",KMPNDTYP="FE" Q
 ;
 S KMPVSTOP=0,KMPVCHKH=+$H
 S KMPPARMS("KMPFMDAY")=KMPFMDAY,KMPPARMS("KMPWORK")=KMPWORK,KMPPARMS("KMPVCHKH")=KMPVCHKH
 S KMPPARMS("KMPINST")=KMPINST,KMPPARMS("KMPNDTYP")=KMPNDTYP
 F  D  Q:KMPVSTOP
 .S KMPON=$$GETVAL^KMPVCCFG("VCSM","ONOFF",8969)
 .I KMPON="ON" S ^KMPTMP("KMPD-CPRS")=1
 .E  K ^KMPTMP("KMPD-CPRS") S KMPVSTOP=1 Q
 .S KMPVH=$H,KMPDLN=1
 .I KMPVH>KMPVCHKH SET KMPVSTOP=1 Q
 .S KMPVSINT=$$GETVAL^KMPVCCFG("VCSM","COLLECTION INTERVAL",8969)
 .S KMPVHANG=KMPVSINT*60
 .S KMPPARMS("KMPVH")=KMPVH,KMPPARMS("KMPVSINT")=KMPVSINT
 .M ^KMPTMP("KMPV","VCSM",KMPVNODE,"PARMS")=KMPPARMS
 .J COLLECT(KMPVNODE)
 .H KMPVHANG
 I $$GETVAL^KMPVCCFG("VCSM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VCSM DRIVER END")
 Q
 ;
COLLECT(KMPVNODE) ;
 N $ES,$ETRAP S $ETRAP="D ^%ZTER Q"
 I $$GETVAL^KMPVCCFG("VCSM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VCSM COLLECTOR")
 N KMPCNT,KMPDATA,KMPDFGBG,KMPDONE,KMPINST,KMPLI,KMPMAX,KMPNDTYP,KMPSTAT,KMPTI,KMPTIMES
 N KMPVSINF,KMPVSITE,B,KMPABAND,KMPNOST
 ;
 M KMPPARMS=^KMPTMP("KMPV","VCSM",KMPVNODE,"PARMS")
 S KMPFMDAY=KMPPARMS("KMPFMDAY")
 S KMPWORK=KMPPARMS("KMPWORK"),KMPVCHKH=KMPPARMS("KMPVCHKH")
 S KMPVH=KMPPARMS("KMPVH"),KMPVSINT=KMPPARMS("KMPVSINT")
 S KMPINST=KMPPARMS("KMPINST"),KMPNDTYP=KMPPARMS("KMPNDTYP")
 S U="^"
 S KMPVSLOT=$$SLOT^KMPVCCFG(KMPVH,KMPVSINT,"HOROLOG")
 K ^KMPTMP("KMPV","VCSM","TRANSMIT")
 ;
 S KMPDFGBG=0,B="|",KMPDLN=1,KMPABAND=0,KMPNOST=0
 I $D(^KMPTMP("KMPDT","ORWCV")) S KMPDFGBG=1
 I $D(^KMPTMP("KMPDT","ORWCV-FT")) S KMPDFGBG=KMPDFGBG+2
 I KMPDFGBG=1 D ORONE("ORWCV")
 I KMPDFGBG=2 D ORONE("ORWCV-FT")
 I KMPDFGBG=3 D ORBOTH
 ;
 S KMPTI="",KMPMAX=40000
 S KMPLI=+$O(^KMPTMP("KMPV","VCSM","TRANSMIT",""),-1)
 I (KMPLI>0)!(KMPABAND>0)!(KMPNOST>0) D
 .S KMPDONE=0
 .F  D  Q:KMPDONE
 ..N KMPJSON,KMPJMSG,KMPDARR
 ..S KMPJSON=##class(%DynamicObject).%New()
 ..S KMPJSON.Function="VCSM"
 ..D SITE^KMPUTLW(KMPJSON)
 ..S KMPJMSG=##class(%DynamicObject).%New()
 ..S KMPTIMES=$$TSTAMP^KMPUTLW(+KMPVH_","_KMPVSLOT,"HOROLOG",1) ; yyy-mm-dd hh:mm:ssZtz
 ..S KMPJMSG.Timestamp=$P(KMPTIMES,"^"),KMPJMSG.UtcOdbc=$P(KMPTIMES,"^",2)
 ..S KMPJMSG.UtcEpoch=$P(KMPTIMES,"^",3),KMPJMSG.IsDst=$P(KMPTIMES,"^",4)
 ..S KMPJMSG.Workday=KMPWORK,KMPJMSG.Instance=KMPINST
 ..S KMPJMSG.Date=$$SHORTDAT^KMPUTLW(+$H,"HOROLOG")
 ..S KMPJMSG.Node=$P(KMPVNODE,":"),KMPJMSG.NodeType=KMPNDTYP
 ..S KMPJMSG.Abandoned=KMPABAND,KMPJMSG.NoStartTime=KMPNOST
 ..S KMPJSON.MessageData=KMPJMSG
 ..S KMPDARR=##class(%DynamicArray).%New()
 ..S KMPCNT=0
 ..F  S KMPTI=$O(^KMPTMP("KMPV","VCSM","TRANSMIT",KMPTI))  Q:KMPTI=""!(KMPCNT>KMPMAX)  D
 ...S KMPDATA=$G(^KMPTMP("KMPV","VCSM","TRANSMIT",KMPTI))
 ...D KMPDARR.%Push(KMPDATA)
 ...I KMPTI>=KMPLI S KMPDONE=1
 ...S KMPCNT=KMPCNT+1
 ..S KMPJSON.Details=KMPDARR
 ..S KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/coversheet",1,"VCSM")
 ..I +KMPSTAT'=200 H 30 S KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/coversheet",1,"VCSM")
 ..S ^XTMP("KMP "_KMPFMDAY,"VCSM","HTTP",KMPVNODE,$P($H,",",2))=KMPSTAT
 ..I +KMPSTAT'=200 D SETRETRY
 ..I KMPLI=0 S KMPDONE=1  ; just in case there is only abandoned entries. Prevents loop.
 .K ^KMPTMP("KMPV","VCSM","TRANSMIT")
 I $$GETVAL^KMPVCCFG("VCSM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VCSM COLLECTOR END")
 Q
 ;
ORONE(KMPDSUB) ;
 N KMPBDTIM,KMPDDAT1,KMPDDATA,KMPDDELT,KMPDETS,KMPDID,KMPDP,KMPETIM,KMPVDAY,KMPVTIME,KMPSTIM,KMPETIM,KMPIPOLD,KMPTCHK
 ;
 S KMPTCHK=+$$GETVAL^KMPVCCFG("VCSM","TASKMAN OPTION",8969)
 S KMPDID=""
 F  S KMPDID=$O(^KMPTMP("KMPDT",KMPDSUB,KMPDID)) Q:KMPDID=""  D
 .S KMPDDAT1=$G(^KMPTMP("KMPDT",KMPDSUB,KMPDID))
 .S KMPVDAY=$P($P(KMPDDAT1,U),",",1)
 .S KMPVTIME=$P($P(KMPDDAT1,U),",",2)
 .I KMPVTIME>=KMPVSLOT,KMPVDAY>=+$H Q
 .;  FG or BG delta
 .S KMPSTIM=$P(KMPDDAT1,U),KMPETIM=$P(KMPDDAT1,U,2)
 .I +KMPSTIM=0 D  Q  ; Initial time not set - count and throw away
 ..K ^KMPTMP("KMPDT",KMPDSUB,KMPDID)
 ..S KMPNOST=KMPNOST+1
 .; Check if abandoned
 .I KMPTCHK>0,$$HDIFF^XLFDT($H,KMPSTIM,2)>(KMPTCHK) D  Q  ;supported by ICR #10103
 ..K ^KMPTMP("KMPDT",KMPDSUB,KMPDID)
 ..S KMPABAND=KMPABAND+1
 .Q:KMPETIM=""  ; may be still in process
 .S KMPDDELT=$$HDIFF^XLFDT(KMPETIM,KMPSTIM,2) ;supported by ICR #10103
 .S KMPDP=$S(KMPDSUB="ORWCV-FT":1,1:2)
 .S $P(KMPDDATA,B,KMPDP)=KMPDDELT
 .; client duz
 .S $P(KMPDDATA,B,3)=$P(KMPDDAT1,U,3)
 .; ip address
 .S $P(KMPDDATA,B,4)=$P(KMPDDAT1,U,4)
 .; ip address old
 .S KMPIPOLD=$P($P(KMPDID,"-")," ",2)
 .I +KMPIPOLD>0 S $P(KMPDDATA,B,5)=KMPIPOLD
 .; patient DFN
 .S $P(KMPDDATA,B,6)=$P(KMPDID,"-",3)
 .; FG DELTA|BG DELTA|CLIENT DUZ|CLIENT IP (was client name)|OLD IP FROM SUBSCRIPT (usually 'No IP Address')|DFN
 .S ^KMPTMP("KMPV","VCSM","TRANSMIT",KMPDLN)=KMPDDATA,KMPDLN=KMPDLN+1
 .K ^KMPTMP("KMPDT",KMPDSUB,KMPDID)
 Q
 ;
ORBOTH ;
 N KMPDBDLT,KMPDBGD,KMPDBGSS,KMPDDATA,KMPDETS,KMPDFDLT,KMPDFGD,KMPDFGSS,KMPDID,KMPVDAY,KMPVTIME
 N KMPFGSTIM,KMPFGETIM,KMPBGSTIM,KMPBGETIM,KMPIPOLD,KMPTCHK
 ; loop foreground node and concurrently look at related background node
 S KMPDBGSS="ORWCV",KMPDFGSS="ORWCV-FT"
 S KMPTCHK=+$$GETVAL^KMPVCCFG("VCSM","TASKMAN OPTION",8969)
 S KMPDID=""
 F  S KMPDID=$O(^KMPTMP("KMPDT",KMPDFGSS,KMPDID)) Q:KMPDID=""  D
 .S KMPDFGD=$G(^KMPTMP("KMPDT",KMPDFGSS,KMPDID))
 .S KMPDBGD=$G(^KMPTMP("KMPDT",KMPDBGSS,KMPDID))
 .S (KMPDFDLT,KMPDBDLT)=""
 .S KMPFGSTIM=$P(KMPDFGD,U),KMPFGETIM=$P(KMPDFGD,U,2)
 .S KMPBGSTIM=$P(KMPDBGD,U),KMPBGETIM=$P(KMPDBGD,U,2)
 .; If start time not set - throw away
 .I (+KMPFGSTIM=0)!(+KMPBGSTIM=0) D  Q
 ..K ^KMPTMP("KMPDT",KMPDFGSS,KMPDID)
 ..K ^KMPTMP("KMPDT",KMPDBGSS,KMPDID)
 ..S KMPNOST=KMPNOST+1
 .; Check if abandoned (no end time after set period
 .I KMPTCHK>0,($$HDIFF^XLFDT($H,KMPBGSTIM,2)>(KMPTCHK))!($$HDIFF^XLFDT($H,KMPFGSTIM,2)>(KMPTCHK)) D  Q  ;supported by ICR #10103
 ..K ^KMPTMP("KMPDT",KMPDFGSS,KMPDID)
 ..K ^KMPTMP("KMPDT",KMPDBGSS,KMPDID)
 ..S KMPABAND=KMPABAND+1
 .; if future then skip
 .S KMPVDAY=$P($P(KMPDFGD,U),",",1)
 .S KMPVTIME=$P($P(KMPDFGD,U),",",2)
 .I KMPVTIME>=KMPVSLOT,KMPVDAY>=+$H Q
 .; wait for ending time to be set
 .I (KMPFGETIM="")!(KMPBGETIM="") Q
 .; Data is good so get timings
 .I $P(KMPDFGD,U,2) S KMPDFDLT=$$HDIFF^XLFDT(KMPFGETIM,KMPFGSTIM,2) ;supported by ICR #10103
 .I $P(KMPDBGD,U,2) S KMPDBDLT=$$HDIFF^XLFDT(KMPBGETIM,KMPBGSTIM,2) ;supported by ICR #10103
 .S $P(KMPDDATA,B,1)=KMPDFDLT
 .S $P(KMPDDATA,B,2)=KMPDBDLT
 .; client duz
 .S $P(KMPDDATA,B,3)=$P(KMPDFGD,U,3)
 .; client ip
 .S $P(KMPDDATA,B,4)=$P(KMPDFGD,U,4)
 .; ip address old
 .S KMPIPOLD=$P($P(KMPDID,"-")," ",2)
 .I KMPIPOLD>0 S $P(KMPDDATA,B,5)=KMPIPOLD
 .; patient DFN
 .S $P(KMPDDATA,B,6)=$P(KMPDID,"-",3)
 .;  FG DELTA|BG DELTA|CLIENT DUZ|CLIENT IP (was client name)|OLD IP FROM SUBSCRIPT (usually 'No IP Address')|DFN
 .S ^KMPTMP("KMPV","VCSM","TRANSMIT",KMPDLN)=KMPDDATA,KMPDLN=KMPDLN+1
 .K ^KMPTMP("KMPDT",KMPDFGSS,KMPDID)
 .K ^KMPTMP("KMPDT",KMPDBGSS,KMPDID)
 ; Loop BG node in case there is an entry that didn't have a FG entry.
 ; The reverse situation already handled in first loop.
 D ORONE("ORWCV")
 Q
 ;
SETRETRY ;
 N KMPTEXT
 S KMPTEXT("SUBJECT")="VSM FAILED SEND: VCSM at "_KMPJSON.Site.SiteCode
 S KMPTEXT(1)="Status Code: "_+KMPSTAT
 S KMPTEXT(2)="Status Text: "_$P(KMPSTAT,"^",2)
 S KMPTEXT(3)="Response Time: "_$P(KMPSTAT,"^",3)
 S KMPTEXT(4)="Node: "_KMPVNODE
 D INFOMSG^KMPUTLW(.KMPTEXT)
 S ^KMPTMP("KMPV","VCSM","RETRY",KMPVNODE,+$H,$H)=KMPJSON.%ToJSON()
 Q
 ;
RETRY ;  retry failed POSTS
 N KMPDAY,KMPI,KMPJSON,KMPSTAT,KMPVNODE,Y
 ;
 D GETENV^%ZOSV S KMPVNODE=$P(Y,"^",3)_":"_$P($P(Y,"^",4),":",2) ;supported by ICR #10097
 S KMPDAY=""
 F  S KMPDAY=$O(^KMPTMP("KMPV","VCSM","RETRY",KMPVNODE,KMPDAY)) Q:KMPDAY=""  D
 .S KMPI=""
 .F  S KMPI=$O(^KMPTMP("KMPV","VCSM","RETRY",KMPVNODE,KMPDAY,KMPI)) Q:KMPI=""  D
 ..S KMPJSON=$G(^KMPTMP("KMPV","VCSM","RETRY",KMPVNODE,KMPDAY,KMPI))
 ..S KMPSTAT=$$POST^KMPUTLW({}.%FromJSON(KMPJSON),"/coversheet",1,"VCSM")
 ..I +KMPSTAT=200 K ^KMPTMP("KMPV","VCSM","RETRY",KMPVNODE,KMPDAY,KMPI)
 ..H $R(10)
 Q