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 Nov 22, 2024@17:51:30 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