SDECUTL ;ALB/MGD - VISTA SCHEDULING RPCS ;Jul 02, 2021@16:42
;;5.3;Scheduling;**627,658,665,790**;Aug 13, 1993;Build 11
;
; Reference to ^GMR(123 is supported by IA #4837
Q
;
SYSSTAT(SDECY) ; SYSTEM STATUS
;SYSSTAT(SDECY) external parameter tag in SDEC
N SDECCNT,SDECD,SDECH,SDECII,SDECROW,SDECROW1,SDECYA
S SDECII=0
S SDECY=$NA(^TMP("SDEC",$J)) K @SDECY
;S SDECYA=$NA(^SDECTMPA($J)) K @SDECYA
S @SDECY@(SDECII)="T00080ERROR_ID^T00080ERROR_TEXT"_$C(30)
S SDECII=SDECII+1 S @SDECY@(SDECII)=$C(30,31)
Q
;
STRIP(SDECSTR) ;
; SDECSTR = input string to parse
N SDECDN,SDECI,SDECPC,SDECPCNT,SDECPDN,SDECRET
Q:$E(SDECSTR,1,8)=" " ""
S SDECI=""
S SDECRET=""
S SDECPCNT=""
S SDECDN=""
F Q:SDECDN D
. S SDECI=SDECI+1
. Q:$E(SDECSTR,SDECI)=" "
. S SDECPCNT=SDECPCNT+1
. S SDECPC=""
. S SDECPDN=""
. F Q:SDECPDN D
. . S SDECPC=SDECPC_$E(SDECSTR,SDECI)
. . S SDECI=SDECI+1
. . I ($E(SDECSTR,SDECI)=" ")!(SDECI>$L(SDECSTR)) S SDECPDN=1
. ;
. S SDECRET=$S(SDECPCNT'=1:SDECRET_U,1:"")_$S(SDECPCNT=4:$E(SDECPC,1,8),1:SDECPC)
. I (SDECPCNT=4)!(SDECI>$L(SDECSTR)) S SDECDN=1
;
Q SDECRET
;
FL(SDECSTR,SDECW,SDECD) ;EP
;format line
; SDECSTR = Text String to be formatted
; SDECW = Maximum width of text line
; SDECD = Delimiter; defaults to double pipe "||" to be used as the line separator
;
;RETURNS string delimited by double pipe "||" to be used as line separator
N SDECOUT,SDECPTR,SDECTMP
I $G(SDECW)="" S SDECW=80
I '+SDECW S SDECW=80
I $L(SDECSTR)'>SDECW Q SDECSTR
I $G(SDECD)="" S SDECD="||"
S SDECOUT=""
S SDECPTR=SDECW
;handle no spaces in the string
I SDECSTR'[" " D
. F Q:SDECSTR="" D
. . I $L(SDECSTR)'>SDECW D
. . . S SDECOUT=$S(SDECOUT'="":SDECOUT_SDECD,1:"")_SDECSTR
. . . S SDECSTR=""
. . I $L(SDECSTR)>SDECW D
. . . S SDECOUT=$S(SDECOUT'="":SDECOUT_SDECD,1:"")_$E(SDECSTR,1,SDECW)
. . . S SDECSTR=$E(SDECSTR,SDECW+1,$L(SDECSTR))
;string does contain a space
I SDECSTR[" " D
. F Q:SDECSTR="" D
. . I $L(SDECSTR)'>SDECW D
. . . S SDECOUT=$S(SDECOUT'="":SDECOUT_SDECD,1:"")_SDECSTR
. . . S SDECSTR=""
. . I $L(SDECSTR)>SDECW D
. . . F Q:$E(SDECSTR,SDECPTR)=" " D
. . . . S SDECPTR=SDECPTR-1
. . . S SDECOUT=$S(SDECOUT'="":SDECOUT_SDECD,1:"")_$E(SDECSTR,1,SDECPTR-1)
. . . S SDECSTR=$E(SDECSTR,SDECPTR+1,$L(SDECSTR))
. . . S SDECPTR=SDECW
Q SDECOUT
;
; Check and validate visit
CHKVISIT(VIEN,DFN,CAT) ;EP
N RET,X0
S RET=$$ISLOCKED(VIEN)
Q:RET $S(RET<0:$$ERR^SDEC44("Visit "_VIEN_" not found."),1:$$ERR^SDEC44("Visit "_VIEN_" is locked."))
S X0=$G(^AUPNVSIT(VIEN,0))
I $G(DFN),$P(X0,U,5)'=DFN S RET=$$ERR^SDEC44("Visit "_VIEN_" does not belong to Patient "_DFN_".")
E I $P(X0,U,11) S RET=$$ERR^SDEC44("Visit "_VIEN_" has been deleted.")
E I $L($G(CAT)),CAT'[$P(X0,U,7) S RET=$$ERR^SDEC44("Service Category of Visit "_VIEN_" is not "_CAT_".",$$EXTERNAL^DILFD(9000010,.07,,$P(X0,U,7)))
Q RET
;
; Returns visit lock status:
; -1: Visit not found
; 0: Visit is not locked
; 1: Visit is locked
ISLOCKED(IEN) ;PEP - Is visit locked?
N DAT,DAYS,EXPDT
S DAT=$$VISREFDT(IEN)
Q:'DAT -1
;IHS/MSC/PLS - 02/18/09 - Parameter now holds lock expiration date
;S EXPDT=$$GET^XPAR("USR","BEHOENCX VISIT LOCK OVERRIDE","`"_IEN)
;Q:EXPDT'<$$DT^XLFDT() 0
;D:EXPDT DEL^XPAR("USR","BEHOENCX VISIT LOCK OVERRIDE","`"_IEN) ; remove expired locked
;Q:$$GET^XPAR("USR","BEHOENCX VISIT LOCK OVERRIDE","`"_IEN) 0
;S DAYS=$$GET^XPAR("ALL","BEHOENCX VISIT LOCKED")
Q $$FMDIFF^XLFDT(DT,DAT)>1 ;$S(DAYS<1:1,1:DAYS)
; Returns reference date for visit lock check
VISREFDT(IEN) ;
N ADM,DIS,DAT
S DAT=$P($G(^AUPNVSIT(+IEN,0)),U,2)
Q:'DAT ""
S ADM=$O(^DGPM("AVISIT",IEN,0))
Q:'ADM DAT
S DIS=$P($G(^DGPM(ADM,0)),U,17)
Q $S(DIS:$P($G(^DGPM(DIS,0)),U),1:DT)
;
; Add/edit a file entry
UPDATE(FDA,FLG,IEN) ;EP
N ERR,DFN,X
I $G(FLG)["@" S FLG=$TR(FLG,"@")
E D
.S X="FDA"
.F S X=$Q(@X) Q:'$L(X) K:'$L(@X) @X
Q:$D(FDA)'>1 ""
D UPDATE^DIE(.FLG,"FDA","IEN","ERR")
K FDA
Q $S($G(ERR("DIERR",1)):-ERR("DIERR",1)_U_ERR("DIERR",1,"TEXT",1),1:"")
;
ISACTIVE(ADT,IDT,CDT) ;is CDT an active date given an active date and inactive date
;INPUT:
; ADT = Activation date in FM format
; IDT = Inactivation date in FM format
; CDT = date to check - default to 'today'
;RETURN:
; 0=inactive
; 1=active
; 2=ADT & IDT null; calling routine can decide if default to active or inactive
; 3=date to check is before both activation and inactivation; calling routine can decide if default to active or inactive
N RET
S RET=""
S ADT=$S($P($G(ADT),".",1)?7N:$P(ADT,".",1),1:"")
S IDT=$S($P($G(IDT),".",1)?7N:$P(IDT,".",1),1:"")
S CDT=$S($P($G(CDT),".",1)?7N:$P(CDT,".",1),1:$P($$NOW^XLFDT,".",1))
;0 0
I ADT="",IDT="" S RET=2
Q:RET'="" RET
;1 0
I ADT'="",IDT="" D
.S RET=1 ;TODO: what if 'today' or CDT is before ADT
Q:RET'="" RET
;0 1
I ADT="",IDT'="" S RET=0 ;TODO: what if 'today' or CDT is before IDT
Q:RET'="" RET
;1 1
; active < T < inactive
I CDT'<ADT,CDT'>IDT S RET=1
Q:RET'="" RET
; active < inactive < T
I ADT<IDT,IDT<CDT S RET=0
Q:RET'="" RET
; inactive < T < active
I IDT<CDT,CDT<ADT S RET=0
Q:RET'="" RET
; inactive < active < T
I IDT<ADT,ADT<CDT S RET=1
Q:RET'="" RET
;T < active < inactive AND T < inactive < active
I RET="" S RET=3 ;should not get here
Q RET
;
APPTGET(DFN,SDBEG,SDCL,SDRES) ;get SDEC APPOINTMENT for given patient, time, and clinic
N SDAPPT,SDI,SDNOD,SDRCL,SDARES,SDBEGINDX,SDEND
S SDAPPT=""
S SDCL=$G(SDCL)
S SDRES=$G(SDRES)
; Reset SDBEG to immediately before actual start time
S SDBEGINDX=SDBEG-.00001
S SDEND=$E(SDBEG,1,7) ; Set stop date
; Utilize APTDT x-ref for speed. VSE-1172
F S SDBEGINDX=$O(^SDEC(409.84,"APTDT",DFN,SDBEGINDX)) Q:'SDBEGINDX!($P(SDBEGINDX,".",1)>SDEND) D Q:SDAPPT'=""
.S SDI=0 F S SDI=$O(^SDEC(409.84,"APTDT",DFN,SDBEGINDX,SDI)) Q:SDI'>0 D Q:SDAPPT'=""
..S SDNOD=$G(^SDEC(409.84,SDI,0))
..; Quit if this record has one of the Cancelled Statuses. VSE-1171
..Q:"^N^NA^C^CA^PC^PCA^"[(U_$P(SDNOD,U,17)_U)
..Q:SDBEG'=$P(SDNOD,U,1)
..I +SDRES Q:+SDRES'=$P(SDNOD,U,7)
..I 'SDRES S SDARES=$P(SDNOD,U,7) S SDRCL=$P($G(^SDEC(409.831,+SDARES,0)),U,4) Q:SDRCL'=SDCL
..S SDAPPT=SDI
Q SDAPPT
;
GETRES(SDCL,INACT) ;get resource for clinic - SDEC RESOURCE
N SDHLN,SDI,SDNOD,SDRES,SDRES1
S (SDRES,SDRES1)=""
S SDHLN=$P($G(^SC(SDCL,0)),U,1)
Q:SDHLN="" ""
S SDI="" F S SDI=$O(^SDEC(409.831,"ALOC",SDCL,SDI)) Q:SDI="" D Q:SDRES'=""
.S SDNOD=$G(^SDEC(409.831,SDI,0))
.I '$G(INACT) Q:$$GET1^DIQ(409.831,SDI_",",.02)="YES"
.S:SDRES1="" SDRES1=SDI
.Q:$P($P(SDNOD,U,11),";",2)'="SC("
.S SDRES=SDI
.;I $$UP^XLFSTR($P(SDNOD,U,1))=SDHLN S SDRES=SDI
I SDRES="",SDRES1'="" S SDRES=SDRES1
Q SDRES
;
RECALL(DFN,SDT,SDCL) ;is this appointment for RECALL
;INPUT:
; DFN = Patient ID pointer to PATIENT file 2
; SDT = Appointment date/time in fm format
N SDI,SDNOD1,SDRET
S SDRET=""
S SDI=0 F S SDI=$O(^SD(403.56,"B",DFN,SDI)) Q:SDI'>0 D Q:SDRET'=""
.S SDNOD1=$G(^SD(403.56,SDI,1))
.Q:$P(SDNOD1,U,1)'=SDT
.Q:$P(SDNOD1,U,2)'=SDCL
.S SDRET=SDI
Q SDRET
;
SDCL(SDAPID) ;get clinic for given SDEC APPOINTMENT id
;INPUT:
; SDAPID - appt ID pointer to SDEC APPOINTMENT file 409.84
;RETURN:
; Clinic ID pointer to HOSPITAL LOCATION file 44
N SDAPTYP,SDCL
S SDCL=""
S SDAPTYP=$$GET1^DIQ(409.84,SDAPID_",",.22,"I")
S:$P(SDAPTYP,"|",2)="SDWL(409.3," SDCL=$$GET1^DIQ(409.3,$P(SDAPTYP,"|",2)_",",13.2,"I")
S:$P(SDAPTYP,"|",1)="SD(403.5," SDCL=$$GET1^DIQ(403.5,$P(SDAPTYP,"|",2)_",",4.5,"I")
S:$P(SDAPTYP,"|",1)="GMR(123," SDCL=$$GET1^DIQ(123,$P(SDAPTYP,"|",2)_",",.04,"I") ;ICR 4837
Q SDCL
;
PTSEC(DFN) ;patient sensitive & record access checks; calls DG SENSITIVE RECORD ACCESS api
;INPUT:
; DFN - patient ID pointer to PATIENT file 2
;RETURN:
; RESULT - the following pipe pieces:
; 1. return code:
; -1-RPC/API failed
; Required variable not defined
; 0-No display/action required
; Not accessing own, employee, or sensitive record
; 1-Display warning message
; Sensitive and DG SENSITIVITY key holder
; or Employee and DG SECURITY OFFICER key holder
; 2-Display warning message/require OK to continue
; Sensitive and not a DG SENSITIVITY key holder
; Employee and not a DG SECURITY OFFICER key holder
; 3-Access to record denied
; Accessing own record
; 4-Access to Patient (#2) file records denied
; SSN not defined
; 2. display text/message
; 3. display text/message
; 4. display text/message
;
N SDI,SDLINE,SDRET,SDSEC,SDTXT
K SDRET,SDSEC
S SDRET=""
;D PTSEC^DGSEC4(.SDSEC,DFN,0) ;alb/sat 658
D PTSEC4(.SDSEC,DFN,0)
S $P(SDRET,"|",1)=SDSEC(1)
S:$G(SDSEC(2))'="" $P(SDRET,"|",2)=SDSEC(2) ;I DUZ=51 S:$G(SDSEC(2))'="" $P(SDRET,"|",2)=$$STRIP1(SDSEC(2))
S:$G(SDSEC(3))'="" $P(SDRET,"|",3)=SDSEC(3) ;I DUZ=51 S:$G(SDSEC(3))'="" $P(SDRET,"|",3)=$$STRIP1(SDSEC(3))
S SDTXT=""
S SDI=3 F S SDI=$O(SDSEC(SDI)) Q:SDI="" D
.S SDLINE=$$STRIP1(SDSEC(SDI))
.Q:SDLINE?." "
.S SDTXT=$S(SDTXT'="":SDTXT,1:"")_SDLINE
S:SDTXT'="" $P(SDRET,"|",4)=SDTXT
Q SDRET
PTSEC4(RESULT,DFN,DGMSG,DGOPT) ;RPC/API entry point for patient sensitive & record access checks ;alb/sat 658
;Output array (Required)
; RESULT(1)= -1-RPC/API failed
; Required variable not defined
; 0-No display/action required
; Not accessing own, employee, or sensitive record
; 1-Display warning message
; Sensitive and DG SENSITIVITY key holder
; or Employee and DG SECURITY OFFICER key holder
; 2-Display warning message/require OK to continue
; Sensitive and not a DG SENSITIVITY key holder
; Employee and not a DG SECURITY OFFICER key holder
; 3-Access to record denied
; Accessing own record
; 4-Access to Patient (#2) file records denied
; SSN not defined
; RESULT(2-10) = error or display messages
;
;Input parameters: DFN = Patient file entry (Required)
; DGMSG = If 1, generate message (optional)
; DGOPT = Option name^Menu text (Optional)
;
K RESULT
I $G(DFN)="" D Q
.S RESULT(1)=-1
.S RESULT(2)="Required variable missing."
S DGMSG=$G(DGMSG,0)
D OWNREC^DGSEC4(.RESULT,DFN,$G(DUZ),DGMSG)
I RESULT(1)=1 S RESULT(1)=3 Q
I RESULT(1)=2 S RESULT(1)=4 Q
K RESULT
D SENS^DGSEC4(.RESULT,DFN,$G(DUZ))
I RESULT(1)=1 D
.I $G(DUZ)="" D Q
..;DUZ must be defined to access sensitive record & update DG Security log
..S RESULT(1)=-1
..S RESULT(2)="Your user code is undefined. This must be defined to access a restricted patient record."
.;D SETLOG1^DGSEC(DFN,DUZ,,$G(DGOPT))
Q
;
STRIP1(SDTXT) ;strip out "*"
N SDI
S SDTXT=$TR(SDTXT,"*","")
F SDI=$L(SDTXT):-1:1 Q:$E(SDTXT,SDI)'=" " S SDTXT=$E(SDTXT,1,$L(SDTXT)-1)
Q SDTXT
;
WP(RET,STR,CH) ;Convert string STR to Word Processing array ;alb/sat 658
;INPUT:
; STR - String to convert
; CH - Max characters per line
;RETURN:
; RET - WP Array RET(<line cnt>,0)=<text>
N CH1,CNT,BEG,END,LCNT
K RET
Q:$G(STR)=""
I '+$G(CH) S CH=80
I $L(STR'>CH) S RET(1,0)=STR Q ;alb/sat 665
S (END,LCNT)=0
S BEG=1
F CNT=1:1:$L(STR) S CH1=$E(STR,CNT) D
.I CH1=" " S END=CNT
.I CNT'=BEG,'((CNT-BEG)#CH) D
..S LCNT=LCNT+1 S RET(LCNT,0)=$E(STR,BEG,$S(END'=0:END,1:CNT))
..S BEG=$S(END'=0:END,1:CNT)+1
..S END=0
I CNT'=BEG S LCNT=LCNT+1 S RET(LCNT,0)=$E(STR,BEG,$L(STR))
Q
WPSTR(ARR) ;convert WP field array to single string ;alb/sat 658
N RET,WPI
S RET=""
Q:'$D(ARR) RET
S WPI=0 F S WPI=$O(ARR(WPI)) Q:WPI="" D
.S RET=RET_ARR(WPI)
Q RET
PF(STRING,SUB,DI) ;piece find
N SDI
S STRING=$G(STRING) Q:STRING="" ""
S SUB=$G(SUB) Q:SUB="" ""
S DI=$G(DI) S:DI="" DI=U
F SDI=1:1:$L(STRING,DI) Q:$P(STRING,DI,SDI)=SUB
Q SDI
PD(STRING,PC,DI) ;piece delete
N SDI,NSTR
S NSTR=""
S STRING=$G(STRING) Q:STRING="" STRING
S PC=$G(PC) Q:'PC STRING
S DI=$G(DI) S:DI="" DI=U
F SDI=1:1:$L(STRING,DI) D
.Q:SDI=PC
.S NSTR=NSTR_$S(NSTR'="":DI,1:"")_$P(STRING,DI,SDI)
Q NSTR
PFD(STRING,SUB,DI) ;piece find/delete delete all pieces with matching SUB values
N SDI,NSTR
S NSTR=""
S STRING=$G(STRING) Q:STRING="" STRING
S SUB=$G(SUB) Q:SUB="" STRING
S DI=$G(DI) S:DI="" DI=U
F SDI=1:1:$L(STRING,DI) S:$P(STRING,DI,SDI)'=SUB NSTR=NSTR_$S(NSTR'="":DI,1:"")_$P(STRING,DI,SDI)
Q NSTR
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HSDECUTL 12944 printed Dec 13, 2024@02:52:52 Page 2
SDECUTL ;ALB/MGD - VISTA SCHEDULING RPCS ;Jul 02, 2021@16:42
+1 ;;5.3;Scheduling;**627,658,665,790**;Aug 13, 1993;Build 11
+2 ;
+3 ; Reference to ^GMR(123 is supported by IA #4837
+4 QUIT
+5 ;
SYSSTAT(SDECY) ; SYSTEM STATUS
+1 ;SYSSTAT(SDECY) external parameter tag in SDEC
+2 NEW SDECCNT,SDECD,SDECH,SDECII,SDECROW,SDECROW1,SDECYA
+3 SET SDECII=0
+4 SET SDECY=$NAME(^TMP("SDEC",$JOB))
KILL @SDECY
+5 ;S SDECYA=$NA(^SDECTMPA($J)) K @SDECYA
+6 SET @SDECY@(SDECII)="T00080ERROR_ID^T00080ERROR_TEXT"_$CHAR(30)
+7 SET SDECII=SDECII+1
SET @SDECY@(SDECII)=$CHAR(30,31)
+8 QUIT
+9 ;
STRIP(SDECSTR) ;
+1 ; SDECSTR = input string to parse
+2 NEW SDECDN,SDECI,SDECPC,SDECPCNT,SDECPDN,SDECRET
+3 if $EXTRACT(SDECSTR,1,8)=" "
QUIT ""
+4 SET SDECI=""
+5 SET SDECRET=""
+6 SET SDECPCNT=""
+7 SET SDECDN=""
+8 FOR
if SDECDN
QUIT
Begin DoDot:1
+9 SET SDECI=SDECI+1
+10 if $EXTRACT(SDECSTR,SDECI)=" "
QUIT
+11 SET SDECPCNT=SDECPCNT+1
+12 SET SDECPC=""
+13 SET SDECPDN=""
+14 FOR
if SDECPDN
QUIT
Begin DoDot:2
+15 SET SDECPC=SDECPC_$EXTRACT(SDECSTR,SDECI)
+16 SET SDECI=SDECI+1
+17 IF ($EXTRACT(SDECSTR,SDECI)=" ")!(SDECI>$LENGTH(SDECSTR))
SET SDECPDN=1
End DoDot:2
+18 ;
+19 SET SDECRET=$SELECT(SDECPCNT'=1:SDECRET_U,1:"")_$SELECT(SDECPCNT=4:$EXTRACT(SDECPC,1,8),1:SDECPC)
+20 IF (SDECPCNT=4)!(SDECI>$LENGTH(SDECSTR))
SET SDECDN=1
End DoDot:1
+21 ;
+22 QUIT SDECRET
+23 ;
FL(SDECSTR,SDECW,SDECD) ;EP
+1 ;format line
+2 ; SDECSTR = Text String to be formatted
+3 ; SDECW = Maximum width of text line
+4 ; SDECD = Delimiter; defaults to double pipe "||" to be used as the line separator
+5 ;
+6 ;RETURNS string delimited by double pipe "||" to be used as line separator
+7 NEW SDECOUT,SDECPTR,SDECTMP
+8 IF $GET(SDECW)=""
SET SDECW=80
+9 IF '+SDECW
SET SDECW=80
+10 IF $LENGTH(SDECSTR)'>SDECW
QUIT SDECSTR
+11 IF $GET(SDECD)=""
SET SDECD="||"
+12 SET SDECOUT=""
+13 SET SDECPTR=SDECW
+14 ;handle no spaces in the string
+15 IF SDECSTR'[" "
Begin DoDot:1
+16 FOR
if SDECSTR=""
QUIT
Begin DoDot:2
+17 IF $LENGTH(SDECSTR)'>SDECW
Begin DoDot:3
+18 SET SDECOUT=$SELECT(SDECOUT'="":SDECOUT_SDECD,1:"")_SDECSTR
+19 SET SDECSTR=""
End DoDot:3
+20 IF $LENGTH(SDECSTR)>SDECW
Begin DoDot:3
+21 SET SDECOUT=$SELECT(SDECOUT'="":SDECOUT_SDECD,1:"")_$EXTRACT(SDECSTR,1,SDECW)
+22 SET SDECSTR=$EXTRACT(SDECSTR,SDECW+1,$LENGTH(SDECSTR))
End DoDot:3
End DoDot:2
End DoDot:1
+23 ;string does contain a space
+24 IF SDECSTR[" "
Begin DoDot:1
+25 FOR
if SDECSTR=""
QUIT
Begin DoDot:2
+26 IF $LENGTH(SDECSTR)'>SDECW
Begin DoDot:3
+27 SET SDECOUT=$SELECT(SDECOUT'="":SDECOUT_SDECD,1:"")_SDECSTR
+28 SET SDECSTR=""
End DoDot:3
+29 IF $LENGTH(SDECSTR)>SDECW
Begin DoDot:3
+30 FOR
if $EXTRACT(SDECSTR,SDECPTR)=" "
QUIT
Begin DoDot:4
+31 SET SDECPTR=SDECPTR-1
End DoDot:4
+32 SET SDECOUT=$SELECT(SDECOUT'="":SDECOUT_SDECD,1:"")_$EXTRACT(SDECSTR,1,SDECPTR-1)
+33 SET SDECSTR=$EXTRACT(SDECSTR,SDECPTR+1,$LENGTH(SDECSTR))
+34 SET SDECPTR=SDECW
End DoDot:3
End DoDot:2
End DoDot:1
+35 QUIT SDECOUT
+36 ;
+37 ; Check and validate visit
CHKVISIT(VIEN,DFN,CAT) ;EP
+1 NEW RET,X0
+2 SET RET=$$ISLOCKED(VIEN)
+3 if RET
QUIT $SELECT(RET<0:$$ERR^SDEC44("Visit "_VIEN_" not found."),1:$$ERR^SDEC44("Visit "_VIEN_" is locked."))
+4 SET X0=$GET(^AUPNVSIT(VIEN,0))
+5 IF $GET(DFN)
IF $PIECE(X0,U,5)'=DFN
SET RET=$$ERR^SDEC44("Visit "_VIEN_" does not belong to Patient "_DFN_".")
+6 IF '$TEST
IF $PIECE(X0,U,11)
SET RET=$$ERR^SDEC44("Visit "_VIEN_" has been deleted.")
+7 IF '$TEST
IF $LENGTH($GET(CAT))
IF CAT'[$PIECE(X0,U,7)
SET RET=$$ERR^SDEC44("Service Category of Visit "_VIEN_" is not "_CAT_".",$$EXTERNAL^DILFD(9000010,.07,,$PIECE(X0,U,7)))
+8 QUIT RET
+9 ;
+10 ; Returns visit lock status:
+11 ; -1: Visit not found
+12 ; 0: Visit is not locked
+13 ; 1: Visit is locked
ISLOCKED(IEN) ;PEP - Is visit locked?
+1 NEW DAT,DAYS,EXPDT
+2 SET DAT=$$VISREFDT(IEN)
+3 if 'DAT
QUIT -1
+4 ;IHS/MSC/PLS - 02/18/09 - Parameter now holds lock expiration date
+5 ;S EXPDT=$$GET^XPAR("USR","BEHOENCX VISIT LOCK OVERRIDE","`"_IEN)
+6 ;Q:EXPDT'<$$DT^XLFDT() 0
+7 ;D:EXPDT DEL^XPAR("USR","BEHOENCX VISIT LOCK OVERRIDE","`"_IEN) ; remove expired locked
+8 ;Q:$$GET^XPAR("USR","BEHOENCX VISIT LOCK OVERRIDE","`"_IEN) 0
+9 ;S DAYS=$$GET^XPAR("ALL","BEHOENCX VISIT LOCKED")
+10 ;$S(DAYS<1:1,1:DAYS)
QUIT $$FMDIFF^XLFDT(DT,DAT)>1
+11 ; Returns reference date for visit lock check
VISREFDT(IEN) ;
+1 NEW ADM,DIS,DAT
+2 SET DAT=$PIECE($GET(^AUPNVSIT(+IEN,0)),U,2)
+3 if 'DAT
QUIT ""
+4 SET ADM=$ORDER(^DGPM("AVISIT",IEN,0))
+5 if 'ADM
QUIT DAT
+6 SET DIS=$PIECE($GET(^DGPM(ADM,0)),U,17)
+7 QUIT $SELECT(DIS:$PIECE($GET(^DGPM(DIS,0)),U),1:DT)
+8 ;
+9 ; Add/edit a file entry
UPDATE(FDA,FLG,IEN) ;EP
+1 NEW ERR,DFN,X
+2 IF $GET(FLG)["@"
SET FLG=$TRANSLATE(FLG,"@")
+3 IF '$TEST
Begin DoDot:1
+4 SET X="FDA"
+5 FOR
SET X=$QUERY(@X)
if '$LENGTH(X)
QUIT
if '$LENGTH(@X)
KILL @X
End DoDot:1
+6 if $DATA(FDA)'>1
QUIT ""
+7 DO UPDATE^DIE(.FLG,"FDA","IEN","ERR")
+8 KILL FDA
+9 QUIT $SELECT($GET(ERR("DIERR",1)):-ERR("DIERR",1)_U_ERR("DIERR",1,"TEXT",1),1:"")
+10 ;
ISACTIVE(ADT,IDT,CDT) ;is CDT an active date given an active date and inactive date
+1 ;INPUT:
+2 ; ADT = Activation date in FM format
+3 ; IDT = Inactivation date in FM format
+4 ; CDT = date to check - default to 'today'
+5 ;RETURN:
+6 ; 0=inactive
+7 ; 1=active
+8 ; 2=ADT & IDT null; calling routine can decide if default to active or inactive
+9 ; 3=date to check is before both activation and inactivation; calling routine can decide if default to active or inactive
+10 NEW RET
+11 SET RET=""
+12 SET ADT=$SELECT($PIECE($GET(ADT),".",1)?7N:$PIECE(ADT,".",1),1:"")
+13 SET IDT=$SELECT($PIECE($GET(IDT),".",1)?7N:$PIECE(IDT,".",1),1:"")
+14 SET CDT=$SELECT($PIECE($GET(CDT),".",1)?7N:$PIECE(CDT,".",1),1:$PIECE($$NOW^XLFDT,".",1))
+15 ;0 0
+16 IF ADT=""
IF IDT=""
SET RET=2
+17 if RET'=""
QUIT RET
+18 ;1 0
+19 IF ADT'=""
IF IDT=""
Begin DoDot:1
+20 ;TODO: what if 'today' or CDT is before ADT
SET RET=1
End DoDot:1
+21 if RET'=""
QUIT RET
+22 ;0 1
+23 ;TODO: what if 'today' or CDT is before IDT
IF ADT=""
IF IDT'=""
SET RET=0
+24 if RET'=""
QUIT RET
+25 ;1 1
+26 ; active < T < inactive
+27 IF CDT'<ADT
IF CDT'>IDT
SET RET=1
+28 if RET'=""
QUIT RET
+29 ; active < inactive < T
+30 IF ADT<IDT
IF IDT<CDT
SET RET=0
+31 if RET'=""
QUIT RET
+32 ; inactive < T < active
+33 IF IDT<CDT
IF CDT<ADT
SET RET=0
+34 if RET'=""
QUIT RET
+35 ; inactive < active < T
+36 IF IDT<ADT
IF ADT<CDT
SET RET=1
+37 if RET'=""
QUIT RET
+38 ;T < active < inactive AND T < inactive < active
+39 ;should not get here
IF RET=""
SET RET=3
+40 QUIT RET
+41 ;
APPTGET(DFN,SDBEG,SDCL,SDRES) ;get SDEC APPOINTMENT for given patient, time, and clinic
+1 NEW SDAPPT,SDI,SDNOD,SDRCL,SDARES,SDBEGINDX,SDEND
+2 SET SDAPPT=""
+3 SET SDCL=$GET(SDCL)
+4 SET SDRES=$GET(SDRES)
+5 ; Reset SDBEG to immediately before actual start time
+6 SET SDBEGINDX=SDBEG-.00001
+7 ; Set stop date
SET SDEND=$EXTRACT(SDBEG,1,7)
+8 ; Utilize APTDT x-ref for speed. VSE-1172
+9 FOR
SET SDBEGINDX=$ORDER(^SDEC(409.84,"APTDT",DFN,SDBEGINDX))
if 'SDBEGINDX!($PIECE(SDBEGINDX,".",1)>SDEND)
QUIT
Begin DoDot:1
+10 SET SDI=0
FOR
SET SDI=$ORDER(^SDEC(409.84,"APTDT",DFN,SDBEGINDX,SDI))
if SDI'>0
QUIT
Begin DoDot:2
+11 SET SDNOD=$GET(^SDEC(409.84,SDI,0))
+12 ; Quit if this record has one of the Cancelled Statuses. VSE-1171
+13 if "^N^NA^C^CA^PC^PCA^"[(U_$PIECE(SDNOD,U,17)_U)
QUIT
+14 if SDBEG'=$PIECE(SDNOD,U,1)
QUIT
+15 IF +SDRES
if +SDRES'=$PIECE(SDNOD,U,7)
QUIT
+16 IF 'SDRES
SET SDARES=$PIECE(SDNOD,U,7)
SET SDRCL=$PIECE($GET(^SDEC(409.831,+SDARES,0)),U,4)
if SDRCL'=SDCL
QUIT
+17 SET SDAPPT=SDI
End DoDot:2
if SDAPPT'=""
QUIT
End DoDot:1
if SDAPPT'=""
QUIT
+18 QUIT SDAPPT
+19 ;
GETRES(SDCL,INACT) ;get resource for clinic - SDEC RESOURCE
+1 NEW SDHLN,SDI,SDNOD,SDRES,SDRES1
+2 SET (SDRES,SDRES1)=""
+3 SET SDHLN=$PIECE($GET(^SC(SDCL,0)),U,1)
+4 if SDHLN=""
QUIT ""
+5 SET SDI=""
FOR
SET SDI=$ORDER(^SDEC(409.831,"ALOC",SDCL,SDI))
if SDI=""
QUIT
Begin DoDot:1
+6 SET SDNOD=$GET(^SDEC(409.831,SDI,0))
+7 IF '$GET(INACT)
if $$GET1^DIQ(409.831,SDI_",",.02)="YES"
QUIT
+8 if SDRES1=""
SET SDRES1=SDI
+9 if $PIECE($PIECE(SDNOD,U,11),";",2)'="SC("
QUIT
+10 SET SDRES=SDI
+11 ;I $$UP^XLFSTR($P(SDNOD,U,1))=SDHLN S SDRES=SDI
End DoDot:1
if SDRES'=""
QUIT
+12 IF SDRES=""
IF SDRES1'=""
SET SDRES=SDRES1
+13 QUIT SDRES
+14 ;
RECALL(DFN,SDT,SDCL) ;is this appointment for RECALL
+1 ;INPUT:
+2 ; DFN = Patient ID pointer to PATIENT file 2
+3 ; SDT = Appointment date/time in fm format
+4 NEW SDI,SDNOD1,SDRET
+5 SET SDRET=""
+6 SET SDI=0
FOR
SET SDI=$ORDER(^SD(403.56,"B",DFN,SDI))
if SDI'>0
QUIT
Begin DoDot:1
+7 SET SDNOD1=$GET(^SD(403.56,SDI,1))
+8 if $PIECE(SDNOD1,U,1)'=SDT
QUIT
+9 if $PIECE(SDNOD1,U,2)'=SDCL
QUIT
+10 SET SDRET=SDI
End DoDot:1
if SDRET'=""
QUIT
+11 QUIT SDRET
+12 ;
SDCL(SDAPID) ;get clinic for given SDEC APPOINTMENT id
+1 ;INPUT:
+2 ; SDAPID - appt ID pointer to SDEC APPOINTMENT file 409.84
+3 ;RETURN:
+4 ; Clinic ID pointer to HOSPITAL LOCATION file 44
+5 NEW SDAPTYP,SDCL
+6 SET SDCL=""
+7 SET SDAPTYP=$$GET1^DIQ(409.84,SDAPID_",",.22,"I")
+8 if $PIECE(SDAPTYP,"|",2)="SDWL(409.3,"
SET SDCL=$$GET1^DIQ(409.3,$PIECE(SDAPTYP,"|",2)_",",13.2,"I")
+9 if $PIECE(SDAPTYP,"|",1)="SD(403.5,"
SET SDCL=$$GET1^DIQ(403.5,$PIECE(SDAPTYP,"|",2)_",",4.5,"I")
+10 ;ICR 4837
if $PIECE(SDAPTYP,"|",1)="GMR(123,"
SET SDCL=$$GET1^DIQ(123,$PIECE(SDAPTYP,"|",2)_",",.04,"I")
+11 QUIT SDCL
+12 ;
PTSEC(DFN) ;patient sensitive & record access checks; calls DG SENSITIVE RECORD ACCESS api
+1 ;INPUT:
+2 ; DFN - patient ID pointer to PATIENT file 2
+3 ;RETURN:
+4 ; RESULT - the following pipe pieces:
+5 ; 1. return code:
+6 ; -1-RPC/API failed
+7 ; Required variable not defined
+8 ; 0-No display/action required
+9 ; Not accessing own, employee, or sensitive record
+10 ; 1-Display warning message
+11 ; Sensitive and DG SENSITIVITY key holder
+12 ; or Employee and DG SECURITY OFFICER key holder
+13 ; 2-Display warning message/require OK to continue
+14 ; Sensitive and not a DG SENSITIVITY key holder
+15 ; Employee and not a DG SECURITY OFFICER key holder
+16 ; 3-Access to record denied
+17 ; Accessing own record
+18 ; 4-Access to Patient (#2) file records denied
+19 ; SSN not defined
+20 ; 2. display text/message
+21 ; 3. display text/message
+22 ; 4. display text/message
+23 ;
+24 NEW SDI,SDLINE,SDRET,SDSEC,SDTXT
+25 KILL SDRET,SDSEC
+26 SET SDRET=""
+27 ;D PTSEC^DGSEC4(.SDSEC,DFN,0) ;alb/sat 658
+28 DO PTSEC4(.SDSEC,DFN,0)
+29 SET $PIECE(SDRET,"|",1)=SDSEC(1)
+30 ;I DUZ=51 S:$G(SDSEC(2))'="" $P(SDRET,"|",2)=$$STRIP1(SDSEC(2))
if $GET(SDSEC(2))'=""
SET $PIECE(SDRET,"|",2)=SDSEC(2)
+31 ;I DUZ=51 S:$G(SDSEC(3))'="" $P(SDRET,"|",3)=$$STRIP1(SDSEC(3))
if $GET(SDSEC(3))'=""
SET $PIECE(SDRET,"|",3)=SDSEC(3)
+32 SET SDTXT=""
+33 SET SDI=3
FOR
SET SDI=$ORDER(SDSEC(SDI))
if SDI=""
QUIT
Begin DoDot:1
+34 SET SDLINE=$$STRIP1(SDSEC(SDI))
+35 if SDLINE?." "
QUIT
+36 SET SDTXT=$SELECT(SDTXT'="":SDTXT,1:"")_SDLINE
End DoDot:1
+37 if SDTXT'=""
SET $PIECE(SDRET,"|",4)=SDTXT
+38 QUIT SDRET
PTSEC4(RESULT,DFN,DGMSG,DGOPT) ;RPC/API entry point for patient sensitive & record access checks ;alb/sat 658
+1 ;Output array (Required)
+2 ; RESULT(1)= -1-RPC/API failed
+3 ; Required variable not defined
+4 ; 0-No display/action required
+5 ; Not accessing own, employee, or sensitive record
+6 ; 1-Display warning message
+7 ; Sensitive and DG SENSITIVITY key holder
+8 ; or Employee and DG SECURITY OFFICER key holder
+9 ; 2-Display warning message/require OK to continue
+10 ; Sensitive and not a DG SENSITIVITY key holder
+11 ; Employee and not a DG SECURITY OFFICER key holder
+12 ; 3-Access to record denied
+13 ; Accessing own record
+14 ; 4-Access to Patient (#2) file records denied
+15 ; SSN not defined
+16 ; RESULT(2-10) = error or display messages
+17 ;
+18 ;Input parameters: DFN = Patient file entry (Required)
+19 ; DGMSG = If 1, generate message (optional)
+20 ; DGOPT = Option name^Menu text (Optional)
+21 ;
+22 KILL RESULT
+23 IF $GET(DFN)=""
Begin DoDot:1
+24 SET RESULT(1)=-1
+25 SET RESULT(2)="Required variable missing."
End DoDot:1
QUIT
+26 SET DGMSG=$GET(DGMSG,0)
+27 DO OWNREC^DGSEC4(.RESULT,DFN,$GET(DUZ),DGMSG)
+28 IF RESULT(1)=1
SET RESULT(1)=3
QUIT
+29 IF RESULT(1)=2
SET RESULT(1)=4
QUIT
+30 KILL RESULT
+31 DO SENS^DGSEC4(.RESULT,DFN,$GET(DUZ))
+32 IF RESULT(1)=1
Begin DoDot:1
+33 IF $GET(DUZ)=""
Begin DoDot:2
+34 ;DUZ must be defined to access sensitive record & update DG Security log
+35 SET RESULT(1)=-1
+36 SET RESULT(2)="Your user code is undefined. This must be defined to access a restricted patient record."
End DoDot:2
QUIT
+37 ;D SETLOG1^DGSEC(DFN,DUZ,,$G(DGOPT))
End DoDot:1
+38 QUIT
+39 ;
STRIP1(SDTXT) ;strip out "*"
+1 NEW SDI
+2 SET SDTXT=$TRANSLATE(SDTXT,"*","")
+3 FOR SDI=$LENGTH(SDTXT):-1:1
if $EXTRACT(SDTXT,SDI)'=" "
QUIT
SET SDTXT=$EXTRACT(SDTXT,1,$LENGTH(SDTXT)-1)
+4 QUIT SDTXT
+5 ;
WP(RET,STR,CH) ;Convert string STR to Word Processing array ;alb/sat 658
+1 ;INPUT:
+2 ; STR - String to convert
+3 ; CH - Max characters per line
+4 ;RETURN:
+5 ; RET - WP Array RET(<line cnt>,0)=<text>
+6 NEW CH1,CNT,BEG,END,LCNT
+7 KILL RET
+8 if $GET(STR)=""
QUIT
+9 IF '+$GET(CH)
SET CH=80
+10 ;alb/sat 665
IF $LENGTH(STR'>CH)
SET RET(1,0)=STR
QUIT
+11 SET (END,LCNT)=0
+12 SET BEG=1
+13 FOR CNT=1:1:$LENGTH(STR)
SET CH1=$EXTRACT(STR,CNT)
Begin DoDot:1
+14 IF CH1=" "
SET END=CNT
+15 IF CNT'=BEG
IF '((CNT-BEG)#CH)
Begin DoDot:2
+16 SET LCNT=LCNT+1
SET RET(LCNT,0)=$EXTRACT(STR,BEG,$SELECT(END'=0:END,1:CNT))
+17 SET BEG=$SELECT(END'=0:END,1:CNT)+1
+18 SET END=0
End DoDot:2
End DoDot:1
+19 IF CNT'=BEG
SET LCNT=LCNT+1
SET RET(LCNT,0)=$EXTRACT(STR,BEG,$LENGTH(STR))
+20 QUIT
WPSTR(ARR) ;convert WP field array to single string ;alb/sat 658
+1 NEW RET,WPI
+2 SET RET=""
+3 if '$DATA(ARR)
QUIT RET
+4 SET WPI=0
FOR
SET WPI=$ORDER(ARR(WPI))
if WPI=""
QUIT
Begin DoDot:1
+5 SET RET=RET_ARR(WPI)
End DoDot:1
+6 QUIT RET
PF(STRING,SUB,DI) ;piece find
+1 NEW SDI
+2 SET STRING=$GET(STRING)
if STRING=""
QUIT ""
+3 SET SUB=$GET(SUB)
if SUB=""
QUIT ""
+4 SET DI=$GET(DI)
if DI=""
SET DI=U
+5 FOR SDI=1:1:$LENGTH(STRING,DI)
if $PIECE(STRING,DI,SDI)=SUB
QUIT
+6 QUIT SDI
PD(STRING,PC,DI) ;piece delete
+1 NEW SDI,NSTR
+2 SET NSTR=""
+3 SET STRING=$GET(STRING)
if STRING=""
QUIT STRING
+4 SET PC=$GET(PC)
if 'PC
QUIT STRING
+5 SET DI=$GET(DI)
if DI=""
SET DI=U
+6 FOR SDI=1:1:$LENGTH(STRING,DI)
Begin DoDot:1
+7 if SDI=PC
QUIT
+8 SET NSTR=NSTR_$SELECT(NSTR'="":DI,1:"")_$PIECE(STRING,DI,SDI)
End DoDot:1
+9 QUIT NSTR
PFD(STRING,SUB,DI) ;piece find/delete delete all pieces with matching SUB values
+1 NEW SDI,NSTR
+2 SET NSTR=""
+3 SET STRING=$GET(STRING)
if STRING=""
QUIT STRING
+4 SET SUB=$GET(SUB)
if SUB=""
QUIT STRING
+5 SET DI=$GET(DI)
if DI=""
SET DI=U
+6 FOR SDI=1:1:$LENGTH(STRING,DI)
if $PIECE(STRING,DI,SDI)'=SUB
SET NSTR=NSTR_$SELECT(NSTR'="":DI,1:"")_$PIECE(STRING,DI,SDI)
+7 QUIT NSTR