PSOPKIV1 ;BHAM ISC/MHA - validate PKI cert. ; 05/09/2002 8:15 am
;;7.0;OUTPATIENT PHARMACY;**131,146,223,148,249,391,426,462,572,630,545**;DEC 1997;Build 270
;Ref. to ^ORDEA is supported by DBIA 5709
;Ref. to ^ORB supported by DBIA 1362
;Ref. to ^XUSSPKI supported by DBIA 3539
;*545 - Replaced 'Certificate expired' with 'Rx processed: PIV Card Cert Expired - NO ACTION REQ'
;*545 - Replaced 'Certificate revoked' with 'Rx NOT processed: PIV Card Certificate Revoked'
CER ;
;N PKIRT
N PKIRT,MSG ;572
D VERIFY(.PKIRT,ORD)
S PKI=+PKIRT I PKI=1!(PKI=89802020) D Q
. ;S PKI1=1,VALMSG="Digitally Signed Order",PKIE="Processing "_VALMSG
. S PKI1=1,MSG="Digitally Signed Order",PKIE="Processing "_MSG ;572
. I PKI=89802020 S PKIE=PKIE_": "_$P($T(@($E(PKI,7,8))),";;",2)
I PKI<2 S VALMSG=$P(PKIRT,"^",2) Q
S PKI1=$S(PKI>89802014&(PKI<89802020)!((PKI>89802020)&(PKI<89802031)):2,1:1)
S PKIE="Digital Signature Failed: "_$P($T(@($E(PKI,7,8))),";;",2)
I PKI1=2 D
.S VALMSG="Signature Failed: "_$P($T(@($E(PKI,7,8))),";;",2)
.S PKIE=PKIE_" - Order Auto Discontinued"
S:$L(PKIE)>80 PKIE=$E(PKIE,1,80)
Q
L1 ;
S PKID=1,IEN=IEN+1,^TMP($S($G(ST)=1:"PSOAO",1:"PSOPO"),$J,IEN,0)=PKIE
Q
ERR(ER) ;
Q:'ER
N ERM S ERM=$P($T(@($E(ER,7,8))),";;",2) I ERM]"" Q "Signature Failed: "_ERM
Q ""
REA ;
D KV^PSOVER1
W ! S DIR("A")="Enter Override Reason ",DIR(0)="F^5:70",DIR("?")="Free text reason must be entered, should be between 5 to 70 characters and must not contain embedded up-arrow, e.g. Spoke with the Provider."
S:$G(PKIR)]"" DIR("B")=PKIR D ^DIR S:'$D(DIRUT) PKIR=Y
I $D(DIRUT) K PKIR I $D(OR0) S:$P(OR0,"^",3)="RNW" PSONEW("QFLG")=1 S:$P(OR0,"^",3)="NW" PSORX("DFLG")=1
D KV^PSOVER1 K Y Q
ACT(DA) ;
Q:'DA
N I,J D AR
S ^PSRX(DA,"A",0)="^52.3DA^"_J_"^"_J,^PSRX(DA,"A",J,0)=%_"^K^"_DUZ_"^0^INVALID PKI CERT. "_PKI
S ^PSRX(DA,"A",J,2,1,0)=PKIR,^PSRX(DA,"A",J,2,0)="^52.34A^1^1"
K PKIR Q
;
AR ;
S (I,J)=0 F S I=$O(^PSRX(DA,"A",I)) Q:'I S J=I
S J=J+1 D NOW^%DTC Q
DCP ;
Q:'$D(^PS(52.41,ORD,0)) N PKIOR,PKIORM
K ^PS(52.41,"AOR",$P(^PS(52.41,ORD,0),"^",2),+$P($G(^PS(52.41,ORD,"INI")),"^"),ORD),^PS(52.41,"AD",$P(^PS(52.41,ORD,0),"^",12),+$P($G(^PS(52.41,ORD,"INI")),"^"),ORD)
S $P(^PS(52.41,ORD,0),"^",3)="DC"
S PKIE=$P(PKIE," - ")_" - "_PKI,$P(^PS(52.41,ORD,4),"^")=PKIE
S PKIOR=$E(PKI,7,8)
S PKIORM=$S(PKIOR=16:"16:Order has been modified. Resubmit or contact Pharmacy.",PKIOR=17:"17:PIV Certificate revoked. Resubmit or contact Pharmacy.",1:PKIE)
D EN^PSOHLSN($P(^PS(52.41,ORD,0),"^"),"OC",PKIORM,"A")
D ^PSOPKIV2
Q
;
DCV ;
W ! D KV^PSOVER1 K PKIR S DIR(0)="Y",DIR("B")="N",DIR("A",1)="Digitally signed Schedule II Rx cannot be deleted, it can only be D/Ced."
S DIR("A")="Are you sure you want to D/C this Rx: " D ^DIR,KV^PSOVER1
I 'Y S VALMSG="No Action Taken!",VALMBCK="R" Q
S:'$D(INCOM) INCOM="DCed by Pharmacy for PKI" S DIR("B")=INCOM
;
W ! S DIR("A")="Reason for D/Cing",DIR(0)="F^5:75",DIR("?")="Reason must be entered and should be 5 to 75 characters and must not contain embedded uparrow"
D ^DIR I $D(DIRUT) D KV^PSOVER1 S VALMSG="No Action Taken!",VALMBCK="R" Q
S PKIR=Y D KV^PSOVER1
DCV0 Q:'$D(^PS(52.4,DA,0))
S $P(^PSRX(DA,"STA"),"^")=12,$P(^PSRX(DA,3),"^",5)=DT
D REVERSE^PSOBPSU1(DA,,"DC",7),CAN^PSOTPCAN(DA) N I,J D AR
S ^PSRX(DA,"A",J,0)=%_"^C^"_DUZ_"^0^Discontinued during verification"
S J=J+1 D ADR
N PKIX S PKIX=DA D EN^PSOHLSN1(DA,"OD","",PKIR,PSONOOR)
S DA=PKIX S DIK="^PS(52.4," D ^DIK K DIK
Q
;
DCV1 N PKIR,PSONOOR,DA S DA=PSONV,PKIR=$P($G(PKIE),"-")_" - "_PKI,PSONOOR="A" D DCV0
Q
ADR ;
S ^PSRX(DA,"A",0)="^52.3DA^"_J_"^"_J
S ^PSRX(DA,"A",J,0)=%_"^K^"_DUZ_"^0^Digitally signed"
S ^PSRX(DA,"A",J,2,1,0)=$S($G(PKIR)]"":PKIR,1:"Digitally signed order Discontinued"),^PSRX(DA,"A",J,2,0)="^52.34A^1^1"
Q
RV ;
N TY,T,T1,T2,MIG,SG
S (T,T2)=0
F S T=$O(^PS(52.41,ORD,"OBX",T)) Q:'T D
.S T1=0,$P(TY(T2)," ",23)=" "
.F S T1=$O(^PS(52.41,ORD,"OBX",T,2,T1)) Q:'T1 D
..S MIG=^PS(52.41,ORD,"OBX",T,2,T1,0)
..F SG=1:1:$L(MIG," ") S:$L(TY(T2)_" "_$P(MIG," ",SG))>80 T2=T2+1,$P(TY(T2)," ",23)=" " S TY(T2)=$G(TY(T2))_" "_$P(MIG," ",SG)
.S T2=T2+4
Q
;
VERIFY(RET,PSIEN) ;Verify PKI Data
;PSIEN = IEN of file 52.41 ;ORIFN;ACTION - NOTE: if no ACTION then 1 (new order) is assumed
;Returned values: "1" if digital signature verifies
; "-1^error message" if DS fails during initial parameter checking
; "898020xx^message" if DS fails during verification
;
N PSO0,DFN,PSIG,I,INFO,INF1,DEA,INST,HASH,DATE
I $G(PSIEN)="" S RET="-1^Invalid order number" Q
K ^TMP("PSOPKIDATA",$J)
S PSO0=$G(^PS(52.41,PSIEN,0))
S ^TMP("PSOPKIDATA",$J,"ISSUANCE DATE",1)=$$FMTE^XLFDT($P($P(PSO0,"^",6),"."))
;patient inf
S DFN=$P(PSO0,"^",2) D DEM^VADPT,ADD^VADPT
S ^TMP("PSOPKIDATA",$J,"PATIENT NAME",2)=VADM(1)
S ^TMP("PSOPKIDATA",$J,"PATIENT ADDRESS",3)=VAPA(1)_"^"_VAPA(2)_"^"_VAPA(3)_"^"_VAPA(4)_"^"_$P(VAPA(5),"^")_"^"_$P(VAPA(5),"^",2)_"^"_VAPA(6)_"^"_VAPA(7)
S ^TMP("PSOPKIDATA",$J,"QUANTITY",5)=$P(PSO0,"^",10)
K ^TMP($J,"ORDEA")
D ARCHIVE^ORDEA(+PSO0)
;POS DOSE
N J,INF0,INF1,PSIG
S J=0 F S J=$O(^PS(52.41,PSIEN,1,J)) Q:'J D
.S INF0=$G(^PS(52.41,PSIEN,9,J,0)),INF1=$G(^PS(52.41,PSIEN,1,J,1))
.S PSIG=INF0_"|"_$P(INF1,"^")_"|"_$S($E($P(INF1,"^",2))="L":"M"_$E($P(INF1,"^",2),2,99),1:$P(INF1,"^",2))_"|"_$P(INF1,"^",6)_"|"_$P(INF1,"^",8)
.S ^TMP("PSOPKIDATA",$J,"DIRECTIONS",6,J)=PSIG
I +$P(PSO0,"^",9),+$P(PSO0,"^",25) S ^TMP("PSOPKIDATA",$J,"DRUG NAME",4)=$$GET1^DIQ(50,$P(PSO0,"^",9),.01)
S DEA=$P($G(^TMP($J,"ORDEA",+PSO0,2)),"^")
S ^TMP("PSOPKIDATA",$J,"PROVIDER NAME",8)=$$GET1^DIQ(200,$P(PSO0,"^",5),.01)
I $D(^TMP($J,"ORDEA",+PSO0,3)) S ^TMP("PSOPKIDATA",$J,"PROVIDER ADDRESS",9)=$P(^(3),"^",2,6)
E D INSTAD
K ^TMP($J,"ORDEA")
D KVA^VADPT
S ^TMP("PSOPKIDATA",$J,"DEA NUMBER",10)=DEA
S ^TMP("PSOPKIDATA",$J,"ORDER NUMBER",11)=$P(PSO0,"^")
S HASH=$$HASHRTN^ORDEA($P(PSO0,"^"))
I '$L(HASH) S RET="-1^Order has no PKI Hash" G VQT
S DATE=$$FMTE^XLFDT($P($P(PSO0,"^",6),"."))
I '$L(DATE) S RET="-1^No date associated with order" G VQT
I +$P($P(^OR(100,+PSO0,8,$O(^OR(100,+PSO0,8,999),-1),0),"^",6),".") S ^TMP("PSOPKIDATA",$J,"ISSUANCE DATE",1)=$$FMTE^XLFDT($P($P(^OR(100,+PSO0,8,$O(^OR(100,+PSO0,8,999),-1),0),"^",6),".")) ;PSO*7*462
S RET=$$VERIFY^XUSSPKI(HASH,$NA(^TMP("PSOPKIDATA",$J)))
I RET="OK"!(RET["No error found for this certificate or chain") S RET=1 G VQT
N ECD S ECD=898020
I RET[ECD S RET=$P(RET,"^",2) G VQT
I RET["not time-valid" S RET=ECD_"20" G VQT
I RET["has been revoked" S RET=ECD_"17" G VQT
I RET["does not have a valid signature" S RET=ECD_"22" G VQT
I RET["not properly time-nested" S RET=ECD_"23" G VQT
I RET["not valid in its proposed usage" S RET=ECD_"24" G VQT
I RET["based on an untrusted root" S RET=ECD_"25" G VQT
I RET["certificates in the certificate chain is unknown" S RET=ECD_"26" G VQT
I RET["authority that the original certificate had certified" S RET=ECD_"27" G VQT
I RET["certificate chain is not complete" S RET=ECD_"28" G VQT
I RET["this chain did not have a valid signature" S RET=ECD_"29" G VQT
I RET["not valid for this usage" S RET=ECD_"30" G VQT
VQT ;
K ^TMP("PSOPKIDATA",$J)
Q
;
INSTAD ;
S INST=$P($G(^PS(52.41,PSIEN,"INI")),"^")
D GETS^DIQ(4,INST,".01;1.01;1.02;1.03;1.04;.02","E","VADR")
S VADD(1)=$G(VADR(4,INST_",",.01,"E")),VADD(2)=$G(VADR(4,INST_",",1.01,"E")),VADD(3)=$G(VADR(4,INST_",",1.02,"E"))
S VADD(4)=$G(VADR(4,INST_",",1.03,"E")),VADD(5)=$G(VADR(4,INST_",",.02,"E")),VADD(6)=$G(VADR(4,INST_",",1.04,"E"))
S ^TMP("PSOPKIDATA",$J,"PROVIDER ADDRESS",9)=VADD(1)_"^"_VADD(2)_"^"_VADD(3)_"^"_VADD(4)_"^"_VADD(5)_"^"_VADD(6)
Q
;
HSHCHK(ARET,PNP) ;Compares digitally signed archived data in file #101.52 against data in OP pending file #52.41
;PSO*7*391/JAM
;Input - PNP - Pending file IEN
;
;Output - returns 1 if the archived data matches the pending file
; 0 if initial parameter checking fails
; -1 if comparison fails; and return array with failed items
;
N DFN,PND0,DRGNM,DEA,DETOX,DFN,J,I,INST,NAM,SIGFL,DOSE,DOSEP,DOSEX,DFRM,TMP,VADD,VADR,INF0,INF1,ASIG,PSIG,ORP,ND
I $G(PNP)="" S ARET=0 Q ARET
S PND0=$G(^PS(52.41,PNP,0)) I PND0="" S ARET=0 Q ARET
S ORP=$P(PND0,"^") I ORP="" S ARET=0 Q ARET
;get archived data from CPRS
K ^TMP($J,"ORDEA")
D ARCHIVE^ORDEA(ORP)
I '$D(^TMP($J,"ORDEA")) S ARET=0 Q ARET
F I=1:1:5 S TMP(I)=$G(^TMP($J,"ORDEA",ORP,I))
I $P($P(PND0,"^",6),".")'=$P(TMP(1),"^",2) S ARET=-1,ARET("ISSUANCE DATE")=$P(TMP(1),"^",2)_"^"_$P($P(PND0,"^",6),".")
S DRGNM=$$GET1^DIQ(50,$P(PND0,"^",9),.01)
I DRGNM'=$P(TMP(1),"^",3) S ARET=-1,ARET("DRUG NAME")=$P(TMP(1),"^",3)_"^"_DRGNM
I $P(PND0,"^",10)'=$P(TMP(1),"^",6) S ARET=-1,ARET("QTY PRESCRIBED")=$P(TMP(1),"^",6)_"^"_$P(PND0,"^",10)
;provider info
S INST=$P($G(^PS(52.41,PNP,"INI")),"^")
;*545
S DEA=$$RXDEA^PSOUTIL(,ORP)
I DEA'=$P(TMP(2),"^") S ARET=-1,ARET("DEA #")=$P(TMP(2),"^")_"^"_DEA
S NAM=$$GET1^DIQ(200,$P(PND0,"^",5),.01) I NAM'=$P(TMP(2),"^",3) S ARET=-1,ARET("PROVIDER NAME")=$P(TMP(2),"^",3)_"^"_NAM
;patient inf
S DFN=$P(PND0,"^",2) D DEM^VADPT,ADD^VADPT
I VADM(1)'=$P(TMP(4),"^") S ARET=-1,ARET("PATIENT NAME")=$P(TMP(4),"^")_"^"_VADM(1)
I VAPA(1)'=$P(TMP(5),"^") S ARET=-1,ARET("PATIENT ADDRESS #1")=$P(TMP(5),"^")_"^"_VAPA(1)
I VAPA(2)'=$P(TMP(5),"^",2) S ARET=-1,ARET("PATIENT ADDRESS #2")=$P(TMP(5),"^",2)_"^"_VAPA(2)
I VAPA(3)'=$P(TMP(5),"^",3) S ARET=-1,ARET("PATIENT ADDRESS #3")=$P(TMP(5),"^",3)_"^"_VAPA(3)
I VAPA(4)'=$P(TMP(5),"^",4) S ARET=-1,ARET("PATIENT CITY")=$P(TMP(5),"^",4)_"^"_VAPA(4)
I $P(VAPA(5),"^",2)'=$P(TMP(5),"^",5) S ARET=-1,ARET("PATIENT STATE")=$P(TMP(5),"^",5)_"^"_$P(VAPA(5),"^",2)
I VAPA(6)'=$P(TMP(5),"^",6) S ARET=-1,ARET("PATIENT ZIP+4")=$P(TMP(5),"^",6)_"^"_VAPA(6)
;sig
M ASIG=^TMP($J,"ORDEA",ORP,6)
S I=0 F S I=$O(^PS(52.41,PNP,1,I)) Q:'I D
.S INF0=$G(^PS(52.41,PNP,9,I,0)),INF1=$G(^PS(52.41,PNP,1,I,1))
.S PSIG(I)=INF0_"|"_$P(INF1,"^")_"|"_$P(INF1,"^",2)_"|"_$P(INF1,"^",6)_"|"_$P(INF1,"^",8)
S I=0 F S I=$O(ASIG(I)) Q:'I I ASIG(I)'=$G(PSIG(I)) S ND="SIG #"_I,ARET=-1 S ARET(ND)=ASIG(I)_"^"_$G(PSIG(I))
D KVA^VADPT
K ^TMP($J,"ORDEA")
Q $S($G(ARET):ARET,1:1)
;
ALERT ;
; ORN=76 - Notification ID (ifn from OE/RR Notifications file #100.9)
; ORBDFN=Patient DFN from Patient file #2
; ORNUM=Order ifn from Order file #100
; ORBADUZ=Provider DUZ - Array of notification recipients requested by the calling package.
; ORBPMSG=Message text
; ORBPDATA=This is an identifier of the package entry which the notification is based on.
; For radiology: Rad/Nuc Med exam/case ifn's(format: exam_ifn;case_ifn)
; For consults: the IEN of the consult in file 123
N PSOX S PSOX=1
S PSOX(+$P(OR0,"^",5))=""
D EN^ORB3(76,PSODFN,$P(OR0,"^"),.PSOX,"Rx processed: PIV Card Cert Expired - NO ACTION REQ","") ;PSO*7*630
Q
;
00 ;;Order Text is blank;;
01 ;;DEA # missing;;
02 ;;Drug Schedule missing;;
03 ;;DEA # not valid;;
04 ;;Valid Certificate not found;;
05 ;;Couldn't load CSP;;
06 ;;Smart card Reader not found;;
07 ;;Certificate with DEA # not found;;
08 ;;Certificate not valid for schedule;;
10 ;;Crypto Error (contact IRM);;
15 ;;Corrupted (Decode failure);;
16 ;;Corrupted (Hash mismatch);;
17 ;;Rx NOT processed: PIV Card Certificate Revoked;;
18 ;;Verification failure;;
19 ;;Before Cert effective date;;
20 ;;Rx processed: PIV Card Cert Expired - NO ACTION REQ;;
21 ;;No Cert with a valid date found;;
22 ;;Signature Check failed (Invalid Signature);;
23 ;;CERT_IS_NOT_TIME_NESTED;;
24 ;;CERT_IS_NOT_VALID_FOR_USAGE;;
25 ;;CERT_IS_UNTRUSTED_ROOT;;
26 ;;CERT_REVOCATION_STATUS_UNKNOWN;;
27 ;;CERT_IS_CYCLIC;;
28 ;;CERT_IS_PARTIAL_CHAIN;;
29 ;;CERT_CTL_IS_NOT_SIGNATURE_VALID;;
30 ;;CERT_CTL_IS_NOT_VALID_FOR_USAGE;;
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HPSOPKIV1 12023 printed Sep 02, 2024@19:17:51 Page 2
PSOPKIV1 ;BHAM ISC/MHA - validate PKI cert. ; 05/09/2002 8:15 am
+1 ;;7.0;OUTPATIENT PHARMACY;**131,146,223,148,249,391,426,462,572,630,545**;DEC 1997;Build 270
+2 ;Ref. to ^ORDEA is supported by DBIA 5709
+3 ;Ref. to ^ORB supported by DBIA 1362
+4 ;Ref. to ^XUSSPKI supported by DBIA 3539
+5 ;*545 - Replaced 'Certificate expired' with 'Rx processed: PIV Card Cert Expired - NO ACTION REQ'
+6 ;*545 - Replaced 'Certificate revoked' with 'Rx NOT processed: PIV Card Certificate Revoked'
CER ;
+1 ;N PKIRT
+2 ;572
NEW PKIRT,MSG
+3 DO VERIFY(.PKIRT,ORD)
+4 SET PKI=+PKIRT
IF PKI=1!(PKI=89802020)
Begin DoDot:1
+5 ;S PKI1=1,VALMSG="Digitally Signed Order",PKIE="Processing "_VALMSG
+6 ;572
SET PKI1=1
SET MSG="Digitally Signed Order"
SET PKIE="Processing "_MSG
+7 IF PKI=89802020
SET PKIE=PKIE_": "_$PIECE($TEXT(@($EXTRACT(PKI,7,8))),";;",2)
End DoDot:1
QUIT
+8 IF PKI<2
SET VALMSG=$PIECE(PKIRT,"^",2)
QUIT
+9 SET PKI1=$SELECT(PKI>89802014&(PKI<89802020)!((PKI>89802020)&(PKI<89802031)):2,1:1)
+10 SET PKIE="Digital Signature Failed: "_$PIECE($TEXT(@($EXTRACT(PKI,7,8))),";;",2)
+11 IF PKI1=2
Begin DoDot:1
+12 SET VALMSG="Signature Failed: "_$PIECE($TEXT(@($EXTRACT(PKI,7,8))),";;",2)
+13 SET PKIE=PKIE_" - Order Auto Discontinued"
End DoDot:1
+14 if $LENGTH(PKIE)>80
SET PKIE=$EXTRACT(PKIE,1,80)
+15 QUIT
L1 ;
+1 SET PKID=1
SET IEN=IEN+1
SET ^TMP($SELECT($GET(ST)=1:"PSOAO",1:"PSOPO"),$JOB,IEN,0)=PKIE
+2 QUIT
ERR(ER) ;
+1 if 'ER
QUIT
+2 NEW ERM
SET ERM=$PIECE($TEXT(@($EXTRACT(ER,7,8))),";;",2)
IF ERM]""
QUIT "Signature Failed: "_ERM
+3 QUIT ""
REA ;
+1 DO KV^PSOVER1
+2 WRITE !
SET DIR("A")="Enter Override Reason "
SET DIR(0)="F^5:70"
SET DIR("?")="Free text reason must be entered, should be between 5 to 70 characters and must not contain embedded up-arrow, e.g. Spoke with the Provider."
+3 if $GET(PKIR)]""
SET DIR("B")=PKIR
DO ^DIR
if '$DATA(DIRUT)
SET PKIR=Y
+4 IF $DATA(DIRUT)
KILL PKIR
IF $DATA(OR0)
if $PIECE(OR0,"^",3)="RNW"
SET PSONEW("QFLG")=1
if $PIECE(OR0,"^",3)="NW"
SET PSORX("DFLG")=1
+5 DO KV^PSOVER1
KILL Y
QUIT
ACT(DA) ;
+1 if 'DA
QUIT
+2 NEW I,J
DO AR
+3 SET ^PSRX(DA,"A",0)="^52.3DA^"_J_"^"_J
SET ^PSRX(DA,"A",J,0)=%_"^K^"_DUZ_"^0^INVALID PKI CERT. "_PKI
+4 SET ^PSRX(DA,"A",J,2,1,0)=PKIR
SET ^PSRX(DA,"A",J,2,0)="^52.34A^1^1"
+5 KILL PKIR
QUIT
+6 ;
AR ;
+1 SET (I,J)=0
FOR
SET I=$ORDER(^PSRX(DA,"A",I))
if 'I
QUIT
SET J=I
+2 SET J=J+1
DO NOW^%DTC
QUIT
DCP ;
+1 if '$DATA(^PS(52.41,ORD,0))
QUIT
NEW PKIOR,PKIORM
+2 KILL ^PS(52.41,"AOR",$PIECE(^PS(52.41,ORD,0),"^",2),+$PIECE($GET(^PS(52.41,ORD,"INI")),"^"),ORD),^PS(52.41,"AD",$PIECE(^PS(52.41,ORD,0),"^",12),+$PIECE($GET(^PS(52.41,ORD,"INI")),"^"),ORD)
+3 SET $PIECE(^PS(52.41,ORD,0),"^",3)="DC"
+4 SET PKIE=$PIECE(PKIE," - ")_" - "_PKI
SET $PIECE(^PS(52.41,ORD,4),"^")=PKIE
+5 SET PKIOR=$EXTRACT(PKI,7,8)
+6 SET PKIORM=$SELECT(PKIOR=16:"16:Order has been modified. Resubmit or contact Pharmacy.",PKIOR=17:"17:PIV Certificate revoked. Resubmit or contact Pharmacy.",1:PKIE)
+7 DO EN^PSOHLSN($PIECE(^PS(52.41,ORD,0),"^"),"OC",PKIORM,"A")
+8 DO ^PSOPKIV2
+9 QUIT
+10 ;
DCV ;
+1 WRITE !
DO KV^PSOVER1
KILL PKIR
SET DIR(0)="Y"
SET DIR("B")="N"
SET DIR("A",1)="Digitally signed Schedule II Rx cannot be deleted, it can only be D/Ced."
+2 SET DIR("A")="Are you sure you want to D/C this Rx: "
DO ^DIR
DO KV^PSOVER1
+3 IF 'Y
SET VALMSG="No Action Taken!"
SET VALMBCK="R"
QUIT
+4 if '$DATA(INCOM)
SET INCOM="DCed by Pharmacy for PKI"
SET DIR("B")=INCOM
+5 ;
+6 WRITE !
SET DIR("A")="Reason for D/Cing"
SET DIR(0)="F^5:75"
SET DIR("?")="Reason must be entered and should be 5 to 75 characters and must not contain embedded uparrow"
+7 DO ^DIR
IF $DATA(DIRUT)
DO KV^PSOVER1
SET VALMSG="No Action Taken!"
SET VALMBCK="R"
QUIT
+8 SET PKIR=Y
DO KV^PSOVER1
DCV0 if '$DATA(^PS(52.4,DA,0))
QUIT
+1 SET $PIECE(^PSRX(DA,"STA"),"^")=12
SET $PIECE(^PSRX(DA,3),"^",5)=DT
+2 DO REVERSE^PSOBPSU1(DA,,"DC",7)
DO CAN^PSOTPCAN(DA)
NEW I,J
DO AR
+3 SET ^PSRX(DA,"A",J,0)=%_"^C^"_DUZ_"^0^Discontinued during verification"
+4 SET J=J+1
DO ADR
+5 NEW PKIX
SET PKIX=DA
DO EN^PSOHLSN1(DA,"OD","",PKIR,PSONOOR)
+6 SET DA=PKIX
SET DIK="^PS(52.4,"
DO ^DIK
KILL DIK
+7 QUIT
+8 ;
DCV1 NEW PKIR,PSONOOR,DA
SET DA=PSONV
SET PKIR=$PIECE($GET(PKIE),"-")_" - "_PKI
SET PSONOOR="A"
DO DCV0
+1 QUIT
ADR ;
+1 SET ^PSRX(DA,"A",0)="^52.3DA^"_J_"^"_J
+2 SET ^PSRX(DA,"A",J,0)=%_"^K^"_DUZ_"^0^Digitally signed"
+3 SET ^PSRX(DA,"A",J,2,1,0)=$SELECT($GET(PKIR)]"":PKIR,1:"Digitally signed order Discontinued")
SET ^PSRX(DA,"A",J,2,0)="^52.34A^1^1"
+4 QUIT
RV ;
+1 NEW TY,T,T1,T2,MIG,SG
+2 SET (T,T2)=0
+3 FOR
SET T=$ORDER(^PS(52.41,ORD,"OBX",T))
if 'T
QUIT
Begin DoDot:1
+4 SET T1=0
SET $PIECE(TY(T2)," ",23)=" "
+5 FOR
SET T1=$ORDER(^PS(52.41,ORD,"OBX",T,2,T1))
if 'T1
QUIT
Begin DoDot:2
+6 SET MIG=^PS(52.41,ORD,"OBX",T,2,T1,0)
+7 FOR SG=1:1:$LENGTH(MIG," ")
if $LENGTH(TY(T2)_" "_$PIECE(MIG," ",SG))>80
SET T2=T2+1
SET $PIECE(TY(T2)," ",23)=" "
SET TY(T2)=$GET(TY(T2))_" "_$PIECE(MIG," ",SG)
End DoDot:2
+8 SET T2=T2+4
End DoDot:1
+9 QUIT
+10 ;
VERIFY(RET,PSIEN) ;Verify PKI Data
+1 ;PSIEN = IEN of file 52.41 ;ORIFN;ACTION - NOTE: if no ACTION then 1 (new order) is assumed
+2 ;Returned values: "1" if digital signature verifies
+3 ; "-1^error message" if DS fails during initial parameter checking
+4 ; "898020xx^message" if DS fails during verification
+5 ;
+6 NEW PSO0,DFN,PSIG,I,INFO,INF1,DEA,INST,HASH,DATE
+7 IF $GET(PSIEN)=""
SET RET="-1^Invalid order number"
QUIT
+8 KILL ^TMP("PSOPKIDATA",$JOB)
+9 SET PSO0=$GET(^PS(52.41,PSIEN,0))
+10 SET ^TMP("PSOPKIDATA",$JOB,"ISSUANCE DATE",1)=$$FMTE^XLFDT($PIECE($PIECE(PSO0,"^",6),"."))
+11 ;patient inf
+12 SET DFN=$PIECE(PSO0,"^",2)
DO DEM^VADPT
DO ADD^VADPT
+13 SET ^TMP("PSOPKIDATA",$JOB,"PATIENT NAME",2)=VADM(1)
+14 SET ^TMP("PSOPKIDATA",$JOB,"PATIENT ADDRESS",3)=VAPA(1)_"^"_VAPA(2)_"^"_VAPA(3)_"^"_VAPA(4)_"^"_$PIECE(VAPA(5),"^")_"^"_$PIECE(VAPA(5),"^",2)_"^"_VAPA(6)_"^"_VAPA(7)
+15 SET ^TMP("PSOPKIDATA",$JOB,"QUANTITY",5)=$PIECE(PSO0,"^",10)
+16 KILL ^TMP($JOB,"ORDEA")
+17 DO ARCHIVE^ORDEA(+PSO0)
+18 ;POS DOSE
+19 NEW J,INF0,INF1,PSIG
+20 SET J=0
FOR
SET J=$ORDER(^PS(52.41,PSIEN,1,J))
if 'J
QUIT
Begin DoDot:1
+21 SET INF0=$GET(^PS(52.41,PSIEN,9,J,0))
SET INF1=$GET(^PS(52.41,PSIEN,1,J,1))
+22 SET PSIG=INF0_"|"_$PIECE(INF1,"^")_"|"_$SELECT($EXTRACT($PIECE(INF1,"^",2))="L":"M"_$EXTRACT($PIECE(INF1,"^",2),2,99),1:$PIECE(INF1,"^",2))_"|"_$PIECE(INF1,"^",6)_"|"_$PIECE(INF1,"^",8)
+23 SET ^TMP("PSOPKIDATA",$JOB,"DIRECTIONS",6,J)=PSIG
End DoDot:1
+24 IF +$PIECE(PSO0,"^",9)
IF +$PIECE(PSO0,"^",25)
SET ^TMP("PSOPKIDATA",$JOB,"DRUG NAME",4)=$$GET1^DIQ(50,$PIECE(PSO0,"^",9),.01)
+25 SET DEA=$PIECE($GET(^TMP($JOB,"ORDEA",+PSO0,2)),"^")
+26 SET ^TMP("PSOPKIDATA",$JOB,"PROVIDER NAME",8)=$$GET1^DIQ(200,$PIECE(PSO0,"^",5),.01)
+27 IF $DATA(^TMP($JOB,"ORDEA",+PSO0,3))
SET ^TMP("PSOPKIDATA",$JOB,"PROVIDER ADDRESS",9)=$PIECE(^(3),"^",2,6)
+28 IF '$TEST
DO INSTAD
+29 KILL ^TMP($JOB,"ORDEA")
+30 DO KVA^VADPT
+31 SET ^TMP("PSOPKIDATA",$JOB,"DEA NUMBER",10)=DEA
+32 SET ^TMP("PSOPKIDATA",$JOB,"ORDER NUMBER",11)=$PIECE(PSO0,"^")
+33 SET HASH=$$HASHRTN^ORDEA($PIECE(PSO0,"^"))
+34 IF '$LENGTH(HASH)
SET RET="-1^Order has no PKI Hash"
GOTO VQT
+35 SET DATE=$$FMTE^XLFDT($PIECE($PIECE(PSO0,"^",6),"."))
+36 IF '$LENGTH(DATE)
SET RET="-1^No date associated with order"
GOTO VQT
+37 ;PSO*7*462
IF +$PIECE($PIECE(^OR(100,+PSO0,8,$ORDER(^OR(100,+PSO0,8,999),-1),0),"^",6),".")
SET ^TMP("PSOPKIDATA",$JOB,"ISSUANCE DATE",1)=$$FMTE^XLFDT($PIECE($PIECE(^OR(100,+PSO0,8,$ORDER(^OR(100,+PSO0,8,999),-1),0),"^",6),"."))
+38 SET RET=$$VERIFY^XUSSPKI(HASH,$NAME(^TMP("PSOPKIDATA",$JOB)))
+39 IF RET="OK"!(RET["No error found for this certificate or chain")
SET RET=1
GOTO VQT
+40 NEW ECD
SET ECD=898020
+41 IF RET[ECD
SET RET=$PIECE(RET,"^",2)
GOTO VQT
+42 IF RET["not time-valid"
SET RET=ECD_"20"
GOTO VQT
+43 IF RET["has been revoked"
SET RET=ECD_"17"
GOTO VQT
+44 IF RET["does not have a valid signature"
SET RET=ECD_"22"
GOTO VQT
+45 IF RET["not properly time-nested"
SET RET=ECD_"23"
GOTO VQT
+46 IF RET["not valid in its proposed usage"
SET RET=ECD_"24"
GOTO VQT
+47 IF RET["based on an untrusted root"
SET RET=ECD_"25"
GOTO VQT
+48 IF RET["certificates in the certificate chain is unknown"
SET RET=ECD_"26"
GOTO VQT
+49 IF RET["authority that the original certificate had certified"
SET RET=ECD_"27"
GOTO VQT
+50 IF RET["certificate chain is not complete"
SET RET=ECD_"28"
GOTO VQT
+51 IF RET["this chain did not have a valid signature"
SET RET=ECD_"29"
GOTO VQT
+52 IF RET["not valid for this usage"
SET RET=ECD_"30"
GOTO VQT
VQT ;
+1 KILL ^TMP("PSOPKIDATA",$JOB)
+2 QUIT
+3 ;
INSTAD ;
+1 SET INST=$PIECE($GET(^PS(52.41,PSIEN,"INI")),"^")
+2 DO GETS^DIQ(4,INST,".01;1.01;1.02;1.03;1.04;.02","E","VADR")
+3 SET VADD(1)=$GET(VADR(4,INST_",",.01,"E"))
SET VADD(2)=$GET(VADR(4,INST_",",1.01,"E"))
SET VADD(3)=$GET(VADR(4,INST_",",1.02,"E"))
+4 SET VADD(4)=$GET(VADR(4,INST_",",1.03,"E"))
SET VADD(5)=$GET(VADR(4,INST_",",.02,"E"))
SET VADD(6)=$GET(VADR(4,INST_",",1.04,"E"))
+5 SET ^TMP("PSOPKIDATA",$JOB,"PROVIDER ADDRESS",9)=VADD(1)_"^"_VADD(2)_"^"_VADD(3)_"^"_VADD(4)_"^"_VADD(5)_"^"_VADD(6)
+6 QUIT
+7 ;
HSHCHK(ARET,PNP) ;Compares digitally signed archived data in file #101.52 against data in OP pending file #52.41
+1 ;PSO*7*391/JAM
+2 ;Input - PNP - Pending file IEN
+3 ;
+4 ;Output - returns 1 if the archived data matches the pending file
+5 ; 0 if initial parameter checking fails
+6 ; -1 if comparison fails; and return array with failed items
+7 ;
+8 NEW DFN,PND0,DRGNM,DEA,DETOX,DFN,J,I,INST,NAM,SIGFL,DOSE,DOSEP,DOSEX,DFRM,TMP,VADD,VADR,INF0,INF1,ASIG,PSIG,ORP,ND
+9 IF $GET(PNP)=""
SET ARET=0
QUIT ARET
+10 SET PND0=$GET(^PS(52.41,PNP,0))
IF PND0=""
SET ARET=0
QUIT ARET
+11 SET ORP=$PIECE(PND0,"^")
IF ORP=""
SET ARET=0
QUIT ARET
+12 ;get archived data from CPRS
+13 KILL ^TMP($JOB,"ORDEA")
+14 DO ARCHIVE^ORDEA(ORP)
+15 IF '$DATA(^TMP($JOB,"ORDEA"))
SET ARET=0
QUIT ARET
+16 FOR I=1:1:5
SET TMP(I)=$GET(^TMP($JOB,"ORDEA",ORP,I))
+17 IF $PIECE($PIECE(PND0,"^",6),".")'=$PIECE(TMP(1),"^",2)
SET ARET=-1
SET ARET("ISSUANCE DATE")=$PIECE(TMP(1),"^",2)_"^"_$PIECE($PIECE(PND0,"^",6),".")
+18 SET DRGNM=$$GET1^DIQ(50,$PIECE(PND0,"^",9),.01)
+19 IF DRGNM'=$PIECE(TMP(1),"^",3)
SET ARET=-1
SET ARET("DRUG NAME")=$PIECE(TMP(1),"^",3)_"^"_DRGNM
+20 IF $PIECE(PND0,"^",10)'=$PIECE(TMP(1),"^",6)
SET ARET=-1
SET ARET("QTY PRESCRIBED")=$PIECE(TMP(1),"^",6)_"^"_$PIECE(PND0,"^",10)
+21 ;provider info
+22 SET INST=$PIECE($GET(^PS(52.41,PNP,"INI")),"^")
+23 ;*545
+24 SET DEA=$$RXDEA^PSOUTIL(,ORP)
+25 IF DEA'=$PIECE(TMP(2),"^")
SET ARET=-1
SET ARET("DEA #")=$PIECE(TMP(2),"^")_"^"_DEA
+26 SET NAM=$$GET1^DIQ(200,$PIECE(PND0,"^",5),.01)
IF NAM'=$PIECE(TMP(2),"^",3)
SET ARET=-1
SET ARET("PROVIDER NAME")=$PIECE(TMP(2),"^",3)_"^"_NAM
+27 ;patient inf
+28 SET DFN=$PIECE(PND0,"^",2)
DO DEM^VADPT
DO ADD^VADPT
+29 IF VADM(1)'=$PIECE(TMP(4),"^")
SET ARET=-1
SET ARET("PATIENT NAME")=$PIECE(TMP(4),"^")_"^"_VADM(1)
+30 IF VAPA(1)'=$PIECE(TMP(5),"^")
SET ARET=-1
SET ARET("PATIENT ADDRESS #1")=$PIECE(TMP(5),"^")_"^"_VAPA(1)
+31 IF VAPA(2)'=$PIECE(TMP(5),"^",2)
SET ARET=-1
SET ARET("PATIENT ADDRESS #2")=$PIECE(TMP(5),"^",2)_"^"_VAPA(2)
+32 IF VAPA(3)'=$PIECE(TMP(5),"^",3)
SET ARET=-1
SET ARET("PATIENT ADDRESS #3")=$PIECE(TMP(5),"^",3)_"^"_VAPA(3)
+33 IF VAPA(4)'=$PIECE(TMP(5),"^",4)
SET ARET=-1
SET ARET("PATIENT CITY")=$PIECE(TMP(5),"^",4)_"^"_VAPA(4)
+34 IF $PIECE(VAPA(5),"^",2)'=$PIECE(TMP(5),"^",5)
SET ARET=-1
SET ARET("PATIENT STATE")=$PIECE(TMP(5),"^",5)_"^"_$PIECE(VAPA(5),"^",2)
+35 IF VAPA(6)'=$PIECE(TMP(5),"^",6)
SET ARET=-1
SET ARET("PATIENT ZIP+4")=$PIECE(TMP(5),"^",6)_"^"_VAPA(6)
+36 ;sig
+37 MERGE ASIG=^TMP($JOB,"ORDEA",ORP,6)
+38 SET I=0
FOR
SET I=$ORDER(^PS(52.41,PNP,1,I))
if 'I
QUIT
Begin DoDot:1
+39 SET INF0=$GET(^PS(52.41,PNP,9,I,0))
SET INF1=$GET(^PS(52.41,PNP,1,I,1))
+40 SET PSIG(I)=INF0_"|"_$PIECE(INF1,"^")_"|"_$PIECE(INF1,"^",2)_"|"_$PIECE(INF1,"^",6)_"|"_$PIECE(INF1,"^",8)
End DoDot:1
+41 SET I=0
FOR
SET I=$ORDER(ASIG(I))
if 'I
QUIT
IF ASIG(I)'=$GET(PSIG(I))
SET ND="SIG #"_I
SET ARET=-1
SET ARET(ND)=ASIG(I)_"^"_$GET(PSIG(I))
+42 DO KVA^VADPT
+43 KILL ^TMP($JOB,"ORDEA")
+44 QUIT $SELECT($GET(ARET):ARET,1:1)
+45 ;
ALERT ;
+1 ; ORN=76 - Notification ID (ifn from OE/RR Notifications file #100.9)
+2 ; ORBDFN=Patient DFN from Patient file #2
+3 ; ORNUM=Order ifn from Order file #100
+4 ; ORBADUZ=Provider DUZ - Array of notification recipients requested by the calling package.
+5 ; ORBPMSG=Message text
+6 ; ORBPDATA=This is an identifier of the package entry which the notification is based on.
+7 ; For radiology: Rad/Nuc Med exam/case ifn's(format: exam_ifn;case_ifn)
+8 ; For consults: the IEN of the consult in file 123
+9 NEW PSOX
SET PSOX=1
+10 SET PSOX(+$PIECE(OR0,"^",5))=""
+11 ;PSO*7*630
DO EN^ORB3(76,PSODFN,$PIECE(OR0,"^"),.PSOX,"Rx processed: PIV Card Cert Expired - NO ACTION REQ","")
+12 QUIT
+13 ;
00 ;;Order Text is blank;;
01 ;;DEA # missing;;
02 ;;Drug Schedule missing;;
03 ;;DEA # not valid;;
04 ;;Valid Certificate not found;;
05 ;;Couldn't load CSP;;
06 ;;Smart card Reader not found;;
07 ;;Certificate with DEA # not found;;
08 ;;Certificate not valid for schedule;;
10 ;;Crypto Error (contact IRM);;
15 ;;Corrupted (Decode failure);;
16 ;;Corrupted (Hash mismatch);;
17 ;;Rx NOT processed: PIV Card Certificate Revoked;;
18 ;;Verification failure;;
19 ;;Before Cert effective date;;
20 ;;Rx processed: PIV Card Cert Expired - NO ACTION REQ;;
21 ;;No Cert with a valid date found;;
22 ;;Signature Check failed (Invalid Signature);;
23 ;;CERT_IS_NOT_TIME_NESTED;;
24 ;;CERT_IS_NOT_VALID_FOR_USAGE;;
25 ;;CERT_IS_UNTRUSTED_ROOT;;
26 ;;CERT_REVOCATION_STATUS_UNKNOWN;;
27 ;;CERT_IS_CYCLIC;;
28 ;;CERT_IS_PARTIAL_CHAIN;;
29 ;;CERT_CTL_IS_NOT_SIGNATURE_VALID;;
30 ;;CERT_CTL_IS_NOT_VALID_FOR_USAGE;;