| [613] | 1 | PSXDODH ;BIR/HTW-HL7 Message Conversion ;01/15/02 13:10:52
 | 
|---|
 | 2 |  ;;2.0;CMOP;**38**;11 Apr 97
 | 
|---|
 | 3 |  ;  Convert CMOP transmission messages from HL7 V 2.3.1 to V 2.1
 | 
|---|
 | 4 | START ;  Create 2.1 format 
 | 
|---|
 | 5 | EN(PATH,FNAME) ; needs directory & file name
 | 
|---|
 | 6 |  ; force an error in the next line
 | 
|---|
 | 7 |  ;S X=ERROR ; generate an undefined error 
 | 
|---|
 | 8 |  I $L(PATH),$L(FNAME) I 1
 | 
|---|
 | 9 |  E  S PSXERR="0^BAD PATH OR FILENAME" G ERRMSG
 | 
|---|
 | 10 |  K ^TMP($J,"PSXDOD")
 | 
|---|
 | 11 |  S GBL="^TMP("_$J_",""PSXDOD"",1)"
 | 
|---|
 | 12 |  S Y=$$FTG^%ZISH(PATH,FNAME,GBL,3)
 | 
|---|
 | 13 |  I Y'>0 S PSXERR="9^"_PATH_U_FNAME_U_" DID NOT LOAD" G ERRMSG
 | 
|---|
 | 14 |  I $D(^TMP($J,"PSXDOD"))'>1 S PSXERR="9^"_PATH_U_FNAME_U_" DID NOT LOAD" G ERRMSG
 | 
|---|
 | 15 | EN1 ;
 | 
|---|
 | 16 |  S PSXERR=""
 | 
|---|
 | 17 |  S G="^TMP($J,""PSXDOD"")" ; for global indirection
 | 
|---|
 | 18 |  ; Perform Patient Safety check and gather a few variables
 | 
|---|
 | 19 |  D BLDSEQ^PSXDODH1,TESTBT^PSXDODH1
 | 
|---|
 | 20 |  ;send acknowledgement message
 | 
|---|
 | 21 |  K ACK
 | 
|---|
 | 22 |  S ACK="MSH|^~\&|VistA||CHCS||20010925202704||ORM^O02|573-013240530|P|2.3.1|||NE|NE"
 | 
|---|
 | 23 |  S BATID=BATIDB,PIECE(BHS,"|",11)=BATID
 | 
|---|
 | 24 |  D NOW^%DTC S BATDTM=+$$HLDATE^HLFNC(%)
 | 
|---|
 | 25 |  F YY="BATID^10","BATDTM^7" D PUT(.ACK,"|",YY)
 | 
|---|
 | 26 |  S ACK(1)=ACK,ACK(2)="MSA|CR|"_BATID
 | 
|---|
 | 27 |  I PSXERR'="" S ACK(2)=ACK(2)_"|"_PSXERR
 | 
|---|
 | 28 |  S FNAME2=$P(FNAME,".",1)_".TAC",PATH=$$GET1^DIQ(554,1,21)
 | 
|---|
 | 29 |  I PSXERR'="" D
 | 
|---|
 | 30 |  . F XX=1:1:5 S Y=$$GTF^%ZISH("ACK(1)",1,PATH,FNAME2) Q:Y=1  H 4
 | 
|---|
 | 31 |  . I Y'=1 D FALERT^PSXDODH1(FNAME2,PATH)
 | 
|---|
 | 32 |  . S PATH=$$GET1^DIQ(554,1,22)
 | 
|---|
 | 33 |  . F XX=1:1:5 S Y=$$GTF^%ZISH("ACK(1)",1,PATH,FNAME2) Q:Y=1  H 4
 | 
|---|
 | 34 |  . I Y'=1 D FALERT^PSXDODH1(FNAME2,PATH)
 | 
|---|
 | 35 |  . ;****TESTING
 | 
|---|
 | 36 |  I PSXERR'="" G ERRMSG
 | 
|---|
 | 37 | EN2 ;entry for processing file into Vista Messages
 | 
|---|
 | 38 |  S (LNCNT,MCNT,LMSGLOC,ORDCNT)=0 ;line count, message line count, last $$MSG location, order count
 | 
