Added DataTables 1.9.0, minus examples and documentation.
[openemr.git] / custom / code_types.inc.php
blob35ab9751192333552a4c489023ebc38cc7d45af4
1 <?php
2 // Copyright (C) 2006-2010 Rod Roark <rod@sunsetsystems.com>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 // This array provides abstraction of billing code types. This is desirable
10 // because different countries or fields of practice use different methods for
11 // coding diagnoses, procedures and supplies. Fees will not be relevant where
12 // medical care is socialized. Attribues are:
14 // id - the numeric identifier of this code type in the codes table
15 // fee - 1 if fees are used, else 0
16 // mod - the maximum length of a modifier, 0 if modifiers are not used
17 // just - the code type used for justification, empty if none
18 // rel - 1 if other billing codes may be "related" to this code type
19 // nofs - 1 if this code type should NOT appear in the Fee Sheet
20 // diag - 1 if this code type is for diagnosis
21 // active - 1 if this code type is activated
22 // label - label used for code type
23 // external - 0 for storing codes in the code table
24 // 1 for storing codes in external ICD10 tables
25 // 2 for storing codes in external SNOMED (RF1) tables
26 // 3 for storing codes in external SNOMED (RF2) tables
28 /*********************************************************************
29 if ($GLOBALS['ippf_specific']) {
30 // IPPF:
31 $code_types = array(
32 'ICD9' => array('id' => 2, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 0, 'diag' => TRUE),
33 'MA' => array('id' => 12, 'fee' => 1, 'mod' => 0, 'just' => '', 'rel' => 1, 'nofs' => 0),
34 'IPPF' => array('id' => 11, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 1),
35 'ACCT' => array('id' => 13, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 1),
37 $default_search_type = 'MA';
39 else if ($GLOBALS['athletic_team']) {
40 // UK Sports Medicine:
41 $code_types = array(
42 'OSICS10' => array('id' => 9, 'fee' => 0, 'mod' => 4, 'just' => '', 'rel' => 0, 'nofs' => 0, 'diag' => TRUE),
43 'OPCS' => array('id' => 6, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 0),
44 'PTCJ' => array('id' => 7, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 0),
45 'CPT4' => array('id' => 1, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 0),
46 'SMPC' => array('id' => 10, 'fee' => 0, 'mod' => 0, 'just' => '', 'rel' => 0, 'nofs' => 0),
48 $default_search_type = 'OSICS10';
50 else {
51 // USA Clinics:
52 $code_types = array(
53 'ICD9' => array('id' => 2, 'fee' => 0, 'mod' => 2, 'just' => '' , 'rel' => 0, 'nofs' => 0, 'diag' => TRUE),
54 'CPT4' => array('id' => 1, 'fee' => 1, 'mod' => 2, 'just' => 'ICD9', 'rel' => 0, 'nofs' => 0),
55 'HCPCS' => array('id' => 3, 'fee' => 1, 'mod' => 2, 'just' => 'ICD9', 'rel' => 0, 'nofs' => 0),
57 $default_search_type = 'ICD9';
59 *********************************************************************/
61 // Code types are now stored in the database.
63 $code_types = array();
64 $default_search_type = '';
65 $ctres = sqlStatement("SELECT * FROM code_types WHERE ct_active=1 ORDER BY ct_seq, ct_key");
66 while ($ctrow = sqlFetchArray($ctres)) {
67 $code_types[$ctrow['ct_key']] = array(
68 'id' => $ctrow['ct_id' ],
69 'fee' => $ctrow['ct_fee' ],
70 'mod' => $ctrow['ct_mod' ],
71 'just' => $ctrow['ct_just'],
72 'rel' => $ctrow['ct_rel' ],
73 'nofs' => $ctrow['ct_nofs'],
74 'diag' => $ctrow['ct_diag'],
75 'mask' => $ctrow['ct_mask'],
76 'label'=> ( (empty($ctrow['ct_label'])) ? $ctrow['ct_key'] : $ctrow['ct_label'] ),
77 'external'=> $ctrow['ct_external']
79 if ($default_search_type === '') $default_search_type = $ctrow['ct_key'];
82 /********************************************************************/
84 function fees_are_used() {
85 global $code_types;
86 foreach ($code_types as $value) { if ($value['fee']) return true; }
87 return false;
90 function modifiers_are_used($fee_sheet=false) {
91 global $code_types;
92 foreach ($code_types as $value) {
93 if ($fee_sheet && !empty($value['nofs'])) continue;
94 if ($value['mod']) return true;
96 return false;
99 function related_codes_are_used() {
100 global $code_types;
101 foreach ($code_types as $value) { if ($value['rel']) return true; }
102 return false;
105 // Convert a code type id to a key
106 function convert_type_id_to_key($id) {
107 global $code_types;
108 foreach ($code_types as $key => $value) {
109 if ($value['id'] == $id) return $key;
113 // Main code set searching function
114 // $form_code_type - code set key (special keywords are PROD and --ALL--)
115 // $search_term - search term
116 // $count - if true, then will only return the number of entries
117 // $active - if true, then will only return active entries (not pertinent for PROD or external code sets)
118 // $start - Query start limit
119 // $end - Query end limit
120 function code_set_search($form_code_type,$search_term="",$count=false,$active=true,$start=NULL,$number=NULL) {
121 global $code_types;
123 $active_query = '';
124 if ($active) {
125 // Only filter for active codes
126 // Note this is not use in PROD or in the external code sets
127 $active_query=" AND active = 1 ";
130 $limit_query = '';
131 if ( !is_null($start) && !is_null($number) ) {
132 $limit_query = " LIMIT $start, $number ";
135 if ($form_code_type == 'PROD') { // Search for products/drugs
136 $query = "SELECT dt.drug_id, dt.selector, d.name " .
137 "FROM drug_templates AS dt, drugs AS d WHERE " .
138 "( d.name LIKE ? OR " .
139 "dt.selector LIKE ? ) " .
140 "AND d.drug_id = dt.drug_id " .
141 "ORDER BY d.name, dt.selector, dt.drug_id $limit_query";
142 $res = sqlStatement($query, array("%".$search_term."%", "%".$search_term."%") );
144 else if ($form_code_type == '--ALL--') { // Search all codes from the default codes table
145 // Note this will not search the external code sets
146 $query = "SELECT * FROM codes " .
147 "WHERE (code_text LIKE ? OR " .
148 "code LIKE ?) " .
149 " $active_query " .
150 "ORDER BY code_type,code+0,code $limit_query";
151 $res = sqlStatement($query, array("%".$search_term."%", "%".$search_term."%") );
153 else if ( !($code_types[$form_code_type]['external']) ) { // Search from default codes table
154 $query = "SELECT * FROM codes " .
155 "WHERE (code_text LIKE ? OR " .
156 "code LIKE ?) " .
157 "AND code_type = ? $active_query " .
158 "ORDER BY code+0,code $limit_query";
159 $res = sqlStatement($query, array("%".$search_term."%", "%".$search_term."%", $code_types[$form_code_type]['id']) );
161 else if ($code_types[$form_code_type]['external'] == 1 ) { // Search from ICD10 codeset tables
162 //placeholder
164 else if ($code_types[$form_code_type]['external'] == 2 ) { // Search from SNOMED (RF1) codeset tables
165 // Ensure the sct_concepts sql table exists
166 $check_table = sqlQuery("SHOW TABLES LIKE 'sct_concepts'");
167 if ( !(empty($check_table)) ) {
168 $query = "SELECT `ConceptId` as code, `FullySpecifiedName` as code_text FROM `sct_concepts` " .
169 "WHERE ( `FullySpecifiedName` LIKE ? OR (`ConceptId` LIKE ? AND `FullySpecifiedName` LIKE '%(disorder)') ) " .
170 "AND `ConceptStatus` = 0 " .
171 "ORDER BY `ConceptId` $limit_query";
172 $res = sqlStatement($query, array("%".$search_term."%(disorder)", "%".$search_term."%") );
175 else if ($code_types[$form_code_type]['external'] == 3 ) { // Search from SNOMED (RF2) codeset tables
176 //placeholder
178 else {
179 //using an external code that is not yet supported, so skip.
181 if (isset($res)) {
182 if ($count) {
183 // just return the count
184 return sqlNumRows($res);
186 else {
187 // return the data
188 return $res;
193 // Look up descriptions for one or more billing codes. Input is of the
194 // form "type:code;type:code; etc.".
196 function lookup_code_descriptions($codes) {
197 global $code_types;
198 $code_text = '';
199 if (!empty($codes)) {
200 $relcodes = explode(';', $codes);
201 foreach ($relcodes as $codestring) {
202 if ($codestring === '') continue;
203 list($codetype, $code) = explode(':', $codestring);
204 if ( !($code_types[$codetype]['external']) ) { // Collect from default codes table
205 $wheretype = "";
206 $sqlArray = array();
207 if (empty($code)) {
208 $code = $codetype;
209 } else {
210 $wheretype = "code_type = ? AND ";
211 array_push($sqlArray,$code_types[$codetype]['id']);
213 $sql = "SELECT code_text FROM codes WHERE " .
214 "$wheretype code = ? ORDER BY id LIMIT 1";
215 array_push($sqlArray,$code);
216 $crow = sqlQuery($sql,$sqlArray);
217 if (!empty($crow['code_text'])) {
218 if ($code_text) $code_text .= '; ';
219 $code_text .= $crow['code_text'];
222 else if ($code_types[$codetype]['external'] == 1) { // Collect from ICD10 codeset tables
223 //placeholder
225 else if ($code_types[$codetype]['external'] == 2) { // Collect from SNOMED (RF1) codeset tables
226 // Ensure the sct_concepts sql table exists
227 $check_table = sqlQuery("SHOW TABLES LIKE 'sct_concepts'");
228 if ( !(empty($check_table)) ) {
229 if ( !(empty($code)) ) {
230 $sql = "SELECT `FullySpecifiedName` FROM `sct_concepts` " .
231 "WHERE `ConceptId` = ? AND `ConceptStatus` = 0 LIMIT 1";
232 $crow = sqlQuery($sql, array($code) );
233 if (!empty($crow['FullySpecifiedName'])) {
234 if ($code_text) $code_text .= '; ';
235 $code_text .= $crow['FullySpecifiedName'];
240 else if ($code_types[$codetype]['external'] == 3) { // Collect from SNOMED (RF2) codeset tables
241 //placeholder
243 else {
244 //using an external code that is not yet supported, so skip.
248 return $code_text;