| 1 | BSDX08  ; VW/UJO/SMH - WINDOWS SCHEDULING RPCS ; 7/9/12 4:22pm | 
|---|
| 2 | ;;1.7;BSDX;;Jun 01, 2013;Build 24 | 
|---|
| 3 | ; | 
|---|
| 4 | ; Original by HMW. New Written by Sam Habiel. Licensed under LGPL. | 
|---|
| 5 | ; | 
|---|
| 6 | ; Change History | 
|---|
| 7 | ; 3101022 UJO/SMH v1.42 | 
|---|
| 8 | ;  - Transaction work. As of v 1.7, all work here has been superceded | 
|---|
| 9 | ;  - Refactoring of AVUPDT - never tested though. | 
|---|
| 10 | ;  - Refactored all of APPDEL. | 
|---|
| 11 | ; | 
|---|
| 12 | ; 3111125 UJO/SMH v1.5 | 
|---|
| 13 | ;  - Added ability to remove checked in appointments. Added a couple | 
|---|
| 14 | ;    of units tests for that under UT2. | 
|---|
| 15 | ; | 
|---|
| 16 | ; 3120625 VEN/SMH v1.7 | 
|---|
| 17 | ;  - Transactions removed. Code refactored to work w/o txns. | 
|---|
| 18 | ;  - Moved AVUPDT to AVUPDTCN in BSDXAPI1. BSDXAPI takes care of calling | 
|---|
| 19 | ;    that. | 
|---|
| 20 | ; | 
|---|
| 21 | ; Error Reference: | 
|---|
| 22 | ;  -1~BSDX08: Appt record is locked. Please contact technical support. | 
|---|
| 23 | ;  -2~BSDX08: Invalid Appointment ID | 
|---|
| 24 | ;  -3~BSDX08: Invalid Appointment ID | 
|---|
| 25 | ;  -4~BSDX08: Cancelled appointment does not have a Resouce ID | 
|---|
| 26 | ;  -5~BSDX08: Resouce ID does not exist in BSDX RESOURCE | 
|---|
| 27 | ;  -6~BSDX08: Invalid Hosp Location stored in Database | 
|---|
| 28 | ;  -7~BSDX08: Patient does not have an appointment in PIMS Clinic | 
|---|
| 29 | ;  -8^BSDX08: Unable to find associated PIMS appointment for this patient | 
|---|
| 30 | ;  -9^BSDX08: BSDXAPI returned an error: (error) | 
|---|
| 31 | ;  -10^BSDX08: $$BSDXCAN failed (Fileman filing error) | 
|---|
| 32 | ;  -100~BSDX08 Error: (Mumps Error) | 
|---|
| 33 | ; | 
|---|
| 34 | APPDELD(BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT) ;EP | 
|---|
| 35 | ;Entry point for debugging | 
|---|
| 36 | ;D DEBUG^%Serenji("APPDEL^BSDX08(.BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT)") | 
|---|
| 37 | Q | 
|---|
| 38 | ; | 
|---|
| 39 | APPDEL(BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT)         ; Private EP | 
|---|
| 40 | ;Called by RPC: BSDX CANCEL APPOINTMENT | 
|---|
| 41 | ;Cancels existing appointment in BSDX APPOINTMENT and 44/2 subfiles | 
|---|
| 42 | ;Input Parameters: | 
|---|
| 43 | ; - BSDXAPTID is entry number in BSDX APPOINTMENT file | 
|---|
| 44 | ; - BSDXTYP is C for clinic-cancelled and PC for patient cancelled | 
|---|
| 45 | ; - BSDXCR is pointer to CANCELLATION REASON File (409.2) | 
|---|
| 46 | ; - BSDXNOT is user note | 
|---|
| 47 | ; | 
|---|
| 48 | ; Returns error code in recordset field ERRORID. Empty string is success. | 
|---|
| 49 | ; Returns Global Array. Must use this type in RPC. | 
|---|
| 50 | ; | 
|---|
| 51 | ; Return Array: set Return and clear array | 
|---|
| 52 | S BSDXY=$NA(^BSDXTMP($J)) | 
|---|
| 53 | K ^BSDXTMP($J) | 
|---|
| 54 | ; | 
|---|
| 55 | ; Set min DUZ vars if they don't exist | 
|---|
| 56 | D ^XBKVAR | 
|---|
| 57 | ; | 
|---|
| 58 | ; $ET | 
|---|
| 59 | N $ET S $ET="G ETRAP^BSDX08" | 
|---|
| 60 | ; | 
|---|
| 61 | ; Counter | 
|---|
| 62 | N BSDXI S BSDXI=0 | 
|---|
| 63 | ; | 
|---|
| 64 | ; Header Node | 
|---|
| 65 | S ^BSDXTMP($J,BSDXI)="T00100ERRORID"_$C(30) | 
|---|
| 66 | ; | 
|---|
| 67 | ; Turn off SDAM APPT PROTOCOL BSDX Entries | 
|---|
| 68 | N BSDXNOEV | 
|---|
| 69 | S BSDXNOEV=1 ;Don't execute BSDX CANCEL APPOINTMENT protocol | 
|---|
| 70 | ; | 
|---|
| 71 | ;;;test for error inside transaction. See if %ZTER works | 
|---|
| 72 | I $G(BSDXDIE1) N X S X=1/0 | 
|---|
| 73 | ; | 
|---|
| 74 | ; Check appointment ID and whether it exists | 
|---|
| 75 | I '+BSDXAPTID D ERR(BSDXI,"-2~BSDX08: Invalid Appointment ID") Q | 
|---|
| 76 | I '$D(^BSDXAPPT(BSDXAPTID,0)) D ERR(BSDXI,"-3~BSDX08: Invalid Appointment ID") Q | 
|---|
| 77 | ; | 
|---|
| 78 | ; Lock BSDX node, only to synchronize access to the globals. | 
|---|
| 79 | ; It's not expected that the error will ever happen as no filing | 
|---|
| 80 | ; is supposed to take 5 seconds. | 
|---|
| 81 | L +^BSDXAPPT(BSDXAPTID):5 E  D ERR(BSDXI,"-1~BSDX08: Appt record is locked. Please contact technical support.") Q | 
|---|
| 82 | ; | 
|---|
| 83 | ; Start Processing: | 
|---|
| 84 | ; First, get data | 
|---|
| 85 | N BSDXNOD S BSDXNOD=^BSDXAPPT(BSDXAPTID,0) ; BSDX Appt Node | 
|---|
| 86 | N BSDXPATID S BSDXPATID=$P(BSDXNOD,U,5) ; Patient ID | 
|---|
| 87 | N BSDXSTART S BSDXSTART=$P(BSDXNOD,U) ; Start Time | 
|---|
| 88 | ; | 
|---|
| 89 | ; Check the resource ID and whether it exists | 
|---|
| 90 | N BSDXSC1 S BSDXSC1=$P(BSDXNOD,U,7) ;RESOURCEID | 
|---|
| 91 | ; If the resource id doesn't exist... | 
|---|
| 92 | I BSDXSC1="" D ERR(BSDXI,"-4~BSDX08: Cancelled appointment does not have a Resouce ID") QUIT | 
|---|
| 93 | I '$D(^BSDXRES(BSDXSC1,0)) D ERR(BSDXI,"-5~BSDX08: Resouce ID does not exist in BSDX RESOURCE") QUIT | 
|---|
| 94 | ; | 
|---|
| 95 | ; | 
|---|
| 96 | ; Check if PIMS will let us cancel the appointment using $$CANCELCK^BSDXAPI | 
|---|
| 97 | ; Get zero node of resouce | 
|---|
| 98 | N BSDXNOD S BSDXNOD=^BSDXRES(BSDXSC1,0) | 
|---|
| 99 | ; Get Hosp location | 
|---|
| 100 | N BSDXLOC S BSDXLOC=$P(BSDXNOD,U,4) | 
|---|
| 101 | ; Error indicator | 
|---|
| 102 | N BSDXERR S BSDXERR=0 | 
|---|
| 103 | ; | 
|---|
| 104 | N BSDXC ; Array to pass to BSDXAPI | 
|---|
| 105 | ; | 
|---|
| 106 | I BSDXLOC D | 
|---|
| 107 | . S BSDXC("PAT")=BSDXPATID | 
|---|
| 108 | . S BSDXC("CLN")=BSDXLOC | 
|---|
| 109 | . S BSDXC("TYP")=BSDXTYP | 
|---|
| 110 | . S BSDXC("ADT")=BSDXSTART | 
|---|
| 111 | . S BSDXC("CDT")=$$NOW^XLFDT() | 
|---|
| 112 | . S BSDXC("NOT")=BSDXNOT | 
|---|
| 113 | . S:'+$G(BSDXCR) BSDXCR=11 ;Other | 
|---|
| 114 | . S BSDXC("CR")=BSDXCR | 
|---|
| 115 | . S BSDXC("USR")=DUZ | 
|---|
| 116 | . ; | 
|---|
| 117 | . S BSDXERR=$$CANCELCK^BSDXAPI(.BSDXC) ; 0 or 1^error message | 
|---|
| 118 | ; If error, quit. No need to rollback as no changes took place. | 
|---|
| 119 | I BSDXERR D ERR(BSDXI,"-9~BSDX08: BSDXAPI reports that "_$P(BSDXERR,U,2)) QUIT | 
|---|
| 120 | ; | 
|---|
| 121 | I $G(BSDXDIE2) N X S X=1/0 | 
|---|
| 122 | ; | 
|---|
| 123 | ; Now cancel the appointment for real | 
|---|
| 124 | ; BSDXAPPT First; no need for rollback if error occured. | 
|---|
| 125 | N BSDXERR S BSDXERR=$$BSDXCAN(BSDXAPTID)  ; Add a cancellation date in BSDX APPOINTMENT | 
|---|
| 126 | I BSDXERR D ERR(BSDXI,"-10~BSDX08: $$BSDXCAN failed (Fileman filing error): "_$P(BSDXERR,U,2)) QUIT | 
|---|
| 127 | ; | 
|---|
| 128 | ; Then PIMS: | 
|---|
| 129 | ; cancel appt in "S" nodes in file 2 and 44, then update Legacy PIMS Availability | 
|---|
| 130 | ; If error happens, must rollback ^BSDXAPPT | 
|---|
| 131 | I BSDXLOC S BSDXERR=$$CANCEL^BSDXAPI(.BSDXC) ; Cancel through BSDXAPI | 
|---|
| 132 | ; Rollback BSDXAPPT if error occurs | 
|---|
| 133 | I BSDXERR D ERR(BSDXI,"-9^BSDX08: BSDXAPI returned an error: "_$P(BSDXERR,U,2)),ROLLBACK(BSDXAPTID)  QUIT | 
|---|
| 134 | ; | 
|---|
| 135 | L -^BSDXAPPT(BSDXAPTID) | 
|---|
| 136 | S BSDXI=BSDXI+1 | 
|---|
| 137 | S ^BSDXTMP($J,BSDXI)=""_$C(30) | 
|---|
| 138 | S BSDXI=BSDXI+1 | 
|---|
| 139 | S ^BSDXTMP($J,BSDXI)=$C(31) | 
|---|
| 140 | Q | 
|---|
| 141 | ; | 
|---|
| 142 | BSDXCAN(BSDXAPTID)      ; $$; Private; Cancel BSDX APPOINTMENT entry | 
|---|
| 143 | ; Input: Appt IEN in ^BSDXAPPT | 
|---|
| 144 | ; Output: 0 for success and 1^Msg for failure | 
|---|
| 145 | N BSDXDATE,BSDXIENS,BSDXFDA,BSDXMSG | 
|---|
| 146 | S BSDXDATE=$$NOW^XLFDT() | 
|---|
| 147 | S BSDXIENS=BSDXAPTID_"," | 
|---|
| 148 | S BSDXFDA(9002018.4,BSDXIENS,.12)=BSDXDATE | 
|---|
| 149 | D FILE^DIE("","BSDXFDA","BSDXMSG") | 
|---|
| 150 | I $D(BSDXMSG) Q 1_U_BSDXMSG("DIERR",1,"TEXT",1) | 
|---|
| 151 | QUIT 0 | 
|---|
| 152 | ; | 
|---|
| 153 | ROLLBACK(BSDXAPTID)      ; Proc; Private; Rollback cancellation | 
|---|
| 154 | ; Input same as $$BSDXCAN | 
|---|
| 155 | N BSDXIENS S BSDXIENS=BSDXAPTID_"," | 
|---|
| 156 | N BSDXFDA S BSDXFDA(9002018.4,BSDXIENS,.12)="@" | 
|---|
| 157 | N BSDXMSG | 
|---|
| 158 | D FILE^DIE("","BSDXFDA","BSDXMSG") | 
|---|
| 159 | ;I $D(BSDXMSG)  ; Not sure what to do. We are already handling an error. | 
|---|
| 160 | QUIT | 
|---|
| 161 | ; | 
|---|
| 162 | CANEVT(BSDXPAT,BSDXSTART,BSDXSC)        ;EP Called by BSDX CANCEL APPOINTMENT event | 
|---|
| 163 | ;when appointments cancelled via PIMS interface. | 
|---|
| 164 | ;Propagates cancellation to BSDXAPPT and raises refresh event to running GUI clients | 
|---|
| 165 | N BSDXFOUND,BSDXRES | 
|---|
| 166 | Q:+$G(BSDXNOEV) | 
|---|
| 167 | Q:'+$G(BSDXSC) | 
|---|
| 168 | S BSDXFOUND=0 | 
|---|
| 169 | I $D(^BSDXRES("ALOC",BSDXSC)) S BSDXRES=$O(^BSDXRES("ALOC",BSDXSC,0)) S BSDXFOUND=$$CANEVT1(BSDXRES,BSDXSTART,BSDXPAT) | 
|---|
| 170 | I BSDXFOUND D CANEVT3(BSDXRES) Q | 
|---|
| 171 | I $D(^BXDXRES("ASSOC",BSDXSC)) S BSDXRES=$O(^BSDXRES("ASSOC",BSDXSC,0)) S BSDXFOUND=$$CANEVT1(BSDXRES,BSDXSTART,BSDXPAT) | 
|---|
| 172 | I BSDXFOUND D CANEVT3(BSDXRES) | 
|---|
| 173 | Q | 
|---|
| 174 | ; | 
|---|
| 175 | CANEVT1(BSDXRES,BSDXSTART,BSDXPAT)      ; | 
|---|
| 176 | ;Get appointment id in BSDXAPT | 
|---|
| 177 | ;If found, call BSDXCAN(BSDXAPPT) and return 1 | 
|---|
| 178 | ;else return 0 | 
|---|
| 179 | N BSDXFOUND,BSDXAPPT | 
|---|
| 180 | S BSDXFOUND=0 | 
|---|
| 181 | Q:'+BSDXRES BSDXFOUND | 
|---|
| 182 | Q:'$D(^BSDXAPPT("ARSRC",BSDXRES,BSDXSTART)) BSDXFOUND | 
|---|
| 183 | S BSDXAPPT=0 F  S BSDXAPPT=$O(^BSDXAPPT("ARSRC",BSDXRES,BSDXSTART,BSDXAPPT)) Q:'+BSDXAPPT  D  Q:BSDXFOUND | 
|---|
| 184 | . N BSDXNOD | 
|---|
| 185 | . S BSDXNOD=$G(^BSDXAPPT(BSDXAPPT,0)) Q:BSDXNOD="" | 
|---|
| 186 | . I $P(BSDXNOD,U,5)=BSDXPAT,$P(BSDXNOD,U,12)="" S BSDXFOUND=1 Q | 
|---|
| 187 | I BSDXFOUND,+$G(BSDXAPPT) N % S %=$$BSDXCAN(BSDXAPPT) I % D ^%ZTER | 
|---|
| 188 | Q BSDXFOUND | 
|---|
| 189 | ; | 
|---|
| 190 | CANEVT3(BSDXRES)        ; | 
|---|
| 191 | ;Call RaiseEvent to notify GUI clients | 
|---|
| 192 | ; | 
|---|
| 193 | N BSDXRESN | 
|---|
| 194 | S BSDXRESN=$G(^BSDXRES(BSDXRES,0)) | 
|---|
| 195 | Q:BSDXRESN="" | 
|---|
| 196 | S BSDXRESN=$P(BSDXRESN,"^") | 
|---|
| 197 | ;D EVENT^BSDX23("SCHEDULE-"_BSDXRESN,"","","") | 
|---|
| 198 | D EVENT^BMXMEVN("BSDX SCHEDULE",BSDXRESN) | 
|---|
| 199 | Q | 
|---|
| 200 | ; | 
|---|
| 201 | ERR(BSDXI,BSDXERR)      ;Error processing | 
|---|
| 202 | ; Unlock first | 
|---|
| 203 | L:$D(BSDXAPTID) -^BSDXAPPT(BSDXAPTID) | 
|---|
| 204 | ; If last line is $C(31), we are done. No more errors to send to client. | 
|---|
| 205 | I ^BSDXTMP($J,$O(^BSDXTMP($J," "),-1))=$C(31) QUIT | 
|---|
| 206 | S BSDXI=BSDXI+1 | 
|---|
| 207 | S BSDXERR=$TR(BSDXERR,"^","~") | 
|---|
| 208 | S ^BSDXTMP($J,BSDXI)=BSDXERR_$C(30) | 
|---|
| 209 | S BSDXI=BSDXI+1 | 
|---|
| 210 | S ^BSDXTMP($J,BSDXI)=$C(31) | 
|---|
| 211 | QUIT | 
|---|
| 212 | ; | 
|---|
| 213 | ETRAP   ;EP Error trap entry | 
|---|
| 214 | N $ET S $ET="D ^%ZTER HALT"  ; Emergency Error Trap | 
|---|
| 215 | D ^%ZTER | 
|---|
| 216 | ; | 
|---|
| 217 | ; Roll back BSDXAPPT; | 
|---|
| 218 | ; NB: What if a Mumps error happens inside fileman in BSDXAPI? | 
|---|
| 219 | ; I have decided the M errors are out of scope for me to handle. | 
|---|
| 220 | D:$G(BSDXAPTID) ROLLBACK(BSDXAPTID) | 
|---|
| 221 | ; | 
|---|
| 222 | ; Log error message and send to client | 
|---|
| 223 | I '$D(BSDXI) N BSDXI S BSDXI=0 | 
|---|
| 224 | D ERR(BSDXI,"-100~BSDX08 Error: "_$G(%ZTERZE)) | 
|---|
| 225 | Q:$Q 1_U_"-100~Mumps Error" Q | 
|---|
| 226 | ; | 
|---|
| 227 | ;;;NB: This is code that is unused in both original and port. | 
|---|
| 228 | ; ; If not appt in the "S" node is found in ^SC then check associated RPMS Clinic Multiple | 
|---|
| 229 | ; I BSDXSCIEN="" D  I 'BSDXZ Q  ;Q:BSDXZ | 
|---|
| 230 | ; . S BSDXERR="BSDX08: Unable to find associated RPMS appointment for this patient. " | 
|---|
| 231 | ; . S BSDXZ=1 | 
|---|
| 232 | ; . ; Check if there are associated RPMS clinics. (not currently used) Does the multiple exist? No, then quit | 
|---|
| 233 | ; . I '$D(^BSDXRES(BSDXSC1,20)) S BSDXZ=0 QUIT | 
|---|
| 234 | ; . ; Loop through the multiple. Get Location and then the ^SC "S" node IEN. | 
|---|
| 235 | ; . N BSDX1 S BSDX1=0 | 
|---|
| 236 | ; . F  S BSDX1=$O(^BSDXRES(BSDXSC1,20,BSDX1)) Q:'+BSDX1  Q:BSDXZ=0  D | 
|---|
| 237 | ; . . Q:'$D(^BSDXRES(BSDXSC1,20,BSDX1,0)) | 
|---|
| 238 | ; . . S BSDXLOC=$P(^BSDXRES(BSDXSC1,20,BSDX1,0),U) | 
|---|
| 239 | ; . . S BSDXSCIEN=$$SCIEN^BSDXAPI(BSDXPATID,BSDXLOC,BSDXSTART) I +BSDXSCIEN S BSDXZ=0 Q | 
|---|