source: Scheduling/trunk/m/BSDX08.m@ 1235

Last change on this file since 1235 was 1187, checked in by Sam Habiel, 14 years ago

Changes to BSDX01 to prevent Scheduled,dc'ed,completed radiology appointments from being cancelled. Updated files to T2.

File size: 13.1 KB
RevLine 
[1161]1BSDX08 ; VW/UJO/SMH - WINDOWS SCHEDULING RPCS ; 4/28/11 10:17am
[1187]2 ;;1.6T2;BSDX;;May 16, 2011
[1076]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 now restartable. Thanks to
9 ; --> Zach Gonzalez and Rick Marshall for fix.
10 ; - Extra TROLLBACK in Lock Statement when lock fails.
11 ; --> Removed--Rollback is already in ERR tag.
12 ; - Added new statements to old SD code in AVUPDT to obviate
13 ; --> need to restore variables in transaction
14 ; - Refactored this chunk of code. Don't really know whether it
15 ; --> worked in the first place. Waiting for bug report to know.
16 ; - Refactored all of APPDEL.
17 ;
[1080]18 ; 3111125 UJO/SMH v1.5
19 ; - Added ability to remove checked in appointments. Added a couple
20 ; of units tests for that under UT2.
21 ; - Minor reformatting because of how KIDS adds tabs.
22 ;
[1076]23 ; Error Reference:
24 ; -1~BSDX08: Appt record is locked. Please contact technical support.
25 ; -2~BSDX08: Invalid Appointment ID
[1007]26 ; -3~BSDX08: Invalid Appointment ID
[1076]27 ; -4~BSDX08: Cancelled appointment does not have a Resouce ID
28 ; -5~BSDX08: Resouce ID does not exist in BSDX RESOURCE
29 ; -6~BSDX08: Invalid Hosp Location stored in Database
30 ; -7~BSDX08: Patient does not have an appointment in PIMS Clinic
31 ; -8^BSDX08: Unable to find associated PIMS appointment for this patient
32 ; -9^BSDX08: BSDXAPI returned an error: (error)
33 ; -100~BSDX08 Error: (Mumps Error)
[614]34 ;
35APPDELD(BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT) ;EP
36 ;Entry point for debugging
[1007]37 D DEBUG^%Serenji("APPDEL^BSDX08(.BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT)")
[614]38 Q
39 ;
[1041]40UT ; Unit Tests
[1076]41 ; Test 1: Make normal appointment and cancel it. See if every thing works
42 N ZZZ
43 D APPADD^BSDX07(.ZZZ,3110123.2,3110123.3,4,"Dr Office",10,"Sam's Note",1)
44 S APPID=+$P(^BSDXTMP($J,1),U)
45 D APPDEL^BSDX08(.ZZZ,APPID,"PC",1,"Sam's Cancel Note")
46 I $P(^BSDXAPPT(APPID,0),U,12)'>0 W "Error in Cancellation-1"
47 I $O(^SC(2,"S",3110123.2,1,0))]"" W "Error in Cancellation-2"
48 I $P(^DPT(4,"S",3110123.2,0),U,2)'="PC" W "Error in Cancellation-3"
49 I ^DPT(4,"S",3110123.2,"R")'="Sam's Cancel Note" W "Error in Cancellation-4"
50 ;
51 ; Test 2: Check for -1
52 ; Make appt
53 D APPADD^BSDX07(.ZZZ,3110125.2,3110125.3,4,"Dr Office",10,"Sam's Note",1)
54 ; Lock the node in another job
55 S APPID=+$P(^BSDXTMP($J,1),U)
56 ; W "Lock ^BSDXAPPT("_APPID_") in another session. You have 10 seconds." H 10
57 D APPDEL^BSDX08(.ZZZ,APPID,"PC",1,"Sam's Cancel Note")
58 ;
59 ; Test 3: Check for -100
60 S bsdxdie=1
61 D APPADD^BSDX07(.ZZZ,3110126.2,3110126.3,4,"Dr Office",10,"Sam's Note",1)
62 S APPID=+$P(^BSDXTMP($J,1),U)
63 D APPDEL^BSDX08(.ZZZ,APPID,"PC",1,"Reasons")
64 I $P(^BSDXTMP($J,1),"~")'=-100 W "Error in -100",!
65 K bsdxdie
66 ;
67 ; Test 4: Restartable transaction
68 S bsdxrestart=1
69 D APPADD^BSDX07(.ZZZ,3110128.2,3110128.3,4,"Dr Office",10,"Sam's Note",1)
70 S APPID=+$P(^BSDXTMP($J,1),U)
71 D APPDEL^BSDX08(.ZZZ,APPID,"PC",1,"Reasons")
72 I $P(^DPT(4,"S",3110128.2,0),U,2)'="PC" W "Error in Restartable Transaction",!
73 ;
74 ; Test 5: for invalid Appointment ID (-2 and -3)
75 D APPDEL^BSDX08(.ZZZ,0,"PC",1,"Reasons")
76 I $P(^BSDXTMP($J,1),"~")'=-2 W "Error in -2",!
77 D APPDEL^BSDX08(.ZZZ,999999,"PC",1,"Reasons")
78 I $P(^BSDXTMP($J,1),"~")'=-3 W "Error in -3",!
[1080]79UT2 ; More unit Tests
[1076]80 ;
[1080]81 ; Test 6: for Cancelling walkin and checked-in appointments
[1076]82 S BSDXSTART=$E($$NOW^XLFDT,1,12),BSDXEND=BSDXSTART+.0001
[1080]83 D APPADD^BSDX07(.ZZZ,BSDXSTART,BSDXEND,4,"Dr Office",10,"Sam's Note",1) ; Add appt
[1076]84 S APPID=+$P(^BSDXTMP($J,1),U)
[1080]85 I APPID=0 W "Error in test 6",!
86 D CHECKIN^BSDX25(.ZZZ,APPID,$$NOW^XLFDT) ; check-in
87 D APPDEL^BSDX08(.ZZZ,APPID,"PC",10,"Cancel Note") ; Delete appt
88 I $P(^BSDXTMP($J,1),$C(30))'="" W "Error in test 6",!
[1077]89 ;
[1080]90 ; Test 7: for cancelling walkin and checked-in appointments
[1077]91 S BSDXSTART=$E($$NOW^XLFDT,1,12)+.0001,BSDXEND=BSDXSTART+.0001
[1080]92 D APPADD^BSDX07(.ZZZ,BSDXSTART,BSDXEND,4,"Dr Office",10,"Sam's Note",1) ; Add appt
[1077]93 S APPID=+$P(^BSDXTMP($J,1),U)
[1080]94 I APPID=0 W "Error in test 6",!
95 D CHECKIN^BSDX25(.ZZZ,APPID,$$NOW^XLFDT) ; Checkin
[1077]96 S BSDXRES=$O(^BSDXRES("B","Dr Office",""))
97 S BSDXCLN=$P(^BSDXRES(BSDXRES,0),U,4)
[1080]98 S BSDXRESULT=$$RMCI^BSDXAPI(4,BSDXCLN,BSDXSTART) ; remove checkin
99 D APPDEL^BSDX08(.ZZZ,APPID,"PC",10,"Cancel Note") ; delete appt
100 I $P(^BSDXTMP($J,1),$C(30))'="" W "Error in test 6",!
[1076]101 QUIT
[614]102APPDEL(BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT) ;EP
[1007]103 ;Called by RPC: BSDX CANCEL APPOINTMENT
104 ;Cancels existing appointment in BSDX APPOINTMENT and 44/2 subfiles
[1080]105 ;Input Parameters:
[1007]106 ; - BSDXAPTID is entry number in BSDX APPOINTMENT file
107 ; - BSDXTYP is C for clinic-cancelled and PC for patient cancelled
108 ; - BSDXCR is pointer to CANCELLATION REASON File (409.2)
109 ; - BSDXNOT is user note
[614]110 ;
[1080]111 ; Returns error code in recordset field ERRORID. Empty string is success.
112 ; Returns Global Array. Must use this type in RPC.
[614]113 ;
[1080]114 ; Return Array: set Return and clear array
[1007]115 S BSDXY=$NA(^BSDXTMP($J))
[1080]116 K ^BSDXTMP($J)
[1007]117 ;
[1080]118 ; Set min DUZ vars if they don't exist
119 D ^XBKVAR
[1007]120 ;
[1080]121 ; $ET
122 N $ET S $ET="G ETRAP^BSDX08"
123 ;
124 ; Counter
[1007]125 N BSDXI S BSDXI=0
[1080]126 ; Header Node
[1041]127 S ^BSDXTMP($J,BSDXI)="T00100ERRORID"_$C(30)
[1007]128 ;
[1080]129 ; Lock BSDX node, only to synchronize access to the globals.
130 ; It's not expected that the error will ever happen as no filing
131 ; is supposed to take 5 seconds.
132 L +^BSDXAPPT(BSDXAPTID):5 I '$T D ERR(BSDXI,"-1~BSDX08: Appt record is locked. Please contact technical support.") Q
[1007]133 ;
[1080]134 ;Restartable Transaction; restore paramters when starting.
135 ; (Params restored are what's passed here + BSDXI)
136 TSTART (BSDXY,BSDXAPTID,BSDXTYP,BSDXCR,BSDXNOT,BSDXI):T="BSDX CANCEL APPOINTEMENT^BSDX08"
[1007]137 ;
[1080]138 ; Turn off SDAM APPT PROTOCOL BSDX Entries
[614]139 N BSDXNOEV
140 S BSDXNOEV=1 ;Don't execute BSDX CANCEL APPOINTMENT protocol
141 ;
[1080]142 ;;;test for error inside transaction. See if %ZTER works
143 I $G(bsdxdie) S X=1/0
144 ;;;test
145 ;;;test for TRESTART
146 I $G(bsdxrestart) K bsdxrestart TRESTART
147 ;;;test
148 ;
149 ; Check appointment ID and whether it exists
150 I '+BSDXAPTID D ERR(BSDXI,"-2~BSDX08: Invalid Appointment ID") Q
[1007]151 I '$D(^BSDXAPPT(BSDXAPTID,0)) D ERR(BSDXI,"-3~BSDX08: Invalid Appointment ID") Q
[614]152 ;
[1007]153 ; Start Processing:
[1080]154 ; First, add cancellation date to appt entry in BSDX APPOINTMENT
[1007]155 N BSDXNOD S BSDXNOD=^BSDXAPPT(BSDXAPTID,0) ; BSDX Appt Node
156 N BSDXPATID S BSDXPATID=$P(BSDXNOD,U,5) ; Patient ID
157 N BSDXSTART S BSDXSTART=$P(BSDXNOD,U) ; Start Time
158 D BSDXCAN(BSDXAPTID) ; Add a cancellation date in BSDX APPOINTMENT
[614]159 ;
[1080]160 ; Second, cancel appt in "S" nodes in file 2 and 44, then update Legacy PIMS Availability
[1007]161 N BSDXSC1 S BSDXSC1=$P(BSDXNOD,U,7) ;RESOURCEID
[1080]162 ; If the resouce id doesn't exist...
[1007]163 I BSDXSC1="" D ERR(BSDXI,"-4~BSDX08: Cancelled appointment does not have a Resouce ID") QUIT
[1080]164 I '$D(^BSDXRES(BSDXSC1,0)) D ERR(BSDXI,"-5~BSDX08: Resouce ID does not exist in BSDX RESOURCE") QUIT
[1007]165 ; Get zero node of resouce
[1080]166 S BSDXNOD=^BSDXRES(BSDXSC1,0)
167 ; Get Hosp location
[1007]168 N BSDXLOC S BSDXLOC=$P(BSDXNOD,U,4)
[1080]169 ; Error indicator for Hosp Location filing for getting out of routine
170 N BSDXERR S BSDXERR=0
171 ; Only file in 2/44 if there is an associated hospital location
172 I BSDXLOC D QUIT:BSDXERR
[1007]173 . I '$D(^SC(BSDXLOC,0)) S BSDXERR=1 D ERR(BSDXI,"-6~BSDX08: Invalid Hosp Location stored in Database") QUIT
[1080]174 . ; Get the IEN of the appointment in the "S" node of ^SC
175 . N BSDXSCIEN
[1007]176 . S BSDXSCIEN=$$SCIEN^BSDXAPI(BSDXPATID,BSDXLOC,BSDXSTART)
[1080]177 . I BSDXSCIEN="" S BSDXERR=1 D ERR(BSDXI,"-7~BSDX08: Patient does not have an appointment in PIMS Clinic") QUIT
[1007]178 . ; Get the appointment node
[1080]179 . S BSDXNOD=$G(^SC(BSDXLOC,"S",BSDXSTART,1,BSDXSCIEN,0))
[1007]180 . I BSDXNOD="" S BSDXERR=1 D ERR(BSDXI,"-8^BSDX08: Unable to find associated PIMS appointment for this patient") QUIT
181 . N BSDXLEN S BSDXLEN=$P(BSDXNOD,U,2)
182 . ; Cancel through BSDXAPI
[1080]183 . N BSDXZ
184 . D APCAN(.BSDXZ,BSDXLOC,BSDXPATID,BSDXSTART)
185 . I +BSDXZ>0 S BSDXERR=1 D ERR(BSDXI,"-9^BSDX08: BSDXAPI returned an error: "_$P(BSDXZ,U,2)) QUIT
[1007]186 . ; Update Legacy PIMS clinic Availability
[614]187 . D AVUPDT(BSDXLOC,BSDXSTART,BSDXLEN)
188 ;
189 TCOMMIT
[1007]190 L -^BSDXAPPT(BSDXAPTID)
[614]191 S BSDXI=BSDXI+1
192 S ^BSDXTMP($J,BSDXI)=""_$C(30)
193 S BSDXI=BSDXI+1
194 S ^BSDXTMP($J,BSDXI)=$C(31)
195 Q
196 ;
[1007]197AVUPDT(BSDXSCD,BSDXSTART,BSDXLEN) ;Update Legacy PIMS Clinic availability
[614]198 ;See SDCNP0
[1007]199 N SD,S ; Start Date
[1080]200 S (SD,S)=BSDXSTART
201 N I ; Clinic IEN in 44
[614]202 S I=BSDXSCD
[1080]203 ; if day has no schedule in legacy PIMS, forget about this update.
[614]204 Q:'$D(^SC(I,"ST",SD\1,1))
[1080]205 N SL ; Clinic characteristics node (length of appt, when appts start etc)
[1007]206 S SL=^SC(I,"SL")
[1080]207 N X ; Hour Clinic Display Begins
208 S X=$P(SL,U,3)
209 N STARTDAY ; When does the day start?
210 S STARTDAY=$S($L(X):X,1:8) ; If defined, use it; otherwise, 8am
211 N SB ; ?? Who knows? Day Start - 1 divided by 100.
212 S SB=STARTDAY-1/100
213 S X=$P(SL,U,6) ; Now X is Display increments per hour
214 N HSI ; Slots per hour, try 1
215 S HSI=$S(X:X,1:4) ; if defined, use it; otherwise, 4
216 N SI ; Slots per hour, try 2
217 S SI=$S(X="":4,X<3:4,X:X,1:4) ; If slots "", or less than 3, then 4
218 N STR ; ??
219 S STR="#@!$* XXWVUTSRQPONMLKJIHGFEDCBA0123456789jklmnopqrstuvwxyz"
220 N SDDIF ; Slots per hour diff??
221 S SDDIF=$S(HSI<3:8/HSI,1:2)
[1007]222 S SL=BSDXLEN ; Dammit, reusing variable; SL now Appt Length from GUI
223 S S=^SC(I,"ST",SD\1,1) ; reusing var again; S now Day Pattern from PIMS
[1080]224 N Y ; Hours since start of Date
225 S Y=SD#1-SB*100 ;SD#1=FM Time portion; -SB minus start of day; conv to hrs
226 N ST ; ??
227 ; Y#1 -> Minutes; *SI -> * Slots per hour; \.6 trunc min to hour
228 ; Y\1 -> Hours since start of day; * SI: * slots
229 S ST=Y#1*SI\.6+(Y\1*SI)
230 N SS ; how many slots are supposed to be taken by appointment
231 S SS=SL*HSI/60 ; (nb: try SL: 30 min; HSI: 4 slots)
[1007]232 N I
[1080]233 I Y'<1 D ; If Hours since start of Date is greater than 1
234 . ; loop through pattern. Tired of documenting.
235 . F I=ST+ST:SDDIF D Q:Y="" Q:SS'>0
236 . . S Y=$E(STR,$F(STR,$E(S,I+1))) Q:Y=""
237 . . S S=$E(S,1,I)_Y_$E(S,I+2,999)
238 . . S SS=SS-1
239 . . Q:SS'>0
[1007]240 S ^SC(BSDXSCD,"ST",SD\1,1)=S ; new pattern; global set
[614]241 Q
242 ;
243APCAN(BSDXZ,BSDXLOC,BSDXDFN,BSDXSD) ;
244 ;Cancel appointment for patient BSDXDFN in clinic BSDXSC1
245 ;at time BSDXSD
246 N BSDXC,%H
247 S BSDXC("PAT")=BSDXPATID
248 S BSDXC("CLN")=BSDXLOC
249 S BSDXC("TYP")=BSDXTYP
250 S BSDXC("ADT")=BSDXSD
251 S %H=$H D YMD^%DTC
252 S BSDXC("CDT")=X+%
253 S BSDXC("NOT")=BSDXNOT
[951]254 S:'+$G(BSDXCR) BSDXCR=11 ;Other
[614]255 S BSDXC("CR")=BSDXCR
256 S BSDXC("USR")=DUZ
257 ;
258 S BSDXZ=$$CANCEL^BSDXAPI(.BSDXC)
259 Q
260 ;
261BSDXCAN(BSDXAPTID) ;
262 ;Cancel BSDX APPOINTMENT entry
263 N %DT,X,BSDXDATE,Y,BSDXIENS,BSDXFDA,BSDXMSG
264 S %DT="XT",X="NOW" D ^%DT ; X ^DD("DD")
265 S BSDXDATE=Y
266 S BSDXIENS=BSDXAPTID_","
267 S BSDXFDA(9002018.4,BSDXIENS,.12)=BSDXDATE
268 K BSDXMSG
269 D FILE^DIE("","BSDXFDA","BSDXMSG")
270 Q
271 ;
272CANEVT(BSDXPAT,BSDXSTART,BSDXSC) ;EP Called by BSDX CANCEL APPOINTMENT event
273 ;when appointments cancelled via PIMS interface.
274 ;Propagates cancellation to BSDXAPPT and raises refresh event to running GUI clients
275 N BSDXFOUND,BSDXRES
276 Q:+$G(BSDXNOEV)
277 Q:'+$G(BSDXSC)
278 S BSDXFOUND=0
279 I $D(^BSDXRES("ALOC",BSDXSC)) S BSDXRES=$O(^BSDXRES("ALOC",BSDXSC,0)) S BSDXFOUND=$$CANEVT1(BSDXRES,BSDXSTART,BSDXPAT)
280 I BSDXFOUND D CANEVT3(BSDXRES) Q
281 I $D(^BXDXRES("ASSOC",BSDXSC)) S BSDXRES=$O(^BSDXRES("ASSOC",BSDXSC,0)) S BSDXFOUND=$$CANEVT1(BSDXRES,BSDXSTART,BSDXPAT)
282 I BSDXFOUND D CANEVT3(BSDXRES)
283 Q
284 ;
285CANEVT1(BSDXRES,BSDXSTART,BSDXPAT) ;
286 ;Get appointment id in BSDXAPT
287 ;If found, call BSDXCAN(BSDXAPPT) and return 1
288 ;else return 0
289 N BSDXFOUND,BSDXAPPT
290 S BSDXFOUND=0
291 Q:'+BSDXRES BSDXFOUND
292 Q:'$D(^BSDXAPPT("ARSRC",BSDXRES,BSDXSTART)) BSDXFOUND
293 S BSDXAPPT=0 F S BSDXAPPT=$O(^BSDXAPPT("ARSRC",BSDXRES,BSDXSTART,BSDXAPPT)) Q:'+BSDXAPPT D Q:BSDXFOUND
294 . S BSDXNOD=$G(^BSDXAPPT(BSDXAPPT,0)) Q:BSDXNOD=""
295 . I $P(BSDXNOD,U,5)=BSDXPAT,$P(BSDXNOD,U,12)="" S BSDXFOUND=1 Q
296 I BSDXFOUND,+$G(BSDXAPPT) D BSDXCAN(BSDXAPPT)
297 Q BSDXFOUND
298 ;
299CANEVT3(BSDXRES) ;
300 ;Call RaiseEvent to notify GUI clients
301 ;
302 N BSDXRESN
303 S BSDXRESN=$G(^BSDXRES(BSDXRES,0))
304 Q:BSDXRESN=""
305 S BSDXRESN=$P(BSDXRESN,"^")
306 ;D EVENT^BSDX23("SCHEDULE-"_BSDXRESN,"","","")
307 D EVENT^BMXMEVN("BSDX SCHEDULE",BSDXRESN)
308 Q
309 ;
310ERR(BSDXI,BSDXERR) ;Error processing
311 S BSDXI=BSDXI+1
312 S BSDXERR=$TR(BSDXERR,"^","~")
[1007]313 I $TL>0 TROLLBACK
[614]314 S ^BSDXTMP($J,BSDXI)=BSDXERR_$C(30)
315 S BSDXI=BSDXI+1
316 S ^BSDXTMP($J,BSDXI)=$C(31)
[1007]317 L -^BSDXAPPT(BSDXAPTID)
318 QUIT
[614]319 ;
320ETRAP ;EP Error trap entry
[1007]321 N $ET S $ET="D ^%ZTER HALT" ; Emergency Error Trap
[1080]322 ; Rollback, otherwise ^XTER will be empty from future rollback
323 I $TL>0 TROLLBACK
324 D ^%ZTER
325 S $EC="" ; Clear Error
[1007]326 ; Log error message and send to client
[1080]327 I '$D(BSDXI) N BSDXI S BSDXI=0
[1007]328 D ERR(BSDXI,"-100~BSDX08 Error: "_$G(%ZTERZE))
329 QUIT
[1080]330 ;
331 ;;;NB: This is code that is unused in both original and port.
332 ; ; If not appt in the "S" node is found in ^SC then check associated RPMS Clinic Multiple
333 ; I BSDXSCIEN="" D I 'BSDXZ Q ;Q:BSDXZ
[1007]334 ; . S BSDXERR="BSDX08: Unable to find associated RPMS appointment for this patient. "
335 ; . S BSDXZ=1
[1080]336 ; . ; Check if there are associated RPMS clinics. (not currently used) Does the multiple exist? No, then quit
[1007]337 ; . I '$D(^BSDXRES(BSDXSC1,20)) S BSDXZ=0 QUIT
[1080]338 ; . ; Loop through the multiple. Get Location and then the ^SC "S" node IEN.
[1007]339 ; . N BSDX1 S BSDX1=0
340 ; . F S BSDX1=$O(^BSDXRES(BSDXSC1,20,BSDX1)) Q:'+BSDX1 Q:BSDXZ=0 D
341 ; . . Q:'$D(^BSDXRES(BSDXSC1,20,BSDX1,0))
342 ; . . S BSDXLOC=$P(^BSDXRES(BSDXSC1,20,BSDX1,0),U)
[1080]343 ; . . S BSDXSCIEN=$$SCIEN^BSDXAPI(BSDXPATID,BSDXLOC,BSDXSTART) I +BSDXSCIEN S BSDXZ=0 Q
Note: See TracBrowser for help on using the repository browser.