Merge pull request #1154 for user interface improvements of left nav and main title
[openemr.git] / interface / drugs / add_edit_drug.php
blobd5a991852d03fb2bae4149f434752097d4248ee8
1 <?php
2 // Copyright (C) 2006-2017 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 require_once("../globals.php");
10 require_once("$srcdir/acl.inc");
11 require_once("drugs.inc.php");
12 require_once("$srcdir/options.inc.php");
14 $alertmsg = '';
15 $drug_id = $_REQUEST['drug'];
16 $info_msg = "";
17 $tmpl_line_no = 0;
19 if (!acl_check('admin', 'drugs')) {
20 die(xlt('Not authorized'));
23 // Format dollars for display.
25 function bucks($amount)
27 if ($amount) {
28 $amount = sprintf("%.2f", $amount);
29 if ($amount != 0.00) {
30 return $amount;
34 return '';
37 // Write a line of data for one template to the form.
39 function writeTemplateLine($selector, $dosage, $period, $quantity, $refills, $prices, $taxrates)
41 global $tmpl_line_no;
42 ++$tmpl_line_no;
44 echo " <tr>\n";
45 echo " <td class='tmplcell drugsonly'>";
46 echo "<input type='text' name='form_tmpl[$tmpl_line_no][selector]' value='" . attr($selector) . "' size='8' maxlength='100'>";
47 echo "</td>\n";
48 echo " <td class='tmplcell drugsonly'>";
49 echo "<input type='text' name='form_tmpl[$tmpl_line_no][dosage]' value='" . attr($dosage) . "' size='6' maxlength='10'>";
50 echo "</td>\n";
51 echo " <td class='tmplcell drugsonly'>";
52 generate_form_field(array(
53 'data_type' => 1,
54 'field_id' => 'tmpl[' . $tmpl_line_no . '][period]',
55 'list_id' => 'drug_interval',
56 'empty_title' => 'SKIP'
57 ), $period);
58 echo "</td>\n";
59 echo " <td class='tmplcell drugsonly'>";
60 echo "<input type='text' name='form_tmpl[$tmpl_line_no][quantity]' value='" . attr($quantity) . "' size='3' maxlength='7'>";
61 echo "</td>\n";
62 echo " <td class='tmplcell drugsonly'>";
63 echo "<input type='text' name='form_tmpl[$tmpl_line_no][refills]' value='" . attr($refills) . "' size='3' maxlength='5'>";
64 echo "</td>\n";
65 foreach ($prices as $pricelevel => $price) {
66 echo " <td class='tmplcell'>";
67 echo "<input type='text' name='form_tmpl[$tmpl_line_no][price][" . attr($pricelevel) . "]' value='" . attr($price) . "' size='6' maxlength='12'>";
68 echo "</td>\n";
71 $pres = sqlStatement("SELECT option_id FROM list_options " .
72 "WHERE list_id = 'taxrate' AND activity = 1 ORDER BY seq");
73 while ($prow = sqlFetchArray($pres)) {
74 echo " <td class='tmplcell'>";
75 echo "<input type='checkbox' name='form_tmpl[$tmpl_line_no][taxrate][" . attr($prow['option_id']) . "]' value='1'";
76 if (strpos(":$taxrates", $prow['option_id']) !== false) {
77 echo " checked";
80 echo " /></td>\n";
83 echo " </tr>\n";
86 // Translation for form fields used in SQL queries.
88 function escapedff($name)
90 return add_escape_custom(trim($_POST[$name]));
92 function numericff($name)
94 $field = trim($_POST[$name]) + 0;
95 return add_escape_custom($field);
98 <html>
99 <head>
100 <?php html_header_show(); ?>
101 <title><?php echo $drug_id ? xlt("Edit") : xlt("Add New");
102 echo ' ' . xlt('Drug'); ?></title>
103 <link rel="stylesheet" href='<?php echo $css_header ?>' type='text/css'>
105 <style>
106 td { font-size:10pt; }
108 <?php if ($GLOBALS['sell_non_drug_products'] == 2) { ?>
109 .drugsonly { display:none; }
110 <?php } else { ?>
111 .drugsonly { }
112 <?php } ?>
114 <?php if (empty($GLOBALS['ippf_specific'])) { ?>
115 .ippfonly { display:none; }
116 <?php } else { ?>
117 .ippfonly { }
118 <?php } ?>
120 </style>
122 <script type="text/javascript" src="<?php echo $webroot ?>/interface/main/tabs/js/include_opener.js"></script>
123 <script type="text/javascript" src="../../library/topdialog.js"></script>
124 <script type="text/javascript" src="../../library/dialog.js?v=<?php echo $v_js_includes; ?>"></script>
125 <script type="text/javascript" src="../../library/textformat.js"></script>
127 <script language="JavaScript">
129 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
131 // This is for callback by the find-code popup.
132 // Appends to or erases the current list of related codes.
133 function set_related(codetype, code, selector, codedesc) {
134 var f = document.forms[0];
135 var s = f.form_related_code.value;
136 if (code) {
137 if (s.length > 0) s += ';';
138 s += codetype + ':' + code;
139 } else {
140 s = '';
142 f.form_related_code.value = s;
145 // This is for callback by the find-code popup.
146 // Returns the array of currently selected codes with each element in codetype:code format.
147 function get_related() {
148 return document.forms[0].form_related_code.value.split(';');
151 // This is for callback by the find-code popup.
152 // Deletes the specified codetype:code from the currently selected list.
153 function del_related(s) {
154 my_del_related(s, document.forms[0].form_related_code, false);
157 // This invokes the find-code popup.
158 function sel_related() {
159 dlgopen('../patient_file/encounter/find_code_dynamic.php', '_blank', 900, 600);
162 </script>
164 </head>
166 <body class="body_top">
167 <?php
168 // If we are saving, then save and close the window.
169 // First check for duplicates.
171 if ($_POST['form_save']) {
172 $crow = sqlQuery("SELECT COUNT(*) AS count FROM drugs WHERE " .
173 "name = '" . escapedff('form_name') . "' AND " .
174 "form = '" . escapedff('form_form') . "' AND " .
175 "size = '" . escapedff('form_size') . "' AND " .
176 "unit = '" . escapedff('form_unit') . "' AND " .
177 "route = '" . escapedff('form_route') . "' AND " .
178 "drug_id != ?", array($drug_id));
179 if ($crow['count']) {
180 $alertmsg = addslashes(xl('Cannot add this entry because it already exists!'));
184 if (($_POST['form_save'] || $_POST['form_delete']) && !$alertmsg) {
185 $new_drug = false;
186 if ($drug_id) {
187 if ($_POST['form_save']) { // updating an existing drug
188 sqlStatement("UPDATE drugs SET " .
189 "name = '" . escapedff('form_name') . "', " .
190 "ndc_number = '" . escapedff('form_ndc_number') . "', " .
191 "drug_code = '" . escapedff('form_drug_code') . "', " .
192 "on_order = '" . escapedff('form_on_order') . "', " .
193 "reorder_point = '" . escapedff('form_reorder_point') . "', " .
194 "max_level = '" . escapedff('form_max_level') . "', " .
195 "form = '" . escapedff('form_form') . "', " .
196 "size = '" . escapedff('form_size') . "', " .
197 "unit = '" . escapedff('form_unit') . "', " .
198 "route = '" . escapedff('form_route') . "', " .
199 "cyp_factor = '" . numericff('form_cyp_factor') . "', " .
200 "related_code = '" . escapedff('form_related_code') . "', " .
201 "allow_multiple = " . (empty($_POST['form_allow_multiple' ]) ? 0 : 1) . ", " .
202 "allow_combining = " . (empty($_POST['form_allow_combining']) ? 0 : 1) . ", " .
203 "active = " . (empty($_POST['form_active']) ? 0 : 1) . " " .
204 "WHERE drug_id = ?", array($drug_id));
205 sqlStatement("DELETE FROM drug_templates WHERE drug_id = ?", array($drug_id));
206 } else { // deleting
207 if (acl_check('admin', 'super')) {
208 sqlStatement("DELETE FROM drug_inventory WHERE drug_id = ?", array($drug_id));
209 sqlStatement("DELETE FROM drug_templates WHERE drug_id = ?", array($drug_id));
210 sqlStatement("DELETE FROM drugs WHERE drug_id = ?", array($drug_id));
211 sqlStatement("DELETE FROM prices WHERE pr_id = ? AND pr_selector != ''", array($drug_id));
214 } else if ($_POST['form_save']) { // saving a new drug
215 $new_drug = true;
216 $drug_id = sqlInsert("INSERT INTO drugs ( " .
217 "name, ndc_number, drug_code, on_order, reorder_point, max_level, form, " .
218 "size, unit, route, cyp_factor, related_code, " .
219 "allow_multiple, allow_combining, active " .
220 ") VALUES ( " .
221 "'" . escapedff('form_name') . "', " .
222 "'" . escapedff('form_ndc_number') . "', " .
223 "'" . escapedff('form_drug_code') . "', " .
224 "'" . escapedff('form_on_order') . "', " .
225 "'" . escapedff('form_reorder_point') . "', " .
226 "'" . escapedff('form_max_level') . "', " .
227 "'" . escapedff('form_form') . "', " .
228 "'" . escapedff('form_size') . "', " .
229 "'" . escapedff('form_unit') . "', " .
230 "'" . escapedff('form_route') . "', " .
231 "'" . numericff('form_cyp_factor') . "', " .
232 "'" . escapedff('form_related_code') . "', " .
233 (empty($_POST['form_allow_multiple' ]) ? 0 : 1) . ", " .
234 (empty($_POST['form_allow_combining']) ? 0 : 1) . ", " .
235 (empty($_POST['form_active']) ? 0 : 1) .
236 ")");
239 if ($_POST['form_save'] && $drug_id) {
240 $tmpl = $_POST['form_tmpl'];
241 // If using the simplified drug form, then force the one and only
242 // selector name to be the same as the product name.
243 if ($GLOBALS['sell_non_drug_products'] == 2) {
244 $tmpl["1"]['selector'] = $_POST['form_name'];
247 sqlStatement("DELETE FROM prices WHERE pr_id = ? AND pr_selector != ''", array($drug_id));
248 for ($lino = 1; isset($tmpl["$lino"]['selector']); ++$lino) {
249 $iter = $tmpl["$lino"];
250 $selector = trim($iter['selector']);
251 if ($selector) {
252 $taxrates = "";
253 if (!empty($iter['taxrate'])) {
254 foreach ($iter['taxrate'] as $key => $value) {
255 $taxrates .= "$key:";
259 sqlInsert(
260 "INSERT INTO drug_templates ( " .
261 "drug_id, selector, dosage, period, quantity, refills, taxrates " .
262 ") VALUES ( ?, ?, ?, ?, ?, ?, ? )",
263 array($drug_id, $selector, trim($iter['dosage']), trim($iter['period']),
264 trim($iter['quantity']),
265 trim($iter['refills']),
266 $taxrates)
269 // Add prices for this drug ID and selector.
270 foreach ($iter['price'] as $key => $value) {
271 $value = $value + 0;
272 if ($value) {
273 sqlStatement(
274 "INSERT INTO prices ( " .
275 "pr_id, pr_selector, pr_level, pr_price ) VALUES ( " .
276 "?, ?, ?, ? )",
277 array($drug_id, $selector, $key, $value)
280 } // end foreach price
281 } // end if selector is present
282 } // end for each selector
283 // Save warehouse-specific mins and maxes for this drug.
284 sqlStatement("DELETE FROM product_warehouse WHERE pw_drug_id = ?", array($drug_id));
285 foreach ($_POST['form_wh_min'] as $whid => $whmin) {
286 $whmin = 0 + $whmin;
287 $whmax = 0 + $_POST['form_wh_max'][$whid];
288 if ($whmin != 0 || $whmax != 0) {
289 sqlStatement("INSERT INTO product_warehouse ( " .
290 "pw_drug_id, pw_warehouse, pw_min_level, pw_max_level ) VALUES ( " .
291 "?, ?, ?, ? )", array($drug_id, $whid, $whmin, $whmax));
294 } // end if saving a drug
296 // Close this window and redisplay the updated list of drugs.
298 echo "<script language='JavaScript'>\n";
299 if ($info_msg) {
300 echo " alert('$info_msg');\n";
303 echo " if (opener.refreshme) opener.refreshme();\n";
304 if ($new_drug) {
305 echo " window.location.href='add_edit_lot.php?drug=$drug_id&lot=0'\n";
306 } else {
307 echo " window.close();\n";
310 echo "</script></body></html>\n";
311 exit();
314 if ($drug_id) {
315 $row = sqlQuery("SELECT * FROM drugs WHERE drug_id = ?", array($drug_id));
316 $tres = sqlStatement("SELECT * FROM drug_templates WHERE " .
317 "drug_id = ? ORDER BY selector", array($drug_id));
318 } else {
319 $row = array(
320 'name' => '',
321 'active' => '1',
322 'allow_multiple' => '1',
323 'allow_combining' => '',
324 'ndc_number' => '',
325 'on_order' => '0',
326 'reorder_point' => '0',
327 'max_level' => '0',
328 'form' => '',
329 'size' => '',
330 'unit' => '',
331 'route' => '',
332 'cyp_factor' => '',
333 'related_code' => '',
338 <form method='post' name='theform' action='add_edit_drug.php?drug=<?php echo $drug_id; ?>'>
339 <center>
341 <table border='0' width='100%'>
343 <tr>
344 <td valign='top' nowrap><b><?php echo xlt('Name'); ?>:</b></td>
345 <td>
346 <input type='text' size='40' name='form_name' maxlength='80' value='<?php echo attr($row['name']) ?>' style='width:100%' />
347 </td>
348 </tr>
350 <tr>
351 <td valign='top' nowrap><b><?php echo xlt('Active'); ?>:</b></td>
352 <td>
353 <input type='checkbox' name='form_active' value='1'<?php
354 if ($row['active']) {
355 echo ' checked';
356 } ?> />
357 </td>
358 </tr>
360 <tr>
361 <td valign='top' nowrap><b><?php echo xlt('Allow'); ?>:</b></td>
362 <td>
363 <input type='checkbox' name='form_allow_multiple' value='1'<?php
364 if ($row['allow_multiple']) {
365 echo ' checked';
366 } ?> />
367 <?php echo xlt('Multiple Lots'); ?> &nbsp;
368 <input type='checkbox' name='form_allow_combining' value='1'<?php
369 if ($row['allow_combining']) {
370 echo ' checked';
371 } ?> />
372 <?php echo xlt('Combining Lots'); ?>
373 </td>
374 </tr>
376 <tr>
377 <td valign='top' nowrap><b><?php echo xlt('NDC Number'); ?>:</b></td>
378 <td>
379 <input type='text' size='40' name='form_ndc_number' maxlength='20'
380 value='<?php echo attr($row['ndc_number']) ?>' style='width:100%'
381 onkeyup='maskkeyup(this,"<?php echo addslashes($GLOBALS['gbl_mask_product_id']); ?>")'
382 onblur='maskblur(this,"<?php echo addslashes($GLOBALS['gbl_mask_product_id']); ?>")'
384 </td>
385 </tr>
386 <tr>
387 <td valign='top' nowrap><b><?php echo xlt('Drug Code'); ?>:</b></td>
388 <td>
389 <input type='text' size='5' name='form_drug_code' maxlength='10'
390 value='<?php echo attr($row['drug_code']) ?>'
392 </td>
393 </tr>
394 <tr>
395 <td valign='top' nowrap><b><?php echo xlt('On Order'); ?>:</b></td>
396 <td>
397 <input type='text' size='5' name='form_on_order' maxlength='7' value='<?php echo attr($row['on_order']) ?>' />
398 </td>
399 </tr>
401 <tr>
402 <td valign='top' nowrap><b><?php echo xlt('Limits'); ?>:</b></td>
403 <td>
404 <table>
405 <tr>
406 <td valign='top' nowrap>&nbsp;</td>
407 <td valign='top' nowrap><?php echo xlt('Global'); ?></td>
408 <?php
409 // One column header per warehouse title.
410 $pwarr = array();
411 $pwres = sqlStatement(
412 "SELECT lo.option_id, lo.title, " .
413 "pw.pw_min_level, pw.pw_max_level " .
414 "FROM list_options AS lo " .
415 "LEFT JOIN product_warehouse AS pw ON " .
416 "pw.pw_drug_id = ? AND " .
417 "pw.pw_warehouse = lo.option_id WHERE " .
418 "lo.list_id = 'warehouse' AND lo.activity = 1 ORDER BY lo.seq, lo.title",
419 array($drug_id)
421 while ($pwrow = sqlFetchArray($pwres)) {
422 $pwarr[] = $pwrow;
423 echo " <td valign='top' nowrap>" .
424 text($pwrow['title']) . "</td>\n";
427 </tr>
428 <tr>
429 <td valign='top' nowrap><?php echo xlt('Min'); ?>&nbsp;</td>
430 <td valign='top'>
431 <input type='text' size='5' name='form_reorder_point' maxlength='7'
432 value='<?php echo attr($row['reorder_point']) ?>'
433 title='<?php echo xla('Reorder point, 0 if not applicable'); ?>'
434 />&nbsp;&nbsp;
435 </td>
436 <?php
437 foreach ($pwarr as $pwrow) {
438 echo " <td valign='top'>";
439 echo "<input type='text' name='form_wh_min[" .
440 attr($pwrow['option_id']) .
441 "]' value='" . attr(0 + $pwrow['pw_min_level']) . "' size='5' " .
442 "title='" . xla('Warehouse minimum, 0 if not applicable') . "' />";
443 echo "&nbsp;&nbsp;</td>\n";
446 </tr>
447 <tr>
448 <td valign='top' nowrap><?php echo xlt('Max'); ?>&nbsp;</td>
449 <td>
450 <input type='text' size='5' name='form_max_level' maxlength='7'
451 value='<?php echo attr($row['max_level']) ?>'
452 title='<?php echo xla('Maximum reasonable inventory, 0 if not applicable'); ?>'
454 </td>
455 <?php
456 foreach ($pwarr as $pwrow) {
457 echo " <td valign='top'>";
458 echo "<input type='text' name='form_wh_max[" .
459 htmlspecialchars($pwrow['option_id']) .
460 "]' value='" . attr(0 + $pwrow['pw_max_level']) . "' size='5' " .
461 "title='" . xla('Warehouse maximum, 0 if not applicable') . "' />";
462 echo "</td>\n";
465 </tr>
466 </table>
467 </td>
468 </tr>
470 <tr class='drugsonly'>
471 <td valign='top' nowrap><b><?php echo xlt('Form'); ?>:</b></td>
472 <td>
473 <?php
474 generate_form_field(array('data_type'=>1,'field_id'=>'form','list_id'=>'drug_form','empty_title'=>'SKIP'), $row['form']);
476 </td>
477 </tr>
479 <tr class='drugsonly'>
480 <td valign='top' nowrap><b><?php echo xlt('Pill Size'); ?>:</b></td>
481 <td>
482 <input type='text' size='5' name='form_size' maxlength='7' value='<?php echo attr($row['size']) ?>' />
483 </td>
484 </tr>
486 <tr class='drugsonly'>
487 <td valign='top' nowrap><b><?php echo xlt('Units'); ?>:</b></td>
488 <td>
489 <?php
490 generate_form_field(array('data_type'=>1,'field_id'=>'unit','list_id'=>'drug_units','empty_title'=>'SKIP'), $row['unit']);
492 </td>
493 </tr>
495 <tr class='drugsonly'>
496 <td valign='top' nowrap><b><?php echo xlt('Route'); ?>:</b></td>
497 <td>
498 <?php
499 generate_form_field(array('data_type'=>1,'field_id'=>'route','list_id'=>'drug_route','empty_title'=>'SKIP'), $row['route']);
501 </td>
502 </tr>
504 <tr class='ippfonly'>
505 <td valign='top' nowrap><b><?php echo xlt('CYP Factor'); ?>:</b></td>
506 <td>
507 <input type='text' size='10' name='form_cyp_factor' maxlength='20' value='<?php echo attr($row['cyp_factor']) ?>' />
508 </td>
509 </tr>
511 <tr>
512 <td valign='top' nowrap><b><?php echo xlt('Relate To'); ?>:</b></td>
513 <td>
514 <input type='text' size='50' name='form_related_code'
515 value='<?php echo attr($row['related_code']) ?>' onclick='sel_related()'
516 title='<?php echo xla('Click to select related code'); ?>'
517 style='width:100%' readonly />
518 </td>
519 </tr>
521 <tr>
522 <td valign='top' nowrap>
523 <b><?php echo $GLOBALS['sell_non_drug_products'] == 2 ? xlt('Fees') : xlt('Templates'); ?>:</b>
524 </td>
525 <td>
526 <table border='0' width='100%'>
527 <tr>
528 <td class='drugsonly'><b><?php echo xlt('Name'); ?></b></td>
529 <td class='drugsonly'><b><?php echo xlt('Schedule'); ?></b></td>
530 <td class='drugsonly'><b><?php echo xlt('Interval'); ?></b></td>
531 <td class='drugsonly'><b><?php echo xlt('Qty'); ?></b></td>
532 <td class='drugsonly'><b><?php echo xlt('Refills'); ?></b></td>
533 <?php
534 // Show a heading for each price level. Also create an array of prices
535 // for new template lines.
536 $emptyPrices = array();
537 $pres = sqlStatement("SELECT option_id, title FROM list_options " .
538 "WHERE list_id = 'pricelevel' AND activity = 1 ORDER BY seq");
539 while ($prow = sqlFetchArray($pres)) {
540 $emptyPrices[$prow['option_id']] = '';
541 echo " <td><b>" .
542 generate_display_field(array('data_type'=>'1','list_id'=>'pricelevel'), $prow['option_id']) .
543 "</b></td>\n";
546 // Show a heading for each tax rate.
547 $pres = sqlStatement("SELECT option_id, title FROM list_options " .
548 "WHERE list_id = 'taxrate' AND activity = 1 ORDER BY seq");
549 while ($prow = sqlFetchArray($pres)) {
550 echo " <td><b>" .
551 generate_display_field(array('data_type'=>'1','list_id'=>'taxrate'), $prow['option_id']) .
552 "</b></td>\n";
555 </tr>
556 <?php
557 $blank_lines = $GLOBALS['sell_non_drug_products'] == 2 ? 1 : 3;
558 if ($tres) {
559 while ($trow = sqlFetchArray($tres)) {
560 $blank_lines = $GLOBALS['sell_non_drug_products'] == 2 ? 0 : 1;
561 $selector = $trow['selector'];
562 // Get array of prices.
563 $prices = array();
564 $pres = sqlStatement(
565 "SELECT lo.option_id, p.pr_price " .
566 "FROM list_options AS lo LEFT OUTER JOIN prices AS p ON " .
567 "p.pr_id = ? AND p.pr_selector = ? AND " .
568 "p.pr_level = lo.option_id " .
569 "WHERE lo.list_id = 'pricelevel' AND lo.activity = 1 ORDER BY lo.seq",
570 array($drug_id, $selector)
572 while ($prow = sqlFetchArray($pres)) {
573 $prices[$prow['option_id']] = $prow['pr_price'];
576 writeTemplateLine(
577 $selector,
578 $trow['dosage'],
579 $trow['period'],
580 $trow['quantity'],
581 $trow['refills'],
582 $prices,
583 $trow['taxrates']
588 for ($i = 0; $i < $blank_lines; ++$i) {
589 $selector = $GLOBALS['sell_non_drug_products'] == 2 ? $row['name'] : '';
590 writeTemplateLine($selector, '', '', '', '', $emptyPrices, '');
593 </table>
594 </td>
595 </tr>
597 </table>
600 <input type='submit' name='form_save' value='<?php echo xla('Save'); ?>' />
602 <?php if (acl_check('admin', 'super')) { ?>
603 &nbsp;
604 <input type='submit' name='form_delete' value='<?php echo xla('Delete'); ?>' style='color:red' />
605 <?php } ?>
607 &nbsp;
608 <input type='button' value='<?php echo xla('Cancel'); ?>' onclick='window.close()' />
610 </p>
612 </center>
613 </form>
615 <script language="JavaScript">
616 <?php
617 if ($alertmsg) {
618 echo "alert('" . htmlentities($alertmsg) . "');\n";
621 </script>
623 </body>
624 </html>