BEHOENC1 ;MSC/IND/DKM - Visit Creation Support ;16-Jul-2009 17:58;PLS
;;1.1;BEH COMPONENTS;**005004;20-Aug-2007 08:41
;=================================================================
; Visit creation API
GETVISIT(IN,OUT) ;
;
; >> All date/time variables must be in FileMan internal format
;
; Special Incoming Variables:
; IN("FORCE ADD") = 1 ; no matter what, create new visit (Optional)
; IN ("NEVER ADD") = 1 ; never add visit, just try to find one or more (Optional)
; IN("ANCILLARY") = 1 ; for ancillary packages to create noon visit if no match found (Optional)
;
; Incoming Variables used in Matching: REQUIRED
; IN("PAT") = patient IEN (file 2 or 9000001)
; IN("VISIT DATE") = visit date & time (same as check-in date & time)
; IN ("SITE") = location of encounter IEN (file 4 or 9999999.06)
; IN("VISIT TYPE") = internal value for field .03 in Visit file
; IN("SRV CAT") = internal value for service category
; IN("TIME RANGE") = # ; range in minutes for matching on visit time; REQUIRED unless FORCE ADD set
; ; zero=exact matches only; -1=don't match on time
;
; These are used to match if sent (Optional)
; IN("PROVIDER") = IEN for provider to match from file 200
; IN("CLINIC CODE") = IEN of clinic stop code (file 40.7)
; IN("HOS LOC") = IEN of hospital location (file 44)
;
; Incoming Variables used in creating appt and visit
; IN("USR") = user IEN in file 200; REQUIRED
;
; Incoming PCC variables for adding additional info to visit (Optional)
; IN("APCDOLOC") = Outside Location (#2101)
;
; Outgoing Array:
; OUT(0) always set
; if = 0 none found and may have error message in 2nd piece
; if = 1 and OUT(visit ien)="ADD" new visit just created
; if = 1 and OUT(visit ien)=#; # is time difference in minutes
; if >1, multiple OUT(visit ien) entries exist
;
N TMP
K OUT
M TMP=IN ;don't mess with incoming array
Q:'$$HAVEREQ(.TMP,.OUT) ;check required fields
; if forced add, skip visit match attempt
I $G(TMP("FORCE ADD")) D ADDVIST(.TMP,.OUT) Q
; attempt to find matching visits; return OUT array
D MATCH(.TMP,.OUT)
; if appt date set, go to check-in
I $G(TMP("APPT DATE")),'$G(TMP("NEVER ADD")) D ADDVIST(.TMP,.OUT) Q
; if only 1 visit found, return ien and quit
; if >1 visits found, return full array and quit
Q:OUT(0)
; if called by ancillary package, just create noon visit and quit
I $G(TMP("ANCILLARY")) D Q
.K TMP("ANCILLARY"),TMP("PROVIDER") ; set up to find other ancillaries
.D MATCH(.TMP,.OUT)
.Q:OUT(0)=1 ; try to match on hos loc or clinic
.Q:$G(TMP("NEVER ADD"))=1 ; if in never add mode, quit after 2nd match
.S TMP("VISIT DATE")=TMP("VISIT DATE")\1 ; take off time; PCC will add noon
.D ADDVIST(.TMP,.OUT) ; create noon visit; no PIMS link
; if no visits found but in never add mode, just quit
Q:$G(TMP("NEVER ADD"))=1
; otherwise, logic falls through to create visit choices
D ADDVIST(.TMP,.OUT)
Q
; Check required fields
HAVEREQ(IN,OUT) ;
I ('$G(IN("FORCE ADD"))),('$D(IN("TIME RANGE"))) S OUT(0)="0^Missing Time Range" Q 0
I '$D(IN("PAT")) S OUT(0)="0^Missing Patient IEN" Q 0
I '$D(IN("VISIT DATE")) S OUT(0)="0^Missing Visit Date" Q 0
I IN("VISIT DATE")\1>DT S OUT(0)="0^Future Dates Not Allowed" Q 0
I '$D(IN("SITE")) S OUT(0)="0^Missing Facility/Site" Q 0
I '$D(IN("VISIT TYPE")) S OUT(0)="0^Missing Visit Type" Q 0
I '$D(IN("SRV CAT")) S OUT(0)="0^Missing Service Category" Q 0
I '$D(IN("USR")) S OUT(0)="0^Missing User IEN" Q 0
I $G(IN("HOS LOC")),'$G(IN("CLINIC CODE")) S IN("CLINIC CODE")=$$GET1^DIQ(44,IN("HOS LOC"),8,"I")
Q 1
; Set DATE and END based on TIME RANGE setting in minutes
TIME(RANGE,VISIT,DATE,END) ;
N TMDIF,SW
S TMDIF=$S(RANGE<1:0,1:RANGE)
S DATE=$$FMADD^XLFDT(VISIT,,,-TMDIF)
S END=$$FMADD^XLFDT(VISIT,,,TMDIF)
I (DATE\1)<(END\1) S SW=(END\1),END=(DATE\1)_".9999",DATE=SW
S DATE=(9999999-(DATE\1)_"."_$P(DATE,".",2))-.0001
S END=9999999-(END\1)_"."_$P(END,".",2)
I RANGE=-1 S END=END\1_".9999",DATE=DATE\1 ;no time range used; go from begin one day to end
Q
; Find matching visits based on IN array
; OUT(0)=# of visits found^optional error message
MATCH(IN,OUT) ;
N END,DATE,VIEN,STOP,DIFF
S OUT(0)=0
D TIME(IN("TIME RANGE"),IN("VISIT DATE"),.DATE,.END)
F S DATE=$O(^AUPNVSIT("AA",IN("PAT"),DATE)) Q:'DATE Q:(DATE>END) D
.S VIEN=0
.F S VIEN=$O(^AUPNVSIT("AA",IN("PAT"),DATE,VIEN)) Q:'VIEN D
..I $P($G(^AUPNVSIT(VIEN,0)),U,11) Q ;check for delete flag just in case xref not killed
..I IN("SITE")'=$$GET1^DIQ(9000010,VIEN,.06,"I") Q ;no match on loc of enc
..I IN("VISIT TYPE")'=$$GET1^DIQ(9000010,VIEN,.03,"I") Q ;no match on vist type
..I IN("SRV CAT")'=$$GET1^DIQ(9000010,VIEN,.07,"I") Q ;no match on service category
..I IN("TIME RANGE")>-1 S STOP=0 D Q:STOP ;check time range
...S DIFF=$$TIMEDIF(IN("VISIT DATE"),VIEN) ;find difference in minutes
...S:$$ABS^XLFMTH(DIFF)>IN("TIME RANGE") STOP=1
..Q:'$$PRVMTCH ; if provider sent and didn't match, skip
..;
..; if called by ancillary, falls through and sets visit into array
..; otherwise, check if app wants to match on clinic code or hosp location
..I '$G(IN("ANCILLARY")) S STOP=0 D Q:STOP
...I $G(IN("HOS LOC")),'$G(IN("CLINIC CODE")) S IN("CLINIC CODE")=$$GET1^DIQ(44,IN("HOS LOC"),8,"I")
...I $G(IN("CLINIC CODE")),IN("CLINIC CODE")'=$$GET1^DIQ(9000010,VIEN,.08,"I") S STOP=1 Q ;no match on clinic code
...I $G(IN("HOS LOC")),(IN("HOS LOC")'=$$GET1^DIQ(9000010,VIEN,.22,"I")) S STOP=1 Q ;no match on hospital location
..S OUT(0)=OUT(0)+1
..S OUT(VIEN)=$$TIMEDIF(IN("VISIT DATE"),VIEN)
Q
; Do visits match on provider?
PRVMTCH() ;
N PRVS,IEN
I '$G(IN("PROVIDER")) Q 1 ; if no provider sent, assume okay
; find all v provider entries for visit
S IEN=0
F S IEN=$O(^AUPNVPRV("AD",VIEN,IEN)) Q:'IEN D
.S PRVS(+$G(^AUPNVPRV(IEN,0)))=""
Q ''$D(PRVS(IN("PROVIDER")))
;
TIMEDIF(VDTTM,VIEN) ; return time difference between incoming time and current visit
Q $$FMDIFF^XLFDT(VDTTM,+$G(^AUPNVSIT(VIEN,0)),2)\60
; Create visit
ADDVIST(IN,OUT) ;
N VSIT,VSITPKG,DFN
S VSIT("VDT")=IN("VISIT DATE")
S VSIT("TYP")=IN("VISIT TYPE")
S VSIT("PAT")=IN("PAT")
S VSIT("INS")=IN("SITE")
S VSIT("SVC")=IN("SRV CAT")
S VSIT("DSS")=$G(IN("CLINIC CODE"))
S VSIT("LOC")=$G(IN("HOS LOC"))
S VSIT("USR")=IN("USR")
S VSIT("OPT")=$G(XQY)
S VSIT("VID")=$$GETVID^VSITVID
S:$D(IN("APCDOLOC")) VSIT("OUT")=IN("APCDOLOC")
S VSIT(0)="F"
S VSITPKG="CIAV"
S DFN=IN("PAT")
D ^VSIT
I $G(VSIT("IEN"))'>0 S OUT(0)="0^Could not create visit."
E S OUT(+VSIT("IEN"))="ADD",OUT(0)=1
Q
BEHOENC1 ;MSC/IND/DKM - Visit Creation Support ;16-Jul-2009 17:58;PLS
+1 ;;1.1;BEH COMPONENTS;**005004;20-Aug-2007 08:41
+2 ;=================================================================
+3 ; Visit creation API
GETVISIT(IN,OUT) ;
+1 ;
+2 ; >> All date/time variables must be in FileMan internal format
+3 ;
+4 ; Special Incoming Variables:
+5 ; IN("FORCE ADD") = 1 ; no matter what, create new visit (Optional)
+6 ; IN ("NEVER ADD") = 1 ; never add visit, just try to find one or more (Optional)
+7 ; IN("ANCILLARY") = 1 ; for ancillary packages to create noon visit if no match found (Optional)
+8 ;
+9 ; Incoming Variables used in Matching: REQUIRED
+10 ; IN("PAT") = patient IEN (file 2 or 9000001)
+11 ; IN("VISIT DATE") = visit date & time (same as check-in date & time)
+12 ; IN ("SITE") = location of encounter IEN (file 4 or 9999999.06)
+13 ; IN("VISIT TYPE") = internal value for field .03 in Visit file
+14 ; IN("SRV CAT") = internal value for service category
+15 ; IN("TIME RANGE") = # ; range in minutes for matching on visit time; REQUIRED unless FORCE ADD set
+16 ; ; zero=exact matches only; -1=don't match on time
+17 ;
+18 ; These are used to match if sent (Optional)
+19 ; IN("PROVIDER") = IEN for provider to match from file 200
+20 ; IN("CLINIC CODE") = IEN of clinic stop code (file 40.7)
+21 ; IN("HOS LOC") = IEN of hospital location (file 44)
+22 ;
+23 ; Incoming Variables used in creating appt and visit
+24 ; IN("USR") = user IEN in file 200; REQUIRED
+25 ;
+26 ; Incoming PCC variables for adding additional info to visit (Optional)
+27 ; IN("APCDOLOC") = Outside Location (#2101)
+28 ;
+29 ; Outgoing Array:
+30 ; OUT(0) always set
+31 ; if = 0 none found and may have error message in 2nd piece
+32 ; if = 1 and OUT(visit ien)="ADD" new visit just created
+33 ; if = 1 and OUT(visit ien)=#; # is time difference in minutes
+34 ; if >1, multiple OUT(visit ien) entries exist
+35 ;
+36 NEW TMP
+37 KILL OUT
+38 ;don't mess with incoming array
MERGE TMP=IN
+39 ;check required fields
IF '$$HAVEREQ(.TMP,.OUT)
QUIT
+40 ; if forced add, skip visit match attempt
+41 IF $GET(TMP("FORCE ADD"))
DO ADDVIST(.TMP,.OUT)
QUIT
+42 ; attempt to find matching visits; return OUT array
+43 DO MATCH(.TMP,.OUT)
+44 ; if appt date set, go to check-in
+45 IF $GET(TMP("APPT DATE"))
IF '$GET(TMP("NEVER ADD"))
DO ADDVIST(.TMP,.OUT)
QUIT
+46 ; if only 1 visit found, return ien and quit
+47 ; if >1 visits found, return full array and quit
+48 IF OUT(0)
QUIT
+49 ; if called by ancillary package, just create noon visit and quit
+50 IF $GET(TMP("ANCILLARY"))
Begin DoDot:1
+51 ; set up to find other ancillaries
KILL TMP("ANCILLARY"),TMP("PROVIDER")
+52 DO MATCH(.TMP,.OUT)
+53 ; try to match on hos loc or clinic
IF OUT(0)=1
QUIT
+54 ; if in never add mode, quit after 2nd match
IF $GET(TMP("NEVER ADD"))=1
QUIT
+55 ; take off time; PCC will add noon
SET TMP("VISIT DATE")=TMP("VISIT DATE")\1
+56 ; create noon visit; no PIMS link
DO ADDVIST(.TMP,.OUT)
End DoDot:1
QUIT
+57 ; if no visits found but in never add mode, just quit
+58 IF $GET(TMP("NEVER ADD"))=1
QUIT
+59 ; otherwise, logic falls through to create visit choices
+60 DO ADDVIST(.TMP,.OUT)
+61 QUIT
+62 ; Check required fields
HAVEREQ(IN,OUT) ;
+1 IF ('$GET(IN("FORCE ADD")))
IF ('$DATA(IN("TIME RANGE")))
SET OUT(0)="0^Missing Time Range"
QUIT 0
+2 IF '$DATA(IN("PAT"))
SET OUT(0)="0^Missing Patient IEN"
QUIT 0
+3 IF '$DATA(IN("VISIT DATE"))
SET OUT(0)="0^Missing Visit Date"
QUIT 0
+4 IF IN("VISIT DATE")\1>DT
SET OUT(0)="0^Future Dates Not Allowed"
QUIT 0
+5 IF '$DATA(IN("SITE"))
SET OUT(0)="0^Missing Facility/Site"
QUIT 0
+6 IF '$DATA(IN("VISIT TYPE"))
SET OUT(0)="0^Missing Visit Type"
QUIT 0
+7 IF '$DATA(IN("SRV CAT"))
SET OUT(0)="0^Missing Service Category"
QUIT 0
+8 IF '$DATA(IN("USR"))
SET OUT(0)="0^Missing User IEN"
QUIT 0
+9 IF $GET(IN("HOS LOC"))
IF '$GET(IN("CLINIC CODE"))
SET IN("CLINIC CODE")=$$GET1^DIQ(44,IN("HOS LOC"),8,"I")
+10 QUIT 1
+11 ; Set DATE and END based on TIME RANGE setting in minutes
TIME(RANGE,VISIT,DATE,END) ;
+1 NEW TMDIF,SW
+2 SET TMDIF=$SELECT(RANGE<1:0,1:RANGE)
+3 SET DATE=$$FMADD^XLFDT(VISIT,,,-TMDIF)
+4 SET END=$$FMADD^XLFDT(VISIT,,,TMDIF)
+5 IF (DATE\1)<(END\1)
SET SW=(END\1)
SET END=(DATE\1)_".9999"
SET DATE=SW
+6 SET DATE=(9999999-(DATE\1)_"."_$PIECE(DATE,".",2))-.0001
+7 SET END=9999999-(END\1)_"."_$PIECE(END,".",2)
+8 ;no time range used; go from begin one day to end
IF RANGE=-1
SET END=END\1_".9999"
SET DATE=DATE\1
+9 QUIT
+10 ; Find matching visits based on IN array
+11 ; OUT(0)=# of visits found^optional error message
MATCH(IN,OUT) ;
+1 NEW END,DATE,VIEN,STOP,DIFF
+2 SET OUT(0)=0
+3 DO TIME(IN("TIME RANGE"),IN("VISIT DATE"),.DATE,.END)
+4 FOR
SET DATE=$ORDER(^AUPNVSIT("AA",IN("PAT"),DATE))
IF 'DATE
QUIT
IF (DATE>END)
QUIT
Begin DoDot:1
+5 SET VIEN=0
+6 FOR
SET VIEN=$ORDER(^AUPNVSIT("AA",IN("PAT"),DATE,VIEN))
IF 'VIEN
QUIT
Begin DoDot:2
+7 ;check for delete flag just in case xref not killed
IF $PIECE($GET(^AUPNVSIT(VIEN,0)),U,11)
QUIT
+8 ;no match on loc of enc
IF IN("SITE")'=$$GET1^DIQ(9000010,VIEN,.06,"I")
QUIT
+9 ;no match on vist type
IF IN("VISIT TYPE")'=$$GET1^DIQ(9000010,VIEN,.03,"I")
QUIT
+10 ;no match on service category
IF IN("SRV CAT")'=$$GET1^DIQ(9000010,VIEN,.07,"I")
QUIT
+11 ;check time range
IF IN("TIME RANGE")>-1
SET STOP=0
Begin DoDot:3
+12 ;find difference in minutes
SET DIFF=$$TIMEDIF(IN("VISIT DATE"),VIEN)
+13 IF $$ABS^XLFMTH(DIFF)>IN("TIME RANGE")
SET STOP=1
End DoDot:3
IF STOP
QUIT
+14 ; if provider sent and didn't match, skip
IF '$$PRVMTCH
QUIT
+15 ;
+16 ; if called by ancillary, falls through and sets visit into array
+17 ; otherwise, check if app wants to match on clinic code or hosp location
+18 IF '$GET(IN("ANCILLARY"))
SET STOP=0
Begin DoDot:3
+19 IF $GET(IN("HOS LOC"))
IF '$GET(IN("CLINIC CODE"))
SET IN("CLINIC CODE")=$$GET1^DIQ(44,IN("HOS LOC"),8,"I")
+20 ;no match on clinic code
IF $GET(IN("CLINIC CODE"))
IF IN("CLINIC CODE")'=$$GET1^DIQ(9000010,VIEN,.08,"I")
SET STOP=1
QUIT
+21 ;no match on hospital location
IF $GET(IN("HOS LOC"))
IF (IN("HOS LOC")'=$$GET1^DIQ(9000010,VIEN,.22,"I"))
SET STOP=1
QUIT
End DoDot:3
IF STOP
QUIT
+22 SET OUT(0)=OUT(0)+1
+23 SET OUT(VIEN)=$$TIMEDIF(IN("VISIT DATE"),VIEN)
End DoDot:2
End DoDot:1
+24 QUIT
+25 ; Do visits match on provider?
PRVMTCH() ;
+1 NEW PRVS,IEN
+2 ; if no provider sent, assume okay
IF '$GET(IN("PROVIDER"))
QUIT 1
+3 ; find all v provider entries for visit
+4 SET IEN=0
+5 FOR
SET IEN=$ORDER(^AUPNVPRV("AD",VIEN,IEN))
IF 'IEN
QUIT
Begin DoDot:1
+6 SET PRVS(+$GET(^AUPNVPRV(IEN,0)))=""
End DoDot:1
+7 QUIT ''$DATA(PRVS(IN("PROVIDER")))
+8 ;
TIMEDIF(VDTTM,VIEN) ; return time difference between incoming time and current visit
+1 QUIT $$FMDIFF^XLFDT(VDTTM,+$GET(^AUPNVSIT(VIEN,0)),2)\60
+2 ; Create visit
ADDVIST(IN,OUT) ;
+1 NEW VSIT,VSITPKG,DFN
+2 SET VSIT("VDT")=IN("VISIT DATE")
+3 SET VSIT("TYP")=IN("VISIT TYPE")
+4 SET VSIT("PAT")=IN("PAT")
+5 SET VSIT("INS")=IN("SITE")
+6 SET VSIT("SVC")=IN("SRV CAT")
+7 SET VSIT("DSS")=$GET(IN("CLINIC CODE"))
+8 SET VSIT("LOC")=$GET(IN("HOS LOC"))
+9 SET VSIT("USR")=IN("USR")
+10 SET VSIT("OPT")=$GET(XQY)
+11 SET VSIT("VID")=$$GETVID^VSITVID
+12 IF $DATA(IN("APCDOLOC"))
SET VSIT("OUT")=IN("APCDOLOC")
+13 SET VSIT(0)="F"
+14 SET VSITPKG="CIAV"
+15 SET DFN=IN("PAT")
+16 DO ^VSIT
+17 IF $GET(VSIT("IEN"))'>0
SET OUT(0)="0^Could not create visit."
+18 IF '$TEST
SET OUT(+VSIT("IEN"))="ADD"
SET OUT(0)=1
+19 QUIT