|---|
 | 39 |  D HEADER^PSXDODH1 ; build $$XMIT & NTE|1 and set into Message    
 | 
|---|
 | 40 |  S XMSUB="DOD CMOP "_FACNUM_"-"_BATNM_" from "_FACNM,XMDUZ=.5
 | 
|---|
 | 41 | XMZ D XMZ^XMA2
 | 
|---|
 | 42 |  S M="^XMB(3.9,XMZ,2)" ; variable reference to MailMan message for construction
 | 
|---|
 | 43 |  S @M@(1,0)=XM
 | 
|---|
 | 44 |  S @M@(2,0)=NTE1,MCNT=2
 | 
|---|
 | 45 |  S LNNUM=3 F  S LNNUM=$O(@G@(LNNUM)) Q:LNNUM'>0  S LN=@G@(LNNUM),SEG=$P(LN,"|") S:SEG["NTE" SEG=$P(LN,"|",1,2) D
 | 
|---|
 | 46 |  . I "NTE|2,NTE|3,NTE|4"[SEG D NTE234
 | 
|---|
 | 47 |  . I SEG="MSH" D MSH
 | 
|---|
 | 48 |  . I SEG="PID" D PID
 | 
|---|
 | 49 |  . I SEG="ORC" D ORC
 | 
|---|
 | 50 |  . I SEG="RXE" D RXE
 | 
|---|
 | 51 |  . I SEG="NTE|7" K NTE7 S NTE7=LN
 | 
|---|
 | 52 |  . I SEG="ZR1" D ZR1,BUILD,SETRX
 | 
|---|
 | 53 |  . I SEG="BTS" D BTS
 | 
|---|
 | 54 |  S ^XMB(3.9,XMZ,2,0)="^^"_MCNT_U_MCNT_U_DT
 | 
|---|
 | 55 |  S XMY("S.PSXX CMOP SERVER")=""
 | 
|---|
 | 56 |  ;S XMY(DUZ)="" ;****TESTING
 | 
|---|
 | 57 |  D ENT1^XMD
 | 
|---|
 | 58 |  D EXIT
 | 
|---|
 | 59 |  Q
 | 
|---|
 | 60 | MSH ;assemble $$MSG, MSH
 | 
|---|
 | 61 |  ;MSH|^~\&|CHCS||VistA||20020219144700||ORM^O01|0124-020501408-1|P|2.3.
 | 
|---|
 | 62 |  D NTE234CK
 | 
|---|
 | 63 |  S DODORD=$P(LN,"|",10),DODORD=$P(DODORD,"-",3)
 | 
|---|
 | 64 |  S ORDCNT=ORDCNT+1
 | 
|---|
 | 65 |  S MCNT=MCNT+1,@M@(MCNT,0)="$MSG^"_ORDCNT ; Set current order $MSG order value
 | 
|---|
 | 66 |  I LMSGLOC S $P(@M@(LMSGLOC,0),"^",3)=MCNT-LMSGLOC ; Set last $MSG's location value of line count
 | 
|---|
 | 67 |  S LMSGLOC=MCNT ; store current $MSGs location
 | 
|---|
 | 68 |  S MSH="MSH|^~\&|CHCS||VistA||20020219144700||ORM|0124-020501408-1|P|2.1|" ;****Testing
 | 
|---|
 | 69 |  S $P(MSH,7,"|")=$P(LN,"|",7),$P(MSH,"|",10)=ORDCNT
 | 
|---|
 | 70 |  S MCNT=MCNT+1,@M@(MCNT,0)=MSH
 | 
|---|
 | 71 |  Q
 | 
|---|
 | 72 | PID ;
 | 
|---|
 | 73 |  ;"PID|||98374511^3^M11||DUCK^CONSTANCE SUSAN||||||1804 MAUMPHREY LANE E.^^HIRANDO^CA^36662||2059880101"
 | 
|---|
 | 74 |  S PID0=$P(LN,"PID|",2)
 | 
|---|
 | 75 |  F YY="PTID^3","PNAME^5","PADD^11","PHONE^13" D PIECE(PID0,"|",YY)
 | 
|---|
 | 76 |  S PT1ST=$P(PNAME,"^",3,99),PTLST=$P(PNAME,"^",1,2) ; VENDOR ADJUSTMENT (REMOVE "^")
 | 
|---|
 | 77 |  S PT1ST=$TR(PT1ST,"^"," "),PNAME=PTLST_"^"_PT1ST ; VENDOR ADJUSTMENT (REMOVE "^")
 | 
|---|
 | 78 |  K PT1ST,PTLST ; VENDOR ADJUSTMENT (REMOVE "^")
 | 
|---|
 | 79 |  S PNAME=$P(PNAME,"^",2,99) ; remove leading "^"
 | 
|---|
 | 80 |  S PID="" F YY="PTID^3","PNAME^5","PADD^11","PHONE^13" D PUT(.PID,"|",YY)
 | 
|---|
 | 81 |  S PID="PID|"_PID
 | 
|---|
 | 82 |  S MCNT=MCNT+1,@M@(MCNT,0)=PID
 | 
|---|
 | 83 |  Q
 | 
|---|
 | 84 |  ;
 | 
|---|
 | 85 | ORC ;Patient Data from ORC and RXE(2.3.1) parse date pieces for RX1,ZX1
 | 
|---|
 | 86 |  ; element mapping contained in document HL7 2.1_2.3 CONVERSION.xls
 | 
|---|
 | 87 |  ;S NODE="ORC|NM|0124-NA1281-2||2^1|||^^^20020213^20020315|||25||^HENDERSON^DIANE|||20020213000000||||||||"
 | 
|---|
 | 88 |  K RX1,ZX1
 | 
|---|
 | 89 |  S ORC=$P(LN,"ORC|",2) ; adjust line for HL7 component counting
 | 
|---|
 | 90 |  F YY="RXINDX^2","RXCNT^4","RXDATES^7","PRVPHY^12","ISSDT^15" D PIECE(ORC,"|",YY)
 | 
|---|
 | 91 |  S RFLDT=$P(RXDATES,"^",4),EXPDT=$P(RXDATES,"^",5)
 | 
|---|
 | 92 |  S MCNT=MCNT+1,@M@(MCNT,0)="ORC|NW|"
 | 
|---|
 | 93 |  Q
 | 
|---|
 | 94 | RXE ;  Start building RX1.  RX1 has data elements from ORC and RXE segments from 3.2.1  
 | 
|---|
 | 95 |  ;S RXE="RXE|100|A0259^AMOXICILLIN 250MG CAP^L|100||CAP||^TAKE ONE FOUR TIMES A DAY AS DIRECTED THEN TAKE 10 THREE TIMES A DAY AS DIRECTE|||||10||25|NA1281|9||20020213151053"
 | 
|---|
 | 96 |  S RXE=$P(LN,"RXE|",2)
 | 
|---|
 | 97 |  F YY="QTY^1","DRUGID^2","SIG^7","NUMRFLS^12","VERPHRM^14","RXNUM^15","RFLRMN^16","LSTRFLDT^18" D PIECE(RXE,"|",YY)
 | 
|---|
 | 98 |  S RXNUM=$P(RXNUM,"-",2)
 | 
|---|
 | 99 |  S ISSDT=$$FMDATE^HLFNC(ISSDT)\1,ISSDT=$$HLDATE^HLFNC(ISSDT) ;strip off time
 | 
|---|
 | 100 |  S LSTRFLDT=$$FMDATE^HLFNC(LSTRFLDT)\1,LSTRFLDT=$$HLDATE^HLFNC(LSTRFLDT)
 | 
|---|
 | 101 |  S SIG=$E(SIG,2,200)
 | 
|---|
 | 102 |  Q
 | 
|---|
 | 103 | ZR1 ;
 | 
|---|
 | 104 |  ;S NODE="ZR1|NA1281|ONSC|1||1|(2of10)|CMOP TEST PHARMACY|30|RXNA1281|||20030213000000|"
 | 
|---|
 | 105 |  S ZR1=$P(LN,"ZR1|",2)
 | 
|---|
 | 106 |  F YY="RXZNUM^1","PATSTAT^2","RNWTYP^3","COPAYID^4","SAFCAP^5","RFLTXT^6","CLNIC^7","DAYSUP^8" D PIECE(ZR1,"|",YY)
 | 
|---|
 | 107 |  F YY="BARCODE^9","WARNFLG^10","RGSTMAIL^11" D PIECE(ZR1,"|",YY)
 | 
|---|
 | 108 |  S MAILID="M",RXCNT=$P(RXCNT,"~",1),PRVPHY=$$FMNAME^HLFNC(PRVPHY,"^")
 | 
|---|
 | 109 |  S LL=$F(PRVPHY," "),$E(PRVPHY,LL-1)="," ;change provider name to FM format "last,first mi jr"
 | 
|---|
 | 110 |  S RXZNUM=$P(RXZNUM,"-",2),SITEID=DIVNUM_"^"_DIVNM
 | 
|---|
 | 111 |  Q
 | 
|---|
 | 112 | BTS ; FINISH
 | 
|---|
 | 113 |  S MCNT=MCNT+1
 | 
|---|
 | 114 |  I LMSGLOC S $P(@M@(LMSGLOC,0),"^",3)=MCNT-LMSGLOC
 | 
|---|
 | 115 |  S END="$$ENDXMIT^^"_DIVNUM_U_BATNM_U_PTCNTB_U_ORDCNTB
 | 
|---|
 | 116 |  ;S END=$$SETELM^PSXDODH1(END,3,"^",693) ;****TESTING
 | 
|---|
 | 117 |  ;S END=$$SETELM^PSXDODH1(END,"4,1","^,-",693) ;****TESTING
 | 
|---|
 | 118 |  S @M@(MCNT,0)=END
 | 
|---|
 | 119 |  Q
 | 
|---|
 | 120 | BUILD ; assemble RX1 & ZX1
 | 
|---|
 | 121 |  ;RX1|NA1367|||||||||||60||P0151^PROPRANOLOL HCL 10MG TAB^L|||||3|20020402|2|||20020502|20020226|0124-NA1367-2||||TAKE ONE TABLET TWICE A DAY
 | 
|---|
 | 122 |  ;ZX1|NA1367|0124^BALBOA|M|1^1|(2of3)|GORDON ,TEVE||20|20020402||1|1|30||RXNA1367||ONSC|BALBOA
 | 
|---|
 | 123 |  ; gather elements from subscripted segment array and assemble the segment
 | 
|---|
 | 124 |  S RXINDX="1"_RXINDX ;****Institution file change for site leading 0s
 | 
|---|
 | 125 |  S RX1=""
 | 
|---|
 | 126 |  F YY="RXINDX^1","QTY^12","DRUGID^14","NUMRFLS^19","ISSDT^20","RFLRMN^21","EXPDT^24","LSTRFLDT^25","RXNUM^26","SIG^30" D PUT(.RX1,"|",YY)
 | 
|---|
 | 127 |  S RX1="RX1|"_RX1
 | 
|---|
 | 128 |  S ZX1=""
 | 
|---|
 | 129 |  S RXCNT=$P(RXCNT,"^",2)
 | 
|---|
 | 130 |  F YY="RXZNUM^1","SITEID^2","MAILID^3","RXCNT^4","RFLTXT^5","PRVPHY^6","RGSTMAIL^7","VERPHRM^8","RFLDT^9" D PUT(.ZX1,"|",YY)
 | 
|---|
 | 131 |  F YY="COPAYID^10","RNWTYP^11","SAFCAP^12","DAYSUP^13","BARCODE^15","WARNFLG^16","PATSTAT^17","CLNIC^18" D PUT(.ZX1,"|",YY)
 | 
|---|
 | 132 |  S ZX1="ZX1|"_ZX1
 | 
|---|
 | 133 |  ; change site number for testing
 | 
|---|
 | 134 |  ;S RX1=$$SETELM^PSXDODH1(RX1,"2,1","|,-",693) ;****TESTING
 | 
|---|
 | 135 |  ;S ZX1=$$SETELM^PSXDODH1(ZX1,"3,1","|,^",693) ;****TESTING
 | 
|---|
 | 136 |  Q
 | 
|---|
 | 137 | SETRX ;put RX1,ZX1,NTE7 into mail message
 | 
|---|
 | 138 |  S MCNT=MCNT+1,@M@(MCNT,0)=RX1
 | 
|---|
 | 139 |  I $L($G(NTE7)) S MCNT=MCNT+1,@M@(MCNT,0)=NTE7 K NTE7
 | 
|---|
 | 140 |  S MCNT=MCNT+1,@M@(MCNT,0)=ZX1
 | 
|---|
 | 141 |  Q
 | 
|---|
 | 142 | NTE234 ; insure 2 3 4 sequence is in place
 | 
|---|
 | 143 |  I SEG="NTE|2" S MCNT=MCNT+1,@M@(MCNT,0)=LN,NTE2=1
 | 
|---|
 | 144 |  I SEG="NTE|3" D  S MCNT=MCNT+1,@M@(MCNT,0)=LN,NTE3=1
 | 
|---|
 | 145 |  . I '$G(NTE2) S MCNT=MCNT+1,@M@(MCNT,0)="NTE|2||",NTE2=1
 | 
|---|
 | 146 |  I SEG="NTE|4" D  S MCNT=MCNT+1,@M@(MCNT,0)=LN,NTE4=1
 | 
|---|
 | 147 |  . I '$G(NTE2) S MCNT=MCNT+1,@M@(MCNT,0)="NTE|2||",NTE2=1
 | 
|---|
 | 148 |  . I '$G(NTE3) S MCNT=MCNT+1,@M@(MCNT,0)="NTE|3||",NTE3=1
 | 
|---|
 | 149 |  Q
 | 
|---|
 | 150 | NTE234CK ; encounter MSH , insure NTE 2,3,4 in place
 | 
|---|
 | 151 |  I '$G(NTE2) S MCNT=MCNT+1,@M@(MCNT,0)="NTE|2||",NTE2=1
 | 
|---|
 | 152 |  I '$G(NTE3) S MCNT=MCNT+1,@M@(MCNT,0)="NTE|3||",NTE3=1
 | 
|---|
 | 153 |  I '$G(NTE4) S MCNT=MCNT+1,@M@(MCNT,0)="NTE|4||",NTE4=1
 | 
|---|
 | 154 |  Q
 | 
|---|
 | 155 | PIECE(REC,DLM,XX) ;
 | 
|---|
 | 156 |  ; Set variable V = piece P of REC using delimiter DLM
 | 
|---|
 | 157 |  N V,P S V=$P(XX,U),P=$P(XX,U,2),@V=$P(REC,DLM,P)
 | 
|---|
 | 158 |  Q
 | 
|---|
 | 159 | PUT(REC,DLM,XX) ;
 | 
|---|
 | 160 |  ; Set Variable V into piece P of REC using delimiter DLM
 | 
|---|
 | 161 |  N V,P S V=$P(XX,U),P=$P(XX,U,2)
 | 
|---|
 | 162 |  S $P(REC,DLM,P)=$G(@V)
 | 
|---|
 | 163 |  Q
 | 
|---|
 | 164 | GETELM(STR,PIECES,SEPS) ;
 | 
|---|
 | 165 |  ; uses STRing and
 | 
|---|
 | 166 |  ; returns value of the element located by path of pieces and separators
 | 
|---|
 | 167 |  ; ex: 1st address line = $$getelm(ORC,"22,1","|,^")
 | 
|---|
 | 168 |  ; or                   = $$getelm(XMIT,"4,2,1","|,\F\,\S|")
 | 
|---|
 | 169 |  N P,S,PI,V,I S V=STR
 | 
|---|
 | 170 |  F I=1:1 S PI=$P(PIECES,",",I) Q:PI=""  S P=I,P(I)=PI,S(I)=$P(SEPS,",",I)
 | 
|---|
 | 171 |  F I=1:1:P S V=$P(V,S(I),P(I))
 | 
|---|
 | 172 |  Q V
 | 
|---|
 | 173 | ERRMSG ;
 | 
|---|
 | 174 | MSGSEQER ;send error message to folks & DOD
 | 
|---|
 | 175 |  ;W !,"error ",PSXERR
 | 
|---|
 | 176 |  S DIRHOLD=$$GET1^DIQ(554,1,23)
 | 
|---|
 | 177 |  S Y=$$GTF^%ZISH($NA(^TMP($J,"PSXDOD",1)),3,DIRHOLD,FNAME)
 | 
|---|
 | 178 |  S XMSUB="DOD CMOP Safety "_FNAME
 | 
|---|
 | 179 |  S XMY("G.PSXX CMOP MANAGERS")=""
 | 
|---|
 | 180 |  ;S XMY(DUZ)="" ;***TESTING
 | 
|---|
 | 181 |  S XMTEXT="PSXTXT("
 | 
|---|
 | 182 |  S PSXTXT(1,0)="DOD CMOP HL7 Conversion to  VA CMOP HL7 experienced an error"
 | 
|---|
 | 183 |  S PSXTXT(2,0)=$G(PSXERR)
 | 
|---|
 | 184 |  S PSXTXT(3,0)="FILE: "_FNAME
 | 
|---|
 | 185 |  S PSXTXT(4,0)="A copy of the file has been placed in the hold directory "_DIRHOLD
 | 
|---|
 | 186 |  D ^XMD
 | 
|---|
 | 187 |  I $E(IOST)="C" W ! F I=1:1:4 W !,PSXTXT(I,0) I I=4 H 3
 | 
|---|
 | 188 |  K PSXTXT,DIRHOLD
 | 
|---|
 | 189 |  Q
 | 
|---|
 | 190 | EXIT ;
 | 
|---|
 | 191 |  K BATIDB,BATIDM,BHS,BTS,DLM,DODORD,END,FHS,FNAME,G,GBL,I,J,JJ,LL,LINE,LMSGLOC
 | 
|---|
 | 192 |  K LN,LNCNT,LNNUM,LSEG,M,MCNT,MSH,NTE1,NTE2,NTE3,NTE4,NTE7,ORC,ORDCNT,ORDCNTB
 | 
|---|
 | 193 |  K P,P1,P2,P3,PATH,PI,PID,PNAME,PSXERR,PSXTXT,PTCNT,PTCNTB,REC,RX1,RXE,RXID1,RXIDC,RXIDE
 | 
|---|
 | 194 |  K S,S1,S2,S3,SEG,SEGSEQ,SEPS,STR,STR0,V,VALUE,XM,XX,Y,YY,ZR1,ZX1
 | 
|---|
 | 195 |  K ADDRESS,BATDTM,BATID,BATIDB,BATIDM,BATNM,DIVISION,DIVNM,DIVNUM,EXPDT,FACNM,FNAME2,FNAME3,ISSDT
 | 
|---|
 | 196 |  K LSTRFLDT,MAILID,NTE1ADD,NTE1DIV,NTE1LOC,PID0,PIECE,PRVPHY,PSXF,RFLDT,RXCNT,RXDATES,RXNUM,RXZNUM
 | 
|---|
 | 197 |  K SIG,SITEID,START,TRANDTS,XMZ
 | 
|---|
 | 198 |  K ^TMP($J,"PSXDOD"),PSXTXT
 | 
|---|
 | 199 |  Q
 | 
|---|
 | 200 | LOADTMP ; load data into ^TMP
 | 
|---|
 | 201 |  K ^TMP($J,"PSXDOD")
 | 
|---|
 | 202 |  F I=1:1 S X=$G(^XMB(3.9,125829,2,I,0)) Q:X=""  S ^TMP($J,"PSXDOD",I)=X
 | 
|---|
 | 203 |  Q
 | 
|---|
 | 204 | CLEARFLS(XX,EXT) ;
 | 
|---|
 | 205 | LOOP K PSXF,PSXL
 | 
|---|
 | 206 |  S PATH=$$GET1^DIQ(554,1,XX),PSXF(EXT)=""
 | 
|---|
 | 207 |  S Y=$$LIST^%ZISH(PATH,"PSXF","PSXL")
 | 
|---|
 | 208 |  W !,"path ",PATH,!,"files ",EXT
 | 
|---|
 | 209 |  Q:$D(PSXL)'>1
 | 
|---|
 | 210 |  S FILE="" F I=0:0 S FILE=$O(PSXL(FILE)) Q:FILE=""  W !,FILE S I=I+1
 | 
|---|
 | 211 |  Q:I'>0
 | 
|---|
 | 212 |  K DIR S DIR(0)="Y",DIR("A")="DELETE FILES ?? ",DIR("B")="N" D ^DIR K DIR Q:Y'>0
 | 
|---|
 | 213 |  W $$DEL^%ZISH(PATH,"PSXL")
 | 
|---|
 | 214 |  G LOOP
 | 
|---|
 | 215 |  Q
 | 
|---|