PXRMVLST ;SLC/PKR - Validate a reminder definition for building a patient list. ;09/07/2010
;;2.0;CLINICAL REMINDERS;**4,18**;Feb 04, 2005;Build 152
;==================================================
CCF(FINDING) ;Check a computed finding to see if it can be used for building
;a list.
N IEN,TEMP,TEXT,TYPE,VALID
S VALID=1
S IEN=$P(FINDING,";",1)
S TEMP=$G(^PXRMD(811.4,IEN,0))
I TEMP="" D Q 0
. S TEXT="Trying to use computed finding number "_IEN_" it does not exist!"
. D EN^DDIOL(TEXT)
S TYPE=$P(TEMP,U,5)
I TYPE="" S TYPE="S"
I TYPE'="L" D
. S VALID=0
. S TEXT(1)="Computed finding "_$P(TEMP,U,1)_" is type "_TYPE_"."
. S TEXT(2)="It cannot be used for building patient lists!"
. D EN^DDIOL(.TEXT)
Q VALID
;
;==================================================
CTERM(DEFARR,FINUM,FINDING) ;Check terms for computed findings and
;health factors to see if they are valid for building a list.
N IEN,IND,TEXT,VALID,WCR
S IEN=$P(FINDING,";",1)
I '$D(^PXRMD(811.5,IEN,0)) D Q 0
. S TEXT="Trying to use term number "_IEN_" it does not exist!"
. D EN^DDIOL(TEXT)
S VALID=1
I $D(^PXRMD(811.5,IEN,20,"E","PXRMD(811.4,")) D
. S IND=0
. F S IND=$O(^PXRMD(811.5,IEN,20,"E","PXRMD(811.4,",IND)) Q:IND="" D
.. S VALID=$$CCF(IND)
.. I 'VALID D
... S TEXT="The computed finding is used in term "_$P(^PXRMD(811.5,IEN,0),U,1)_"."
... D EN^DDIOL(TEXT)
Q VALID
;
;==================================================
HF(DEFARR,FINUM) ;
;If a health factor is used its Within Category Rank must be 0.
N WCR,TEXT
S WCR=$P(DEFARR(20,FINUM,0),U,10)
I WCR=0 Q 1
S TEXT="Finding "_FINUM_" is a health factor and its Within Category Rank is not 0!"
D EN^DDIOL(TEXT)
Q 0
;
;==================================================
VDEF(RIEN) ;Check a reminder definition and see if it is valid for
;use in creating a patient list.
N AGEFI,AGR,AT,DEFARR,FFL,FI,FIL,FILIST,FINDING,FINUM,FREQ,FUNCTION
N FUNN,IND,OPER,MAXAGE,MINAGE,NUMAFI,PCLOG,PFSTACK,ROUTINE
N SAAFI,SEXFI,SSTACK,TEMP,TEXT,TYPE,VALID,VF
I RIEN="" Q 0
I '$D(^PXD(811.9,RIEN)) D Q 0
. S TEXT="The reminder does not exist!"
. D EN^DDIOL(TEXT)
;
;See if the reminder is inactive.
I $P($G(^PXD(811.9,RIEN,0)),U,6) D Q 0
. S TEXT="This reminder is inactive!"
. D EN^DDIOL(TEXT)
;
D DEF^PXRMLDR(RIEN,.DEFARR)
S PCLOG=DEFARR(31)
I PCLOG="" D Q 0
. S TEXT="This reminder does not contain any patient cohort logic!"
. D EN^DDIOL(TEXT)
;
;The cohort logic cannot contain the old-style MRD.
I $G(^PXD(811.9,RIEN,30))["MRD" D Q 0
. S TEXT="The patient cohort logic cannot contain the old-style MRD!"
. D EN^DDIOL(TEXT)
;
;The cohort logic cannot start with a not.
I $E(PCLOG,1)="'" D Q 0
. S TEXT="The patient cohort logic cannot start with a not!"
. D EN^DDIOL(TEXT)
;
;The cohort logic cannot contain or not.
;Change any !(' to !' before checking.
S TEMP=$TR(PCLOG,"(","")
S TEMP=$TR(TEMP,")","")
I TEMP["!'" D Q 0
. S TEXT="The patient cohort logic cannot contain or not!"
. D EN^DDIOL(TEXT)
;
S OPER="!&~"
S PCLOG=$$STRREP^PXRMUTIL(PCLOG,"&'","~")
D POSTFIX^PXRMSTAC(PCLOG,OPER,.PFSTACK)
D CFSAA^PXRMPLST(.PFSTACK)
M SSTACK=PFSTACK
S (AGEFI,SAAFI,SEXFI)=0
F IND=1:1:PFSTACK(0) D
. S TEMP=$$POP^PXRMSTAC(.PFSTACK)
. I TEMP="AGE" S AGEFI=IND
. I TEMP="SAA" S SAAFI=IND
. I TEMP="SEX" S SEXFI=IND
. I TEMP="'SEX" S SEXFI=IND
;
;If AGE is defined then make sure a baseline age range is defined.
I (AGEFI)!(SAAFI) D
. S (AGR,IND)=0
. F S IND=+$O(DEFARR(7,IND)) Q:IND=0 D
.. S TEMP=DEFARR(7,IND,0)
.. I $P(TEMP,U,2)'="" S AGR=1
.. I $P(TEMP,U,3)'="" S AGR=1
;
S TEMP=DEFARR(40)
S NUMAFI=+$P(TEMP,U,1)
S FILIST=$P(TEMP,U,2)
I (AGEFI!SAAFI),('AGR&(NUMAFI=0)) D Q 0
. S TEXT(1)="Age is used in the cohort logic and neither a baseline age range or any age"
. S TEXT(2)="findings have been defined!"
. D EN^DDIOL(.TEXT)
;
;SEX cannot be the first element unless it is followed by & AGE.
I (SEXFI=1),('SAAFI) D Q 0
. S TEXT="SEX must be followed by & AGE when it starts the patient cohort logic!"
. D EN^DDIOL(TEXT)
;If SEX is defined and there is not a combined sex & age finding then
;a sex must be defined and the logical operator cannot be an or.
S VALID=1
I (SEXFI),('SAAFI) D
. I $P(^PXD(811.9,RIEN,0),U,9)="" D
.. S VALID=0
.. S TEXT(1)="Sex is used in the patient cohort logic and no sex is defined in the reminder"
.. S TEXT(2)="definition!"
.. D EN^DDIOL(.TEXT)
. I VALID D
.. S TEMP=SSTACK(SEXFI+1)
.. I TEMP="!" D
... S VALID=0
... S TEXT="SEX cannot be used in conjunction with the or operator!"
... D EN^DDIOL(TEXT)
I 'VALID Q VALID
;
;Check the age findings and see if any of them set the frequency to
;0Y. If they do they cannot have an associated age range.
F IND=1:1:NUMAFI D
. S FINUM=$P(FILIST,";",IND)
. S TEMP=$S(FINUM["FF":DEFARR(25,FINUM,0),1:DEFARR(20,FINUM,0))
. S MINAGE=$P(TEMP,U,2)
. S MAXAGE=$P(TEMP,U,3)
. S FREQ=$P(TEMP,U,4)
. I FREQ="0Y",((MINAGE'="")!(MAXAGE'="")) D
.. S VALID=0
.. S TEXT(1)="Finding "_FINUM_" sets the frequency to 0Y and also sets an age range."
.. S TEXT(2)="An age range is not allowed with a frequency of 0Y!"
.. D EN^DDIOL(.TEXT)
;
;Build a list of all the findings that affect whether or not the
;patient is in the cohort and check to see if any of them use a
;computed finding. If they use a computed finding then it must be
;a list type. Health factors must have within category rank of 0.
F IND=1:1:SSTACK(0) D
. I (SSTACK(IND)["FI") D
.. S FINUM=$G(SSTACK(IND+1))
.. S FIL(FINUM)=""
. I (SSTACK(IND)["FF") D
.. S FINUM=$G(SSTACK(IND+1))
.. S FFL(FINUM)="FF"_FINUM
;Add any age findings to the list.
F IND=1:1:NUMAFI D
. S TEMP=$P(FILIST,";",IND)
. I TEMP=+TEMP S FIL(TEMP)=""
. I TEMP["FF" S FFL($P(TEMP,"FF",2))=TEMP
;Add findings used by function findings to the list.
S IND=0
F S IND=$O(FFL(IND)) Q:IND="" D
. S FUNN=0
. S FUNN=$O(DEFARR(25,FFL(IND),5,FUNN)) Q:FUNN="" D
.. S FUNCTION=$P(DEFARR(25,FFL(IND),5,FUNN,0),U,2)
.. S ROUTINE=$P(^PXRMD(802.4,FUNCTION,0),U,1)
.. S ROUTINE=$TR(ROUTINE,"_","")
.. S FI=0
.. F S FI=$O(DEFARR(25,FFL(IND),5,FUNN,20,FI)) Q:FI="" D
... S FINUM=DEFARR(25,FFL(IND),5,FUNN,20,FI,0)
...;Determine if this subscript is a finding or not before checking
...;if the finding exists.
... S AT=$$ARGTYPE^PXRMFFAT(ROUTINE,FI)
... I AT'="F" Q
... S FIL(FINUM)=""
... I '$D(DEFARR(20,FINUM)) D Q
.... S VALID=0
.... S TEXT="Finding "_FINUM_" is used in FF("_IND_") and it does not exist!"
.... D EN^DDIOL(TEXT)
I 'VALID Q VALID
S IND=0
F S IND=$O(FIL(IND)) Q:IND="" D
. S FINDING=$P($G(DEFARR(20,IND,0)),U,1)
. I FINDING="" D Q
.. S VALID=0
.. S TEXT="Finding number "_IND_" does not exist!"
.. D EN^DDIOL(TEXT)
. S TEMP=$P(FINDING,";",2)
. S TYPE=$S(TEMP="AUTTHF(":"HF",TEMP="PXRMD(811.4,":"CF",TEMP="PXRMD(811.5,":"TERM",1:"REG")
. I TYPE="REG" Q
. I TYPE="CF" S VF=$$CCF(FINDING)
. I TYPE="HF" S VF=$$HF(.DEFARR,IND)
. I TYPE="TERM" S VF=$$CTERM(.DEFARR,IND,FINDING)
. I VF=0 D
.. S VALID=0
.. S TEXT="Finding number "_IND_" is the problem finding."
.. D EN^DDIOL(TEXT)
Q VALID
;
PXRMVLST ;SLC/PKR - Validate a reminder definition for building a patient list. ;09/07/2010
+1 ;;2.0;CLINICAL REMINDERS;**4,18**;Feb 04, 2005;Build 152
+2 ;==================================================
CCF(FINDING) ;Check a computed finding to see if it can be used for building
+1 ;a list.
+2 NEW IEN,TEMP,TEXT,TYPE,VALID
+3 SET VALID=1
+4 SET IEN=$PIECE(FINDING,";",1)
+5 SET TEMP=$GET(^PXRMD(811.4,IEN,0))
+6 IF TEMP=""
Begin DoDot:1
+7 SET TEXT="Trying to use computed finding number "_IEN_" it does not exist!"
+8 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+9 SET TYPE=$PIECE(TEMP,U,5)
+10 IF TYPE=""
SET TYPE="S"
+11 IF TYPE'="L"
Begin DoDot:1
+12 SET VALID=0
+13 SET TEXT(1)="Computed finding "_$PIECE(TEMP,U,1)_" is type "_TYPE_"."
+14 SET TEXT(2)="It cannot be used for building patient lists!"
+15 DO EN^DDIOL(.TEXT)
End DoDot:1
+16 QUIT VALID
+17 ;
+18 ;==================================================
CTERM(DEFARR,FINUM,FINDING) ;Check terms for computed findings and
+1 ;health factors to see if they are valid for building a list.
+2 NEW IEN,IND,TEXT,VALID,WCR
+3 SET IEN=$PIECE(FINDING,";",1)
+4 IF '$DATA(^PXRMD(811.5,IEN,0))
Begin DoDot:1
+5 SET TEXT="Trying to use term number "_IEN_" it does not exist!"
+6 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+7 SET VALID=1
+8 IF $DATA(^PXRMD(811.5,IEN,20,"E","PXRMD(811.4,"))
Begin DoDot:1
+9 SET IND=0
+10 FOR
SET IND=$ORDER(^PXRMD(811.5,IEN,20,"E","PXRMD(811.4,",IND))
IF IND=""
QUIT
Begin DoDot:2
+11 SET VALID=$$CCF(IND)
+12 IF 'VALID
Begin DoDot:3
+13 SET TEXT="The computed finding is used in term "_$PIECE(^PXRMD(811.5,IEN,0),U,1)_"."
+14 DO EN^DDIOL(TEXT)
End DoDot:3
End DoDot:2
End DoDot:1
+15 QUIT VALID
+16 ;
+17 ;==================================================
HF(DEFARR,FINUM) ;
+1 ;If a health factor is used its Within Category Rank must be 0.
+2 NEW WCR,TEXT
+3 SET WCR=$PIECE(DEFARR(20,FINUM,0),U,10)
+4 IF WCR=0
QUIT 1
+5 SET TEXT="Finding "_FINUM_" is a health factor and its Within Category Rank is not 0!"
+6 DO EN^DDIOL(TEXT)
+7 QUIT 0
+8 ;
+9 ;==================================================
VDEF(RIEN) ;Check a reminder definition and see if it is valid for
+1 ;use in creating a patient list.
+2 NEW AGEFI,AGR,AT,DEFARR,FFL,FI,FIL,FILIST,FINDING,FINUM,FREQ,FUNCTION
+3 NEW FUNN,IND,OPER,MAXAGE,MINAGE,NUMAFI,PCLOG,PFSTACK,ROUTINE
+4 NEW SAAFI,SEXFI,SSTACK,TEMP,TEXT,TYPE,VALID,VF
+5 IF RIEN=""
QUIT 0
+6 IF '$DATA(^PXD(811.9,RIEN))
Begin DoDot:1
+7 SET TEXT="The reminder does not exist!"
+8 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+9 ;
+10 ;See if the reminder is inactive.
+11 IF $PIECE($GET(^PXD(811.9,RIEN,0)),U,6)
Begin DoDot:1
+12 SET TEXT="This reminder is inactive!"
+13 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+14 ;
+15 DO DEF^PXRMLDR(RIEN,.DEFARR)
+16 SET PCLOG=DEFARR(31)
+17 IF PCLOG=""
Begin DoDot:1
+18 SET TEXT="This reminder does not contain any patient cohort logic!"
+19 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+20 ;
+21 ;The cohort logic cannot contain the old-style MRD.
+22 IF $GET(^PXD(811.9,RIEN,30))["MRD"
Begin DoDot:1
+23 SET TEXT="The patient cohort logic cannot contain the old-style MRD!"
+24 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+25 ;
+26 ;The cohort logic cannot start with a not.
+27 IF $EXTRACT(PCLOG,1)="'"
Begin DoDot:1
+28 SET TEXT="The patient cohort logic cannot start with a not!"
+29 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+30 ;
+31 ;The cohort logic cannot contain or not.
+32 ;Change any !(' to !' before checking.
+33 SET TEMP=$TRANSLATE(PCLOG,"(","")
+34 SET TEMP=$TRANSLATE(TEMP,")","")
+35 IF TEMP["!'"
Begin DoDot:1
+36 SET TEXT="The patient cohort logic cannot contain or not!"
+37 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+38 ;
+39 SET OPER="!&~"
+40 SET PCLOG=$$STRREP^PXRMUTIL(PCLOG,"&'","~")
+41 DO POSTFIX^PXRMSTAC(PCLOG,OPER,.PFSTACK)
+42 DO CFSAA^PXRMPLST(.PFSTACK)
+43 MERGE SSTACK=PFSTACK
+44 SET (AGEFI,SAAFI,SEXFI)=0
+45 FOR IND=1:1:PFSTACK(0)
Begin DoDot:1
+46 SET TEMP=$$POP^PXRMSTAC(.PFSTACK)
+47 IF TEMP="AGE"
SET AGEFI=IND
+48 IF TEMP="SAA"
SET SAAFI=IND
+49 IF TEMP="SEX"
SET SEXFI=IND
+50 IF TEMP="'SEX"
SET SEXFI=IND
End DoDot:1
+51 ;
+52 ;If AGE is defined then make sure a baseline age range is defined.
+53 IF (AGEFI)!(SAAFI)
Begin DoDot:1
+54 SET (AGR,IND)=0
+55 FOR
SET IND=+$ORDER(DEFARR(7,IND))
IF IND=0
QUIT
Begin DoDot:2
+56 SET TEMP=DEFARR(7,IND,0)
+57 IF $PIECE(TEMP,U,2)'=""
SET AGR=1
+58 IF $PIECE(TEMP,U,3)'=""
SET AGR=1
End DoDot:2
End DoDot:1
+59 ;
+60 SET TEMP=DEFARR(40)
+61 SET NUMAFI=+$PIECE(TEMP,U,1)
+62 SET FILIST=$PIECE(TEMP,U,2)
+63 IF (AGEFI!SAAFI)
IF ('AGR&(NUMAFI=0))
Begin DoDot:1
+64 SET TEXT(1)="Age is used in the cohort logic and neither a baseline age range or any age"
+65 SET TEXT(2)="findings have been defined!"
+66 DO EN^DDIOL(.TEXT)
End DoDot:1
QUIT 0
+67 ;
+68 ;SEX cannot be the first element unless it is followed by & AGE.
+69 IF (SEXFI=1)
IF ('SAAFI)
Begin DoDot:1
+70 SET TEXT="SEX must be followed by & AGE when it starts the patient cohort logic!"
+71 DO EN^DDIOL(TEXT)
End DoDot:1
QUIT 0
+72 ;If SEX is defined and there is not a combined sex & age finding then
+73 ;a sex must be defined and the logical operator cannot be an or.
+74 SET VALID=1
+75 IF (SEXFI)
IF ('SAAFI)
Begin DoDot:1
+76 IF $PIECE(^PXD(811.9,RIEN,0),U,9)=""
Begin DoDot:2
+77 SET VALID=0
+78 SET TEXT(1)="Sex is used in the patient cohort logic and no sex is defined in the reminder"
+79 SET TEXT(2)="definition!"
+80 DO EN^DDIOL(.TEXT)
End DoDot:2
+81 IF VALID
Begin DoDot:2
+82 SET TEMP=SSTACK(SEXFI+1)
+83 IF TEMP="!"
Begin DoDot:3
+84 SET VALID=0
+85 SET TEXT="SEX cannot be used in conjunction with the or operator!"
+86 DO EN^DDIOL(TEXT)
End DoDot:3
End DoDot:2
End DoDot:1
+87 IF 'VALID
QUIT VALID
+88 ;
+89 ;Check the age findings and see if any of them set the frequency to
+90 ;0Y. If they do they cannot have an associated age range.
+91 FOR IND=1:1:NUMAFI
Begin DoDot:1
+92 SET FINUM=$PIECE(FILIST,";",IND)
+93 SET TEMP=$SELECT(FINUM["FF":DEFARR(25,FINUM,0),1:DEFARR(20,FINUM,0))
+94 SET MINAGE=$PIECE(TEMP,U,2)
+95 SET MAXAGE=$PIECE(TEMP,U,3)
+96 SET FREQ=$PIECE(TEMP,U,4)
+97 IF FREQ="0Y"
IF ((MINAGE'="")!(MAXAGE'=""))
Begin DoDot:2
+98 SET VALID=0
+99 SET TEXT(1)="Finding "_FINUM_" sets the frequency to 0Y and also sets an age range."
+100 SET TEXT(2)="An age range is not allowed with a frequency of 0Y!"
+101 DO EN^DDIOL(.TEXT)
End DoDot:2
End DoDot:1
+102 ;
+103 ;Build a list of all the findings that affect whether or not the
+104 ;patient is in the cohort and check to see if any of them use a
+105 ;computed finding. If they use a computed finding then it must be
+106 ;a list type. Health factors must have within category rank of 0.
+107 FOR IND=1:1:SSTACK(0)
Begin DoDot:1
+108 IF (SSTACK(IND)["FI")
Begin DoDot:2
+109 SET FINUM=$GET(SSTACK(IND+1))
+110 SET FIL(FINUM)=""
End DoDot:2
+111 IF (SSTACK(IND)["FF")
Begin DoDot:2
+112 SET FINUM=$GET(SSTACK(IND+1))
+113 SET FFL(FINUM)="FF"_FINUM
End DoDot:2
End DoDot:1
+114 ;Add any age findings to the list.
+115 FOR IND=1:1:NUMAFI
Begin DoDot:1
+116 SET TEMP=$PIECE(FILIST,";",IND)
+117 IF TEMP=+TEMP
SET FIL(TEMP)=""
+118 IF TEMP["FF"
SET FFL($PIECE(TEMP,"FF",2))=TEMP
End DoDot:1
+119 ;Add findings used by function findings to the list.
+120 SET IND=0
+121 FOR
SET IND=$ORDER(FFL(IND))
IF IND=""
QUIT
Begin DoDot:1
+122 SET FUNN=0
+123 SET FUNN=$ORDER(DEFARR(25,FFL(IND),5,FUNN))
IF FUNN=""
QUIT
Begin DoDot:2
+124 SET FUNCTION=$PIECE(DEFARR(25,FFL(IND),5,FUNN,0),U,2)
+125 SET ROUTINE=$PIECE(^PXRMD(802.4,FUNCTION,0),U,1)
+126 SET ROUTINE=$TRANSLATE(ROUTINE,"_","")
+127 SET FI=0
+128 FOR
SET FI=$ORDER(DEFARR(25,FFL(IND),5,FUNN,20,FI))
IF FI=""
QUIT
Begin DoDot:3
+129 SET FINUM=DEFARR(25,FFL(IND),5,FUNN,20,FI,0)
+130 ;Determine if this subscript is a finding or not before checking
+131 ;if the finding exists.
+132 SET AT=$$ARGTYPE^PXRMFFAT(ROUTINE,FI)
+133 IF AT'="F"
QUIT
+134 SET FIL(FINUM)=""
+135 IF '$DATA(DEFARR(20,FINUM))
Begin DoDot:4
+136 SET VALID=0
+137 SET TEXT="Finding "_FINUM_" is used in FF("_IND_") and it does not exist!"
+138 DO EN^DDIOL(TEXT)
End DoDot:4
QUIT
End DoDot:3
End DoDot:2
End DoDot:1
+139 IF 'VALID
QUIT VALID
+140 SET IND=0
+141 FOR
SET IND=$ORDER(FIL(IND))
IF IND=""
QUIT
Begin DoDot:1
+142 SET FINDING=$PIECE($GET(DEFARR(20,IND,0)),U,1)
+143 IF FINDING=""
Begin DoDot:2
+144 SET VALID=0
+145 SET TEXT="Finding number "_IND_" does not exist!"
+146 DO EN^DDIOL(TEXT)
End DoDot:2
QUIT
+147 SET TEMP=$PIECE(FINDING,";",2)
+148 SET TYPE=$SELECT(TEMP="AUTTHF(":"HF",TEMP="PXRMD(811.4,":"CF",TEMP="PXRMD(811.5,":"TERM",1:"REG")
+149 IF TYPE="REG"
QUIT
+150 IF TYPE="CF"
SET VF=$$CCF(FINDING)
+151 IF TYPE="HF"
SET VF=$$HF(.DEFARR,IND)
+152 IF TYPE="TERM"
SET VF=$$CTERM(.DEFARR,IND,FINDING)
+153 IF VF=0
Begin DoDot:2
+154 SET VALID=0
+155 SET TEXT="Finding number "_IND_" is the problem finding."
+156 DO EN^DDIOL(TEXT)
End DoDot:2
End DoDot:1
+157 QUIT VALID
+158 ;