Issue Type list gui improvements
[openemr.git] / interface / super / edit_list.php
blob71be0fce68c04bf44e2aa427e2dc13e332e9bf5d
1 <?php
2 /**
3 * library/sql_upgrade_fx.php Upgrading and patching functions of database.
5 * Functions to allow safe database modifications
6 * during upgrading and patches.
8 * Copyright (C) 2007-2011 Rod Roark <rod@sunsetsystems.com>
10 * LICENSE: This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
21 * @package OpenEMR
22 * @author Rod Roark <rod@sunsetsystems.com>
23 * @author Brady Miller <brady@sparmy.com>
24 * @author Teny <teny@zhservices.com>
25 * @link http://www.open-emr.org
28 require_once("../globals.php");
29 require_once("$srcdir/acl.inc");
30 require_once("$srcdir/formdata.inc.php");
31 require_once("$srcdir/lists.inc");
32 require_once("../../custom/code_types.inc.php");
34 $list_id = empty($_REQUEST['list_id']) ? 'language' : $_REQUEST['list_id'];
36 // Check authorization.
37 $thisauth = acl_check('admin', 'super');
38 if (!$thisauth) die(xl('Not authorized'));
40 // If we are saving, then save.
42 if ($_POST['formaction']=='save' && $list_id) {
43 $opt = $_POST['opt'];
44 if ($list_id == 'feesheet') {
45 // special case for the feesheet list
46 sqlStatement("DELETE FROM fee_sheet_options");
47 for ($lino = 1; isset($opt["$lino"]['category']); ++$lino) {
48 $iter = $opt["$lino"];
49 $category = formTrim($iter['category']);
50 $option = formTrim($iter['option']);
51 $codes = formTrim($iter['codes']);
52 if (strlen($category) > 0 && strlen($option) > 0) {
53 sqlInsert("INSERT INTO fee_sheet_options ( " .
54 "fs_category, fs_option, fs_codes " .
55 ") VALUES ( " .
56 "'$category', " .
57 "'$option', " .
58 "'$codes' " .
59 ")");
63 else if ($list_id == 'code_types') {
64 // special case for code types
65 sqlStatement("DELETE FROM code_types");
66 for ($lino = 1; isset($opt["$lino"]['ct_key']); ++$lino) {
67 $iter = $opt["$lino"];
68 $ct_key = formTrim($iter['ct_key']);
69 $ct_id = formTrim($iter['ct_id']) + 0;
70 $ct_seq = formTrim($iter['ct_seq']) + 0;
71 $ct_mod = formTrim($iter['ct_mod']) + 0;
72 $ct_just = formTrim($iter['ct_just']);
73 $ct_mask = formTrim($iter['ct_mask']);
74 $ct_fee = empty($iter['ct_fee' ]) ? 0 : 1;
75 $ct_rel = empty($iter['ct_rel' ]) ? 0 : 1;
76 $ct_nofs = empty($iter['ct_nofs']) ? 0 : 1;
77 $ct_diag = empty($iter['ct_diag']) ? 0 : 1;
78 $ct_active = empty($iter['ct_active' ]) ? 0 : 1;
79 $ct_label = formTrim($iter['ct_label']);
80 $ct_external = formTrim($iter['ct_external']) + 0;
81 $ct_claim = empty($iter['ct_claim']) ? 0 : 1;
82 $ct_proc = empty($iter['ct_proc']) ? 0 : 1;
83 $ct_term = empty($iter['ct_term']) ? 0 : 1;
84 $ct_problem = empty($iter['ct_problem']) ? 0 : 1;
85 if (strlen($ct_key) > 0 && $ct_id > 0) {
86 sqlInsert("INSERT INTO code_types ( " .
87 "ct_key, ct_id, ct_seq, ct_mod, ct_just, ct_mask, ct_fee, ct_rel, ct_nofs, ct_diag, ct_active, ct_label, ct_external, ct_claim, ct_proc, ct_term, ct_problem " .
88 ") VALUES ( " .
89 "'$ct_key' , " .
90 "'$ct_id' , " .
91 "'$ct_seq' , " .
92 "'$ct_mod' , " .
93 "'$ct_just', " .
94 "'$ct_mask', " .
95 "'$ct_fee' , " .
96 "'$ct_rel' , " .
97 "'$ct_nofs', " .
98 "'$ct_diag', " .
99 "'$ct_active', " .
100 "'$ct_label', " .
101 "'$ct_external', " .
102 "'$ct_claim', " .
103 "'$ct_proc', " .
104 "'$ct_term', " .
105 "'$ct_problem' " .
106 ")");
110 else if ($list_id == 'issue_types') {
111 // special case for issue_types
112 sqlStatement("DELETE FROM issue_types");
113 for ($lino = 1; isset($opt["$lino"]['category']); ++$lino) {
114 $iter = $opt["$lino"];
115 $it_active = formTrim($iter['active']);
116 $it_category = formTrim($iter['category']);
117 $it_ordering = formTrim($iter['ordering']);
118 $it_type = formTrim($iter['type']);
119 $it_plural = formTrim($iter['plural']);
120 $it_singular = formTrim($iter['singular']);
121 $it_abbr = formTrim($iter['abbreviation']);
122 $it_style = formTrim($iter['style']);
123 $it_fshow = formTrim($iter['force_show']);
125 if ( (strlen($it_category) > 0) && (strlen($it_type) > 0) ) {
126 sqlInsert("INSERT INTO issue_types ( " .
127 "`active`,`category`,`ordering`, `type`, `plural`, `singular`, `abbreviation`, `style`, `force_show` " .
128 ") VALUES ( " .
129 "'$it_active' , " .
130 "'$it_category' , " .
131 "'$it_ordering' , " .
132 "'$it_type' , " .
133 "'$it_plural' , " .
134 "'$it_singular' , " .
135 "'$it_abbr' , " .
136 "'$it_style', " .
137 "'$it_fshow' " .
138 ")");
142 else {
143 // all other lists
145 // erase lists options and recreate them from the submitted form data
146 sqlStatement("DELETE FROM list_options WHERE list_id = '$list_id'");
147 for ($lino = 1; isset($opt["$lino"]['id']); ++$lino) {
148 $iter = $opt["$lino"];
149 $value = empty($iter['value']) ? 0 : (formTrim($iter['value']) + 0);
150 $id = formTrim($iter['id']);
151 if (strlen($id) > 0) {
153 // Special processing for the immunizations list
154 // Map the entered cvx codes into the immunizations table cvx_code
155 sqlStatement ("UPDATE `immunizations` " .
156 "SET `cvx_code`='".$value."' " .
157 "WHERE `immunization_id`='".$id."'");
159 // Force List Based Form names to start with LBF.
160 if ($list_id == 'lbfnames' && substr($id,0,3) != 'LBF')
161 $id = "LBF$id";
162 sqlInsert("INSERT INTO list_options ( " .
163 "list_id, option_id, title, seq, is_default, option_value, mapping, notes, codes " .
164 ") VALUES ( " .
165 "'$list_id', " .
166 "'" . $id . "', " .
167 "'" . formTrim($iter['title']) . "', " .
168 "'" . formTrim($iter['seq']) . "', " .
169 "'" . formTrim($iter['default']) . "', " .
170 "'" . $value . "', " .
171 "'" . formTrim($iter['mapping']) . "', " .
172 "'" . formTrim($iter['notes']) . "', " .
173 "'" . formTrim($iter['codes']) . "' " .
174 ")");
179 else if ($_POST['formaction']=='addlist') {
180 // make a new list ID from the new list name
181 $newlistID = $_POST['newlistname'];
182 $newlistID = preg_replace("/\W/", "_", $newlistID);
184 // determine the position of this new list
185 $row = sqlQuery("SELECT max(seq) as maxseq FROM list_options WHERE list_id= 'lists'");
187 // add the new list to the list-of-lists
188 sqlInsert("INSERT INTO list_options ( " .
189 "list_id, option_id, title, seq, is_default, option_value " .
190 ") VALUES ( " .
191 "'lists',". // the master list-of-lists
192 "'".$newlistID."',".
193 "'".$_POST['newlistname']."', ".
194 "'".($row['maxseq']+1)."',".
195 "'1', '0')"
198 else if ($_POST['formaction']=='deletelist') {
199 // delete the lists options
200 sqlStatement("DELETE FROM list_options WHERE list_id = '".$_POST['list_id']."'");
201 // delete the list from the master list-of-lists
202 sqlStatement("DELETE FROM list_options WHERE list_id = 'lists' and option_id='".$_POST['list_id']."'");
205 $opt_line_no = 0;
207 // Given a string of multiple instances of code_type|code|selector,
208 // make a description for each.
209 // @TODO Instead should use a function from custom/code_types.inc.php and need to remove casing functions
210 function getCodeDescriptions($codes) {
211 global $code_types;
212 $arrcodes = explode('~', $codes);
213 $s = '';
214 foreach ($arrcodes as $codestring) {
215 if ($codestring === '') continue;
216 $arrcode = explode('|', $codestring);
217 $code_type = $arrcode[0];
218 $code = $arrcode[1];
219 $selector = $arrcode[2];
220 $desc = '';
221 if ($code_type == 'PROD') {
222 $row = sqlQuery("SELECT name FROM drugs WHERE drug_id = '$code' ");
223 $desc = "$code:$selector " . $row['name'];
225 else {
226 $row = sqlQuery("SELECT code_text FROM codes WHERE " .
227 "code_type = '" . $code_types[$code_type]['id'] . "' AND " .
228 "code = '$code' ORDER BY modifier LIMIT 1");
229 $desc = "$code_type:$code " . ucfirst(strtolower($row['code_text']));
231 $desc = str_replace('~', ' ', $desc);
232 if ($s) $s .= '~';
233 $s .= $desc;
235 return $s;
238 // Write one option line to the form.
240 function writeOptionLine($option_id, $title, $seq, $default, $value, $mapping='', $notes='', $codes='') {
241 global $opt_line_no, $list_id;
242 ++$opt_line_no;
243 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
244 $checked = $default ? " checked" : "";
246 echo " <tr bgcolor='$bgcolor'>\n";
248 echo " <td align='center' class='optcell'>";
249 echo "<input type='text' name='opt[$opt_line_no][id]' value='" .
250 htmlspecialchars($option_id, ENT_QUOTES) . "' size='12' maxlength='63' class='optin' />";
251 echo "</td>\n";
253 echo " <td align='center' class='optcell'>";
254 echo "<input type='text' name='opt[$opt_line_no][title]' value='" .
255 htmlspecialchars($title, ENT_QUOTES) . "' size='20' maxlength='63' class='optin' />";
256 echo "</td>\n";
258 // if not english and translating lists then show the translation
259 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
260 echo " <td align='center' class='translation'>" . (htmlspecialchars( xl($title), ENT_QUOTES)) . "</td>\n";
263 echo " <td align='center' class='optcell'>";
264 echo "<input type='text' name='opt[$opt_line_no][seq]' value='" .
265 htmlspecialchars($seq, ENT_QUOTES) . "' size='4' maxlength='10' class='optin' />";
266 echo "</td>\n";
268 echo " <td align='center' class='optcell'>";
269 echo "<input type='checkbox' name='opt[$opt_line_no][default]' value='1' " .
270 "onclick='defClicked($opt_line_no)' class='optin'$checked />";
271 echo "</td>\n";
273 // Tax rates, contraceptive methods and LBF names have an additional attribute.
275 if ($list_id == 'taxrate' || $list_id == 'contrameth' || $list_id == 'lbfnames') {
276 echo " <td align='center' class='optcell'>";
277 echo "<input type='text' name='opt[$opt_line_no][value]' value='" .
278 htmlspecialchars($value, ENT_QUOTES) . "' size='8' maxlength='15' class='optin' />";
279 echo "</td>\n";
282 // Adjustment reasons use option_value as a reason category. This is
283 // needed to distinguish between adjustments that change the invoice
284 // balance and those that just shift responsibility of payment or
285 // are used as comments.
287 else if ($list_id == 'adjreason') {
288 echo " <td align='center' class='optcell'>";
289 echo "<select name='opt[$opt_line_no][value]' class='optin'>";
290 foreach (array(
291 1 => xl('Charge adjustment'),
292 2 => xl('Coinsurance'),
293 3 => xl('Deductible'),
294 4 => xl('Other pt resp'),
295 5 => xl('Comment'),
296 ) as $key => $desc) {
297 echo "<option value='$key'";
298 if ($key == $value) echo " selected";
299 echo ">" . htmlspecialchars($desc) . "</option>";
301 echo "</select>";
302 echo "</td>\n";
305 // Address book categories use option_value to flag category as a
306 // person-centric vs company-centric vs indifferent.
308 else if ($list_id == 'abook_type') {
309 echo " <td align='center' class='optcell'>";
310 echo "<select name='opt[$opt_line_no][value]' class='optin'>";
311 foreach (array(
312 1 => xl('Unassigned'),
313 2 => xl('Person'),
314 3 => xl('Company'),
315 ) as $key => $desc) {
316 echo "<option value='$key'";
317 if ($key == $value) echo " selected";
318 echo ">" . htmlspecialchars($desc) . "</option>";
320 echo "</select>";
321 echo "</td>\n";
324 // Immunization categories use option_value to map list items
325 // to CVX codes.
327 else if ($list_id == 'immunizations') {
328 echo " <td align='center' class='optcell'>";
329 echo "<input type='text' size='10' name='opt[$opt_line_no][value]' " .
330 "value='" . htmlspecialchars($value,ENT_QUOTES) . "' onclick='sel_cvxcode(this)' " .
331 "title='" . htmlspecialchars( xl('Click to select or change CVX code'), ENT_QUOTES) . "'/>";
332 echo "</td>\n";
335 // IPPF includes the ability to map each list item to a "master" identifier.
336 // Sports teams use this for some extra info for fitness levels.
338 if ($GLOBALS['ippf_specific'] || $list_id == 'fitness') {
339 echo " <td align='center' class='optcell'>";
340 echo "<input type='text' name='opt[$opt_line_no][mapping]' value='" .
341 htmlspecialchars($mapping, ENT_QUOTES) . "' size='12' maxlength='15' class='optin' />";
342 echo "</td>\n";
345 echo " <td align='center' class='optcell'>";
346 echo "<input type='text' name='opt[$opt_line_no][notes]' value='" .
347 htmlspecialchars($notes, ENT_QUOTES) . "' size='25' maxlength='255' class='optin' />";
348 echo "</td>\n";
350 echo " <td align='center' class='optcell'>";
351 echo "<input type='text' name='opt[$opt_line_no][codes]' title='" .
352 xla('Clinical Term Code(s)') ."' value='" .
353 htmlspecialchars($codes, ENT_QUOTES) . "' onclick='select_clin_term_code(this)' size='25' maxlength='255' class='optin' />";
354 echo "</td>\n";
356 echo " </tr>\n";
359 // Write a form line as above but for the special case of the Fee Sheet.
361 function writeFSLine($category, $option, $codes) {
362 global $opt_line_no;
364 ++$opt_line_no;
365 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
367 $descs = getCodeDescriptions($codes);
369 echo " <tr bgcolor='$bgcolor'>\n";
371 echo " <td align='center' class='optcell'>";
372 echo "<input type='text' name='opt[$opt_line_no][category]' value='" .
373 htmlspecialchars($category, ENT_QUOTES) . "' size='20' maxlength='63' class='optin' />";
374 echo "</td>\n";
376 echo " <td align='center' class='optcell'>";
377 echo "<input type='text' name='opt[$opt_line_no][option]' value='" .
378 htmlspecialchars($option, ENT_QUOTES) . "' size='20' maxlength='63' class='optin' />";
379 echo "</td>\n";
381 echo " <td align='left' class='optcell'>";
382 echo " <div id='codelist_$opt_line_no'>";
383 if (strlen($descs)) {
384 $arrdescs = explode('~', $descs);
385 $i = 0;
386 foreach ($arrdescs as $desc) {
387 echo "<a href='' onclick='return delete_code($opt_line_no,$i)' title='" . xl('Delete') . "'>";
388 echo "[x]&nbsp;</a>$desc<br />";
389 ++$i;
392 echo "</div>";
393 echo "<a href='' onclick='return select_code($opt_line_no)'>";
394 echo "[" . xl('Add') . "]</a>";
396 echo "<input type='hidden' name='opt[$opt_line_no][codes]' value='" .
397 htmlspecialchars($codes, ENT_QUOTES) . "' />";
398 echo "<input type='hidden' name='opt[$opt_line_no][descs]' value='" .
399 htmlspecialchars($descs, ENT_QUOTES) . "' />";
400 echo "</td>\n";
402 echo " </tr>\n";
407 * Helper functions for writeITLine() and writeCTLine().
409 function ctGenCell($opt_line_no, $data_array, $name, $size, $maxlength, $title='') {
410 $value = isset($data_array[$name]) ? $data_array[$name] : '';
411 $s = " <td align='center' class='optcell'";
412 if ($title) $s .= " title='" . attr($title) . "'";
413 $s .= ">";
414 $s .= "<input type='text' name='opt[$opt_line_no][$name]' value='";
415 $s .= attr($value);
416 $s .= "' size='$size' maxlength='$maxlength' class='optin' />";
417 $s .= "</td>\n";
418 return $s;
421 function ctGenCbox($opt_line_no, $data_array, $name, $title='') {
422 $checked = empty($data_array[$name]) ? '' : 'checked ';
423 $s = " <td align='center' class='optcell'";
424 if ($title) $s .= " title='" . attr($title) . "'";
425 $s .= ">";
426 $s .= "<input type='checkbox' name='opt[$opt_line_no][$name]' value='1' ";
427 $s .= "$checked/>";
428 $s .= "</td>\n";
429 return $s;
432 function ctSelector($opt_line_no, $data_array, $name, $option_array, $title='') {
433 $value = isset($data_array[$name]) ? $data_array[$name] : '';
434 $s = " <td title='" . attr($title) . "' align='center' class='optcell'>";
435 $s .= "<select name='opt[$opt_line_no][$name]' class='optin'>";
436 foreach ( $option_array as $key => $desc) {
437 $s .= "<option value='" . attr($key) . "'";
438 if ($key == $value) $s .= " selected";
439 $s .= ">" . text($desc) . "</option>";
441 $s .= "</select>";
442 $s .= "</td>\n";
443 return $s;
446 // Write a form line as above but for the special case of Code Types.
448 function writeCTLine($ct_array) {
449 global $opt_line_no,$cd_external_options;
451 ++$opt_line_no;
452 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
454 echo " <tr bgcolor='$bgcolor'>\n";
456 echo ctGenCBox($opt_line_no, $ct_array, 'ct_active',
457 xl('Is this code type active?'));
458 echo ctGenCell($opt_line_no, $ct_array, 'ct_key' , 6, 15,
459 xl('Unique human-readable identifier for this type'));
460 echo ctGenCell($opt_line_no, $ct_array, 'ct_id' , 2, 11,
461 xl('Unique numeric identifier for this type'));
462 echo ctGenCell($opt_line_no, $ct_array, 'ct_label' , 6, 30,
463 xl('Label for this type'));
464 // if not english and translating lists then show the translation
465 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
466 echo " <td align='center' class='translation'>" . xlt($ct_array['ct_label']) . "</td>\n";
468 echo ctGenCell($opt_line_no, $ct_array, 'ct_seq' , 2, 3,
469 xl('Numeric display order'));
470 echo ctGenCell($opt_line_no, $ct_array, 'ct_mod' , 1, 2,
471 xl('Length of modifier, 0 if none'));
472 echo ctGenCell($opt_line_no, $ct_array, 'ct_just', 4, 15,
473 xl('If billing justification is used enter the name of the diagnosis code type.'));
474 echo ctGenCell($opt_line_no, $ct_array, 'ct_mask', 6, 9,
475 xl('Specifies formatting for codes. # = digit, @ = alpha, * = any character. Empty if not used.'));
476 echo ctGenCBox($opt_line_no, $ct_array, 'ct_claim',
477 xl('Is this code type used in claims?'));
478 echo ctGenCBox($opt_line_no, $ct_array, 'ct_fee',
479 xl('Are fees charged for this type?'));
480 echo ctGenCBox($opt_line_no, $ct_array, 'ct_rel',
481 xl('Does this type allow related codes?'));
482 echo ctGenCBox($opt_line_no, $ct_array, 'ct_nofs',
483 xl('Is this type hidden in the fee sheet?'));
484 echo ctGenCBox($opt_line_no, $ct_array, 'ct_proc',
485 xl('Is this a procedure/service type?'));
486 echo ctGenCBox($opt_line_no, $ct_array, 'ct_diag',
487 xl('Is this a diagnosis type?'));
488 echo ctGenCBox($opt_line_no, $ct_array, 'ct_term',
489 xl('Is this a Clinical Term code type?'));
490 echo ctGenCBox($opt_line_no, $ct_array, 'ct_problem',
491 xl('Is this a Medical Problem code type?'));
492 echo ctSelector($opt_line_no, $ct_array, 'ct_external',
493 $cd_external_options, xl('Is this using external sql tables? If it is, then choose the format.'));
494 echo " </tr>\n";
498 * Special case of Issue Types
500 function writeITLine($it_array) {
501 global $opt_line_no,$ISSUE_TYPE_CATEGORIES,$ISSUE_TYPE_STYLES;
502 ++$opt_line_no;
503 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
504 echo " <tr bgcolor='$bgcolor'>\n";
505 echo ctSelector($opt_line_no, $it_array, 'category', $ISSUE_TYPE_CATEGORIES, xl('OpenEMR Application Category'));
506 echo ctGenCBox($opt_line_no, $it_array, 'active', xl('Is this active?'));
507 echo ctGenCell($opt_line_no, $it_array, 'ordering' , 10, 10, xl('Order'));
508 echo ctGenCell($opt_line_no, $it_array, 'type' , 20, 75, xl('Issue Type'));
509 echo ctGenCell($opt_line_no, $it_array, 'plural' , 20, 75, xl('Plural'));
510 // if not english and translating lists then show the translation
511 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
512 echo " <td align='center' class='translation'>" . xlt($it_array['plural']) . "</td>\n";
514 echo ctGenCell($opt_line_no, $it_array, 'singular' , 20, 75, xl('Singular'));
515 // if not english and translating lists then show the translation
516 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
517 echo " <td align='center' class='translation'>" . xlt($it_array['singular']) . "</td>\n";
519 echo ctGenCell($opt_line_no, $it_array, 'abbreviation' , 10, 10, xl('Abbreviation'));
520 // if not english and translating lists then show the translation
521 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
522 echo " <td align='center' class='translation'>" . xlt($it_array['abbreviation']) . "</td>\n";
524 echo ctSelector($opt_line_no, $it_array, 'style', $ISSUE_TYPE_STYLES, xl('Standard; Simplified: only title, start date, comments and an Active checkbox;no diagnosis, occurrence, end date, referred-by or sports fields. ; Football Injury'));
525 echo ctGenCBox($opt_line_no, $it_array, 'force_show', xl('Show this category on the patient summary screen even if no issues have been entered for this category.'));
526 echo " </tr>\n";
530 <html>
532 <head>
533 <?php html_header_show();?>
535 <!-- supporting javascript code -->
536 <script type="text/javascript" src="<?php echo $GLOBALS['webroot'] ?>/library/js/jquery.js"></script>
538 <link rel="stylesheet" href='<?php echo $css_header ?>' type='text/css'>
539 <title><?php xl('List Editor','e'); ?></title>
541 <style>
542 tr.head { font-size:10pt; background-color:#cccccc; text-align:center; }
543 tr.detail { font-size:10pt; }
544 td { font-size:10pt; }
545 input { font-size:10pt; }
546 a, a:visited, a:hover { color:#0000cc; }
547 .optcell { }
548 .optin { background-color:transparent; }
549 .help { cursor:help; }
550 .translation { color:green; }
551 </style>
553 <script type="text/javascript" src="../../library/dialog.js"></script>
555 <script language="JavaScript">
557 var current_lino = 0;
559 // Helper function to set the contents of a div.
560 // This is for Fee Sheet administration.
561 function setDivContent(id, content) {
562 if (document.getElementById) {
563 var x = document.getElementById(id);
564 x.innerHTML = '';
565 x.innerHTML = content;
567 else if (document.all) {
568 var x = document.all[id];
569 x.innerHTML = content;
573 // Given a line number, redisplay its descriptive list of codes.
574 // This is for Fee Sheet administration.
575 function displayCodes(lino) {
576 var f = document.forms[0];
577 var s = '';
578 var descs = f['opt[' + lino + '][descs]'].value;
579 if (descs.length) {
580 var arrdescs = descs.split('~');
581 for (var i = 0; i < arrdescs.length; ++i) {
582 s += "<a href='' onclick='return delete_code(" + lino + "," + i + ")' title='<?php xl('Delete','e'); ?>'>";
583 s += "[x]&nbsp;</a>" + arrdescs[i] + "<br />";
586 setDivContent('codelist_' + lino, s);
589 // Helper function to remove a Fee Sheet code.
590 function dc_substring(s, i) {
591 var r = '';
592 var j = s.indexOf('~', i);
593 if (j < 0) { // deleting last segment
594 if (i > 0) r = s.substring(0, i-1); // omits trailing ~
596 else { // not last segment
597 r = s.substring(0, i) + s.substring(j + 1);
599 return r;
602 // Remove a generated Fee Sheet code.
603 function delete_code(lino, seqno) {
604 var f = document.forms[0];
605 var celem = f['opt[' + lino + '][codes]'];
606 var delem = f['opt[' + lino + '][descs]'];
607 var ci = 0;
608 var di = 0;
609 for (var i = 0; i < seqno; ++i) {
610 ci = celem.value.indexOf('~', ci) + 1;
611 di = delem.value.indexOf('~', di) + 1;
613 celem.value = dc_substring(celem.value, ci);
614 delem.value = dc_substring(delem.value, di);
615 displayCodes(lino);
616 return false;
619 // This invokes the find-code popup.
620 // For Fee Sheet administration.
621 function select_code(lino) {
622 current_lino = lino;
623 dlgopen('../patient_file/encounter/find_code_popup.php', '_blank', 700, 400);
624 return false;
627 // This invokes the find-code popup.
628 // For CVX/immunization code administration.
629 function sel_cvxcode(e) {
630 current_sel_name = e.name;
631 dlgopen('../patient_file/encounter/find_code_popup.php?codetype=CVX', '_blank', 500, 400);
634 // This invokes the find-code popup.
635 // For CVX/immunization code administration.
636 function select_clin_term_code(e) {
637 current_sel_clin_term = e.name;
638 dlgopen('../patient_file/encounter/find_code_popup.php?codetype=<?php echo attr(collect_codetypes("clinical_term","csv")) ?>', '_blank', 500, 400);
641 // This is for callback by the find-code popup.
642 function set_related(codetype, code, selector, codedesc) {
643 if (typeof(current_sel_name) == 'undefined' && typeof(current_sel_clin_term) == 'undefined')
645 // Coming from Fee Sheet edit
646 var f = document.forms[0];
647 var celem = f['opt[' + current_lino + '][codes]'];
648 var delem = f['opt[' + current_lino + '][descs]'];
649 var i = 0;
650 while ((i = codedesc.indexOf('~')) >= 0) {
651 codedesc = codedesc.substring(0, i) + ' ' + codedesc.substring(i+1);
653 if (code) {
654 if (celem.value) {
655 celem.value += '~';
656 delem.value += '~';
658 celem.value += codetype + '|' + code + '|' + selector;
659 if (codetype == 'PROD') delem.value += code + ':' + selector + ' ' + codedesc;
660 else delem.value += codetype + ':' + code + ' ' + codedesc;
661 } else {
662 celem.value = '';
663 delem.value = '';
665 displayCodes(current_lino);
667 else if (typeof(current_sel_name) == 'undefined') {
668 // Coming from the Clinical Terms Code(s) edit
669 var f = document.forms[0][current_sel_clin_term];
670 var s = f.value;
671 if (code) {
672 if (s.length > 0) s += ';';
673 s += codetype + ':' + code;
675 else {
676 s = '';
678 f.value = s;
680 else {
681 // Coming from Immunizations edit
682 var f = document.forms[0][current_sel_name];
683 var s = f.value;
684 if (code) {
685 s = code;
687 else {
688 s = '0';
690 f.value = s;
694 // Called when a "default" checkbox is clicked. Clears all the others.
695 function defClicked(lino) {
696 var f = document.forms[0];
697 for (var i = 1; f['opt[' + i + '][default]']; ++i) {
698 if (i != lino) f['opt[' + i + '][default]'].checked = false;
702 // Form validation and submission.
703 // This needs more validation.
704 function mysubmit() {
705 var f = document.forms[0];
706 if (f.list_id.value == 'code_types') {
707 for (var i = 1; f['opt[' + i + '][ct_key]'].value; ++i) {
708 var ikey = 'opt[' + i + ']';
709 for (var j = i+1; f['opt[' + j + '][ct_key]'].value; ++j) {
710 var jkey = 'opt[' + j + ']';
711 if (f[ikey+'[ct_key]'].value == f[jkey+'[ct_key]'].value) {
712 alert('<?php echo xl('Error: duplicated name on line') ?>' + ' ' + j);
713 return;
715 if (parseInt(f[ikey+'[ct_id]'].value) == parseInt(f[jkey+'[ct_id]'].value)) {
716 alert('<?php echo xl('Error: duplicated ID on line') ?>' + ' ' + j);
717 return;
722 f.submit();
725 </script>
727 </head>
729 <body class="body_top">
731 <form method='post' name='theform' id='theform' action='edit_list.php'>
732 <input type="hidden" name="formaction" id="formaction">
734 <p><b><?php xl('Edit list','e'); ?>:</b>&nbsp;
735 <select name='list_id' id="list_id">
736 <?php
738 // List order depends on language translation options.
739 $lang_id = empty($_SESSION['language_choice']) ? '1' : $_SESSION['language_choice'];
741 if (($lang_id == '1' && !empty($GLOBALS['skip_english_translation'])) ||
742 !$GLOBALS['translate_lists'])
744 $res = sqlStatement("SELECT option_id, title FROM list_options WHERE " .
745 "list_id = 'lists' ORDER BY title, seq");
747 else {
748 // Use and sort by the translated list name.
749 $res = sqlStatement("SELECT lo.option_id, " .
750 "IF(LENGTH(ld.definition),ld.definition,lo.title) AS title " .
751 "FROM list_options AS lo " .
752 "LEFT JOIN lang_constants AS lc ON lc.constant_name = lo.title " .
753 "LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND " .
754 "ld.lang_id = '$lang_id' " .
755 "WHERE lo.list_id = 'lists' " .
756 "ORDER BY IF(LENGTH(ld.definition),ld.definition,lo.title), lo.seq");
759 while ($row = sqlFetchArray($res)) {
760 $key = $row['option_id'];
761 echo "<option value='$key'";
762 if ($key == $list_id) echo " selected";
763 echo ">" . $row['title'] . "</option>\n";
767 </select>
768 <input type="button" id="<?php echo $list_id; ?>" class="deletelist" value=<?php xl('Delete List','e','\'','\''); ?>>
769 <input type="button" id="newlist" class="newlist" value=<?php xl('New List','e','\'','\''); ?>>
770 </p>
772 <center>
774 <table cellpadding='2' cellspacing='0'>
775 <tr class='head'>
776 <?php if ($list_id == 'feesheet') { ?>
777 <td><b><?php xl('Group' ,'e'); ?></b></td>
778 <td><b><?php xl('Option' ,'e'); ?></b></td>
779 <td><b><?php xl('Generates','e'); ?></b></td>
780 <?php } else if ($list_id == 'code_types') { ?>
781 <td><b><?php xl('Active' ,'e'); ?></b></td>
782 <td><b><?php xl('Key' ,'e'); ?></b></td>
783 <td><b><?php xl('ID' ,'e'); ?></b></td>
784 <td><b><?php xl('Label' ,'e'); ?></b></td>
785 <?php //show translation column if not english and the translation lists flag is set
786 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
787 echo "<td><b>".xl('Translation')."</b><span class='help' title='".xl('The translated Title that will appear in current language')."'> (?)</span></td>";
788 } ?>
789 <td><b><?php xl('Seq' ,'e'); ?></b></td>
790 <td><b><?php xl('ModLength' ,'e'); ?></b></td>
791 <td><b><?php xl('Justify' ,'e'); ?></b></td>
792 <td><b><?php xl('Mask' ,'e'); ?></b></td>
793 <td><b><?php xl('Claims' ,'e'); ?></b></td>
794 <td><b><?php xl('Fees' ,'e'); ?></b></td>
795 <td><b><?php xl('Relations' ,'e'); ?></b></td>
796 <td><b><?php xl('Hide' ,'e'); ?></b></td>
797 <td><b><?php xl('Procedure' ,'e'); ?></b></td>
798 <td><b><?php xl('Diagnosis' ,'e'); ?></b></td>
799 <td><b><?php xl('Clinical Term','e'); ?></b></td>
800 <td><b><?php xl('Medical Problem' ,'e'); ?></b></td>
801 <td><b><?php xl('External' ,'e'); ?></b></td>
802 <?php } else if ($list_id == 'issue_types') { ?>
803 <td><b><?php echo xlt('OpenEMR Application Category'); ?></b></td>
804 <td><b><?php echo xlt('Active'); ?></b></td>
805 <td><b><?php echo xlt('Order'); ?></b></td>
806 <td><b><?php echo xlt('Type'); ?></b></td>
807 <td><b><?php echo xlt('Plural'); ?></b></td>
808 <?php //show translation column if not english and the translation lists flag is set
809 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
810 echo "<td><b>".xl('Translation')."</b><span class='help' title='".xl('The translated Title that will appear in current language')."'> (?)</span></td>";
811 } ?>
812 <td><b><?php echo xlt('Singular'); ?></b></td>
813 <?php //show translation column if not english and the translation lists flag is set
814 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
815 echo "<td><b>".xl('Translation')."</b><span class='help' title='".xl('The translated Title that will appear in current language')."'> (?)</span></td>";
816 } ?>
817 <td><b><?php echo xlt('Abbreviation'); ?></b></td>
818 <?php //show translation column if not english and the translation lists flag is set
819 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
820 echo "<td><b>".xl('Translation')."</b><span class='help' title='".xl('The translated Title that will appear in current language')."'> (?)</span></td>";
821 } ?>
822 <td><b><?php echo xlt('Style'); ?></b></td>
823 <td><b><?php echo xlt('Force Show'); ?></b></td>
824 <?php } else { ?>
825 <td title=<?php xl('Click to edit','e','\'','\''); ?>><b><?php xl('ID','e'); ?></b></td>
826 <td><b><?php xl('Title' ,'e'); ?></b></td>
827 <?php //show translation column if not english and the translation lists flag is set
828 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
829 echo "<td><b>".xl('Translation')."</b><span class='help' title='".xl('The translated Title that will appear in current language')."'> (?)</span></td>";
830 } ?>
831 <td><b><?php xl('Order' ,'e'); ?></b></td>
832 <td><b><?php xl('Default','e'); ?></b></td>
833 <?php if ($list_id == 'taxrate') { ?>
834 <td><b><?php xl('Rate' ,'e'); ?></b></td>
835 <?php } else if ($list_id == 'contrameth') { ?>
836 <td><b><?php xl('Effectiveness','e'); ?></b></td>
837 <?php } else if ($list_id == 'lbfnames') { ?>
838 <td title='<?php xl('Number of past history columns','e'); ?>'><b><?php xl('Repeats','e'); ?></b></td>
839 <?php } else if ($list_id == 'fitness') { ?>
840 <td><b><?php xl('Color:Abbr','e'); ?></b></td>
841 <?php } else if ($list_id == 'adjreason' || $list_id == 'abook_type') { ?>
842 <td><b><?php xl('Type','e'); ?></b></td>
843 <?php } else if ($list_id == 'immunizations') { ?>
844 <td><b>&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('CVX Code Mapping','e'); ?></b></td>
845 <?php } if ($GLOBALS['ippf_specific']) { ?>
846 <td><b><?php xl('Global ID','e'); ?></b></td>
847 <?php } ?>
848 <td><b><?php xl('Notes','e'); ?></b></td>
849 <td><b><?php xl('Code(s)','e'); ?></b></td>
850 <?php } // end not fee sheet ?>
851 </tr>
853 <?php
854 // Get the selected list's elements.
855 if ($list_id) {
856 if ($list_id == 'feesheet') {
857 $res = sqlStatement("SELECT * FROM fee_sheet_options " .
858 "ORDER BY fs_category, fs_option");
859 while ($row = sqlFetchArray($res)) {
860 writeFSLine($row['fs_category'], $row['fs_option'], $row['fs_codes']);
862 for ($i = 0; $i < 3; ++$i) {
863 writeFSLine('', '', '');
866 else if ($list_id == 'code_types') {
867 $res = sqlStatement("SELECT * FROM code_types " .
868 "ORDER BY ct_seq, ct_key");
869 while ($row = sqlFetchArray($res)) {
870 writeCTLine($row);
872 for ($i = 0; $i < 3; ++$i) {
873 writeCTLine(array());
876 else if ($list_id == 'issue_types') {
877 $res = sqlStatement("SELECT * FROM issue_types " .
878 "ORDER BY category, ordering ASC");
879 while ($row = sqlFetchArray($res)) {
880 writeITLine($row);
882 for ($i = 0; $i < 3; ++$i) {
883 writeITLine(array());
886 else {
887 $res = sqlStatement("SELECT * FROM list_options WHERE " .
888 "list_id = '$list_id' ORDER BY seq,title");
889 while ($row = sqlFetchArray($res)) {
890 writeOptionLine($row['option_id'], $row['title'], $row['seq'],
891 $row['is_default'], $row['option_value'], $row['mapping'],
892 $row['notes'],$row['codes']);
894 for ($i = 0; $i < 3; ++$i) {
895 writeOptionLine('', '', '', '', 0);
901 </table>
904 <input type='button' name='form_save' id='form_save' value='<?php xl('Save','e'); ?>' />
905 </p>
906 </center>
908 </form>
910 <!-- template DIV that appears when user chooses to make a new list -->
911 <div id="newlistdetail" style="border: 1px solid black; padding: 3px; display: none; visibility: hidden; background-color: lightgrey;">
912 <?php xl('List Name','e'); ?>: <input type="textbox" size="20" maxlength="30" name="newlistname" id="newlistname">
913 <br>
914 <input type="button" class="savenewlist" value=<?php xl('Save New List','e','\'','\''); ?>>
915 <input type="button" class="cancelnewlist" value=<?php xl('Cancel','e','\'','\''); ?>>
916 </div>
917 </body>
918 <script language="javascript">
919 // jQuery stuff to make the page a little easier to use
921 $(document).ready(function(){
922 $("#form_save").click(function() { SaveChanges(); });
923 $("#list_id").change(function() { $('#theform').submit(); });
925 $(".newlist").click(function() { NewList(this); });
926 $(".savenewlist").click(function() { SaveNewList(this); });
927 $(".deletelist").click(function() { DeleteList(this); });
928 $(".cancelnewlist").click(function() { CancelNewList(this); });
930 var SaveChanges = function() {
931 $("#formaction").val("save");
932 // $('#theform').submit();
933 mysubmit();
936 // show the DIV to create a new list
937 var NewList = function(btnObj) {
938 // show the field details DIV
939 $('#newlistdetail').css('visibility', 'visible');
940 $('#newlistdetail').css('display', 'block');
941 $(btnObj).parent().append($("#newlistdetail"));
942 $('#newlistdetail > #newlistname').focus();
944 // save the new list
945 var SaveNewList = function() {
946 // the list name can only have letters, numbers, spaces and underscores
947 // AND it cannot start with a number
948 if ($("#newlistname").val().match(/^\d+/)) {
949 alert("<?php xl('List names cannot start with numbers.','e'); ?>");
950 return false;
952 var validname = $("#newlistname").val().replace(/[^A-za-z0-9 -]/g, "_"); // match any non-word characters and replace them
953 if (validname != $("#newlistname").val()) {
954 if (! confirm("<?php xl('Your list name has been changed to meet naming requirements.','e','','\n') . xl('Please compare the new name','e','',', \''); ?>"+validname+"<?php xl('with the old name','e','\' ',', \''); ?>"+$("#newlistname").val()+"<?php xl('Do you wish to continue with the new name?','e','\'.\n',''); ?>"))
956 return false;
959 $("#newlistname").val(validname);
961 // submit the form to add a new field to a specific group
962 $("#formaction").val("addlist");
963 $("#theform").submit();
965 // actually delete an entire list from the database
966 var DeleteList = function(btnObj) {
967 var listid = $(btnObj).attr("id");
968 if (confirm("<?php xl('WARNING','e','',' - ') . xl('This action cannot be undone.','e','','\n') . xl('Are you sure you wish to delete the entire list','e',' ','('); ?>"+listid+")?")) {
969 // submit the form to add a new field to a specific group
970 $("#formaction").val("deletelist");
971 $("#deletelistname").val(listid);
972 $("#theform").submit();
976 // just hide the new list DIV
977 var CancelNewList = function(btnObj) {
978 // hide the list details DIV
979 $('#newlistdetail').css('visibility', 'hidden');
980 $('#newlistdetail').css('display', 'none');
981 // reset the new group values to a default
982 $('#newlistdetail > #newlistname').val("");
986 </script>
988 </html>