RORUTL02 ;HCIOFO/SG - UTILITIES ;8/25/05 10:20am
;;1.5;CLINICAL CASE REGISTRIES;**21,27,31,33,34**;Feb 17, 2006;Build 45
;
;******************************************************************************
;******************************************************************************
; --- ROUTINE MODIFICATION LOG ---
;
;PKG/PATCH DATE DEVELOPER MODIFICATION
;----------- ---------- ----------- ----------------------------------------
;ROR*1.5*27 FEB 2015 T KOPP Changed LOCKREG entry point to loop thru
; registries to lock only 15 at a time to
; prevent maxstring errors when lock
; command is executed.
;ROR*1.5*31 MAY 2017 M FERRARESE Adding PACT and PCP as additional identifiers.
;ROR*1.5*33 MAY 2017 F TRAXLER Added FUTAPPT subroutine.
;ROR*1.5*34 SEP 2018 F TRAXLER Modified FUTAPPT subroutine.
;******************************************************************************
;
; This routine uses the following IAs:
;
; #2701 $$GETICN^MPIF001 Gets ICN (supported)
; $$IFLOCAL^MPIF001 (checks for local ICN) (supported)
; #3556 $$GCPR^LA7QRY
; #3557 Access to the field .01 and x-ref "B"
; of the file 95.3
; #3646 $$EMPL^DGSEC4
; #10035 Access to the field #.09 of the file #2
;
Q
;
;***** REMOVES THE INACTIVE REGISTRIES FROM THE LIST
;
; .REGLST( A list of registry names (as subscripts)
; RegName) Registry IEN (output)
;
; Return values:
; <0 Error code
; 0 Ok
;
; This function removes names of those registries that are
; inactive or cannot be updated for any other reasons from
; the list. It also associates registry IENs with the names
; of registries remaining on the list.
;
; Moreover, it records corresponding messages about skipped
; registries to the current open log.
;
ARLST(REGLST) ;
N INFO,RC,REGIEN,REGNAME,RORBUF,TMP K DSTLST
S REGNAME="",RC=0
F S REGNAME=$O(REGLST(REGNAME)) Q:REGNAME="" D Q:RC<0
. S REGIEN=$$REGIEN(REGNAME,"@;11I;21.05I",.RORBUF)
. ;--- Cannot find (or load) the registry parameters
. I REGIEN'>0 D Q
. . D ERROR^RORERR(REGIEN,,REGNAME)
. . K REGLST(REGNAME)
. ;--- Check if the registry is marked as 'inactive'
. I $G(RORBUF("DILIST","ID",1,11)) D Q
. . D ERROR^RORERR(-48,,,,REGNAME)
. . K REGLST(REGNAME)
. ;--- Check if the registry has not been populated
. I '$G(RORBUF("DILIST","ID",1,21.05)),'$G(RORPARM("SETUP")) D Q
. . D TEXT^RORTXT(7980000.02,.INFO)
. . D ERROR^RORERR(-103,,.INFO,,REGNAME)
. . K INFO,REGLST(REGNAME)
. ;--- Store the registry IEN
. S REGLST(REGNAME)=REGIEN
Q RC
;
;***** RETURNS A FULL NATIONAL ICN OF THE PATIENT
;
; PTIEN Patient IEN
;
; Return Values:
; <0 Error code
; "" ICN has not been assigned or ICN is a local ICN
; >0 Patient National ICN
;
ICN(PTIEN) ;
N ICN,L,TMP
I $$IFLOCAL^MPIF001(PTIEN) Q ""
S ICN=$$GETICN^MPIF001(PTIEN)
I ICN'>0 D Q ""
. S TMP=$$ERROR^RORERR(-57,,$P(ICN,U,2),PTIEN,+ICN,"$$GETICN^MPIF001")
;--- Validate the checksum (just in case ;-)
S L=$L($P(ICN,"V",2))
Q $S(L<6:$P(ICN,"V")_"V"_$E("000000",1,6-L)_$P(ICN,"V",2),1:ICN)
;
PACT(DFN) ;returns ien & name of pc team PATCH 30
; DFN - pointer to patient file
; Date of interest (Default=DT)
;
Q $P($$OUTPTTM^SDUTL3(DFN,DT),U,2)
;
PCP(DFN) ;returns ien & name of pract filling pc position PATCH 30
; DFN - pointer to patient file
; DATE - date of interest
; PCROLE - Practitioner Position where '1' = PC provider ; '2' = PC attending
; '3' = PC associate provider
;
; returns (ien^name), or "" if none or -1 if error
;
;
Q $P($$OUTPTPR^SDUTL3(DFN,DT,1),"^",2)
;
FUTAPPT(DFN,DAYS) ; PATCH 33
N RORAPPTDT,RORAPPTCNE,VASD
I $D(DAYS) D
.N X,X1,X2
.D NOW^%DTC S (VASD("F"),X1)=X,X2=DAYS D C^%DTC S VASD("T")=X
.S VASD("W")="1"
.D SDA^VADPT
I $D(^UTILITY("VASD",$J)) D Q RORAPPTDT_U_RORAPPTCNE ;patch 34 change
.S RORAPPTDT=$$DATE^RORXU002($P($G(^UTILITY("VASD",$J,1,"I")),U,1)\1) ;appt d/t
.S RORAPPTCNE=$P($G(^UTILITY("VASD",$J,1,"E")),U,2) ;appt clinic name (external)
;I $D(^UTILITY("VASD",$J)) Q $$DATE^RORXU002($P($G(^UTILITY("VASD",$J,1,"I")),"^",1)\1) ;patch 33 code
Q 0
;***** LOADS THE LAB RESULTS
;
; PTIEN Patient IEN
;
; SDT Start date of the results
; EDT End date of the results
;
; [ROR8DST] Closed root of the destination array
; (the ^TMP("RORTMP",$J) node, by default)
;
; Return values:
; <0 Error code
; 0 Ok
;
LABRSLTS(PTIEN,SDT,EDT,ROR8DST) ;
N H7CH,RC,RORMSG,TMP
S:$G(ROR8DST)="" ROR8DST=$NA(^TMP("RORTMP",$J))
K @ROR8DST
I $D(RORLRC)<10 Q:$G(RORLRC)="" 0
;--- Get the Patient ID (ICN or SSN)
S PTID=$$PTID(PTIEN) Q:PTID<0 PTID
;--- Get the Lab data
S H7CH=$G(RORHL("FS"))_$G(RORHL("ECH"))
S RC=$$GCPR^LA7QRY(PTID,SDT,EDT,.RORLRC,"*",.RORMSG,ROR8DST,H7CH)
I RC="",$D(RORMSG)>1 D
. N ERR,I,LST
. S (ERR,LST)=""
. F I=1:1 S ERR=$O(RORMSG(ERR)) Q:ERR="" D
. . S LST=LST_","_ERR,TMP=RORMSG(ERR)
. . K RORMSG(ERR) S RORMSG(I)=TMP
. S LST=$P(LST,",",2,999) Q:(LST=3)!(LST=99)
. S RC=$$ERROR^RORERR(-27,,.RORMSG,PTIEN)
Q $S(RC<0:RC,1:0)
;
;***** RETURNS THE LOINC CODE WITH THE CONTROL DIGIT
;
; LNCODE LOINC code
;
; Besides adding a control digit to the LOINC code, the function
; checks the code against the LAB LOINC file (#95.3).
;
; Return values:
; <0 Error code
; >0 LOINC code with the control digit
;
LNCODE(LNCODE) ;
N RC,RORBUF,RORMSG
D FIND^DIC(95.3,,"@;.01E","X",$P(LNCODE,"-"),2,"B",,,"RORBUF","RORMSG")
Q:$G(DIERR) $$DBS^RORERR("RORMSG",-9,,,95.3)
I $G(RORBUF("DILIST",0))<1 D Q RC ; Non-existent code
. S RC=$$ERROR^RORERR(-29,,,,LNCODE)
I $G(RORBUF("DILIST",0))>1 D Q RC ; Duplicate records
. S RC=$$ERROR^RORERR(-30,,,,LNCODE)
Q RORBUF("DILIST","ID",1,.01)
;
;***** LOCK/UNLOCK REGISTRIES BEING PROCESSED
;
; .REGLST Reference to a local array containing registry names
; as subscripts and optional registry IENs as values
; [MODE] 0 - Unlock (default), 1 - Lock
; [TO] LOCK timeout (3 sec by defualt)
; [NAME] Name of the process/task
;
; Return Values:
; <0 Error code
; 0 Some of the registries has been locked by another job
; 1 Ok
;
LOCKREG(REGLST,MODE,TO,NAME) ;
Q:$D(REGLST)<10 1
N LOCKLST,RORLIST,RC,REGIEN,REGNAME
N CT,FAILS,Q,Q0,Z
; RORLIST = 0 if less than 15 entries to lock
; = 1 if 15 or more entries to lock
; (n,x,y) = the array in LOCKLST(x,y) at that point
; (where n = the # identifying the set of 15
; registries being locked at one time)
; FAILS = <0 or 1 ... lock failed = 0 ... lock was successful
S REGNAME="",CT=0,RORLIST=0
F S REGNAME=$O(REGLST(REGNAME)) Q:REGNAME="" D Q:REGIEN<0
. S REGIEN=+$G(REGLST(REGNAME))
. I REGIEN'>0 S REGIEN=$$REGIEN^RORUTL02(REGNAME) Q:REGIEN'>0
. S CT=CT+1
. S LOCKLST(798.1,REGIEN_",")=""
. I '(CT#15) D ; Split the locks into smaller chunks every 15 entries
.. M RORLIST(CT/15)=LOCKLST S RORLIST=1
.. K LOCKLST
Q:$G(REGIEN)<0 REGIEN
I RORLIST,$O(LOCKLST(""))'="" M RORLIST((CT/15\1)+1)=LOCKLST K LOCKLST
Q:$D(LOCKLST)<10&'$O(RORLIST(0)) 1
I $G(MODE) S RC=0 D
. I 'RORLIST S RC=$$LOCK^RORLOCK(.LOCKLST,,,+$G(TO,3),$G(NAME)) Q
. F Q=1:1 Q:'$D(RORLIST(Q))!RC D
.. K LOCKLST M LOCKLST=RORLIST(Q)
.. S FAILS=$$LOCK^RORLOCK(.LOCKLST,,,+$G(TO,3),$G(NAME)),RC=FAILS
.. ; If lock fails for at least one set of nodes [=1 or <0] - unlock previous locks
.. I FAILS D:Q>1
... F Q0=1:1:Q-1 K LOCKLST M LOCKLST=RORLIST(Q0) S Z=$$UNLOCK^RORLOCK(.LOCKLST)
E D
. I 'RORLIST S RC=$$UNLOCK^RORLOCK(.LOCKLST) Q
. S RC=0
. F Q=1:1 K LOCKLST Q:'$D(RORLIST(Q)) D
.. M LOCKLST=RORLIST(Q) S FAILS=$$UNLOCK^RORLOCK(.LOCKLST)
.. S:FAILS RC=FAILS
Q $S('RC:1,RC<0:RC,1:0)
;
;***** RETURNS A PATIENT ID (ICN OR SSN)
;
; PTIEN Patient IEN
;
; Return Values:
; <0 Error code
; "" Neither ICN nor SSN has been assigned
; >0 Patient ICN (or SSN if ICN is not available)
;
PTID(PTIEN) ;
N L,PTID,RC,RORMSG
S PTID=$$GETICN^MPIF001(PTIEN)
I PTID>0 D Q PTID
. ;--- Validate the checksum (just in case ;-)
. S L=$L($P(PTID,"V",2)) Q:L'<6
. ;S RC=$$ERROR^RORERR(-59,,,PTIEN)
. S $P(PTID,"V",2)=$E("000000",1,6-L)_$P(PTID,"V",2)
;--- Get SSN if ICN is not available
S PTID=$$GET1^DIQ(2,PTIEN_",",.09,,,"RORMSG")
Q:$G(DIERR) $$DBS^RORERR("RORMSG",-9,,PTIEN,2)
Q PTID
;
;***** RETURNS IEN OF THE REGISTRY PARAMETERS
;
; REGNAME Name of the registry
; [FIELDS] List of fields (separated by semicolons) to load
; [.RORTRGT] Reference to a local variable where field values will
; be stored by the FIND^DIC call
;
; Return Values:
; <0 Error code
; >0 Registry parameters IEN
;
REGIEN(REGNAME,FIELDS,RORTRGT) ;
N RC,REGIEN,RORMSG K RORTRGT
D FIND^DIC(798.1,,"@;"_$G(FIELDS),"UX",REGNAME,2,"B",,,"RORTRGT","RORMSG")
Q:$G(DIERR) $$DBS^RORERR("RORMSG",-9,,,798.1)
S RC=+$G(RORTRGT("DILIST",0))
Q $S(RC<1:-1,RC>1:-2,1:+RORTRGT("DILIST",2,1))
;
;***** RETURNS NUMBER OF RECORDS IN THE REGISTRY
;
; REGIEN Registry IEN
; [.LOWIEN] The smallest IEN will be returned via this parameter
; [.HIGHIEN] The biggest IEN will be returned via this parameter
;
; Return Values:
; <0 Error code
; 0 The registry is empty
; >0 Number of records in the registry
;
REGSIZE(REGIEN,LOWIEN,HIGHIEN) ;
N I,NODE,NRE,RC,RORFDA,RORMSG
S NODE=$NA(^RORDATA(798,"AC",REGIEN))
S LOWIEN=$O(@NODE@(""))
S HIGHIEN=$O(@NODE@(""),-1)
;--- Get number of records from the parameters
S NRE=$$GET1^DIQ(798.1,REGIEN_",",19.1,,,"RORMSG")
Q:$G(DIERR) $$DBS^RORERR("RORMSG",-9,,,798.1,REGIEN)
Q:NRE>0 NRE
;--- Count the records of the registry
S I="",NRE=0
F S I=$O(@NODE@(I)) Q:I="" S NRE=NRE+1
;--- Store the value in the parameters
S RORFDA(798.1,REGIEN_",",19.1)=NRE
D FILE^DIE("K","RORFDA","RORMSG")
Q NRE
;
;***** CHECKS IF AN EMPLOYEE SHOULD BE SKIPPED
;
; PTIEN Patient IEN
;
; [.]REGIEN Registry IEN
;
; If you are going to call this function for several
; patients in a row (in a cycle), you can pass the
; second parameter by reference. This will eliminate
; repetitive access to the registry parameters (the
; REGIEN("SE") node will be used as a "cache" for the
; value of the EXCLUDE EMPLOYEES field).
;
; Return Values:
; 0 Patient can be added to the registry
; 1 Patient should be skipped
;
; The function checks if the patient is an employee and if he/she
; can be added to the registry (according to the value of the
; EXCLUDE EMPLOYEES field of the ROR REGISTRY PARAMETERS file).
;
SKIPEMPL(PTIEN,REGIEN) ;
Q:'$$EMPL^DGSEC4(PTIEN,"P") 0
S:'$D(REGIEN("SE")) REGIEN("SE")=+$P($G(^ROR(798.1,+REGIEN,0)),U,10)
Q +REGIEN("SE")
;
;***** RETURNS IEN OF THE SELECTION RULE
;
; RULENAME Name of the selection rule
; [FIELDS] List of fields (separated by semicolons) to load
; [.RORTRGT] Reference to a local variable where field values will
; be stored by the FIND^DIC call.
;
; Return Values:
; <0 Error code
; >0 Selection rule IEN
;
SRLIEN(RULENAME,FIELDS,RORTRGT) ;
N RC,RULEIEN,RORMSG K RORTRGT
D FIND^DIC(798.2,,"@;"_$G(FIELDS),"X",RULENAME,2,"B",,,"RORTRGT","RORMSG")
Q:$G(DIERR) $$DBS^RORERR("RORMSG",-9,,,798.2)
S RC=+$G(RORTRGT("DILIST",0))
Q $S(RC<1:-3,RC>1:-4,1:+RORTRGT("DILIST",2,1))
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HRORUTL02 12223 printed Oct 16, 2024@17:44:47 Page 2
RORUTL02 ;HCIOFO/SG - UTILITIES ;8/25/05 10:20am
+1 ;;1.5;CLINICAL CASE REGISTRIES;**21,27,31,33,34**;Feb 17, 2006;Build 45
+2 ;
+3 ;******************************************************************************
+4 ;******************************************************************************
+5 ; --- ROUTINE MODIFICATION LOG ---
+6 ;
+7 ;PKG/PATCH DATE DEVELOPER MODIFICATION
+8 ;----------- ---------- ----------- ----------------------------------------
+9 ;ROR*1.5*27 FEB 2015 T KOPP Changed LOCKREG entry point to loop thru
+10 ; registries to lock only 15 at a time to
+11 ; prevent maxstring errors when lock
+12 ; command is executed.
+13 ;ROR*1.5*31 MAY 2017 M FERRARESE Adding PACT and PCP as additional identifiers.
+14 ;ROR*1.5*33 MAY 2017 F TRAXLER Added FUTAPPT subroutine.
+15 ;ROR*1.5*34 SEP 2018 F TRAXLER Modified FUTAPPT subroutine.
+16 ;******************************************************************************
+17 ;
+18 ; This routine uses the following IAs:
+19 ;
+20 ; #2701 $$GETICN^MPIF001 Gets ICN (supported)
+21 ; $$IFLOCAL^MPIF001 (checks for local ICN) (supported)
+22 ; #3556 $$GCPR^LA7QRY
+23 ; #3557 Access to the field .01 and x-ref "B"
+24 ; of the file 95.3
+25 ; #3646 $$EMPL^DGSEC4
+26 ; #10035 Access to the field #.09 of the file #2
+27 ;
+28 QUIT
+29 ;
+30 ;***** REMOVES THE INACTIVE REGISTRIES FROM THE LIST
+31 ;
+32 ; .REGLST( A list of registry names (as subscripts)
+33 ; RegName) Registry IEN (output)
+34 ;
+35 ; Return values:
+36 ; <0 Error code
+37 ; 0 Ok
+38 ;
+39 ; This function removes names of those registries that are
+40 ; inactive or cannot be updated for any other reasons from
+41 ; the list. It also associates registry IENs with the names
+42 ; of registries remaining on the list.
+43 ;
+44 ; Moreover, it records corresponding messages about skipped
+45 ; registries to the current open log.
+46 ;
ARLST(REGLST) ;
+1 NEW INFO,RC,REGIEN,REGNAME,RORBUF,TMP
KILL DSTLST
+2 SET REGNAME=""
SET RC=0
+3 FOR
SET REGNAME=$ORDER(REGLST(REGNAME))
if REGNAME=""
QUIT
Begin DoDot:1
+4 SET REGIEN=$$REGIEN(REGNAME,"@;11I;21.05I",.RORBUF)
+5 ;--- Cannot find (or load) the registry parameters
+6 IF REGIEN'>0
Begin DoDot:2
+7 DO ERROR^RORERR(REGIEN,,REGNAME)
+8 KILL REGLST(REGNAME)
End DoDot:2
QUIT
+9 ;--- Check if the registry is marked as 'inactive'
+10 IF $GET(RORBUF("DILIST","ID",1,11))
Begin DoDot:2
+11 DO ERROR^RORERR(-48,,,,REGNAME)
+12 KILL REGLST(REGNAME)
End DoDot:2
QUIT
+13 ;--- Check if the registry has not been populated
+14 IF '$GET(RORBUF("DILIST","ID",1,21.05))
IF '$GET(RORPARM("SETUP"))
Begin DoDot:2
+15 DO TEXT^RORTXT(7980000.02,.INFO)
+16 DO ERROR^RORERR(-103,,.INFO,,REGNAME)
+17 KILL INFO,REGLST(REGNAME)
End DoDot:2
QUIT
+18 ;--- Store the registry IEN
+19 SET REGLST(REGNAME)=REGIEN
End DoDot:1
if RC<0
QUIT
+20 QUIT RC
+21 ;
+22 ;***** RETURNS A FULL NATIONAL ICN OF THE PATIENT
+23 ;
+24 ; PTIEN Patient IEN
+25 ;
+26 ; Return Values:
+27 ; <0 Error code
+28 ; "" ICN has not been assigned or ICN is a local ICN
+29 ; >0 Patient National ICN
+30 ;
ICN(PTIEN) ;
+1 NEW ICN,L,TMP
+2 IF $$IFLOCAL^MPIF001(PTIEN)
QUIT ""
+3 SET ICN=$$GETICN^MPIF001(PTIEN)
+4 IF ICN'>0
Begin DoDot:1
+5 SET TMP=$$ERROR^RORERR(-57,,$PIECE(ICN,U,2),PTIEN,+ICN,"$$GETICN^MPIF001")
End DoDot:1
QUIT ""
+6 ;--- Validate the checksum (just in case ;-)
+7 SET L=$LENGTH($PIECE(ICN,"V",2))
+8 QUIT $SELECT(L<6:$PIECE(ICN,"V")_"V"_$EXTRACT("000000",1,6-L)_$PIECE(ICN,"V",2),1:ICN)
+9 ;
PACT(DFN) ;returns ien & name of pc team PATCH 30
+1 ; DFN - pointer to patient file
+2 ; Date of interest (Default=DT)
+3 ;
+4 QUIT $PIECE($$OUTPTTM^SDUTL3(DFN,DT),U,2)
+5 ;
PCP(DFN) ;returns ien & name of pract filling pc position PATCH 30
+1 ; DFN - pointer to patient file
+2 ; DATE - date of interest
+3 ; PCROLE - Practitioner Position where '1' = PC provider ; '2' = PC attending
+4 ; '3' = PC associate provider
+5 ;
+6 ; returns (ien^name), or "" if none or -1 if error
+7 ;
+8 ;
+9 QUIT $PIECE($$OUTPTPR^SDUTL3(DFN,DT,1),"^",2)
+10 ;
FUTAPPT(DFN,DAYS) ; PATCH 33
+1 NEW RORAPPTDT,RORAPPTCNE,VASD
+2 IF $DATA(DAYS)
Begin DoDot:1
+3 NEW X,X1,X2
+4 DO NOW^%DTC
SET (VASD("F"),X1)=X
SET X2=DAYS
DO C^%DTC
SET VASD("T")=X
+5 SET VASD("W")="1"
+6 DO SDA^VADPT
End DoDot:1
+7 ;patch 34 change
IF $DATA(^UTILITY("VASD",$JOB))
Begin DoDot:1
+8 ;appt d/t
SET RORAPPTDT=$$DATE^RORXU002($PIECE($GET(^UTILITY("VASD",$JOB,1,"I")),U,1)\1)
+9 ;appt clinic name (external)
SET RORAPPTCNE=$PIECE($GET(^UTILITY("VASD",$JOB,1,"E")),U,2)
End DoDot:1
QUIT RORAPPTDT_U_RORAPPTCNE
+10 ;I $D(^UTILITY("VASD",$J)) Q $$DATE^RORXU002($P($G(^UTILITY("VASD",$J,1,"I")),"^",1)\1) ;patch 33 code
+11 QUIT 0
+12 ;***** LOADS THE LAB RESULTS
+13 ;
+14 ; PTIEN Patient IEN
+15 ;
+16 ; SDT Start date of the results
+17 ; EDT End date of the results
+18 ;
+19 ; [ROR8DST] Closed root of the destination array
+20 ; (the ^TMP("RORTMP",$J) node, by default)
+21 ;
+22 ; Return values:
+23 ; <0 Error code
+24 ; 0 Ok
+25 ;
LABRSLTS(PTIEN,SDT,EDT,ROR8DST) ;
+1 NEW H7CH,RC,RORMSG,TMP
+2 if $GET(ROR8DST)=""
SET ROR8DST=$NAME(^TMP("RORTMP",$JOB))
+3 KILL @ROR8DST
+4 IF $DATA(RORLRC)<10
if $GET(RORLRC)=""
QUIT 0
+5 ;--- Get the Patient ID (ICN or SSN)
+6 SET PTID=$$PTID(PTIEN)
if PTID<0
QUIT PTID
+7 ;--- Get the Lab data
+8 SET H7CH=$GET(RORHL("FS"))_$GET(RORHL("ECH"))
+9 SET RC=$$GCPR^LA7QRY(PTID,SDT,EDT,.RORLRC,"*",.RORMSG,ROR8DST,H7CH)
+10 IF RC=""
IF $DATA(RORMSG)>1
Begin DoDot:1
+11 NEW ERR,I,LST
+12 SET (ERR,LST)=""
+13 FOR I=1:1
SET ERR=$ORDER(RORMSG(ERR))
if ERR=""
QUIT
Begin DoDot:2
+14 SET LST=LST_","_ERR
SET TMP=RORMSG(ERR)
+15 KILL RORMSG(ERR)
SET RORMSG(I)=TMP
End DoDot:2
+16 SET LST=$PIECE(LST,",",2,999)
if (LST=3)!(LST=99)
QUIT
+17 SET RC=$$ERROR^RORERR(-27,,.RORMSG,PTIEN)
End DoDot:1
+18 QUIT $SELECT(RC<0:RC,1:0)
+19 ;
+20 ;***** RETURNS THE LOINC CODE WITH THE CONTROL DIGIT
+21 ;
+22 ; LNCODE LOINC code
+23 ;
+24 ; Besides adding a control digit to the LOINC code, the function
+25 ; checks the code against the LAB LOINC file (#95.3).
+26 ;
+27 ; Return values:
+28 ; <0 Error code
+29 ; >0 LOINC code with the control digit
+30 ;
LNCODE(LNCODE) ;
+1 NEW RC,RORBUF,RORMSG
+2 DO FIND^DIC(95.3,,"@;.01E","X",$PIECE(LNCODE,"-"),2,"B",,,"RORBUF","RORMSG")
+3 if $GET(DIERR)
QUIT $$DBS^RORERR("RORMSG",-9,,,95.3)
+4 ; Non-existent code
IF $GET(RORBUF("DILIST",0))<1
Begin DoDot:1
+5 SET RC=$$ERROR^RORERR(-29,,,,LNCODE)
End DoDot:1
QUIT RC
+6 ; Duplicate records
IF $GET(RORBUF("DILIST",0))>1
Begin DoDot:1
+7 SET RC=$$ERROR^RORERR(-30,,,,LNCODE)
End DoDot:1
QUIT RC
+8 QUIT RORBUF("DILIST","ID",1,.01)
+9 ;
+10 ;***** LOCK/UNLOCK REGISTRIES BEING PROCESSED
+11 ;
+12 ; .REGLST Reference to a local array containing registry names
+13 ; as subscripts and optional registry IENs as values
+14 ; [MODE] 0 - Unlock (default), 1 - Lock
+15 ; [TO] LOCK timeout (3 sec by defualt)
+16 ; [NAME] Name of the process/task
+17 ;
+18 ; Return Values:
+19 ; <0 Error code
+20 ; 0 Some of the registries has been locked by another job
+21 ; 1 Ok
+22 ;
LOCKREG(REGLST,MODE,TO,NAME) ;
+1 if $DATA(REGLST)<10
QUIT 1
+2 NEW LOCKLST,RORLIST,RC,REGIEN,REGNAME
+3 NEW CT,FAILS,Q,Q0,Z
+4 ; RORLIST = 0 if less than 15 entries to lock
+5 ; = 1 if 15 or more entries to lock
+6 ; (n,x,y) = the array in LOCKLST(x,y) at that point
+7 ; (where n = the # identifying the set of 15
+8 ; registries being locked at one time)
+9 ; FAILS = <0 or 1 ... lock failed = 0 ... lock was successful
+10 SET REGNAME=""
SET CT=0
SET RORLIST=0
+11 FOR
SET REGNAME=$ORDER(REGLST(REGNAME))
if REGNAME=""
QUIT
Begin DoDot:1
+12 SET REGIEN=+$GET(REGLST(REGNAME))
+13 IF REGIEN'>0
SET REGIEN=$$REGIEN^RORUTL02(REGNAME)
if REGIEN'>0
QUIT
+14 SET CT=CT+1
+15 SET LOCKLST(798.1,REGIEN_",")=""
+16 ; Split the locks into smaller chunks every 15 entries
IF '(CT#15)
Begin DoDot:2
+17 MERGE RORLIST(CT/15)=LOCKLST
SET RORLIST=1
+18 KILL LOCKLST
End DoDot:2
End DoDot:1
if REGIEN<0
QUIT
+19 if $GET(REGIEN)<0
QUIT REGIEN
+20 IF RORLIST
IF $ORDER(LOCKLST(""))'=""
MERGE RORLIST((CT/15\1)+1)=LOCKLST
KILL LOCKLST
+21 if $DATA(LOCKLST)<10&'$ORDER(RORLIST(0))
QUIT 1
+22 IF $GET(MODE)
SET RC=0
Begin DoDot:1
+23 IF 'RORLIST
SET RC=$$LOCK^RORLOCK(.LOCKLST,,,+$GET(TO,3),$GET(NAME))
QUIT
+24 FOR Q=1:1
if '$DATA(RORLIST(Q))!RC
QUIT
Begin DoDot:2
+25 KILL LOCKLST
MERGE LOCKLST=RORLIST(Q)
+26 SET FAILS=$$LOCK^RORLOCK(.LOCKLST,,,+$GET(TO,3),$GET(NAME))
SET RC=FAILS
+27 ; If lock fails for at least one set of nodes [=1 or <0] - unlock previous locks
+28 IF FAILS
if Q>1
Begin DoDot:3
+29 FOR Q0=1:1:Q-1
KILL LOCKLST
MERGE LOCKLST=RORLIST(Q0)
SET Z=$$UNLOCK^RORLOCK(.LOCKLST)
End DoDot:3
End DoDot:2
End DoDot:1
+30 IF '$TEST
Begin DoDot:1
+31 IF 'RORLIST
SET RC=$$UNLOCK^RORLOCK(.LOCKLST)
QUIT
+32 SET RC=0
+33 FOR Q=1:1
KILL LOCKLST
if '$DATA(RORLIST(Q))
QUIT
Begin DoDot:2
+34 MERGE LOCKLST=RORLIST(Q)
SET FAILS=$$UNLOCK^RORLOCK(.LOCKLST)
+35 if FAILS
SET RC=FAILS
End DoDot:2
End DoDot:1
+36 QUIT $SELECT('RC:1,RC<0:RC,1:0)
+37 ;
+38 ;***** RETURNS A PATIENT ID (ICN OR SSN)
+39 ;
+40 ; PTIEN Patient IEN
+41 ;
+42 ; Return Values:
+43 ; <0 Error code
+44 ; "" Neither ICN nor SSN has been assigned
+45 ; >0 Patient ICN (or SSN if ICN is not available)
+46 ;
PTID(PTIEN) ;
+1 NEW L,PTID,RC,RORMSG
+2 SET PTID=$$GETICN^MPIF001(PTIEN)
+3 IF PTID>0
Begin DoDot:1
+4 ;--- Validate the checksum (just in case ;-)
+5 SET L=$LENGTH($PIECE(PTID,"V",2))
if L'<6
QUIT
+6 ;S RC=$$ERROR^RORERR(-59,,,PTIEN)
+7 SET $PIECE(PTID,"V",2)=$EXTRACT("000000",1,6-L)_$PIECE(PTID,"V",2)
End DoDot:1
QUIT PTID
+8 ;--- Get SSN if ICN is not available
+9 SET PTID=$$GET1^DIQ(2,PTIEN_",",.09,,,"RORMSG")
+10 if $GET(DIERR)
QUIT $$DBS^RORERR("RORMSG",-9,,PTIEN,2)
+11 QUIT PTID
+12 ;
+13 ;***** RETURNS IEN OF THE REGISTRY PARAMETERS
+14 ;
+15 ; REGNAME Name of the registry
+16 ; [FIELDS] List of fields (separated by semicolons) to load
+17 ; [.RORTRGT] Reference to a local variable where field values will
+18 ; be stored by the FIND^DIC call
+19 ;
+20 ; Return Values:
+21 ; <0 Error code
+22 ; >0 Registry parameters IEN
+23 ;
REGIEN(REGNAME,FIELDS,RORTRGT) ;
+1 NEW RC,REGIEN,RORMSG
KILL RORTRGT
+2 DO FIND^DIC(798.1,,"@;"_$GET(FIELDS),"UX",REGNAME,2,"B",,,"RORTRGT","RORMSG")
+3 if $GET(DIERR)
QUIT $$DBS^RORERR("RORMSG",-9,,,798.1)
+4 SET RC=+$GET(RORTRGT("DILIST",0))
+5 QUIT $SELECT(RC<1:-1,RC>1:-2,1:+RORTRGT("DILIST",2,1))
+6 ;
+7 ;***** RETURNS NUMBER OF RECORDS IN THE REGISTRY
+8 ;
+9 ; REGIEN Registry IEN
+10 ; [.LOWIEN] The smallest IEN will be returned via this parameter
+11 ; [.HIGHIEN] The biggest IEN will be returned via this parameter
+12 ;
+13 ; Return Values:
+14 ; <0 Error code
+15 ; 0 The registry is empty
+16 ; >0 Number of records in the registry
+17 ;
REGSIZE(REGIEN,LOWIEN,HIGHIEN) ;
+1 NEW I,NODE,NRE,RC,RORFDA,RORMSG
+2 SET NODE=$NAME(^RORDATA(798,"AC",REGIEN))
+3 SET LOWIEN=$ORDER(@NODE@(""))
+4 SET HIGHIEN=$ORDER(@NODE@(""),-1)
+5 ;--- Get number of records from the parameters
+6 SET NRE=$$GET1^DIQ(798.1,REGIEN_",",19.1,,,"RORMSG")
+7 if $GET(DIERR)
QUIT $$DBS^RORERR("RORMSG",-9,,,798.1,REGIEN)
+8 if NRE>0
QUIT NRE
+9 ;--- Count the records of the registry
+10 SET I=""
SET NRE=0
+11 FOR
SET I=$ORDER(@NODE@(I))
if I=""
QUIT
SET NRE=NRE+1
+12 ;--- Store the value in the parameters
+13 SET RORFDA(798.1,REGIEN_",",19.1)=NRE
+14 DO FILE^DIE("K","RORFDA","RORMSG")
+15 QUIT NRE
+16 ;
+17 ;***** CHECKS IF AN EMPLOYEE SHOULD BE SKIPPED
+18 ;
+19 ; PTIEN Patient IEN
+20 ;
+21 ; [.]REGIEN Registry IEN
+22 ;
+23 ; If you are going to call this function for several
+24 ; patients in a row (in a cycle), you can pass the
+25 ; second parameter by reference. This will eliminate
+26 ; repetitive access to the registry parameters (the
+27 ; REGIEN("SE") node will be used as a "cache" for the
+28 ; value of the EXCLUDE EMPLOYEES field).
+29 ;
+30 ; Return Values:
+31 ; 0 Patient can be added to the registry
+32 ; 1 Patient should be skipped
+33 ;
+34 ; The function checks if the patient is an employee and if he/she
+35 ; can be added to the registry (according to the value of the
+36 ; EXCLUDE EMPLOYEES field of the ROR REGISTRY PARAMETERS file).
+37 ;
SKIPEMPL(PTIEN,REGIEN) ;
+1 if '$$EMPL^DGSEC4(PTIEN,"P")
QUIT 0
+2 if '$DATA(REGIEN("SE"))
SET REGIEN("SE")=+$PIECE($GET(^ROR(798.1,+REGIEN,0)),U,10)
+3 QUIT +REGIEN("SE")
+4 ;
+5 ;***** RETURNS IEN OF THE SELECTION RULE
+6 ;
+7 ; RULENAME Name of the selection rule
+8 ; [FIELDS] List of fields (separated by semicolons) to load
+9 ; [.RORTRGT] Reference to a local variable where field values will
+10 ; be stored by the FIND^DIC call.
+11 ;
+12 ; Return Values:
+13 ; <0 Error code
+14 ; >0 Selection rule IEN
+15 ;
SRLIEN(RULENAME,FIELDS,RORTRGT) ;
+1 NEW RC,RULEIEN,RORMSG
KILL RORTRGT
+2 DO FIND^DIC(798.2,,"@;"_$GET(FIELDS),"X",RULENAME,2,"B",,,"RORTRGT","RORMSG")
+3 if $GET(DIERR)
QUIT $$DBS^RORERR("RORMSG",-9,,,798.2)
+4 SET RC=+$GET(RORTRGT("DILIST",0))
+5 QUIT $SELECT(RC<1:-3,RC>1:-4,1:+RORTRGT("DILIST",2,1))