Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: PXVWICE

PXVWICE.m

Go to the documentation of this file.
  1. PXVWICE ;ISP/LMT - ICE interface main routine ;Jun 06, 2019@07:59:57
  1. ;;1.0;PCE PATIENT CARE ENCOUNTER;**217**;Aug 12, 1996;Build 134
  1. ;
  1. ; Thanks to George Lilly for developing (and sharing) his prototype of the interface of VistA and ICE;
  1. ; it was instrumental in the development of this production version.
  1. ;
  1. ; TODO:
  1. ; - Create national Clinical Reminders and update Build Logic
  1. ; in PX ICE MESSAGE entries that call into GETREM^PXVWVMR
  1. ; to use national reminders.
  1. ; - Add code to SELECT^ORWPC to check if ICE cache has been validated today;
  1. ; and if not, task job to validate cache, and if necessary update cache
  1. ;
  1. ;
  1. RPC(PXRETURN,DFN,PXCHKCACHE,PXASYNC) ; Entry point for RPC
  1. ;
  1. ; Returns ICE recommendations
  1. ;
  1. ;Input:
  1. ; DFN - Patient (#2) IEN
  1. ; PXCHKCACHE - Use cached results, if available? 1=Yes; 0=No (default: 1)
  1. ; PXASYNC - Call ICE asynchronously? 1=Yes; 0=No; Handle; (default: 0)
  1. ; (See EN tag below for more info on asynchronous functionality).
  1. ;
  1. ;Returns:
  1. ; If Unsuccessful:
  1. ; 0) = X^Error Message
  1. ; Note: X can be one of the following values:
  1. ; 0: Cache is in middle of being built; check back later
  1. ; -1: Invalid input
  1. ; -2: Could not make SOAP call (e.g., URL not populated in 920.75, etc.)
  1. ; -3: HTTP call returned unsuccessful status code (i.e., Server returned status code other than 200)
  1. ; -4: Unable to process incoming message from ICE
  1. ; -5: Error during asynchronous process.
  1. ; -6: Interface is down/disabled
  1. ; n) = If SOAP call was unsuccessful, this will be the message returned by the ICE server.
  1. ;
  1. ; If Successful:
  1. ; 0) = 1 ^ Number of Lines
  1. ; n) = GRP ^ Vaccine Group Name ^ Group/CVX Code Recommended ^ Group/CVX Display Name ^ Earliest Recommended Date ^
  1. ; Overdue Date ^ Recommend Code ^ Recommend Display Name ^ Doses Remaining
  1. ; 1: GRP
  1. ; 2: Vaccine Group Name - This is the vaccine group for this recommendation
  1. ; 3: Group/CVX Code Recommended - Vaccine or vaccine group recommended.
  1. ; If a specific vaccine is recommended, this will be the CVX code, in the format C:CVX_Code.
  1. ; More commonly, this will be populated with the vaccine group, in the format G:Group_Name
  1. ; 4: Group/CVX Display Name - Display Name for CVX/Group in piece #3.
  1. ; 5: Recommended Date
  1. ; 6: Overdue Date
  1. ; 7: Earliest Date
  1. ; 8: Recommend Code (currently either RECOMMENDED, FUTURE_RECOMMENDED, CONDITIONALLY_RECOMMENDED, or NOT_RECOMMENDED)
  1. ; 9: Recommend Display Name
  1. ; 10: Doses Remaining
  1. ; n) = RSN ^ Reason Code ^ Reason Display Name
  1. ; Note: This is the reason(s) for the recommendation above.
  1. ; 1: RSN
  1. ; 2: Reason Code
  1. ; 3: Reason Display Name
  1. ; n) = HIST ^ V Immunization IEN ^ Immunization Name ^ Administered CVX Code ^ Admin date/time ^ Dose Number ^
  1. ; Component CVX Code ^ CVX Display Name ^ Validity Code ^ Validity Display Name
  1. ; 1: HIST
  1. ; 2: V Immunization IEN (#9000010.11 IEN)
  1. ; 3: Immunization Name (#9999999.14, #.01)
  1. ; 4: Administered CVX Code (#9999999.14, #.03)
  1. ; 5: Admin date/time
  1. ; 6: Dose Number
  1. ; 7: Component CVX Code (for combination vaccines, this can defer from the CVX administered)
  1. ; 8: CVX Display Name
  1. ; 9: Validity Code
  1. ; 10: Validity Display Name
  1. ; n) = HISTRSN ^ Reason Code ^ Reason Display Name
  1. ; Note: This is the reason(s) why the vaccine is valid, invalid or accepted.
  1. ; 1: HISTRSN
  1. ; 2: Reason Code
  1. ; 3: Reason Display Name
  1. ;
  1. N PXCNT,PXI,PXICEWEB,PXJ,PXK
  1. ;
  1. S PXRETURN=$NA(^TMP("PXICERPC",$J))
  1. K ^TMP("PXICERPC",$J)
  1. ;
  1. D EN(.PXICEWEB,$G(DFN),$G(PXCHKCACHE),$G(PXASYNC))
  1. ;
  1. S PXCNT=0
  1. ;
  1. S ^TMP("PXICERPC",$J,0)=$G(^TMP("PXICEWEB",$J,0))
  1. ;
  1. ; If Unsuccessful
  1. I $P(^TMP("PXICERPC",$J,0),U,1)<1 D Q
  1. . M ^TMP("PXICERPC",$J)=^TMP("PXICEWEB",$J)
  1. ;
  1. ; If Successful, flatten output
  1. S PXI=0
  1. F S PXI=$O(^TMP("PXICEWEB",$J,PXI)) Q:PXI="" D
  1. . S PXCNT=PXCNT+1
  1. . S ^TMP("PXICERPC",$J,PXCNT)="GRP^"_PXI_U_$G(^TMP("PXICEWEB",$J,PXI))
  1. . ;
  1. . S PXJ=""
  1. . F S PXJ=$O(^TMP("PXICEWEB",$J,PXI,"REASON",PXJ)) Q:PXJ="" D
  1. . . S PXCNT=PXCNT+1
  1. . . S ^TMP("PXICERPC",$J,PXCNT)="RSN^"_$G(^TMP("PXICEWEB",$J,PXI,"REASON",PXJ))
  1. . ;
  1. . S PXJ=""
  1. . F S PXJ=$O(^TMP("PXICEWEB",$J,PXI,"HISTORY",PXJ)) Q:PXJ="" D
  1. . . S PXCNT=PXCNT+1
  1. . . S ^TMP("PXICERPC",$J,PXCNT)="HIST^"_PXJ_U_$G(^TMP("PXICEWEB",$J,PXI,"HISTORY",PXJ))
  1. . . ;
  1. . . S PXK=""
  1. . . F S PXK=$O(^TMP("PXICEWEB",$J,PXI,"HISTORY",PXJ,"REASON",PXK)) Q:PXK="" D
  1. . . . S PXCNT=PXCNT+1
  1. . . . S ^TMP("PXICERPC",$J,PXCNT)="HISTRSN^"_$G(^TMP("PXICEWEB",$J,PXI,"HISTORY",PXJ,"REASON",PXK))
  1. ;
  1. S $P(^TMP("PXICERPC",$J,0),U,2)=PXCNT
  1. ;
  1. K ^TMP("PXICEWEB",$J)
  1. ;
  1. Q
  1. ;
  1. ;
  1. EN(PXRETURN,DFN,PXCHKCACHE,PXASYNC) ; Entry point for API
  1. ;
  1. ; Returns ICE recommendations
  1. ;
  1. ;Input:
  1. ; DFN - Patient (#2) IEN
  1. ; PXCHKCACHE - Use cached results, if available? 1=Yes; 0=No; (default: 1)
  1. ; PXASYNC - Call ICE asynchronously? 1=Yes; 0=No; Handle; (default: 0)
  1. ; When calling ICE asynchronously, first pass "1" as the PXASYNC argument.
  1. ; If cached results are available (AND PXCHKCACHE is set to 1),
  1. ; we will return them immediately.
  1. ; If cached results are not available (OR PXCHKCACHE is set to 0),
  1. ; we will task a job to call ICE, and return a handle to the calling
  1. ; process. This handle should be passed in as the PXASYNC paramater
  1. ; on future calls. The calling process should keep checking back to see
  1. ; if the ICE task completed. On these subsequent calls, the same arguments
  1. ; should be passed in as the original call, except that in the subsequent
  1. ; calls, the PXASYNC argument should be the "handle" returned in the original
  1. ; call.
  1. ;
  1. ;
  1. ;Returns:
  1. ;
  1. ; If called asynchronously (i.e., PXASYNC>0) AND a background task was queued (or is still running):
  1. ; @PXRETURN@(0)=0^Handle
  1. ; This "Handle" is a number >1 and should be passed in on future calls.
  1. ;
  1. ; If Unsuccessful:
  1. ; @PXRETURN@(0)=X^Error Message
  1. ; Note: X can be one of the following values:
  1. ; -1: Invalid input
  1. ; -2: Could not make SOAP call (e.g., URL not populated in 920.75, etc.)
  1. ; -3: HTTP call returned unsuccessful status code (i.e., Server returned status code other than 200)
  1. ; -4: Unable to process incoming message from ICE
  1. ; -5: Error during asynchronous process.
  1. ; -6: Interface is down/disabled
  1. ; @PXRETURN@(n)=If SOAP call was unsuccessful, this will be the message returned by the ICE server.
  1. ;
  1. ; If Successful:
  1. ; @PXRETURN@(0)=1
  1. ; @PXRETURN@(VaccineGroup)=Group/CVX Code Recommended ^ Group/CVX Display Name ^ Recommended Date ^ Overdue Date ^
  1. ; Earliest Date ^ Recommend Code ^ Recommend Display Name ^ Doses Remaining
  1. ; @PXRETURN@(VaccineGroup,"REASON",n)=Reason Code ^ Reason Display Name
  1. ; @PXRETURN@(VaccineGroup,"HISTORY",V_Imm_IEN)=Immunization Name ^ Administered CVX Code ^ Admin date/time ^
  1. ; Dose Number ^ Component CVX Code ^ CVX Display Name ^
  1. ; Validity Code ^ Validity Display Name
  1. ; @PXRETURN@(VaccineGroup,"HISTORY",V_Imm_IEN,"REASON",n)=Reason Code ^ Reason Display Name
  1. ;
  1. N PXCACHESTAT,PXCNT,PXDESC,PXHANDLE,PXRTN,PXSTALL,PXTASK,PXURL,PXVARS,PXVOTH
  1. ;
  1. S PXRETURN=$NA(^TMP("PXICEWEB",$J))
  1. K ^TMP("PXICEWEB",$J)
  1. K ^TMP("PXVWMSG",$J)
  1. S PXCNT=0
  1. ;
  1. ; TODO - if ICE is down, should we allow to return from cache if available?
  1. ; currently, if disabled, we dont check cache; but if unavailable, we check
  1. I $$CHKSTAT^PXVWSTAT()=0 D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-6^ICE interface is disabled"
  1. ;
  1. I $G(PXCHKCACHE)'?1(1"0",1"1") S PXCHKCACHE=1
  1. I $G(PXASYNC)="" S PXASYNC=0
  1. I PXASYNC>1 S PXHANDLE="PXVWICETMP-"_PXASYNC
  1. ;
  1. I '$G(DFN) D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-1^Missing DFN parameter"
  1. S PXURL=$$GETURL()
  1. I PXURL="" D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-2^Unable to determine default ICE server"
  1. ;
  1. ; Check asynchronous background task and quit
  1. I PXASYNC>1 D Q
  1. . D ASYNC(PXHANDLE,DFN,PXASYNC,PXCNT)
  1. . D LOGSTAT^PXVWSTAT(DFN)
  1. ;
  1. ; if synchronous, call ICE in this process
  1. I 'PXASYNC D CALLICE
  1. ;
  1. ; if asynchronous, call ICE in tasked process. Return handle to caller.
  1. I PXASYNC D
  1. . ;
  1. . ; Before tasking background process, check cache. If cache is
  1. . ; valid, return from cache and no need to task background job.
  1. . I PXCHKCACHE,$$EXIST^PXVWCCH(DFN) D Q:$G(PXCACHESTAT)=1
  1. . . D BLDVMR^PXVWVMR(DFN)
  1. . . I '$D(^TMP("PXVWMSG",$J)) D Q
  1. . . . S ^TMP("PXICEWEB",$J,PXCNT)="-2^Unable to generate outbound VMR message"
  1. . . . S PXCACHESTAT=1
  1. . . S PXCACHESTAT=$$CHKCACHE(DFN,0)
  1. . . K ^TMP("PXVWMSG",$J)
  1. . ;
  1. . I '$$CHKSTAT^PXVWSTAT() D Q
  1. . . S ^TMP("PXICEWEB",$J,PXCNT)="-6^ICE interface is down"
  1. . ;
  1. . ; Task process to call ICE
  1. . S PXHANDLE=$$HANDLE(DFN)
  1. . S PXRTN="CALLICE^PXVWICE"
  1. . S PXDESC="PCE Call ICE Engine (Immunizations)"
  1. . S PXVARS="PXCHKCACHE;PXURL;DFN;PXHANDLE"
  1. . S PXVOTH("ZTDTH")=$H
  1. . S PXTASK=$$NODEV^XUTMDEVQ(PXRTN,PXDESC,PXVARS,.PXVOTH)
  1. . ;
  1. . I $G(PXTASK)>0 D
  1. . . S ^XTMP(PXHANDLE,"STATUS")=0_U_PXTASK
  1. . . S ^TMP("PXICEWEB",$J,PXCNT)="0^"_$P(PXHANDLE,"-",2)
  1. . ;
  1. . I $G(PXTASK)=-1 D
  1. . . S ^TMP("PXICEWEB",$J,PXCNT)="-5^Error tasking asynchronous process."
  1. . . K ^XTMP(PXHANDLE)
  1. ;
  1. D LOGSTAT^PXVWSTAT(DFN)
  1. ;
  1. K ^TMP("PXVWMSG",$J)
  1. ;
  1. Q
  1. ;
  1. ;
  1. CHKCACHE(DFN,PXSTALL) ;Check Cache for DFN
  1. ;
  1. ; Requires vMR to already be created in ^TMP("PXVWMSG",$J)
  1. ;
  1. N PXCACHESTAT,PXI
  1. ;
  1. S PXCACHESTAT=$$STAT^PXVWCCH(DFN)
  1. ;
  1. I $G(PXSTALL),PXCACHESTAT=2 D
  1. . F PXI=1:1:40 D Q:PXCACHESTAT'=2
  1. . . H .5
  1. . . S PXCACHESTAT=$$STAT^PXVWCCH(DFN)
  1. ;
  1. I PXCACHESTAT'=1 Q PXCACHESTAT
  1. ;
  1. D LOAD^PXVWCCH(DFN)
  1. ;
  1. Q PXCACHESTAT
  1. ;
  1. ;
  1. ASYNC(PXHANDLE,DFN,PXASYNC,PXCNT) ;Check asynchronous background task
  1. ;
  1. N PXDT
  1. ;
  1. I '$D(^XTMP(PXHANDLE)) D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-5^Error during asynchronous process."
  1. ;
  1. I $P($G(^XTMP(PXHANDLE,1)),U,1)'=DFN D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-5^Error during asynchronous process. DFN does not match."
  1. ;
  1. S PXDT=$P($G(^XTMP(PXHANDLE,"DT")),U,1)
  1. I 'PXDT D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-5^Error during asynchronous process."
  1. ; if background task is running for more than 2 min, return error
  1. I $$HDIFF^XLFDT($H,PXDT,2)>120 D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-5^Error during asynchronous process. Process timed out."
  1. ;
  1. ; background task completed.
  1. I $P($G(^XTMP(PXHANDLE,"STATUS")),U,1)=1 D Q
  1. . M ^TMP("PXICEWEB",$J)=^XTMP(PXHANDLE,"ICE")
  1. . K ^XTMP(PXHANDLE)
  1. ;
  1. ; background task is still running
  1. I $P($G(^XTMP(PXHANDLE,"STATUS")),U,1)=0 D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="0^"_PXASYNC
  1. ;
  1. Q
  1. ;
  1. ;
  1. CALLICE ;
  1. ;
  1. ; ZEXCEPT: PXCHKCACHE,PXURL,DFN,PXHANDLE,ZTQUEUED,ZTREQ
  1. ;
  1. N PXCACHESTAT,PXCNT,PXNOW
  1. ;
  1. S ZTREQ="@"
  1. K ^TMP("PXICEWEB",$J)
  1. K ^TMP("PXVWMSG",$J)
  1. S PXNOW=$$NOW^XLFDT
  1. S PXCNT=0
  1. ;
  1. D BLDVMR^PXVWVMR(DFN)
  1. ;
  1. I '$D(^TMP("PXVWMSG",$J)) D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-2^Unable to generate outbound VMR message"
  1. . I $G(PXHANDLE)'="" D MOVERES(PXHANDLE)
  1. ;
  1. ; check cache
  1. I PXCHKCACHE D Q:$G(PXCACHESTAT)=1
  1. . S PXCACHESTAT=$$CHKCACHE(DFN,1) ;Check Cache for DFN
  1. . I PXCACHESTAT=1 D
  1. . . I $G(PXHANDLE)'="" D MOVERES(PXHANDLE)
  1. . . K ^TMP("PXVWMSG",$J)
  1. ;
  1. I '$$CHKSTAT^PXVWSTAT() D Q
  1. . S ^TMP("PXICEWEB",$J,PXCNT)="-6^ICE interface is down"
  1. . I $G(PXHANDLE)'="" D MOVERES(PXHANDLE)
  1. ;
  1. ; Set flag that cache is in middle of building
  1. D BLDNG^PXVWCCH(DFN)
  1. ;
  1. D EN^PXVWSOAP(PXURL) ; Call ICE
  1. ;
  1. ; if ICE call successfull, save output to cache
  1. I $P($G(^TMP("PXICEWEB",$J,0)),U,1)=1 D SAVE^PXVWCCH(DFN,PXNOW)
  1. ;
  1. ; Clear flag that cache is in middle of building
  1. D CLRBLDNG^PXVWCCH(DFN)
  1. ;
  1. ; if this is a background task, save output to XTMP
  1. I $G(PXHANDLE)'="" D MOVERES(PXHANDLE)
  1. ;
  1. K ^TMP("PXVWMSG",$J)
  1. ;
  1. Q
  1. ;
  1. ;
  1. MOVERES(PXHANDLE) ;
  1. M ^XTMP(PXHANDLE,"ICE")=^TMP("PXICEWEB",$J)
  1. S ^XTMP(PXHANDLE,"STATUS")=1
  1. K ^TMP("PXICEWEB",$J)
  1. Q
  1. ;
  1. ;
  1. HANDLE(DFN) ;Return a unique handle into ^XTMP
  1. ;
  1. N PXHANDLE,PXI,PXSUCCESS
  1. ;
  1. S PXI=$R(9999)+2
  1. S PXHANDLE="PXVWICETMP-"_PXI
  1. F D Q:$G(PXSUCCESS)
  1. . S PXSUCCESS=$$HANDLE2(PXHANDLE,DFN)
  1. . I $G(PXSUCCESS) Q
  1. . S PXI=PXI+1
  1. . S PXHANDLE="PXVWICETMP-"_PXI
  1. ;
  1. Q PXHANDLE
  1. ;
  1. HANDLE2(PXHANDLE,DFN) ;
  1. ;
  1. I $D(^XTMP(PXHANDLE)) Q 0
  1. ;
  1. L +^XTMP(PXHANDLE):DILOCKTM
  1. I '$T Q 0
  1. ;
  1. I $D(^XTMP(PXHANDLE)) L -^XTMP(PXHANDLE) Q 0
  1. ;
  1. S ^XTMP(PXHANDLE,0)=DT_".24^"_DT
  1. S ^XTMP(PXHANDLE,1)=DFN
  1. S ^XTMP(PXHANDLE,"STATUS")=0
  1. S ^XTMP(PXHANDLE,"DT")=$H
  1. ;
  1. L -^XTMP(PXHANDLE)
  1. ;
  1. Q 1
  1. ;
  1. ;
  1. GETURL() ; Get ICE Server URL
  1. ;
  1. N PXIEN,PXTMP
  1. ;
  1. S PXIEN=$$GET^XPAR("ALL","PX ICE WEB DEFAULT SERVER")
  1. ; If the value has not been set, then see if there is only one
  1. I 'PXIEN D
  1. . S PXTMP=$O(^PXV(920.75,0))
  1. . I $O(^PXV(920.75,PXTMP))'>0 S PXIEN=PXTMP
  1. I 'PXIEN Q ""
  1. Q $$GET1^DIQ(920.75,PXIEN,8)
  1. ;
  1. ;
  1. TESTICE() ; Test ICE Interface
  1. ; Returns:
  1. ; 1 - Success
  1. ; 0 - Fail
  1. ;
  1. N PXSUCCESS,PXURL
  1. ;
  1. S PXURL=$$GETURL()
  1. I PXURL="" Q 0
  1. ;
  1. K ^TMP("PXICEWEB",$J)
  1. K ^TMP("PXVWMSG",$J)
  1. ;
  1. D TESTVMR^PXVWVMR
  1. ;
  1. I '$D(^TMP("PXVWMSG",$J)) Q 0
  1. ;
  1. D EN^PXVWSOAP(PXURL) ; Call ICE
  1. ;
  1. S PXSUCCESS=0
  1. I $P($G(^TMP("PXICEWEB",$J,0)),U,1)=1 S PXSUCCESS=1
  1. ;
  1. K ^TMP("PXICEWEB",$J)
  1. K ^TMP("PXVWMSG",$J)
  1. ;
  1. Q PXSUCCESS