- XQALSURO ;ISC-SF.SEA/JLI,ISD/HGW - SURROGATES FOR ALERTS ; May 12, 2021@14:27
- ;;8.0;KERNEL;**114,125,173,285,366,443,513,602,730,754**;Jul 10, 1995;Build 1
- ;Per VHA Directive 2004-038, this routine should not be modified
- Q
- OTHRSURO ; OPT:- XQALERT SURROGATE SET/REMOVE -- OTHERS SPECIFY SURROGATE FOR SELECTED USER
- N XQAUSER,DIR,Y
- S DIR(0)="PD^200:AEMQ",DIR("A",1)="SURROGATE related to which"
- S DIR("A")="NEW PERSON entry"
- D ^DIR K DIR Q:Y'>0 W " ",$P(Y,U,2)
- S XQAUSER=+Y
- G SURROGAT
- Q
- ;
- SURROGAT ; USER SPECIFICATION OF SURROGATE
- I '$D(XQAUSER) N XQAUSER S XQAUSER=DUZ
- D SURRO1^XQALSUR1(XQAUSER)
- Q
- ;
- CYCLIC(XQALSURO,XQAUSER,XQASTRT,XQAEND) ; code added to prevent cyclical surrogates
- I '$$ACTIVE^XUSER(XQALSURO) Q "You cannot have an INACTIVE USER ("_$$NAME^XUSER(XQALSURO,"F")_") as a surrogate!" ;P443
- I XQALSURO=XQAUSER Q "You cannot specify yourself as your own surrogate!" ; moved in P443
- I $G(XQASTRT)>0 Q $$DCYCLIC^XQALSUR1(XQALSURO,XQAUSER,XQASTRT,$G(XQAEND))
- ;p602 in SURRO11^XQALSUR1 split the check for cyclical surrogates into two parts. The following code becomes unnecessary.
- ;N XQALSTRT
- ;S XQALSTRT=$$CURRSURO(XQALSURO) I XQALSTRT>0 D
- ;. I XQALSTRT=XQAUSER S XQALSURO="YOU are designated as the surrogate for this user ("_XQALSURO_") - can't do it!" Q
- ;. F S XQALSTRT=$$CURRSURO(XQALSTRT) Q:XQALSTRT'>0 I XQALSTRT=XQAUSER S XQALSURO="This forms a circle which leads back to you - can't do it!" Q
- ;. Q
- Q XQALSURO
- ;
- SETSURO(XQAUSER,XQALSURO,XQALSTRT,XQALEND) ; SR. ICR #2790 (Supported)
- ; Use SETSURO1 instead
- N XQALVAL ; P443
- S XQALVAL=$$SETSURO1(XQAUSER,XQALSURO,$G(XQALSTRT),$G(XQALEND)) ; P443
- Q
- ;
- SETSUROX(XQAUSER,XQALSURO,XQALSTRT,XQALEND) ; SETSURO CODE MOVED TO HERE TO PERMIT AN ERROR TO BE GENERATED AT THE OLD ENTRY POINT
- N XQALFM,XQALIEN,XQAIENS
- I '$D(^XTV(8992,XQAUSER,0)) D
- . N XQALFM,XQALFM1
- . S XQALFM1(1)=XQAUSER
- . S XQALFM(8992,"+1,",.01)=XQAUSER
- . D UPDATE^DIE("","XQALFM","XQALFM1")
- . Q
- S XQAIENS=XQAUSER_","
- ; P366 - force no start date/time to NOW, and anything less than NOW to NOW
- I $G(XQALSTRT)<$$NOW^XLFDT() S XQALSTRT=$$NOW^XLFDT()
- ; P366 - add values to new multiple
- S XQALFM(8992.02,"+1,"_XQAIENS,.01)=XQALSTRT
- S XQALFM(8992.02,"+1,"_XQAIENS,.02)=XQALSURO
- I (XQALEND>0)&(XQALEND'>XQALSTRT) S XQALEND=$$FMADD^XLFDT(XQALSTRT,0,0,0,1) ;p602 force end date/time to be after start date/time
- I XQALEND>0 S XQALFM(8992.02,"+1,"_XQAIENS,.03)=XQALEND
- K XQALIEN D UPDATE^DIE("","XQALFM","XQALIEN")
- ; P366 - if start date time is already in effect - place in old locations to make active
- ;D ACTIVATE(XQAUSER,XQALIEN(1)) ; P513 activate if current or next
- I XQALSTRT'>$$NOW^XLFDT() D ACTIVATE(XQAUSER,XQALIEN(1)) ; p602 activate only if current
- N XQAMESG,XMSUB,XMTEXT
- S XQAMESG(1,0)="You have been specified as a surrogate recipient for alerts for"
- S XQAMESG(2,0)=$$GET1^DIQ(200,XQAIENS,.01,"E")_" (IEN="_XQAUSER_") effective "_$$FMTE^XLFDT(XQALSTRT)
- I $G(XQALEND)'>0 S XQAMESG(2,0)=XQAMESG(2,0)_"."
- E S XQAMESG(3,0)="until "_$$FMTE^XLFDT(XQALEND)
- S XMSUB="Surrogate Recipient for "_$$GET1^DIQ(200,XQAIENS,.01,"E")
- S XMTEXT="XQAMESG("
- ; ZEXCEPT: XTMUNIT - Defined if unit tests are being run
- D:'$D(XTMUNIT) SENDMESG
- Q
- ;
- ACTIVATE(XQAUSER,XQALIEN) ; activates a surrogate
- N X0,XQALFM,XQALSURO,XQALSTRT,XQALEND
- S X0=$G(^XTV(8992,XQAUSER,2,XQALIEN,0)) Q:X0="" S XQALSTRT=$P(X0,U),XQALSURO=$P(X0,U,2),XQALEND=$P(X0,U,3)
- S X0=^XTV(8992,XQAUSER,0)
- I $P(X0,U,2)>0,$P(X0,U,3)'>$$NOW^XLFDT() D REMVSURO(XQAUSER) ; If we are activating a new surrogate, if one exists simply remove.
- K XQALFM S XQALFM(8992,XQAUSER_",",.03)=XQALSTRT
- S XQALFM(8992,XQAUSER_",",.02)=XQALSURO
- S XQALFM(8992,XQAUSER_",",.04)=$S($G(XQALEND)>0:XQALEND,1:"@")
- D FILE^DIE("","XQALFM")
- Q
- ;
- ; usage $$SETSURO1(XQAUSER,XQALSURO,XQALSTRT,XQALEND) returns 0 if invalid, otherwise > 0
- SETSURO1(XQAUSER,XQALSURO,XQALSTRT,XQALEND) ;EXTRINSIC. ICR #3213 (supported)
- ; This should be used instead of SETSURO
- I $G(XQAUSER)'>0 Q "Invalid Internal Entry Number for user ("_XQAUSER_")" ; P513 moved from SETSUROX+2
- I $G(XQALSURO)'>0 Q "Invalid Internal Entry Number for surrogate ("_XQALSURO_")" ; P513 moved from SETSUROX+3
- I $G(XQALSTRT)'>0 S XQALSTRT=$$NOW^XLFDT()
- N XQAVAL
- S XQAVAL=$$CYCLIC(XQALSURO,XQAUSER,XQALSTRT,$G(XQALEND)) I XQAVAL'>0 Q XQAVAL ; Can't use as surrogate
- D SETSUROX(XQAUSER,XQALSURO,XQALSTRT,$G(XQALEND)) ; P443
- Q XQALSURO
- ;
- CHKREMV ;
- N DIR,XQAI,XQAQUIT,XQASLIST,XQAVAL,YVAL,Y
- ; ZEXCEPT: XQAUSER (EXTERNAL VALUE)
- ; p730
- ;D SUROLIST^XQALSUR1(XQAUSER,.XQASLIST)
- ; Display list and allow user to remove surrogate periods until satisfied
- S XQAQUIT=0 F D Q:$G(XQASLIST)<1!XQAQUIT
- . D DISPSUR^XQALSUR2(XQAUSER,.XQASLIST)
- . Q:$G(XQASLIST)<=0
- . S DIR(0)="Y",DIR("B")="NO"
- . S DIR("A")="Do you want to REMOVE "_$S(XQASLIST>1:"a",1:"THIS")_" surrogate recipient"
- . S DIR("?")="A surrogate will receive your alerts until they are removed as surrogate."
- . D ^DIR K DIR S XQAQUIT='+Y
- . Q:XQAQUIT
- . S DIR("A")="Enter a list (comma separated, e.g., 1,2) of the surrogate(s) to remove"
- . S Y=1 I XQASLIST>1 S DIR(0)="L^1:"_XQASLIST D ^DIR K DIR
- . I Y>0 S YVAL=Y F XQAI=1:1 S XQAVAL=+$P(YVAL,",",XQAI) Q:XQAVAL'>0 D REMVSURO(XQAUSER,$P(XQASLIST(XQAVAL),U),$P(XQASLIST(XQAVAL),U,3))
- . W !
- Q
- ;
- ; P366 - added OPTIONAL second and third arguments to permit deletion of a specific pending surrogate and start date
- REMVSURO(XQAUSER,XQALSURO,XQALSTRT) ;SR. ICR #2790 (supported)
- ; Ends the currently active surrogate relationship
- I $G(XQAUSER)'>0 Q
- D REMVSURO^XQALSUR1(XQAUSER,$G(XQALSURO),$G(XQALSTRT))
- Q
- ;
- ; P366 - added OPTIONAL second and third arguments to determine surrogate for specified time range
- CURRSURO(XQAUSER,XQASTRT,XQAEND) ;SR. ICR #2790 (supported)
- ; Returns current surrogate for user or -1 usage $$CURRSURO^XQALSURO(DUZ)
- N X,ACTIVE,XQANOW,XQASTR1,XQAIVAL,XQA0,XQAI
- D CHEKSUBS^XQALSUR2(XQAUSER)
- I $G(XQASTRT)>0 Q $$DATESURO^XQALSUR1(XQAUSER,XQASTRT,$G(XQAEND)) ; P366 - check for current in specified date/times
- ;
- ; P366 - find the latest start time which is now or past or the first one in the future
- S XQANOW=$$NOW^XLFDT() D
- . S XQAIVAL=0,XQASTR1=0
- . F XQASTRT=0:0 S XQASTRT=$O(^XTV(8992,XQAUSER,2,"B",XQASTRT)) Q:XQASTRT'>0 Q:XQASTRT'<XQANOW S XQASTR1=XQASTRT F XQAI=0:0 S XQAI=$O(^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI)) Q:XQAI'>0 D
- . . ; p754 somebody removed surr by gbl kill, cleanup
- . . I '$D(^XTV(8992,XQAUSER,2,XQAI,0)) K ^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI) Q
- . . S XQAEND=$P(^XTV(8992,XQAUSER,2,XQAI,0),U,3) I (XQAEND="")!(XQAEND>XQANOW) S XQAIVAL=XQAI
- . . Q
- . ; to be compatible with the past, if there is not a current surrogate, show the next scheduled on the zero node if there is one
- . I XQAIVAL=0 S XQASTRT=$O(^XTV(8992,XQAUSER,2,"B",XQASTR1)) Q:XQASTRT="" F XQAI=0:0 S XQAI=$O(^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI)) Q:XQAI'>0 D Q:XQAIVAL>0
- . . ; p754 somebody removed surr by gbl kill, cleanup
- . . I '$D(^XTV(8992,XQAUSER,2,XQAI,0)) K ^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI) Q
- . . S XQAEND=$P(^XTV(8992,XQAUSER,2,XQAI,0),U,3) I (XQAEND="")!(XQAEND>XQANOW) S XQAIVAL=XQAI
- . . Q
- . I XQAIVAL>0 S XQA0=^XTV(8992,XQAUSER,2,XQAIVAL,0),XQASTRT=^XTV(8992,XQAUSER,0) I ($P(XQA0,U,2)'=$P(XQASTRT,U,2))!($P(XQA0,U)'=$P(XQASTRT,U,3))!(+$P(XQA0,U,3)'=+$P(XQASTRT,U,4)) D ACTIVATE(XQAUSER,XQAIVAL)
- . Q
- ; P366 - end
- S X=$G(^XTV(8992,XQAUSER,0))
- ; now check for a CURRENT surrogate, already started and not expired or cyclic
- I $P(X,U,2)>0,+$P(X,U,3)'>XQANOW D I $P($G(^XTV(8992,XQAUSER,0)),U,2)>0 Q +$P(^XTV(8992,XQAUSER,0),U,2)
- . N DATE ; Get Current date/time to check date/times if present
- . ; FOLLOWING LINES MODIFIED IN P443 TO ELIMINATE A STACK ERROR WHEN SURROGATE WAS CIRCULAR
- . ; Current Date/time past End date for surrogate
- . S DATE=$P(X,U,4) I (DATE>0&(DATE<XQANOW)) D REMVSURO(XQAUSER) Q
- . ; P513 quit if not already active
- . S DATE=$P(X,U,3) S:DATE="" DATE=XQANOW I DATE>XQANOW Q ; P513
- . N XQASURO,XQASURO1 S XQASURO1=+$P(^XTV(8992,XQAUSER,0),U,2)
- . ; REMOVE IF SURROGATE IS USER
- . I XQASURO1=XQAUSER D REMVSURO(XQAUSER) Q
- . Q ; p754 cyclic checks are done at surrogate creation time and the following is not needed
- Q -1
- ;. N XQALLIST,XQAUDATE S XQAUDATE=DATE,XQALLIST(XQAUSER,DATE)="" ; P513 JLI 100504 add XQAUDATE to be able to check earlier start time
- ;. ; REMOVE IF CYCLES BACK TO USER - thought about removing inactive, but best to let those be handled by groups for unprocessed alerts
- ;. ; P513 but ignore if surrogate isn't already active - JLI 100504
- ;. ; begin changes in P513
- ;. S XQASURO1=XQAUSER
- ;. F S XQASURO=$P($G(^XTV(8992,XQASURO1,0)),U,2) Q:XQASURO'>0 Q:'$$ISACTIVE(XQASURO) S DATE=$P(^XTV(8992,XQASURO,0),U,3) Q:DATE>XQANOW D S XQASURO1=XQASURO ; JLI 100504
- ;. . ;I $D(XQALLIST(XQASURO1)) D
- ;. . I $D(XQALLIST(XQASURO)) D ; p730 check on NEXT surrogate and not on XQAUSER for first pass
- ;. . . N DATE1 S DATE1=$O(XQALLIST(XQASURO1,""))
- ;. . . ; remove the surrogate relationship that started earliest
- ;. . . I DATE<DATE1 D REMVSURO(XQASURO)
- ;. . . I DATE1<=DATE D REMVSURO(XQASURO1)
- ;. . . S XQASURO=XQAUSER K XQALLIST S DATE=XQAUDATE ; start over
- ;. . . Q
- ;. . S XQALLIST(XQASURO,DATE)=""
- ;. . ; end of P513 modification
- ;. . Q
- ;. ; END OF P443 MODIFICATION
- ;. Q
- ;Q -1
- ;
- ISACTIVE(XQAUSER) ; checks for whether a surrogate relationship is active or not (returns 0 or 1)
- N DATA
- S DATA=$G(^XTV(8992,XQAUSER,0)) Q:$P(DATA,U,2)="" 0 ; NO SURROGATE SPECIFIED
- I $P(DATA,U,3)>0,$P(DATA,U,3)>$$NOW^XLFDT() Q 0 ; START DATE/TIME NOT YET
- I $P(DATA,U,4)>0,$P(DATA,U,4)<$$NOW^XLFDT() Q 0 ; PAST END DATE/TIME
- Q 1
- ;
- ACTVSURO(XQAUSER) ;SR. ICR #2790 (supported)
- ; Returns the actual surrogate at this time
- N CURRSURO,NEXTSURO,SURODATA,NOW
- S NOW=$$NOW^XLFDT()
- S CURRSURO=$$CURRSURO(XQAUSER),SURODATA=$$GETSURO(XQAUSER) I (CURRSURO'>0)!(+$P(SURODATA,U,3)>NOW)!('(+$$ACTIVE^XUSER(CURRSURO))) Q -1
- F S NEXTSURO=$$CURRSURO(CURRSURO),SURODATA=$$GETSURO(CURRSURO) Q:NEXTSURO'>0 Q:+$P(SURODATA,U,3)>NOW Q:'(+$$ACTIVE^XUSER(NEXTSURO)) S CURRSURO=NEXTSURO
- Q CURRSURO
- ;
- GETSURO(XQAUSER) ;EXTRINSIC. ICR #3213 (supported)
- ; Returns data for surrogate for user including times
- I $$CURRSURO(XQAUSER)'>0 Q ""
- N GLOBREF,IENS,X
- S IENS=XQAUSER_",",GLOBREF=$NA(^TMP($J,"XQALSURO")) K @GLOBREF
- D GETS^DIQ(8992,IENS,".02;.03;.04","IE",GLOBREF)
- S GLOBREF=$NA(@GLOBREF@(8992,IENS))
- S X=$G(@GLOBREF@(.02,"I"))_U_$G(@GLOBREF@(.02,"E"))_U_$G(@GLOBREF@(.03,"I"))_U_$G(@GLOBREF@(.04,"I"))
- K @GLOBREF
- Q X
- ;
- GETFOR ;OPT.
- N XQAUSER,VALUES,XQACNT,DIR,DIRUT,I,Y
- S DIR(0)="PD^200:AEMQ"
- S DIR("A")="Select Surrogate (NEW PERSON entry)"
- S DIR("A",1)="",DIR("A",2)=""
- S DIR("A",3)=" - List Users who have chosen this User to be their current Surrogate." ;p602
- S DIR("A",4)=""
- D ^DIR K DIR Q:Y'>0 W " ",$P(Y,U,2)
- S XQAUSER=+Y
- D SUROFOR(.VALUES,XQAUSER) I VALUES'>0 W !,"No entries found.",!! Q
- S XQACNT=0 K DIRUT F I=0:0 S I=$O(VALUES(I)) Q:I'>0 D:(XQACNT>(IOSL-4)) Q:$D(DIRUT) W !,?5,$P(VALUES(I),U,2) S XQACNT=XQACNT+1
- . S DIR(0)="E" D ^DIR K DIR
- . Q
- K DIRUT
- Q
- ;
- SUROLIST(XQAUSER,XQALIST) ;SR. ICR #3213 (supported)
- ; Returns list of current and scheduled surrogates for XQAUSER
- D SUROLIST^XQALSUR1(XQAUSER,.XQALIST)
- Q
- ;
- SUROFOR(LIST,XQAUSER) ;SR. ICR #3213 (supported)
- ; Returns list of users XQAUSER is acting as a surrogate for
- I $G(XQAUSER)="" Q
- N I,COUNT S I=0,COUNT=0 F S I=$O(^XTV(8992,"AC",XQAUSER,I)) Q:I'>0 I $$CURRSURO(I)>0 D
- . S COUNT=COUNT+1,LIST(COUNT)=I_U_$$GET1^DIQ(200,(I_","),".01","E")_U_$$GET1^DIQ(8992,(I_","),".03","E")_U_$$GET1^DIQ(8992,(I_","),".04","E")
- S LIST=COUNT
- Q
- ;
- SENDMESG ;
- N XMY,XMDUZ,XMCHAN
- ; ZEXCEPT: XQALSURO (EXTERNAL VALUE)
- S XMY(XQALSURO)="",XMDUZ=.5
- D ^XMD
- Q
- --- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HXQALSURO 11988 printed Mar 13, 2025@21:10:25 Page 2
- XQALSURO ;ISC-SF.SEA/JLI,ISD/HGW - SURROGATES FOR ALERTS ; May 12, 2021@14:27
- +1 ;;8.0;KERNEL;**114,125,173,285,366,443,513,602,730,754**;Jul 10, 1995;Build 1
- +2 ;Per VHA Directive 2004-038, this routine should not be modified
- +3 QUIT
- OTHRSURO ; OPT:- XQALERT SURROGATE SET/REMOVE -- OTHERS SPECIFY SURROGATE FOR SELECTED USER
- +1 NEW XQAUSER,DIR,Y
- +2 SET DIR(0)="PD^200:AEMQ"
- SET DIR("A",1)="SURROGATE related to which"
- +3 SET DIR("A")="NEW PERSON entry"
- +4 DO ^DIR
- KILL DIR
- if Y'>0
- QUIT
- WRITE " ",$PIECE(Y,U,2)
- +5 SET XQAUSER=+Y
- +6 GOTO SURROGAT
- +7 QUIT
- +8 ;
- SURROGAT ; USER SPECIFICATION OF SURROGATE
- +1 IF '$DATA(XQAUSER)
- NEW XQAUSER
- SET XQAUSER=DUZ
- +2 DO SURRO1^XQALSUR1(XQAUSER)
- +3 QUIT
- +4 ;
- CYCLIC(XQALSURO,XQAUSER,XQASTRT,XQAEND) ; code added to prevent cyclical surrogates
- +1 ;P443
- IF '$$ACTIVE^XUSER(XQALSURO)
- QUIT "You cannot have an INACTIVE USER ("_$$NAME^XUSER(XQALSURO,"F")_") as a surrogate!"
- +2 ; moved in P443
- IF XQALSURO=XQAUSER
- QUIT "You cannot specify yourself as your own surrogate!"
- +3 IF $GET(XQASTRT)>0
- QUIT $$DCYCLIC^XQALSUR1(XQALSURO,XQAUSER,XQASTRT,$GET(XQAEND))
- +4 ;p602 in SURRO11^XQALSUR1 split the check for cyclical surrogates into two parts. The following code becomes unnecessary.
- +5 ;N XQALSTRT
- +6 ;S XQALSTRT=$$CURRSURO(XQALSURO) I XQALSTRT>0 D
- +7 ;. I XQALSTRT=XQAUSER S XQALSURO="YOU are designated as the surrogate for this user ("_XQALSURO_") - can't do it!" Q
- +8 ;. F S XQALSTRT=$$CURRSURO(XQALSTRT) Q:XQALSTRT'>0 I XQALSTRT=XQAUSER S XQALSURO="This forms a circle which leads back to you - can't do it!" Q
- +9 ;. Q
- +10 QUIT XQALSURO
- +11 ;
- SETSURO(XQAUSER,XQALSURO,XQALSTRT,XQALEND) ; SR. ICR #2790 (Supported)
- +1 ; Use SETSURO1 instead
- +2 ; P443
- NEW XQALVAL
- +3 ; P443
- SET XQALVAL=$$SETSURO1(XQAUSER,XQALSURO,$GET(XQALSTRT),$GET(XQALEND))
- +4 QUIT
- +5 ;
- SETSUROX(XQAUSER,XQALSURO,XQALSTRT,XQALEND) ; SETSURO CODE MOVED TO HERE TO PERMIT AN ERROR TO BE GENERATED AT THE OLD ENTRY POINT
- +1 NEW XQALFM,XQALIEN,XQAIENS
- +2 IF '$DATA(^XTV(8992,XQAUSER,0))
- Begin DoDot:1
- +3 NEW XQALFM,XQALFM1
- +4 SET XQALFM1(1)=XQAUSER
- +5 SET XQALFM(8992,"+1,",.01)=XQAUSER
- +6 DO UPDATE^DIE("","XQALFM","XQALFM1")
- +7 QUIT
- End DoDot:1
- +8 SET XQAIENS=XQAUSER_","
- +9 ; P366 - force no start date/time to NOW, and anything less than NOW to NOW
- +10 IF $GET(XQALSTRT)<$$NOW^XLFDT()
- SET XQALSTRT=$$NOW^XLFDT()
- +11 ; P366 - add values to new multiple
- +12 SET XQALFM(8992.02,"+1,"_XQAIENS,.01)=XQALSTRT
- +13 SET XQALFM(8992.02,"+1,"_XQAIENS,.02)=XQALSURO
- +14 ;p602 force end date/time to be after start date/time
- IF (XQALEND>0)&(XQALEND'>XQALSTRT)
- SET XQALEND=$$FMADD^XLFDT(XQALSTRT,0,0,0,1)
- +15 IF XQALEND>0
- SET XQALFM(8992.02,"+1,"_XQAIENS,.03)=XQALEND
- +16 KILL XQALIEN
- DO UPDATE^DIE("","XQALFM","XQALIEN")
- +17 ; P366 - if start date time is already in effect - place in old locations to make active
- +18 ;D ACTIVATE(XQAUSER,XQALIEN(1)) ; P513 activate if current or next
- +19 ; p602 activate only if current
- IF XQALSTRT'>$$NOW^XLFDT()
- DO ACTIVATE(XQAUSER,XQALIEN(1))
- +20 NEW XQAMESG,XMSUB,XMTEXT
- +21 SET XQAMESG(1,0)="You have been specified as a surrogate recipient for alerts for"
- +22 SET XQAMESG(2,0)=$$GET1^DIQ(200,XQAIENS,.01,"E")_" (IEN="_XQAUSER_") effective "_$$FMTE^XLFDT(XQALSTRT)
- +23 IF $GET(XQALEND)'>0
- SET XQAMESG(2,0)=XQAMESG(2,0)_"."
- +24 IF '$TEST
- SET XQAMESG(3,0)="until "_$$FMTE^XLFDT(XQALEND)
- +25 SET XMSUB="Surrogate Recipient for "_$$GET1^DIQ(200,XQAIENS,.01,"E")
- +26 SET XMTEXT="XQAMESG("
- +27 ; ZEXCEPT: XTMUNIT - Defined if unit tests are being run
- +28 if '$DATA(XTMUNIT)
- DO SENDMESG
- +29 QUIT
- +30 ;
- ACTIVATE(XQAUSER,XQALIEN) ; activates a surrogate
- +1 NEW X0,XQALFM,XQALSURO,XQALSTRT,XQALEND
- +2 SET X0=$GET(^XTV(8992,XQAUSER,2,XQALIEN,0))
- if X0=""
- QUIT
- SET XQALSTRT=$PIECE(X0,U)
- SET XQALSURO=$PIECE(X0,U,2)
- SET XQALEND=$PIECE(X0,U,3)
- +3 SET X0=^XTV(8992,XQAUSER,0)
- +4 ; If we are activating a new surrogate, if one exists simply remove.
- IF $PIECE(X0,U,2)>0
- IF $PIECE(X0,U,3)'>$$NOW^XLFDT()
- DO REMVSURO(XQAUSER)
- +5 KILL XQALFM
- SET XQALFM(8992,XQAUSER_",",.03)=XQALSTRT
- +6 SET XQALFM(8992,XQAUSER_",",.02)=XQALSURO
- +7 SET XQALFM(8992,XQAUSER_",",.04)=$SELECT($GET(XQALEND)>0:XQALEND,1:"@")
- +8 DO FILE^DIE("","XQALFM")
- +9 QUIT
- +10 ;
- +11 ; usage $$SETSURO1(XQAUSER,XQALSURO,XQALSTRT,XQALEND) returns 0 if invalid, otherwise > 0
- SETSURO1(XQAUSER,XQALSURO,XQALSTRT,XQALEND) ;EXTRINSIC. ICR #3213 (supported)
- +1 ; This should be used instead of SETSURO
- +2 ; P513 moved from SETSUROX+2
- IF $GET(XQAUSER)'>0
- QUIT "Invalid Internal Entry Number for user ("_XQAUSER_")"
- +3 ; P513 moved from SETSUROX+3
- IF $GET(XQALSURO)'>0
- QUIT "Invalid Internal Entry Number for surrogate ("_XQALSURO_")"
- +4 IF $GET(XQALSTRT)'>0
- SET XQALSTRT=$$NOW^XLFDT()
- +5 NEW XQAVAL
- +6 ; Can't use as surrogate
- SET XQAVAL=$$CYCLIC(XQALSURO,XQAUSER,XQALSTRT,$GET(XQALEND))
- IF XQAVAL'>0
- QUIT XQAVAL
- +7 ; P443
- DO SETSUROX(XQAUSER,XQALSURO,XQALSTRT,$GET(XQALEND))
- +8 QUIT XQALSURO
- +9 ;
- CHKREMV ;
- +1 NEW DIR,XQAI,XQAQUIT,XQASLIST,XQAVAL,YVAL,Y
- +2 ; ZEXCEPT: XQAUSER (EXTERNAL VALUE)
- +3 ; p730
- +4 ;D SUROLIST^XQALSUR1(XQAUSER,.XQASLIST)
- +5 ; Display list and allow user to remove surrogate periods until satisfied
- +6 SET XQAQUIT=0
- FOR
- Begin DoDot:1
- +7 DO DISPSUR^XQALSUR2(XQAUSER,.XQASLIST)
- +8 if $GET(XQASLIST)<=0
- QUIT
- +9 SET DIR(0)="Y"
- SET DIR("B")="NO"
- +10 SET DIR("A")="Do you want to REMOVE "_$SELECT(XQASLIST>1:"a",1:"THIS")_" surrogate recipient"
- +11 SET DIR("?")="A surrogate will receive your alerts until they are removed as surrogate."
- +12 DO ^DIR
- KILL DIR
- SET XQAQUIT='+Y
- +13 if XQAQUIT
- QUIT
- +14 SET DIR("A")="Enter a list (comma separated, e.g., 1,2) of the surrogate(s) to remove"
- +15 SET Y=1
- IF XQASLIST>1
- SET DIR(0)="L^1:"_XQASLIST
- DO ^DIR
- KILL DIR
- +16 IF Y>0
- SET YVAL=Y
- FOR XQAI=1:1
- SET XQAVAL=+$PIECE(YVAL,",",XQAI)
- if XQAVAL'>0
- QUIT
- DO REMVSURO(XQAUSER,$PIECE(XQASLIST(XQAVAL),U),$PIECE(XQASLIST(XQAVAL),U,3))
- +17 WRITE !
- End DoDot:1
- if $GET(XQASLIST)<1!XQAQUIT
- QUIT
- +18 QUIT
- +19 ;
- +20 ; P366 - added OPTIONAL second and third arguments to permit deletion of a specific pending surrogate and start date
- REMVSURO(XQAUSER,XQALSURO,XQALSTRT) ;SR. ICR #2790 (supported)
- +1 ; Ends the currently active surrogate relationship
- +2 IF $GET(XQAUSER)'>0
- QUIT
- +3 DO REMVSURO^XQALSUR1(XQAUSER,$GET(XQALSURO),$GET(XQALSTRT))
- +4 QUIT
- +5 ;
- +6 ; P366 - added OPTIONAL second and third arguments to determine surrogate for specified time range
- CURRSURO(XQAUSER,XQASTRT,XQAEND) ;SR. ICR #2790 (supported)
- +1 ; Returns current surrogate for user or -1 usage $$CURRSURO^XQALSURO(DUZ)
- +2 NEW X,ACTIVE,XQANOW,XQASTR1,XQAIVAL,XQA0,XQAI
- +3 DO CHEKSUBS^XQALSUR2(XQAUSER)
- +4 ; P366 - check for current in specified date/times
- IF $GET(XQASTRT)>0
- QUIT $$DATESURO^XQALSUR1(XQAUSER,XQASTRT,$GET(XQAEND))
- +5 ;
- +6 ; P366 - find the latest start time which is now or past or the first one in the future
- +7 SET XQANOW=$$NOW^XLFDT()
- Begin DoDot:1
- +8 SET XQAIVAL=0
- SET XQASTR1=0
- +9 FOR XQASTRT=0:0
- SET XQASTRT=$ORDER(^XTV(8992,XQAUSER,2,"B",XQASTRT))
- if XQASTRT'>0
- QUIT
- if XQASTRT'<XQANOW
- QUIT
- SET XQASTR1=XQASTRT
- FOR XQAI=0:0
- SET XQAI=$ORDER(^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI))
- if XQAI'>0
- QUIT
- Begin DoDot:2
- +10 ; p754 somebody removed surr by gbl kill, cleanup
- +11 IF '$DATA(^XTV(8992,XQAUSER,2,XQAI,0))
- KILL ^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI)
- QUIT
- +12 SET XQAEND=$PIECE(^XTV(8992,XQAUSER,2,XQAI,0),U,3)
- IF (XQAEND="")!(XQAEND>XQANOW)
- SET XQAIVAL=XQAI
- +13 QUIT
- End DoDot:2
- +14 ; to be compatible with the past, if there is not a current surrogate, show the next scheduled on the zero node if there is one
- +15 IF XQAIVAL=0
- SET XQASTRT=$ORDER(^XTV(8992,XQAUSER,2,"B",XQASTR1))
- if XQASTRT=""
- QUIT
- FOR XQAI=0:0
- SET XQAI=$ORDER(^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI))
- if XQAI'>0
- QUIT
- Begin DoDot:2
- +16 ; p754 somebody removed surr by gbl kill, cleanup
- +17 IF '$DATA(^XTV(8992,XQAUSER,2,XQAI,0))
- KILL ^XTV(8992,XQAUSER,2,"B",XQASTRT,XQAI)
- QUIT
- +18 SET XQAEND=$PIECE(^XTV(8992,XQAUSER,2,XQAI,0),U,3)
- IF (XQAEND="")!(XQAEND>XQANOW)
- SET XQAIVAL=XQAI
- +19 QUIT
- End DoDot:2
- if XQAIVAL>0
- QUIT
- +20 IF XQAIVAL>0
- SET XQA0=^XTV(8992,XQAUSER,2,XQAIVAL,0)
- SET XQASTRT=^XTV(8992,XQAUSER,0)
- IF ($PIECE(XQA0,U,2)'=$PIECE(XQASTRT,U,2))!($PIECE(XQA0,U)'=$PIECE(XQASTRT,U,3))!(+$PIECE(XQA0,U,3)'=+$PIECE(XQASTRT,U,4))
- DO ACTIVATE(XQAUSER,XQAIVAL)
- +21 QUIT
- End DoDot:1
- +22 ; P366 - end
- +23 SET X=$GET(^XTV(8992,XQAUSER,0))
- +24 ; now check for a CURRENT surrogate, already started and not expired or cyclic
- +25 IF $PIECE(X,U,2)>0
- IF +$PIECE(X,U,3)'>XQANOW
- Begin DoDot:1
- +26 ; Get Current date/time to check date/times if present
- NEW DATE
- +27 ; FOLLOWING LINES MODIFIED IN P443 TO ELIMINATE A STACK ERROR WHEN SURROGATE WAS CIRCULAR
- +28 ; Current Date/time past End date for surrogate
- +29 SET DATE=$PIECE(X,U,4)
- IF (DATE>0&(DATE<XQANOW))
- DO REMVSURO(XQAUSER)
- QUIT
- +30 ; P513 quit if not already active
- +31 ; P513
- SET DATE=$PIECE(X,U,3)
- if DATE=""
- SET DATE=XQANOW
- IF DATE>XQANOW
- QUIT
- +32 NEW XQASURO,XQASURO1
- SET XQASURO1=+$PIECE(^XTV(8992,XQAUSER,0),U,2)
- +33 ; REMOVE IF SURROGATE IS USER
- +34 IF XQASURO1=XQAUSER
- DO REMVSURO(XQAUSER)
- QUIT
- +35 ; p754 cyclic checks are done at surrogate creation time and the following is not needed
- QUIT
- End DoDot:1
- IF $PIECE($GET(^XTV(8992,XQAUSER,0)),U,2)>0
- QUIT +$PIECE(^XTV(8992,XQAUSER,0),U,2)
- +36 QUIT -1
- +37 ;. N XQALLIST,XQAUDATE S XQAUDATE=DATE,XQALLIST(XQAUSER,DATE)="" ; P513 JLI 100504 add XQAUDATE to be able to check earlier start time
- +38 ;. ; REMOVE IF CYCLES BACK TO USER - thought about removing inactive, but best to let those be handled by groups for unprocessed alerts
- +39 ;. ; P513 but ignore if surrogate isn't already active - JLI 100504
- +40 ;. ; begin changes in P513
- +41 ;. S XQASURO1=XQAUSER
- +42 ;. F S XQASURO=$P($G(^XTV(8992,XQASURO1,0)),U,2) Q:XQASURO'>0 Q:'$$ISACTIVE(XQASURO) S DATE=$P(^XTV(8992,XQASURO,0),U,3) Q:DATE>XQANOW D S XQASURO1=XQASURO ; JLI 100504
- +43 ;. . ;I $D(XQALLIST(XQASURO1)) D
- +44 ;. . I $D(XQALLIST(XQASURO)) D ; p730 check on NEXT surrogate and not on XQAUSER for first pass
- +45 ;. . . N DATE1 S DATE1=$O(XQALLIST(XQASURO1,""))
- +46 ;. . . ; remove the surrogate relationship that started earliest
- +47 ;. . . I DATE<DATE1 D REMVSURO(XQASURO)
- +48 ;. . . I DATE1<=DATE D REMVSURO(XQASURO1)
- +49 ;. . . S XQASURO=XQAUSER K XQALLIST S DATE=XQAUDATE ; start over
- +50 ;. . . Q
- +51 ;. . S XQALLIST(XQASURO,DATE)=""
- +52 ;. . ; end of P513 modification
- +53 ;. . Q
- +54 ;. ; END OF P443 MODIFICATION
- +55 ;. Q
- +56 ;Q -1
- +57 ;
- ISACTIVE(XQAUSER) ; checks for whether a surrogate relationship is active or not (returns 0 or 1)
- +1 NEW DATA
- +2 ; NO SURROGATE SPECIFIED
- SET DATA=$GET(^XTV(8992,XQAUSER,0))
- if $PIECE(DATA,U,2)=""
- QUIT 0
- +3 ; START DATE/TIME NOT YET
- IF $PIECE(DATA,U,3)>0
- IF $PIECE(DATA,U,3)>$$NOW^XLFDT()
- QUIT 0
- +4 ; PAST END DATE/TIME
- IF $PIECE(DATA,U,4)>0
- IF $PIECE(DATA,U,4)<$$NOW^XLFDT()
- QUIT 0
- +5 QUIT 1
- +6 ;
- ACTVSURO(XQAUSER) ;SR. ICR #2790 (supported)
- +1 ; Returns the actual surrogate at this time
- +2 NEW CURRSURO,NEXTSURO,SURODATA,NOW
- +3 SET NOW=$$NOW^XLFDT()
- +4 SET CURRSURO=$$CURRSURO(XQAUSER)
- SET SURODATA=$$GETSURO(XQAUSER)
- IF (CURRSURO'>0)!(+$PIECE(SURODATA,U,3)>NOW)!('(+$$ACTIVE^XUSER(CURRSURO)))
- QUIT -1
- +5 FOR
- SET NEXTSURO=$$CURRSURO(CURRSURO)
- SET SURODATA=$$GETSURO(CURRSURO)
- if NEXTSURO'>0
- QUIT
- if +$PIECE(SURODATA,U,3)>NOW
- QUIT
- if '(+$$ACTIVE^XUSER(NEXTSURO))
- QUIT
- SET CURRSURO=NEXTSURO
- +6 QUIT CURRSURO
- +7 ;
- GETSURO(XQAUSER) ;EXTRINSIC. ICR #3213 (supported)
- +1 ; Returns data for surrogate for user including times
- +2 IF $$CURRSURO(XQAUSER)'>0
- QUIT ""
- +3 NEW GLOBREF,IENS,X
- +4 SET IENS=XQAUSER_","
- SET GLOBREF=$NAME(^TMP($JOB,"XQALSURO"))
- KILL @GLOBREF
- +5 DO GETS^DIQ(8992,IENS,".02;.03;.04","IE",GLOBREF)
- +6 SET GLOBREF=$NAME(@GLOBREF@(8992,IENS))
- +7 SET X=$GET(@GLOBREF@(.02,"I"))_U_$GET(@GLOBREF@(.02,"E"))_U_$GET(@GLOBREF@(.03,"I"))_U_$GET(@GLOBREF@(.04,"I"))
- +8 KILL @GLOBREF
- +9 QUIT X
- +10 ;
- GETFOR ;OPT.
- +1 NEW XQAUSER,VALUES,XQACNT,DIR,DIRUT,I,Y
- +2 SET DIR(0)="PD^200:AEMQ"
- +3 SET DIR("A")="Select Surrogate (NEW PERSON entry)"
- +4 SET DIR("A",1)=""
- SET DIR("A",2)=""
- +5 ;p602
- SET DIR("A",3)=" - List Users who have chosen this User to be their current Surrogate."
- +6 SET DIR("A",4)=""
- +7 DO ^DIR
- KILL DIR
- if Y'>0
- QUIT
- WRITE " ",$PIECE(Y,U,2)
- +8 SET XQAUSER=+Y
- +9 DO SUROFOR(.VALUES,XQAUSER)
- IF VALUES'>0
- WRITE !,"No entries found.",!!
- QUIT
- +10 SET XQACNT=0
- KILL DIRUT
- FOR I=0:0
- SET I=$ORDER(VALUES(I))
- if I'>0
- QUIT
- if (XQACNT>(IOSL-4))
- Begin DoDot:1
- +11 SET DIR(0)="E"
- DO ^DIR
- KILL DIR
- +12 QUIT
- End DoDot:1
- if $DATA(DIRUT)
- QUIT
- WRITE !,?5,$PIECE(VALUES(I),U,2)
- SET XQACNT=XQACNT+1
- +13 KILL DIRUT
- +14 QUIT
- +15 ;
- SUROLIST(XQAUSER,XQALIST) ;SR. ICR #3213 (supported)
- +1 ; Returns list of current and scheduled surrogates for XQAUSER
- +2 DO SUROLIST^XQALSUR1(XQAUSER,.XQALIST)
- +3 QUIT
- +4 ;
- SUROFOR(LIST,XQAUSER) ;SR. ICR #3213 (supported)
- +1 ; Returns list of users XQAUSER is acting as a surrogate for
- +2 IF $GET(XQAUSER)=""
- QUIT
- +3 NEW I,COUNT
- SET I=0
- SET COUNT=0
- FOR
- SET I=$ORDER(^XTV(8992,"AC",XQAUSER,I))
- if I'>0
- QUIT
- IF $$CURRSURO(I)>0
- Begin DoDot:1
- +4 SET COUNT=COUNT+1
- SET LIST(COUNT)=I_U_$$GET1^DIQ(200,(I_","),".01","E")_U_$$GET1^DIQ(8992,(I_","),".03","E")_U_$$GET1^DIQ(8992,(I_","),".04","E")
- End DoDot:1
- +5 SET LIST=COUNT
- +6 QUIT
- +7 ;
- SENDMESG ;
- +1 NEW XMY,XMDUZ,XMCHAN
- +2 ; ZEXCEPT: XQALSURO (EXTERNAL VALUE)
- +3 SET XMY(XQALSURO)=""
- SET XMDUZ=.5
- +4 DO ^XMD
- +5 QUIT