- DGAUDIT1 ; ISL/DKA - Dataset 1 of VAS VistA Audit Solution ; 03 Aug 2021 1:05 PM
- ;;5.3;Registration;**964,1097,1108,1120**;Aug 13, 1993;Build 6
- ;;Per VA Directive 6402, this routine should not be modified.
- ;
- ; Reference to ^VA(200 in ICR #1262
- ; Reference to FILE^DID in ICR #2052
- ; Reference to GETS^DIQ in ICR #2056
- ; Reference to ^DIA in ICR #2602
- ; Reference to ENCODE^XLFJSON in ICR #6682
- ; Reference to ^DD(9000001 in ICR #7187
- ; Reference to ^DIC in ICR #10006
- ; Reference to FILE^DICN in ICR #10009
- ; Reference to EN^DIQ1 in ICR #10015
- ; Reference to ^DIE in ICR #10018
- ; Reference to $$FMTH^XLFDT in ICR #10103
- ; Reference to $$FMTHL7^XLFDT in ICR #10103
- ; Reference to $$GETICN^MPIF001 in ICR #2701
- ;
- ; Local process variable DGAUDMAX NEWed in calling routine ^DGAUDIT
- ; Local process variable DGAUDSHUT NEWed in calling routine ^DGAUDIT
- ; Local process variable DGAUDSTOP NEWed in calling routine ^DGAUDIT
- ; Local process variable DGBATSIZE NEWed in calling routine ^DGAUDIT
- ; Local process variable DGDONE NEWed in calling routine ^DGAUDIT
- ;
- Q ; No entry from top
- ;
- ;
- NEWAUDEX ; Export newly added AUDIT (#1.1) records
- ; Loop through the File Numbers in ^DIA()
- ; If there's a Patient-Related File that doesn't exist in DG VAS EXPORT, ; FLS Changed VSRA TO VAS 3/16/2021
- ; then add a new record to that File and set the LAST RECORD EXPORTED to 0.
- ; Start with the next record following the LAST RECORD EXPORTED recorded in DG VAS EXPORT (#46.4) ; FLS Changed VSRA TO VAS 3/16/2021
- N AUDGREF,CNTREC,D,D0,DA,DD,DIC,DICR,DIE,DIU,DIV,DO,DR,DTOUT,DUOUT,FILENUM,GREF,IEN,REC,RECDATA,DGABORT
- N VD,VM,X,Y,DGSEC,DGSTOPFLG,DGDEBUGON
- L +^DGAUDIT1(0):1 Q:'$T
- S DGDEBUGON=$$GET^XPAR("ALL","DG VAS DEBUGGING FLAG") ; Changed XPAR names from VSRA to VAS 3/17/21
- S AUDGREF=$NA(^DIA),GREF=$NA(^DGAUDIT1)
- S (CNTREC,FILENUM,DGABORT)=0
- F S FILENUM=$O(@AUDGREF@(FILENUM)) Q:'FILENUM!$G(DGAUDSTOP)!'$G(DGAUDSHUT)!$$S^%ZTLOAD!$G(DGDONE)!$G(DGABORT) D
- . S DGAUDSHUT=$$GET1^DIQ(46.5,1,.02,"I") ; Check send switch. NEWed in DGAUDIT
- . N LASTDIA,RECDATA,SWITCHDT,EXPRTIEN,RECDATE
- . S LASTDIA=$$GET1^DIQ(1.1,FILENUM,.03) Q:(LASTDIA<1)
- . Q:'$$PATREL(FILENUM)
- . K DIC S DIC="^DGAUDIT1(",X=FILENUM D ^DIC D:Y<1 Q:Y'>0
- . . K DIC S DIC="^DGAUDIT1(",DIC(0)="",DIC("DR")=".02///0;.04///"_$$NOW^XLFDT,X=FILENUM D FILE^DICN
- . ; Y now contains the IEN of DG AUDIT EXPORT, whether newly created or not.
- . S EXPRTIEN=+Y S REC=+$$GET1^DIQ(46.4,EXPRTIEN,.02) S:'REC REC=$O(@AUDGREF@(FILENUM,+LASTDIA),-1) S:'REC REC=LASTDIA
- . ; If the REC is not in the AUDIT file, reset the REC to the next-to-last IEN in the AUDIT file.
- . I '$D(@AUDGREF@(FILENUM,+REC,0)) S REC=$O(@AUDGREF@(FILENUM,+LASTDIA),-1) Q:'REC
- . ; If starting record isn't already set to the last record in ^DIA, and the record's audit date is prior to the switch date, reset REC to last IEN in the AUDIT file.
- . I REC'=LASTDIA S RECDATA=$G(@AUDGREF@(FILENUM,REC,0)),RECDATE=$P(RECDATA,"^",2),SWITCHDT=$P($G(^DGAUDIT1(EXPRTIEN,0)),"^",4) D Q:'REC
- .. I SWITCHDT'?7N.E S SWITCHDT=$$NOW^XLFDT N DGFDA,DGFILERR S DGFDA(46.4,EXPRTIEN_",",.04)=SWITCHDT D FILE^DIE(,"DGFDA","DGFILERR")
- .. Q:RECDATE>SWITCHDT ; Record's audit date is after send switch date, use this record
- .. S RECDATE=0 F Q:$G(RECDATE) S REC=$O(^DIA(FILENUM,REC)) Q:'REC D Q:'REC ; Find next audit record
- ... S RECDATA=$G(@AUDGREF@(FILENUM,REC,0)),RECDATE=$P(RECDATA,"^",2)
- ... I SWITCHDT?7N.E,(RECDATE<SWITCHDT) S RECDATE="" Q ; Check audit date, quit and move to next record if before send switch date
- ... S REC=$O(^DIA(FILENUM,REC),-1) ; Found audit date>send switch date, set REC=previous record ($O will start with this record)
- . F S REC=$O(@AUDGREF@(FILENUM,REC)) Q:'REC!$G(DGAUDSTOP)!'$G(DGAUDSHUT)!$G(DGABORT)!(REC>LASTDIA) D
- .. S DGAUDSHUT=$$GET1^DIQ(46.5,1,.02,"I") ; Check send switch. NEWed in DGAUDIT
- .. S CNTREC=CNTREC+($$FMAUD(FILENUM,REC)>0)
- .. K DIC S DIC="^DGAUDIT1(",X=FILENUM D ^DIC
- .. K DIE,DR,DA S DIE=46.4,DA=+Y,DR=".02///"_REC_";.03///"_$TR($G(@AUDGREF@(FILENUM,REC,0)),U,"%") D ^DIE
- .. I $$PENDING>(DGAUDMAX/4) D EXPORT3^DGAUDIT(.DGABORT) ; If queue is more than 25% full, clear it out by sending all queued records
- .. S:$$FROZEN^DGAUDIT(70) DGABORT=1 ; Queue should be empty now - if queue remains more than 70% full, there's a problem.
- . I DGDEBUGON D
- .. D DBEMAIL("NEWAUDEX^DGAUDIT1")
- .. S DGDEBUGON=0
- .. D EN^XPAR("SYS","DG VAS DEBUGGING FLAG",1,DGDEBUGON) ; Turn debug mode off. ; Changed XPAR names from VSRA to VAS 3/17/21
- . I $$PENDING>+$G(DGBATSIZE) D EXPORT3^DGAUDIT(.DGABORT) ; Clear out queue by sending all records for file FILENUM from ^DIA
- . S:$$FROZEN^DGAUDIT(70) DGABORT=1 ; Queue should be empty now - if queue remains more than 70% full, there's a problem.
- L -^DGAUDIT1(0)
- Q
- ;
- FMAUD(FILENUM,AUDIEN) ; Send the data for a given AUDIT (#1.1) record
- N AUDARR,JSON,C,DA,DATETIME,DIA,DIC,DIQ,DR,ERR,FILEDATA,N,X,DGVARR,DGVDATA,DGVDFN,DGVDUZ,DGVREF,DGVMSG,DGVOFFN,DGVINST,DGAUDSTANUM,DGMVI,DGCTRL,DCCI
- S:'$G(DGAUDMAX) DGAUDMAX=$$GET^XPAR("ALL","DG VAS MAX QUEUE ENTRIES")
- Q:$$PENDING'<DGAUDMAX
- S DIA=FILENUM ; This is a special variable used for accessing AUDIT entries
- S DIC="^DIA(DIA,",DA=AUDIEN,DIQ="DGVDATA"
- ; Get the fields for which we want both Internal and External values
- S DIQ(0)="IEN",DR=".02;.04;4.1"
- D EN^DIQ1
- I '$D(DGVDATA) Q -1
- ;
- S DGVREF=$NA(@$Q(DGVDATA),2)
- S DIQ(0)="N" ; DICMX allows the lookup on Field 2.14 without <UNDEFINED>
- S DR=".01;.03;.05;.06;1;1.1;2;2.1;2.2;2.9;3;3.1;3.2;4.2"
- D EN^DIQ1
- F DCCI=0:1:31 S DGCTRL=$G(DGCTRL)_$c(DCCI) ; Build string of non-printable control characters
- F DCCI=127:1:159 S DGCTRL=$G(DGCTRL)_$c(DCCI)
- ;
- ; If the AUDIT File can't identify the Patient,
- ; Then see if the Field being changed is the .01 Field and has an Old Value but a blank New Value
- ; and the Field Type is a Pointer to the PATIENT File (#2) or the PATIENT/IHS File (#9000001),
- ; and if so, then set the Patient value to the DFN from the OLD VALUE field.
- ; If we still don't have a Patient, then Quit.
- ;
- I $G(@DGVREF@(2.9))="",$G(@DGVREF@(.03))=".01",$G(@DGVREF@(2.2))["P2'"!($G(@DGVREF@(2.2))["P9000001'"),$G(@DGVREF@(3))="<deleted>" S @DGVREF@(2.9)=$G(@DGVREF@(2.1))
- I $G(@DGVREF@(2.9))="" Q -2
- I $$ANON($G(@DGVREF@(.04,"I"))) Q 0
- S DGVARR=$NA(AUDARR("data","HEADER"))
- S DGVDFN=$G(@DGVREF@(2.9))
- ; These are the additional fields that we want to send with each record to the Audit Solution
- S DATETIME=$G(@DGVREF@(.02,"I"))
- I DATETIME'="" D
- . S @DGVARR@("DateTime")=$$FMTHL7^XLFDT(DATETIME)
- . ;S @DGVARR@("Week")=$SYSTEM.SQL.WEEK(+$$FMTH^XLFDT(DATETIME))
- . ;S @DGVARR@("Year")=$SYSTEM.SQL.YEAR(+$$FMTH^XLFDT(DATETIME))
- . S @DGVARR@("Week")=$$WEEK^DGAUDIT1($P(DATETIME,"."))
- . S @DGVARR@("Year")=+$$FMTE^XLFDT(DATETIME,7)
- S @DGVARR@("RequestType")=$S($G(@DGVREF@(.05))="Added Record":"CREATE",$G(@DGVREF@(.03))=.01&($G(@DGVREF@(3))="<deleted>"):"DELETE",1:"UPDATE")
- S @DGVARR@("SchemaType")="FMAUDIT"
- S DGVARR=$NA(AUDARR("data","HEADER","Patient"))
- S @DGVARR@("DFN")=$TR(DGVDFN,DGCTRL)
- S DGMVI=$$GETICN^MPIF001(DGVDFN),DGMVI=$S(DGMVI>0:DGMVI,1:"")
- S @DGVARR@("MVI")=$TR(DGMVI,DGCTRL)
- S @DGVARR@("PatientName")=$TR($$GET1^DIQ(2,DGVDFN,.01),DGCTRL)
- S @DGVARR@("SSN")=$TR($$GET1^DIQ(2,DGVDFN,.09),DGCTRL)
- S @DGVARR@("INITPLUS4")=$TR($$GET1^DIQ(2,DGVDFN,.0905),DGCTRL)
- S @DGVARR@("DOB")=$TR($$FMTHL7^XLFDT($$GET1^DIQ(2,DGVDFN,.03,"I")),DGCTRL)
- ;
- S DGVARR=$NA(AUDARR("data","HEADER","User"))
- S (DGVDUZ,@DGVARR@("DUZ"))=$TR($G(@DGVREF@(.04,"I")),DGCTRL)
- S @DGVARR@("UID")=$TR($$GET1^DIQ(200,$G(@DGVREF@(.04,"I")),205.4),DGCTRL)
- S @DGVARR@("UserName")=$TR($G(@DGVREF@(.04,"E")),DGCTRL)
- S @DGVARR@("Title")=$TR($$GET1^DIQ(200,$G(@DGVREF@(.04,"I")),8),DGCTRL)
- ;
- S DGVARR=$NA(AUDARR("data","HEADER","Location"))
- S:DGVDUZ'="" DGVINST=$O(^VA(200,DGVDUZ,2,"AX1",1,"")) ; Get User's Default Division
- S:$G(DGVINST)="" DGVINST=$$GET1^DIQ(8989.3,1,217,"I") ; Default Institution
- S DGVOFFN=$TR($$GET1^DIQ(4,DGVINST,100),DGCTRL) ; Official VA Name
- S @DGVARR@("Site")=$S(DGVOFFN'="":$TR(DGVOFFN,DGCTRL),1:$TR($$GET1^DIQ(8989.3,1,217),DGCTRL)) ; External value of the Default Institution
- S @DGVARR@("StationNumber")=$TR($$GET1^DIQ(4,DGVINST,99),DGCTRL) ; Station Number for the Default Institution
- ;
- S DGVARR=$NA(AUDARR("data","SCHEMA"))
- S @DGVARR@("FILE NUMBER")=FILENUM
- D FILE^DID(FILENUM,,"NAME","FILEDATA")
- S @DGVARR@("FILE NAME")=$G(FILEDATA("NAME"),"null")
- ; These are fields supplied by the AUDIT Data Dictionary (#1.1) that we have chosen to send.
- S @DGVARR@("RECORD ADDED")=$TR($G(@DGVREF@(.05),"null"),DGCTRL)
- S @DGVARR@("ACCESSED")=$TR($G(@DGVREF@(.06),"null"),DGCTRL)
- S @DGVARR@("FIELD NAME")=$TR($G(@DGVREF@(1.1),"null"),DGCTRL)
- S @DGVARR@("OLD VALUE")=$TR($G(@DGVREF@(2),"null"),DGCTRL)
- S @DGVARR@("NEW VALUE")=$TR($G(@DGVREF@(3),"null"),DGCTRL)
- S @DGVARR@("MENU OPTION USED")=$TR($G(@DGVREF@(4.1,"E"),"null"),DGCTRL)
- S @DGVARR@("PROTOCOL or OPTION USED")=$TR($G(@DGVREF@(4.2),"null"),DGCTRL)
- ;
- D PAYLOAD(.JSON,.AUDARR,DGVARR,FILENUM,AUDIEN)
- Q 1
- ;
- ;
- PAYLOAD(DATA,HDRDATA,DGVARR,FILENUM,AUDIEN) ; Take ARRAY and send it the Audit Solution
- Q:'$$GET1^DIQ(46.5,1,.02,"I") ; Audit flag blank/0=do not add to queue, 1=add to queue, 2=add to queue
- N DA,DO,DIC,X,Y,DGAUDECNT,LOCKED,DGFDA,DGNOWDTM,DGJSONID,JSONERR,DGAUDIEN,DGAUDJSON,TMPJSON,DGFMERR
- ;
- S DGNOWDTM=$$NOW^XLFDT
- S DGJSONID=+$G(FILENUM)_"."_+$G(AUDIEN)_"."_DGNOWDTM
- S DGAUDECNT="+1,"
- S DGVARR=$NA(HDRDATA("id"))
- S @DGVARR=DGJSONID ;DGNOWDTM_"."_$$HL7TFM^XLFDT($G(HDRDATA("data","HEADER","DateTime"))) ; Record ID - File 46.3 IEN_"."_FMDATETIME
- ;
- N DGSTATION,DGSITENAM,DGSITEIEN
- S DGVARR=$NA(HDRDATA("station"))
- S DGSTATION=$$STA^XUAF4($$KSP^XUPARAM("INST"))
- S @DGVARR=DGSTATION
- S DGVARR=$NA(HDRDATA("site"))
- S DGSITEIEN=$$FIND1^DIC(4,,"X",DGSTATION,"D")
- S DGSITENAM=$$GET1^DIQ(4,DGSITEIEN,.01)
- S @DGVARR=DGSITENAM
- ;
- D ENCODE^XLFJSON($NA(@DGVARR,0),"DGAUDJSON","JSONERR")
- I '$G(JSONERR) D DECODE^XLFJSON("DGAUDJSON","TMPJSON","JSONERR")
- ;
- S DGFDA(46.3,DGAUDECNT,.01)=DGNOWDTM
- S DGFDA(46.3,DGAUDECNT,.02)="UPDATE"
- S DGFDA(46.3,DGAUDECNT,.03)=$$HL7TFM^XLFDT($G(HDRDATA("data","HEADER","DateTime")))
- S DGFDA(46.3,DGAUDECNT,.04)=$G(HDRDATA("data","HEADER","Patient","DFN"))
- S DGFDA(46.3,DGAUDECNT,.05)=$G(HDRDATA("data","HEADER","User","DUZ"))
- S DGFDA(46.3,DGAUDECNT,.06)=$G(HDRDATA("data","SCHEMA","MENU OPTION USED"))
- S DGFDA(46.3,DGAUDECNT,.07)=$G(HDRDATA("data","SCHEMA","FILE NUMBER"))
- S DGFDA(46.3,DGAUDECNT,.08)=$G(HDRDATA("data","HEADER","Location","StationNumber"))
- S DGFDA(46.3,DGAUDECNT,1)=DGAUDJSON(1)
- ;
- I ($L($G(DGFDA(46.3,DGAUDECNT,1)))<30)!$G(JSONERR(0)) D Q
- . M DGFDA(46.3,DGAUDECNT,1)=HDRDATA
- . I $G(JSONERR(0)) S JSONERR=0 F S JSONERR=$O(JSONERR(JSONERR)) Q:'JSONERR S DGFDA(46.3,DGAUDECNT_",",1,"JSON ERROR",.999+JSONERR)=$G(JSONERR(JSONERR))
- . D BADJSON^DGAUDIT2(0,+$G(DGAUDKPX),.DGFDA)
- D UPDATE^DIE("S","DGFDA","DGAUDIEN","DGFMERR") S DGAUDIEN=$G(DGAUDIEN(1))
- I 'DGAUDIEN!'$L($G(^DGAUDIT(+DGAUDIEN,1))) D
- . M DGFDA(46.3,DGAUDECNT,1)=HDRDATA
- . I $D(DGFMERR("DIERR",1,"TEXT")) S DGFDA(46.3,DGAUDECNT,1,"JSON ERROR",1.999)="FileMan Filer Error: "_$G(DGFMERR("DIERR",1,"TEXT",1))
- . D BADJSON^DGAUDIT2(+$G(DGAUDIEN),+$G(DGAUDKPX),.DGFDA)
- Q
- ;
- PATREL(FILENUM) ; Return 1 if this is a patient-related File
- Q $D(^DD(2,0,"PT",FILENUM))>0!($D(^DD(9000001,0,"PT",FILENUM))>0)
- ;
- DBEMAIL(TAG) ; send email if debugging turned on
- N DGVOFFN,DGVDUZ,DGSUBJ,DGMSG,DGXMTO,DGGLO,DGGLB,DGXMINSTR,DGVINST,DGSITE,DGAUDSTANUM,DGNOW,DGEMAIL ; JPN ADDED 03/31/21
- N DGSQ,DGSUB,DGVAR,Y,%,DGINST
- S DGNOW=$$FMTE^XLFDT($$NOW^XLFDT)
- S DGVDUZ=$G(DUZ)
- S:DGVDUZ'="" DGVINST=$O(^VA(200,DGVDUZ,2,"AX1",1,"")) ; Get User's Default Division
- S DGAUDSTANUM=$$STA^XUAF4($$KSP^XUPARAM("INST"))
- D F4^XUAF4(DGAUDSTANUM,.DGINST)
- S DGSITE=$G(DGINST("VA NAME"))
- S DGSUBJ=TAG_" sent from "_$G(DGSITE)_" - "_$G(DGAUDSTANUM)
- S DGSUBJ=$E(DGSUBJ,1,65)
- S DGMSG(2)=""
- S DGMSG(3)=" Name: "_$G(DGSITE)
- S DGMSG(4)=" Station#: "_+$$STA^XUAF4($$KSP^XUPARAM("INST"))
- S DGMSG(5)=" Domain: "_$G(^XMB("NETNAME"))
- S DGMSG(6)=" Date/Time: "_DGNOW
- S DGMSG(7)=" By: "_$P($G(^VA(200,DUZ,0)),U,1)
- S DGMSG(8)=""
- S DGMSG(9)=""
- S DGSQ=9
- S %="" F S %=$O(@%) Q:%="" S DGSQ=$G(DGSQ)+1,DGMSG(DGSQ)=%_"="_$G(@%)
- ;Copy mesage to OIT team?
- S DGXMTO(DUZ)=""
- S DGEMAIL=$$GET^XPAR("ALL","DG VAS MONITOR GROUP") ;JPN ADDED 3/31/21
- S DGXMTO("G."_DGEMAIL)="" ;JPN ADDED 3/31/21
- S DGXMINSTR("FROM")="noreply.domain.ext"
- ;
- D SENDMSG^XMXAPI(DUZ,DGSUBJ,"DGMSG",.DGXMTO,.DGXMINSTR)
- Q:'$D(^TMP("XMERR",$J)) ; no email problems
- ;
- D MES^XPDUTL("MailMan reported a problem trying to send the notification message.")
- D MES^XPDUTL(" ")
- S (DGGLO,DGGLB)="^TMP(""XMERR"","_$J
- S DGGLO=DGGLO_")"
- F S DGGLO=$Q(@DGGLO) Q:DGGLO'[DGGLB D MES^XPDUTL(" "_DGGLO_" = "_$G(@DGGLO))
- D MES^XPDUTL(" ")
- Q
- ;
- ANON(DGDUZ) ; Check to see if the user fits the definition of an anoymous user
- ; Currently checking users with user types below
- N RTN,UNAME
- S RTN=0,UNAME=$$GET1^DIQ(200,DGDUZ,.01)
- I DGDUZ="" Q 1
- I $$ACTIVE^XUSAP(DGDUZ) D
- . ;I $SYSTEM.SQL.UPPER(UNAME)["ANONYMOUS" S RTN=1
- . I $$UP^XLFSTR(UNAME)["ANONYMOUS" S RTN=1
- . I $$USERTYPE^XUSAP(DGDUZ,"CONNECTOR PROXY") S RTN=1
- . I $$USERTYPE^XUSAP(DGDUZ,"APPLICATION PROXY") S RTN=1
- Q RTN
- ;
- WEEK(FMDATE) ; Accept Fileman Date, Return Week
- N DAYOFYR,YRBEGDOW,YRBEG,WEEK
- S WEEK=""
- Q:'$G(FMDATE) ""
- S FMDATE=$P(FMDATE,".") Q:'(FMDATE?7N) ""
- S YRBEG=$E(FMDATE,1,3)_"0101"
- S YRBEGDOW=$$DOW^XLFDT(YRBEG,1)
- S DAYOFYR=$$FMDIFF^XLFDT(FMDATE,$$FMADD^XLFDT(YRBEG+(6-YRBEGDOW))) ; Partial Week at beginning of year - add 1 to week below
- S WEEK=(DAYOFYR/7)+1 S WEEK=$S($P(WEEK,".",2):WEEK\1+1,1:WEEK)
- I (WEEK>53)!(WEEK<1) S WEEK=""
- Q WEEK
- ;
- ESCAPE(INPUT) ; Escape XML characters from INPUT
- N ESCHAR,ESCAPED,CHAR,CHARARY,POS
- S INPUT=$G(INPUT),ESCAPED=""
- F CHAR="':'","&:&","<:<",">:>" S CHARARY($P(CHAR,":"))=$P(CHAR,":",2)
- F POS=1:1:$L(INPUT) S CHAR=$E(INPUT,POS) D
- .I $D(CHARARY(CHAR)) S ESCAPED=$G(ESCAPED)_CHARARY(CHAR) Q
- .S ESCAPED=$G(ESCAPED)_CHAR
- Q ESCAPED
- ;
- GETTEXT(ERRARRAY) ;
- ; @DESC Gets the error text from the array
- ;
- ; @ERRARRAY Error array stores error in format defined by web service product.
- ;
- ; @RETURNS Error info as a single string
- ;
- NEW DGAUD
- ;
- ; Loop through the text subscript of error array and concatenate
- SET DGAUD("errorText")=""
- SET DGAUD("I")=""
- FOR SET DGAUD("I")=$ORDER(ERRARRAY("text",DGAUD("I"))) QUIT:DGAUD("I")="" DO
- . SET DGAUD("errorText")=DGAUD("errorText")_ERRARRAY("text",DGAUD("I"))
- . QUIT
- ;
- QUIT DGAUD("errorText")
- ;
- ERRSPMSG(DGRESPERR,DGRESPETXT) ;
- ; Input : DGRESPERR (Required) - response error from Post call
- ; Return: response code/txt (ex: DGERR(400) from Init)_response code/msg (ex: ADDRVAL###)
- N DGERRCODE,DGEMSG
- S DGERRCODE=DGRESPERR.code
- DO ERR2ARR^XOBWLIB(.DGRESPERR,.DGRESPETXT)
- ; Example:
- ; S DGRESPETXT("errorType")="HTTP"
- ; S DGRESPETXT("statusLine")="HTTP/1.1 504 Gateway Timeout"
- ; S DGRESPETXT("text")=1
- ; S DGRESPETXT("text",1)={"message":"Unable to parse data. Not JSON format"}
- S DGEMSG=$G(DGRESPETXT("text",1))
- I DGEMSG="" S DGEMSG=DGRESPETXT("statusLine")
- S DGERR(DGERRCODE)=DGERRCODE_$S($L(DGEMSG)>1:DGEMSG,1:" VAS Service Error.")
- Q DGERR(DGERRCODE)
- ;
- PENDING() ; Return number of entries in queue
- N DGQIEN,DGQCNT
- S DGQCNT=0
- S DGQCNT=$P(^DGAUDIT(0),U,4)
- ;I ($G(DGQCNT)'>0),$O(^DGAUDIT(0)) S (DGQIEN,DGQCNT)=0 F S DGQIEN=$O(^DGAUDIT(DGQIEN)) Q:'DGQIEN
- S (DGQIEN,DGQCNT)=0 F DGQCNT=0:1 S DGQIEN=$O(^DGAUDIT(DGQIEN)) Q:'DGQIEN
- Q DGQCNT
- ;
- GENERR(DGAUDERR,DGALTSUB) ; General Error, DGAUDERR specific text
- N DGSRVID,DGSSLPORT,DGAUDNUM,DGAUDER2,DGAUDDATA
- S DGAUDER2=1
- S DGSRVID=$$FIND1^DIC(18.12,,"B","DG VAS WEB SERVER")
- S DGAUDER2(DGAUDER2)="Date/Time: "_$$FMTE^XLFDT($$NOW^XLFDT),DGAUDER2=DGAUDER2+1
- ; If SSL enabled PORT=$$GET1^DIQ(18.12,SRVID,3.03)
- S DGSSLPORT=$$GET1^DIQ(18.12,DGSRVID,3.03)
- I $G(DGSRVID) D
- . S DGAUDER2(DGAUDER2)="Error from DG VAS WEB SERVER: "_$$GET1^DIQ(18.12,DGSRVID,.04)_" on port: "_$S($G(DGSSLPORT):DGSSLPORT,1:$$GET1^DIQ(18.12,DGSRVID,.03))
- . S DGAUDER2=DGAUDER2+1
- . S DGAUDER2(DGAUDER2)="",DGAUDER2=DGAUDER2+1
- S DGAUDERR=0 F S DGAUDERR=$O(DGAUDERR(DGAUDERR)) Q:'DGAUDERR S DGAUDER2(DGAUDER2)=DGAUDERR(DGAUDERR),DGAUDER2=DGAUDER2+1
- D FILE^DID(46.3,,"ENTRIES","DGAUDDATA")
- S DGAUDNUM=$G(DGAUDDATA("ENTRIES"))
- S DGAUDER2(DGAUDER2)="",DGAUDER2=DGAUDER2+1
- S DGAUDER2(DGAUDER2)="The ^DGAUDIT global contains "_DGAUDNUM_" entr"_$S(DGAUDNUM=1:"y",1:"ies")_".",DGAUDER2=DGAUDER2+1
- S DGAUDER2(DGAUDER2)="The maximum number of entries in the queue is "_$$GET^XPAR("ALL","DG VAS MAX QUEUE ENTRIES")_".",DGAUDER2=DGAUDER2+1
- S DGAUDER2(DGAUDER2)="",DGAUDER2=DGAUDER2+1
- D SNDMSG^DGAUDIT(.DGAUDER2,,$G(DGALTSUB)) K DGAUDERR,DGAUDER2
- Q
- --- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HDGAUDIT1 17374 printed Apr 23, 2025@18:55:33 Page 2
- DGAUDIT1 ; ISL/DKA - Dataset 1 of VAS VistA Audit Solution ; 03 Aug 2021 1:05 PM
- +1 ;;5.3;Registration;**964,1097,1108,1120**;Aug 13, 1993;Build 6
- +2 ;;Per VA Directive 6402, this routine should not be modified.
- +3 ;
- +4 ; Reference to ^VA(200 in ICR #1262
- +5 ; Reference to FILE^DID in ICR #2052
- +6 ; Reference to GETS^DIQ in ICR #2056
- +7 ; Reference to ^DIA in ICR #2602
- +8 ; Reference to ENCODE^XLFJSON in ICR #6682
- +9 ; Reference to ^DD(9000001 in ICR #7187
- +10 ; Reference to ^DIC in ICR #10006
- +11 ; Reference to FILE^DICN in ICR #10009
- +12 ; Reference to EN^DIQ1 in ICR #10015
- +13 ; Reference to ^DIE in ICR #10018
- +14 ; Reference to $$FMTH^XLFDT in ICR #10103
- +15 ; Reference to $$FMTHL7^XLFDT in ICR #10103
- +16 ; Reference to $$GETICN^MPIF001 in ICR #2701
- +17 ;
- +18 ; Local process variable DGAUDMAX NEWed in calling routine ^DGAUDIT
- +19 ; Local process variable DGAUDSHUT NEWed in calling routine ^DGAUDIT
- +20 ; Local process variable DGAUDSTOP NEWed in calling routine ^DGAUDIT
- +21 ; Local process variable DGBATSIZE NEWed in calling routine ^DGAUDIT
- +22 ; Local process variable DGDONE NEWed in calling routine ^DGAUDIT
- +23 ;
- +24 ; No entry from top
- QUIT
- +25 ;
- +26 ;
- NEWAUDEX ; Export newly added AUDIT (#1.1) records
- +1 ; Loop through the File Numbers in ^DIA()
- +2 ; If there's a Patient-Related File that doesn't exist in DG VAS EXPORT, ; FLS Changed VSRA TO VAS 3/16/2021
- +3 ; then add a new record to that File and set the LAST RECORD EXPORTED to 0.
- +4 ; Start with the next record following the LAST RECORD EXPORTED recorded in DG VAS EXPORT (#46.4) ; FLS Changed VSRA TO VAS 3/16/2021
- +5 NEW AUDGREF,CNTREC,D,D0,DA,DD,DIC,DICR,DIE,DIU,DIV,DO,DR,DTOUT,DUOUT,FILENUM,GREF,IEN,REC,RECDATA,DGABORT
- +6 NEW VD,VM,X,Y,DGSEC,DGSTOPFLG,DGDEBUGON
- +7 LOCK +^DGAUDIT1(0):1
- if '$TEST
- QUIT
- +8 ; Changed XPAR names from VSRA to VAS 3/17/21
- SET DGDEBUGON=$$GET^XPAR("ALL","DG VAS DEBUGGING FLAG")
- +9 SET AUDGREF=$NAME(^DIA)
- SET GREF=$NAME(^DGAUDIT1)
- +10 SET (CNTREC,FILENUM,DGABORT)=0
- +11 FOR
- SET FILENUM=$ORDER(@AUDGREF@(FILENUM))
- if 'FILENUM!$GET(DGAUDSTOP)!'$GET(DGAUDSHUT)!$$S^%ZTLOAD!$G(DGDONE)!$GET(DGABORT)
- QUIT
- Begin DoDot:1
- +12 ; Check send switch. NEWed in DGAUDIT
- SET DGAUDSHUT=$$GET1^DIQ(46.5,1,.02,"I")
- +13 NEW LASTDIA,RECDATA,SWITCHDT,EXPRTIEN,RECDATE
- +14 SET LASTDIA=$$GET1^DIQ(1.1,FILENUM,.03)
- if (LASTDIA<1)
- QUIT
- +15 if '$$PATREL(FILENUM)
- QUIT
- +16 KILL DIC
- SET DIC="^DGAUDIT1("
- SET X=FILENUM
- DO ^DIC
- if Y<1
- Begin DoDot:2
- +17 KILL DIC
- SET DIC="^DGAUDIT1("
- SET DIC(0)=""
- SET DIC("DR")=".02///0;.04///"_$$NOW^XLFDT
- SET X=FILENUM
- DO FILE^DICN
- End DoDot:2
- if Y'>0
- QUIT
- +18 ; Y now contains the IEN of DG AUDIT EXPORT, whether newly created or not.
- +19 SET EXPRTIEN=+Y
- SET REC=+$$GET1^DIQ(46.4,EXPRTIEN,.02)
- if 'REC
- SET REC=$ORDER(@AUDGREF@(FILENUM,+LASTDIA),-1)
- if 'REC
- SET REC=LASTDIA
- +20 ; If the REC is not in the AUDIT file, reset the REC to the next-to-last IEN in the AUDIT file.
- +21 IF '$DATA(@AUDGREF@(FILENUM,+REC,0))
- SET REC=$ORDER(@AUDGREF@(FILENUM,+LASTDIA),-1)
- if 'REC
- QUIT
- +22 ; If starting record isn't already set to the last record in ^DIA, and the record's audit date is prior to the switch date, reset REC to last IEN in the AUDIT file.
- +23 IF REC'=LASTDIA
- SET RECDATA=$GET(@AUDGREF@(FILENUM,REC,0))
- SET RECDATE=$PIECE(RECDATA,"^",2)
- SET SWITCHDT=$PIECE($GET(^DGAUDIT1(EXPRTIEN,0)),"^",4)
- Begin DoDot:2
- +24 IF SWITCHDT'?7N.E
- SET SWITCHDT=$$NOW^XLFDT
- NEW DGFDA,DGFILERR
- SET DGFDA(46.4,EXPRTIEN_",",.04)=SWITCHDT
- DO FILE^DIE(,"DGFDA","DGFILERR")
- +25 ; Record's audit date is after send switch date, use this record
- if RECDATE>SWITCHDT
- QUIT
- +26 ; Find next audit record
- SET RECDATE=0
- FOR
- if $GET(RECDATE)
- QUIT
- SET REC=$ORDER(^DIA(FILENUM,REC))
- if 'REC
- QUIT
- Begin DoDot:3
- +27 SET RECDATA=$GET(@AUDGREF@(FILENUM,REC,0))
- SET RECDATE=$PIECE(RECDATA,"^",2)
- +28 ; Check audit date, quit and move to next record if before send switch date
- IF SWITCHDT?7N.E
- IF (RECDATE<SWITCHDT)
- SET RECDATE=""
- QUIT
- +29 ; Found audit date>send switch date, set REC=previous record ($O will start with this record)
- SET REC=$ORDER(^DIA(FILENUM,REC),-1)
- End DoDot:3
- if 'REC
- QUIT
- End DoDot:2
- if 'REC
- QUIT
- +30 FOR
- SET REC=$ORDER(@AUDGREF@(FILENUM,REC))
- if 'REC!$GET(DGAUDSTOP)!'$GET(DGAUDSHUT)!$GET(DGABORT)!(REC>LASTDIA)
- QUIT
- Begin DoDot:2
- +31 ; Check send switch. NEWed in DGAUDIT
- SET DGAUDSHUT=$$GET1^DIQ(46.5,1,.02,"I")
- +32 SET CNTREC=CNTREC+($$FMAUD(FILENUM,REC)>0)
- +33 KILL DIC
- SET DIC="^DGAUDIT1("
- SET X=FILENUM
- DO ^DIC
- +34 KILL DIE,DR,DA
- SET DIE=46.4
- SET DA=+Y
- SET DR=".02///"_REC_";.03///"_$TRANSLATE($GET(@AUDGREF@(FILENUM,REC,0)),U,"%")
- DO ^DIE
- +35 ; If queue is more than 25% full, clear it out by sending all queued records
- IF $$PENDING>(DGAUDMAX/4)
- DO EXPORT3^DGAUDIT(.DGABORT)
- +36 ; Queue should be empty now - if queue remains more than 70% full, there's a problem.
- if $$FROZEN^DGAUDIT(70)
- SET DGABORT=1
- End DoDot:2
- +37 IF DGDEBUGON
- Begin DoDot:2
- +38 DO DBEMAIL("NEWAUDEX^DGAUDIT1")
- +39 SET DGDEBUGON=0
- +40 ; Turn debug mode off. ; Changed XPAR names from VSRA to VAS 3/17/21
- DO EN^XPAR("SYS","DG VAS DEBUGGING FLAG",1,DGDEBUGON)
- End DoDot:2
- +41 ; Clear out queue by sending all records for file FILENUM from ^DIA
- IF $$PENDING>+$G(DGBATSIZE)
- DO EXPORT3^DGAUDIT(.DGABORT)
- +42 ; Queue should be empty now - if queue remains more than 70% full, there's a problem.
- if $$FROZEN^DGAUDIT(70)
- SET DGABORT=1
- End DoDot:1
- +43 LOCK -^DGAUDIT1(0)
- +44 QUIT
- +45 ;
- FMAUD(FILENUM,AUDIEN) ; Send the data for a given AUDIT (#1.1) record
- +1 NEW AUDARR,JSON,C,DA,DATETIME,DIA,DIC,DIQ,DR,ERR,FILEDATA,N,X,DGVARR,DGVDATA,DGVDFN,DGVDUZ,DGVREF,DGVMSG,DGVOFFN,DGVINST,DGAUDSTANUM,DGMVI,DGCTRL,DCCI
- +2 if '$GET(DGAUDMAX)
- SET DGAUDMAX=$$GET^XPAR("ALL","DG VAS MAX QUEUE ENTRIES")
- +3 if $$PENDING'<DGAUDMAX
- QUIT
- +4 ; This is a special variable used for accessing AUDIT entries
- SET DIA=FILENUM
- +5 SET DIC="^DIA(DIA,"
- SET DA=AUDIEN
- SET DIQ="DGVDATA"
- +6 ; Get the fields for which we want both Internal and External values
- +7 SET DIQ(0)="IEN"
- SET DR=".02;.04;4.1"
- +8 DO EN^DIQ1
- +9 IF '$DATA(DGVDATA)
- QUIT -1
- +10 ;
- +11 SET DGVREF=$NAME(@$QUERY(DGVDATA),2)
- +12 ; DICMX allows the lookup on Field 2.14 without <UNDEFINED>
- SET DIQ(0)="N"
- +13 SET DR=".01;.03;.05;.06;1;1.1;2;2.1;2.2;2.9;3;3.1;3.2;4.2"
- +14 DO EN^DIQ1
- +15 ; Build string of non-printable control characters
- FOR DCCI=0:1:31