1 | ICDAPIU ;DLS/DEK/KER - ICD UTILITIES FOR APIS ; 04/18/2004
|
---|
2 | ;;18.0;DRG Grouper;**6,11,12,15**;Oct 20, 2000
|
---|
3 | ;
|
---|
4 | ; External References
|
---|
5 | ; DBIA 10103 $$DT^XLFDT
|
---|
6 | ;
|
---|
7 | DTBR(CDT,CS) ; Date Business Rules
|
---|
8 | ; Input:
|
---|
9 | ; CDT - Code Date to check (FileMan format, default=Today)
|
---|
10 | ; CS - Code System (0:ICD, 1:CPT/HCPCS, 2:DRG, Default=0)
|
---|
11 | ;
|
---|
12 | ; Output:
|
---|
13 | ; If CDT < 2781001 and CS=0, use 2781001
|
---|
14 | ; If CDT < 2890101 and CS=1, use 2890101
|
---|
15 | ; If CDT < 2821001 and CS=2, use 2821001
|
---|
16 | ; If CDT is year only, use first of the year
|
---|
17 | ; If CDT is year and month only, use first of the month
|
---|
18 | ;
|
---|
19 | Q:'$G(CDT) $$DT^XLFDT ;nothing passed - use today
|
---|
20 | Q:$L($P(CDT,"."))'=7 $$DT^XLFDT ;bad date format - use today
|
---|
21 | N BRDAT ;Business rule date
|
---|
22 | S CS=+$G(CS) S:CS>2!(CS<0) CS=0
|
---|
23 | S BRDAT=+$P("2781001^2890101^2821001","^",CS+1)
|
---|
24 | I CDT#10000=0 S CDT=CDT+101
|
---|
25 | S:CDT#100=0 CDT=CDT+1
|
---|
26 | Q $S(CDT<BRDAT:BRDAT,1:CDT)
|
---|
27 | ;
|
---|
28 | MSG(CDT,CS) ; inform of code text inaccuracy
|
---|
29 | ; Input:
|
---|
30 | ; CDT - Code Date to check (FileMan format, Default = today)
|
---|
31 | ; CS - Code System (0:ICD, 1:CPT/HCPCS, 2:DRG, 3:LEX, Default=0)
|
---|
32 | ; Output: User Alert
|
---|
33 | ;
|
---|
34 | S CS=+$G(CS) S:CS>3!(CS<0) CS=0
|
---|
35 | S CDT=$S($G(CDT)="":$$DT^XLFDT,1:$$DTBR(CDT,CS))
|
---|
36 | N MSGTXT,MSGDAT S MSGDAT=3021001,MSGTXT="CODE TEXT MAY BE INACCURATE"
|
---|
37 | I CS<3 Q $S(CDT<MSGDAT:MSGTXT,1:"")
|
---|
38 | I CS=3,CDT'<3031001 Q ""
|
---|
39 | Q MSGTXT
|
---|
40 | ;
|
---|
41 | STATCHK(CODE,CDT) ; Check Status of ICD Code
|
---|
42 | ; Input:
|
---|
43 | ; CODE - ICD Code REQUIRED
|
---|
44 | ; CDT - Date to screen against (FileMan format, default = today)
|
---|
45 | ; Output:
|
---|
46 | ; 2-Piece String containing the code's status
|
---|
47 | ; and the IEN if the code exists, else -1.
|
---|
48 | ; The following are possible outputs:
|
---|
49 | ; 1^IEN Active Code
|
---|
50 | ; 0^IEN Inactive Code
|
---|
51 | ; 0^-1 Code not Found
|
---|
52 | ;
|
---|
53 | ; This API requires the ACT Cross-Reference
|
---|
54 | ; ^ICD9("ACT",<code>,<status>,<date>,<ien>)
|
---|
55 | ; ^ICD0("ACT",<code>,<status>,<date>,<ien>)
|
---|
56 | ;
|
---|
57 | N ICDC,ICDD,ICDIEN,ICDI,ICDA,ICDG,ICDR,X
|
---|
58 | S ICDC=$G(CODE) Q:'$L(ICDC) "0^-1"
|
---|
59 | ; Case 1: Not Valid 0^-1
|
---|
60 | ; Fails Pattern Match for Code
|
---|
61 | S CODE=$$CODEN^ICDCODE(CODE),ICDG=$P(CODE,"~",2),ICDIEN=+CODE
|
---|
62 | Q:ICDIEN<1 "0^-1"
|
---|
63 | ; Case 2: Never Active 0^IEN
|
---|
64 | ; No Active/Inactive Date
|
---|
65 | S ICDD=$S($G(CDT)="":$$DT^XLFDT,1:$$DTBR($G(CDT),1)),ICDD=ICDD+.001
|
---|
66 | S ICDR=$$ACTROOT(ICDG,ICDC,1,ICDD),ICDA=$O(@(ICDR_")"),-1)
|
---|
67 | I '$L(ICDA) D Q X
|
---|
68 | . S ICDA=$O(@(ICDR_")")),X="0^-1" Q:'$L(ICDA)
|
---|
69 | . S ICDR=$$ACTROOT(ICDG,ICDC,1,ICDA)
|
---|
70 | . S ICDIEN=$O(@(ICDR_",0)")) S:+ICDIEN<1 ICDIEN=-1
|
---|
71 | . S X="0^"_ICDIEN
|
---|
72 | ; Case 3: Active, Never Inactive 1^IEN
|
---|
73 | ; Has an Activation Date
|
---|
74 | ; No Inactivation Date
|
---|
75 | S ICDR=$$ACTROOT(ICDG,ICDC,0,ICDD),ICDI=$O(@(ICDR_")"),-1)
|
---|
76 | I $L(ICDA),'$L(ICDI) D Q X
|
---|
77 | . S ICDR=$$ACTROOT(ICDG,ICDC,1,ICDA),ICDIEN=$O(@(ICDR_",0)"))
|
---|
78 | . S X=$S(+ICDIEN=0:"0^-1",1:"1^"_ICDIEN)
|
---|
79 | ; Case 4: Active, but later Inactivated 0^IEN
|
---|
80 | ; Has an Activation Date
|
---|
81 | ; Has an Inactivation Date
|
---|
82 | I $L(ICDA),$L(ICDI),ICDI>ICDA,ICDI<ICDD D Q X
|
---|
83 | . S ICDR=$$ACTROOT(ICDG,ICDC,0,ICDI),ICDIEN=$O(@(ICDR_",0)"))
|
---|
84 | . S X=$S(+ICDIEN=0:"0^-1",1:"0^"_ICDIEN)
|
---|
85 | ; Case 5: Active, and not later Inactivated 1^IEN
|
---|
86 | ; Has an Activation Date
|
---|
87 | ; Has an Inactivation Date
|
---|
88 | ; Has a Newer Activation Date
|
---|
89 | I $L(ICDA),$L(ICDI),ICDI'>ICDA D Q X
|
---|
90 | . S ICDR=$$ACTROOT(ICDG,ICDC,0,ICDI),ICDIEN=$O(@(ICDR_",1)"))
|
---|
91 | . S X=$S(+$O(@(ICDR_",0)"))=0:"0^-1",1:"1^"_ICDIEN)
|
---|
92 | ; Case 6: Fails Time Test 0^-1
|
---|
93 | Q ("0^"_$S(+($G(ICDIEN))>0:+($G(ICDIEN)),1:"-1"))
|
---|
94 | ;
|
---|
95 | NEXT(CODE) ; Next ICD Code (active or inactive)
|
---|
96 | ; Input:
|
---|
97 | ; CODE = ICD Code REQUIRED
|
---|
98 | ; Output:
|
---|
99 | ; The Next ICD Code, Null if none
|
---|
100 | ;
|
---|
101 | N ICDC,ICDG S ICDC=$G(CODE) Q:'$L(ICDC) ""
|
---|
102 | Q:ICDC?1.9N "" ;app passed an IEN
|
---|
103 | S ICDG=$P($$CODEN^ICDCODE(ICDC),"~",2)
|
---|
104 | Q:ICDG="INVALID CODE" ""
|
---|
105 | S ICDC=$O(@(ICDG_"""BA"","""_ICDC_" "")"))
|
---|
106 | Q $S(ICDC="":"",1:$E(ICDC,1,$L(ICDC)-1))
|
---|
107 | ;
|
---|
108 | PREV(CODE) ; Previous ICD Code (active or inactive)
|
---|
109 | ; Input:
|
---|
110 | ; CODE = ICD Code REQUIRED
|
---|
111 | ; Output:
|
---|
112 | ; The Previous ICD Code, Null if none
|
---|
113 | ;
|
---|
114 | N ICDC,ICDG
|
---|
115 | S ICDC=$G(CODE) Q:'$L(ICDC) ""
|
---|
116 | Q:ICDC?1.9N "" ;app passed an IEN
|
---|
117 | S ICDG=$P($$CODEN^ICDCODE(ICDC),"~",2)
|
---|
118 | Q:ICDG="INVALID CODE" ""
|
---|
119 | S ICDC=$O(@(ICDG_"""BA"","""_ICDC_" "")"),-1)
|
---|
120 | Q $S(ICDC="":"",1:$E(ICDC,1,$L(ICDC)-1))
|
---|
121 | ;
|
---|
122 | HIST(CODE,ARY) ; Activation History
|
---|
123 | ; Input:
|
---|
124 | ; CODE - ICD Code REQUIRED
|
---|
125 | ; .ARY - Array, passed by Reference REQUIRED
|
---|
126 | ;
|
---|
127 | ; Output: Mirrors ARY(0) (or, -1 on error)
|
---|
128 | ; ARY(0) = Number of Activation History Entries
|
---|
129 | ; ARY(<date>) = status where: 1 is Active
|
---|
130 | ; ARY("IEN") = <ien>
|
---|
131 | ;
|
---|
132 | Q:$G(CODE)="" -1
|
---|
133 | N ICDC,ICDI,ICDA,ICDN,ICDD,ICDG,ICDF
|
---|
134 | S ICDI=$$CODEN^ICDCODE(CODE),ICDG=$P(ICDI,"~",2)
|
---|
135 | S ICDI=+ICDI Q:ICDI<1 -1
|
---|
136 | S ARY("IEN")=ICDI,ICDA="" M ICDA=@(ICDG_ICDI_",66)")
|
---|
137 | K ICDA("B") S ARY(0)=+($P($G(ICDA(0)),"^",4))
|
---|
138 | S:+ARY(0)=0 ARY(0)=-1 K:ARY(0)=-1 ARY("IEN")
|
---|
139 | S (ICDI,ICDC)=0 F S ICDI=$O(ICDA(ICDI)) Q:+ICDI=0 D
|
---|
140 | . S ICDD=$P($G(ICDA(ICDI,0)),"^",1) Q:+ICDD=0
|
---|
141 | . S ICDF=$P($G(ICDA(ICDI,0)),"^",2) Q:'$L(ICDF)
|
---|
142 | . S ICDC=ICDC+1,ARY(0)=ICDC,ARY(ICDD)=ICDF
|
---|
143 | Q ARY(0)
|
---|
144 | ;
|
---|
145 | PERIOD(CODE,ARY) ; return Activation/Inactivation Period in ARY
|
---|
146 | ;
|
---|
147 | ; Input: CODE ICD Code (required)
|
---|
148 | ; ARY Array, passed by Reference (required)
|
---|
149 | ;
|
---|
150 | ; Output: ARY(0) = IEN^Selectable
|
---|
151 | ; Where IEN = -1 if error
|
---|
152 | ; Selectable = 0 for VA Only codes
|
---|
153 | ;
|
---|
154 | ; ARY(Activation Date) = Inactivation Date^Short Name
|
---|
155 | ;
|
---|
156 | ; Where the Short Name is the Versioned text (field 1 of the 67
|
---|
157 | ; multiple), and the text is versioned as follows:
|
---|
158 | ;
|
---|
159 | ; Period is active - Versioned text for TODAY's date
|
---|
160 | ; Period is inactive - Versioned text for inactivation date
|
---|
161 | ;
|
---|
162 | ; or
|
---|
163 | ;
|
---|
164 | ; -1^0 (no period or error)
|
---|
165 | ;
|
---|
166 | I $G(CODE)="" S ARY(0)="-1^0" Q
|
---|
167 | N ICDC,ICDI,ICDA,ICDG,ICDF,ICDBA,ICDBI,ICDST,ICDS,ICDZ,ICDV,ICDN,ICDCA
|
---|
168 | S ICDC=$$CODEN^ICDCODE(CODE),ICDG=$P(ICDC,"~",2),ICDC=+ICDC
|
---|
169 | I ICDC<1 S ARY(0)="-1^0" Q
|
---|
170 | S ICDI=$S(ICDG="^ICD9(":3,1:4),ICDZ=$G(@(ICDG_ICDC_",0)"))
|
---|
171 | ; Versioned text for TODAY
|
---|
172 | S ICDN=$$VST^ICDCODE(ICDC,$$DT^XLFDT,ICDG)
|
---|
173 | S ICDS=$P(ICDZ,"^",ICDI),ARY(0)=ICDC_"^"_'$P(ICDZ,"^",8)
|
---|
174 | S (ICDA,ICDBA)=0,ICDG=ICDG_ICDC_",66,"
|
---|
175 | F Q:ICDBA D
|
---|
176 | . S ICDA=$O(@(ICDG_"""B"","_ICDA_")"))
|
---|
177 | . I ICDA="" S ICDBA=1 Q
|
---|
178 | . S ICDF=$O(@(ICDG_"""B"","_ICDA_",0)"))
|
---|
179 | . I '+ICDF S ICDBA=1 Q
|
---|
180 | . S ICDST=$P($G(@(ICDG_ICDF_",0)")),"^",2)
|
---|
181 | . Q:'ICDST ;outer loop looks for active
|
---|
182 | . ; Versioned text for activation date
|
---|
183 | . S ICDV=$$VST^ICDCODE(ICDC,ICDA,ICDG),ICDCA=1
|
---|
184 | . S:$L(ICDV) ICDS=ICDV
|
---|
185 | . S ARY(ICDA)="^"_ICDS,ICDBI=0,ICDI=ICDA
|
---|
186 | . F Q:ICDBI D
|
---|
187 | . . S ICDI=$O(@(ICDG_"""B"","_ICDI_")"))
|
---|
188 | . . ; If no inactivation date for ICDA then use TODAY's text
|
---|
189 | . . I ICDI="" S ARY(ICDA)="^"_ICDN,(ICDBI,ICDBA)=1 Q
|
---|
190 | . . S ICDF=$O(@(ICDG_"""B"","_ICDI_",0)"))
|
---|
191 | . . ; If no effective date ICDF for ICDI then use TODAY's text
|
---|
192 | . . I '+ICDF S ARY(ICDA)="^"_ICDN,(ICDBI,ICDBA)=1 Q
|
---|
193 | . . S ICDST=$P($G(@(ICDG_ICDF_",0)")),"^",2)
|
---|
194 | . . ; If Status ICDST not Inactive then use TODAY's text
|
---|
195 | . . I ICDST S ARY(ICDA)="^"_ICDN,ICDBI=1 Q
|
---|
196 | . . ; Versioned text for inactive date
|
---|
197 | . . S ICDV=$$VST^ICDCODE(ICDC,ICDI,ICDG)
|
---|
198 | . . S:$L(ICDV) $P(ARY(ICDA),"^",2)=ICDV
|
---|
199 | . . S $P(ARY(ICDA),"^")=ICDI
|
---|
200 | . . S ICDBI=1,ICDA=ICDI,ICDCA=0
|
---|
201 | Q
|
---|
202 | ;
|
---|
203 | ACTROOT(ICDG,ICDC,ICDS,ICDD) ; Return "ACT" root
|
---|
204 | Q (ICDG_"""ACT"","""_ICDC_" "","_ICDS_","_ICDD)
|
---|