consolidate attr_url function (#2143)
[openemr.git] / interface / drugs / add_edit_drug.php
blobb0dfae8333c2a7b8716fa4c4ea26b0b2f62ae11b
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 use OpenEMR\Core\Header;
16 $alertmsg = '';
17 $drug_id = $_REQUEST['drug'];
18 $info_msg = "";
19 $tmpl_line_no = 0;
21 if (!acl_check('admin', 'drugs')) {
22 die(xlt('Not authorized'));
25 // Write a line of data for one template to the form.
27 function writeTemplateLine($selector, $dosage, $period, $quantity, $refills, $prices, $taxrates)
29 global $tmpl_line_no;
30 ++$tmpl_line_no;
32 echo " <tr>\n";
33 echo " <td class='tmplcell drugsonly'>";
34 echo "<input class='form-control' name='form_tmpl[" . attr($tmpl_line_no) . "][selector]' value='" . attr($selector) . "' size='8' maxlength='100'>";
35 echo "</td>\n";
36 echo " <td class='tmplcell drugsonly'>";
37 echo "<input class='form-control' name='form_tmpl[" . attr($tmpl_line_no) . "][dosage]' value='" . attr($dosage) . "' size='6' maxlength='10'>";
38 echo "</td>\n";
39 echo " <td class='tmplcell drugsonly'>";
40 generate_form_field(array(
41 'data_type' => 1,
42 'field_id' => 'tmpl[' . attr($tmpl_line_no) . '][period]',
43 'list_id' => 'drug_interval',
44 'empty_title' => 'SKIP'
45 ), $period);
46 echo "</td>\n";
47 echo " <td class='tmplcell drugsonly'>";
48 echo "<input class='form-control' name='form_tmpl[" . attr($tmpl_line_no) . "][quantity]' value='" . attr($quantity) . "' size='3' maxlength='7'>";
49 echo "</td>\n";
50 echo " <td class='tmplcell drugsonly'>";
51 echo "<input class='form-control' name='form_tmpl[" . attr($tmpl_line_no) . "][refills]' value='" . attr($refills) . "' size='3' maxlength='5'>";
52 echo "</td>\n";
53 foreach ($prices as $pricelevel => $price) {
54 echo " <td class='tmplcell'>";
55 echo "<input class='form-control' name='form_tmpl[" . attr($tmpl_line_no) . "][price][" . attr($pricelevel) . "]' value='" . attr($price) . "' size='6' maxlength='12'>";
56 echo "</td>\n";
59 $pres = sqlStatement("SELECT option_id FROM list_options " .
60 "WHERE list_id = 'taxrate' AND activity = 1 ORDER BY seq");
61 while ($prow = sqlFetchArray($pres)) {
62 echo " <td class='tmplcell'>";
63 echo "<input type='checkbox' name='form_tmpl[" . attr($tmpl_line_no) . "][taxrate][" . attr($prow['option_id']) . "]' value='1'";
64 if (strpos(":$taxrates", $prow['option_id']) !== false) {
65 echo " checked";
68 echo " /></td>\n";
71 echo " </tr>\n";
74 <html>
75 <head>
76 <?php html_header_show(); ?>
77 <title><?php echo $drug_id ? xlt("Edit") : xlt("Add New");
78 echo ' ' . xlt('Drug'); ?></title>
79 <link rel="stylesheet" href='<?php echo $css_header ?>' type='text/css'>
81 <style>
82 td { font-size:10pt; }
84 <?php if ($GLOBALS['sell_non_drug_products'] == 2) { ?>
85 .drugsonly { display:none; }
86 <?php } else { ?>
87 .drugsonly { }
88 <?php } ?>
90 <?php if (empty($GLOBALS['ippf_specific'])) { ?>
91 .ippfonly { display:none; }
92 <?php } else { ?>
93 .ippfonly { }
94 <?php } ?>
96 </style>
97 <?php Header::setupHeader(["jquery-ui","opener"]); ?>
99 <script language="JavaScript">
101 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
103 // This is for callback by the find-code popup.
104 // Appends to or erases the current list of related codes.
105 function set_related(codetype, code, selector, codedesc) {
106 var f = document.forms[0];
107 var s = f.form_related_code.value;
108 if (code) {
109 if (s.length > 0) s += ';';
110 s += codetype + ':' + code;
111 } else {
112 s = '';
114 f.form_related_code.value = s;
117 // This is for callback by the find-code popup.
118 // Returns the array of currently selected codes with each element in codetype:code format.
119 function get_related() {
120 return document.forms[0].form_related_code.value.split(';');
123 // This is for callback by the find-code popup.
124 // Deletes the specified codetype:code from the currently selected list.
125 function del_related(s) {
126 my_del_related(s, document.forms[0].form_related_code, false);
129 // This invokes the find-code popup.
130 function sel_related() {
131 dlgopen('../patient_file/encounter/find_code_dynamic.php', '_blank', 900, 800);
134 </script>
136 </head>
138 <body class="body_top">
139 <?php
140 // If we are saving, then save and close the window.
141 // First check for duplicates.
143 if ($_POST['form_save']) {
144 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
145 csrfNotVerified();
148 $crow = sqlQuery(
149 "SELECT COUNT(*) AS count FROM drugs WHERE " .
150 "name = ? AND " .
151 "form = ? AND " .
152 "size = ? AND " .
153 "unit = ? AND " .
154 "route = ? AND " .
155 "drug_id != ?",
156 array(
157 trim($_POST['form_name']),
158 trim($_POST['form_form']),
159 trim($_POST['form_size']),
160 trim($_POST['form_unit']),
161 trim($_POST['form_route']),
162 $drug_id
165 if ($crow['count']) {
166 $alertmsg = xl('Cannot add this entry because it already exists!');
170 if (($_POST['form_save'] || $_POST['form_delete']) && !$alertmsg) {
171 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
172 csrfNotVerified();
175 $new_drug = false;
176 if ($drug_id) {
177 if ($_POST['form_save']) { // updating an existing drug
178 sqlStatement(
179 "UPDATE drugs SET " .
180 "name = ?, " .
181 "ndc_number = ?, " .
182 "drug_code = ?, " .
183 "on_order = ?, " .
184 "reorder_point = ?, " .
185 "max_level = ?, " .
186 "form = ?, " .
187 "size = ?, " .
188 "unit = ?, " .
189 "route = ?, " .
190 "cyp_factor = ?, " .
191 "related_code = ?, " .
192 "allow_multiple = ?, " .
193 "allow_combining = ?, " .
194 "active = ? " .
195 "WHERE drug_id = ?",
196 array(
197 trim($_POST['form_name']),
198 trim($_POST['form_ndc_number']),
199 trim($_POST['form_drug_code']),
200 trim($_POST['form_on_order']),
201 trim($_POST['form_reorder_point']),
202 trim($_POST['form_max_level']),
203 trim($_POST['form_form']),
204 trim($_POST['form_size']),
205 trim($_POST['form_unit']),
206 trim($_POST['form_route']),
207 trim($_POST['form_cyp_factor']),
208 trim($_POST['form_related_code']),
209 (empty($_POST['form_allow_multiple' ]) ? 0 : 1),
210 (empty($_POST['form_allow_combining']) ? 0 : 1),
211 (empty($_POST['form_active']) ? 0 : 1),
212 $drug_id
215 sqlStatement("DELETE FROM drug_templates WHERE drug_id = ?", array($drug_id));
216 } else { // deleting
217 if (acl_check('admin', 'super')) {
218 sqlStatement("DELETE FROM drug_inventory WHERE drug_id = ?", array($drug_id));
219 sqlStatement("DELETE FROM drug_templates WHERE drug_id = ?", array($drug_id));
220 sqlStatement("DELETE FROM drugs WHERE drug_id = ?", array($drug_id));
221 sqlStatement("DELETE FROM prices WHERE pr_id = ? AND pr_selector != ''", array($drug_id));
224 } else if ($_POST['form_save']) { // saving a new drug
225 $new_drug = true;
226 $drug_id = sqlInsert(
227 "INSERT INTO drugs ( " .
228 "name, ndc_number, drug_code, on_order, reorder_point, max_level, form, " .
229 "size, unit, route, cyp_factor, related_code, " .
230 "allow_multiple, allow_combining, active " .
231 ") VALUES ( " .
232 "?, " .
233 "?, " .
234 "?, " .
235 "?, " .
236 "?, " .
237 "?, " .
238 "?, " .
239 "?, " .
240 "?, " .
241 "?, " .
242 "?, " .
243 "?, " .
244 "?, " .
245 "?, " .
246 "?)",
247 array(
248 trim($_POST['form_name']),
249 trim($_POST['form_ndc_number']),
250 trim($_POST['form_drug_code']),
251 trim($_POST['form_on_order']),
252 trim($_POST['form_reorder_point']),
253 trim($_POST['form_max_level']),
254 trim($_POST['form_form']),
255 trim($_POST['form_size']),
256 trim($_POST['form_unit']),
257 trim($_POST['form_route']),
258 trim($_POST['form_cyp_factor']),
259 trim($_POST['form_related_code']),
260 (empty($_POST['form_allow_multiple' ]) ? 0 : 1),
261 (empty($_POST['form_allow_combining']) ? 0 : 1),
262 (empty($_POST['form_active']) ? 0 : 1)
267 if ($_POST['form_save'] && $drug_id) {
268 $tmpl = $_POST['form_tmpl'];
269 // If using the simplified drug form, then force the one and only
270 // selector name to be the same as the product name.
271 if ($GLOBALS['sell_non_drug_products'] == 2) {
272 $tmpl["1"]['selector'] = $_POST['form_name'];
275 sqlStatement("DELETE FROM prices WHERE pr_id = ? AND pr_selector != ''", array($drug_id));
276 for ($lino = 1; isset($tmpl["$lino"]['selector']); ++$lino) {
277 $iter = $tmpl["$lino"];
278 $selector = trim($iter['selector']);
279 if ($selector) {
280 $taxrates = "";
281 if (!empty($iter['taxrate'])) {
282 foreach ($iter['taxrate'] as $key => $value) {
283 $taxrates .= "$key:";
287 sqlInsert(
288 "INSERT INTO drug_templates ( " .
289 "drug_id, selector, dosage, period, quantity, refills, taxrates " .
290 ") VALUES ( ?, ?, ?, ?, ?, ?, ? )",
291 array($drug_id, $selector, trim($iter['dosage']), trim($iter['period']),
292 trim($iter['quantity']),
293 trim($iter['refills']),
294 $taxrates)
297 // Add prices for this drug ID and selector.
298 foreach ($iter['price'] as $key => $value) {
299 $value = $value + 0;
300 if ($value) {
301 sqlStatement(
302 "INSERT INTO prices ( " .
303 "pr_id, pr_selector, pr_level, pr_price ) VALUES ( " .
304 "?, ?, ?, ? )",
305 array($drug_id, $selector, $key, $value)
308 } // end foreach price
309 } // end if selector is present
310 } // end for each selector
311 // Save warehouse-specific mins and maxes for this drug.
312 sqlStatement("DELETE FROM product_warehouse WHERE pw_drug_id = ?", array($drug_id));
313 foreach ($_POST['form_wh_min'] as $whid => $whmin) {
314 $whmin = 0 + $whmin;
315 $whmax = 0 + $_POST['form_wh_max'][$whid];
316 if ($whmin != 0 || $whmax != 0) {
317 sqlStatement("INSERT INTO product_warehouse ( " .
318 "pw_drug_id, pw_warehouse, pw_min_level, pw_max_level ) VALUES ( " .
319 "?, ?, ?, ? )", array($drug_id, $whid, $whmin, $whmax));
322 } // end if saving a drug
324 // Close this window and redisplay the updated list of drugs.
326 echo "<script language='JavaScript'>\n";
327 if ($info_msg) {
328 echo " alert('" . addslashes($info_msg) . "');\n";
331 echo " if (opener.refreshme) opener.refreshme();\n";
332 if ($new_drug) {
333 echo " window.location.href='add_edit_lot.php?drug=" . attr_url($drug_id) . "&lot=0'\n";
334 } else {
335 echo " window.close();\n";
338 echo "</script></body></html>\n";
339 exit();
342 if ($drug_id) {
343 $row = sqlQuery("SELECT * FROM drugs WHERE drug_id = ?", array($drug_id));
344 $tres = sqlStatement("SELECT * FROM drug_templates WHERE " .
345 "drug_id = ? ORDER BY selector", array($drug_id));
346 } else {
347 $row = array(
348 'name' => '',
349 'active' => '1',
350 'allow_multiple' => '1',
351 'allow_combining' => '',
352 'ndc_number' => '',
353 'on_order' => '0',
354 'reorder_point' => '0',
355 'max_level' => '0',
356 'form' => '',
357 'size' => '',
358 'unit' => '',
359 'route' => '',
360 'cyp_factor' => '',
361 'related_code' => '',
366 <form class="form" method='post' name='theform' action='add_edit_drug.php?drug=<?php echo attr_url($drug_id); ?>'>
367 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>" />
368 <center>
370 <table class="table" border='0' width='100%'>
372 <tr>
373 <td valign='top' nowrap><b><?php echo xlt('Name'); ?>:</b></td>
374 <td>
375 <input class="form-control" size='40' name='form_name' maxlength='80' value='<?php echo attr($row['name']) ?>' style='width:100%' />
376 </td>
377 </tr>
379 <tr>
380 <td valign='top' nowrap><b><?php echo xlt('Active'); ?>:</b></td>
381 <td>
382 <input type='checkbox' name='form_active' value='1'<?php
383 if ($row['active']) {
384 echo ' checked';
385 } ?> />
386 </td>
387 </tr>
389 <tr>
390 <td valign='top' nowrap><b><?php echo xlt('Allow'); ?>:</b></td>
391 <td>
392 <input type='checkbox' name='form_allow_multiple' value='1'<?php
393 if ($row['allow_multiple']) {
394 echo ' checked';
395 } ?> />
396 <?php echo xlt('Multiple Lots'); ?> &nbsp;
397 <input type='checkbox' name='form_allow_combining' value='1'<?php
398 if ($row['allow_combining']) {
399 echo ' checked';
400 } ?> />
401 <?php echo xlt('Combining Lots'); ?>
402 </td>
403 </tr>
405 <tr>
406 <td valign='top' nowrap><b><?php echo xlt('NDC Number'); ?>:</b></td>
407 <td>
408 <input class="form-control" size='40' name='form_ndc_number' maxlength='20'
409 value='<?php echo attr($row['ndc_number']) ?>' style='width:100%'
410 onkeyup='maskkeyup(this,"<?php echo attr(addslashes($GLOBALS['gbl_mask_product_id'])); ?>")'
411 onblur='maskblur(this,"<?php echo attr(addslashes($GLOBALS['gbl_mask_product_id'])); ?>")'
413 </td>
414 </tr>
415 <tr>
416 <td valign='top' nowrap><b><?php echo xlt('Drug Code'); ?>:</b></td>
417 <td>
418 <input class="form-control" size='5' name='form_drug_code' maxlength='10'
419 value='<?php echo attr($row['drug_code']) ?>'
421 </td>
422 </tr>
423 <tr>
424 <td valign='top' nowrap><b><?php echo xlt('On Order'); ?>:</b></td>
425 <td>
426 <input class="form-control" size='5' name='form_on_order' maxlength='7' value='<?php echo attr($row['on_order']) ?>' />
427 </td>
428 </tr>
430 <tr>
431 <td valign='top' nowrap><b><?php echo xlt('Limits'); ?>:</b></td>
432 <td>
433 <table>
434 <tr>
435 <td valign='top' nowrap>&nbsp;</td>
436 <td valign='top' nowrap><?php echo xlt('Global'); ?></td>
437 <?php
438 // One column header per warehouse title.
439 $pwarr = array();
440 $pwres = sqlStatement(
441 "SELECT lo.option_id, lo.title, " .
442 "pw.pw_min_level, pw.pw_max_level " .
443 "FROM list_options AS lo " .
444 "LEFT JOIN product_warehouse AS pw ON " .
445 "pw.pw_drug_id = ? AND " .
446 "pw.pw_warehouse = lo.option_id WHERE " .
447 "lo.list_id = 'warehouse' AND lo.activity = 1 ORDER BY lo.seq, lo.title",
448 array($drug_id)
450 while ($pwrow = sqlFetchArray($pwres)) {
451 $pwarr[] = $pwrow;
452 echo " <td valign='top' nowrap>" .
453 text($pwrow['title']) . "</td>\n";
456 </tr>
457 <tr>
458 <td valign='top' nowrap><?php echo xlt('Min'); ?>&nbsp;</td>
459 <td valign='top'>
460 <input class="form-control" size='5' name='form_reorder_point' maxlength='7'
461 value='<?php echo attr($row['reorder_point']) ?>'
462 title='<?php echo xla('Reorder point, 0 if not applicable'); ?>'
463 />&nbsp;&nbsp;
464 </td>
465 <?php
466 foreach ($pwarr as $pwrow) {
467 echo " <td valign='top'>";
468 echo "<input class='form-control' name='form_wh_min[" .
469 attr($pwrow['option_id']) .
470 "]' value='" . attr(0 + $pwrow['pw_min_level']) . "' size='5' " .
471 "title='" . xla('Warehouse minimum, 0 if not applicable') . "' />";
472 echo "&nbsp;&nbsp;</td>\n";
475 </tr>
476 <tr>
477 <td valign='top' nowrap><?php echo xlt('Max'); ?>&nbsp;</td>
478 <td>
479 <input class='form-control' size='5' name='form_max_level' maxlength='7'
480 value='<?php echo attr($row['max_level']) ?>'
481 title='<?php echo xla('Maximum reasonable inventory, 0 if not applicable'); ?>'
483 </td>
484 <?php
485 foreach ($pwarr as $pwrow) {
486 echo " <td valign='top'>";
487 echo "<input class='form-control' name='form_wh_max[" .
488 attr($pwrow['option_id']) .
489 "]' value='" . attr(0 + $pwrow['pw_max_level']) . "' size='5' " .
490 "title='" . xla('Warehouse maximum, 0 if not applicable') . "' />";
491 echo "</td>\n";
494 </tr>
495 </table>
496 </td>
497 </tr>
499 <tr class='drugsonly'>
500 <td valign='top' nowrap><b><?php echo xlt('Form'); ?>:</b></td>
501 <td>
502 <?php
503 generate_form_field(array('data_type'=>1,'field_id'=>'form','list_id'=>'drug_form','empty_title'=>'SKIP'), $row['form']);
505 </td>
506 </tr>
508 <tr class='drugsonly'>
509 <td valign='top' nowrap><b><?php echo xlt('Pill Size'); ?>:</b></td>
510 <td>
511 <input class="form-control" size='5' name='form_size' maxlength='7' value='<?php echo attr($row['size']) ?>' />
512 </td>
513 </tr>
515 <tr class='drugsonly'>
516 <td valign='top' nowrap><b><?php echo xlt('Units'); ?>:</b></td>
517 <td>
518 <?php
519 generate_form_field(array('data_type'=>1,'field_id'=>'unit','list_id'=>'drug_units','empty_title'=>'SKIP'), $row['unit']);
521 </td>
522 </tr>
524 <tr class='drugsonly'>
525 <td valign='top' nowrap><b><?php echo xlt('Route'); ?>:</b></td>
526 <td>
527 <?php
528 generate_form_field(array('data_type'=>1,'field_id'=>'route','list_id'=>'drug_route','empty_title'=>'SKIP'), $row['route']);
530 </td>
531 </tr>
533 <tr class='ippfonly'>
534 <td valign='top' nowrap><b><?php echo xlt('CYP Factor'); ?>:</b></td>
535 <td>
536 <input class="form-control" size='10' name='form_cyp_factor' maxlength='20' value='<?php echo attr($row['cyp_factor']) ?>' />
537 </td>
538 </tr>
540 <tr>
541 <td valign='top' nowrap><b><?php echo xlt('Relate To'); ?>:</b></td>
542 <td>
543 <input class="form-control" type='text' size='50' name='form_related_code'
544 value='<?php echo attr($row['related_code']) ?>' onclick='sel_related()'
545 title='<?php echo xla('Click to select related code'); ?>'
546 style='width:100%' readonly />
547 </td>
548 </tr>
550 <tr>
551 <td valign='top' nowrap>
552 <b><?php echo $GLOBALS['sell_non_drug_products'] == 2 ? xlt('Fees') : xlt('Templates'); ?>:</b>
553 </td>
554 <td>
555 <table border='0' width='100%'>
556 <tr>
557 <td class='drugsonly'><b><?php echo xlt('Name'); ?></b></td>
558 <td class='drugsonly'><b><?php echo xlt('Schedule'); ?></b></td>
559 <td class='drugsonly'><b><?php echo xlt('Interval'); ?></b></td>
560 <td class='drugsonly'><b><?php echo xlt('Qty'); ?></b></td>
561 <td class='drugsonly'><b><?php echo xlt('Refills'); ?></b></td>
562 <?php
563 // Show a heading for each price level. Also create an array of prices
564 // for new template lines.
565 $emptyPrices = array();
566 $pres = sqlStatement("SELECT option_id, title FROM list_options " .
567 "WHERE list_id = 'pricelevel' AND activity = 1 ORDER BY seq");
568 while ($prow = sqlFetchArray($pres)) {
569 $emptyPrices[$prow['option_id']] = '';
570 echo " <td><b>" .
571 generate_display_field(array('data_type'=>'1','list_id'=>'pricelevel'), $prow['option_id']) .
572 "</b></td>\n";
575 // Show a heading for each tax rate.
576 $pres = sqlStatement("SELECT option_id, title FROM list_options " .
577 "WHERE list_id = 'taxrate' AND activity = 1 ORDER BY seq");
578 while ($prow = sqlFetchArray($pres)) {
579 echo " <td><b>" .
580 generate_display_field(array('data_type'=>'1','list_id'=>'taxrate'), $prow['option_id']) .
581 "</b></td>\n";
584 </tr>
585 <?php
586 $blank_lines = $GLOBALS['sell_non_drug_products'] == 2 ? 1 : 3;
587 if ($tres) {
588 while ($trow = sqlFetchArray($tres)) {
589 $blank_lines = $GLOBALS['sell_non_drug_products'] == 2 ? 0 : 1;
590 $selector = $trow['selector'];
591 // Get array of prices.
592 $prices = array();
593 $pres = sqlStatement(
594 "SELECT lo.option_id, p.pr_price " .
595 "FROM list_options AS lo LEFT OUTER JOIN prices AS p ON " .
596 "p.pr_id = ? AND p.pr_selector = ? AND " .
597 "p.pr_level = lo.option_id " .
598 "WHERE lo.list_id = 'pricelevel' AND lo.activity = 1 ORDER BY lo.seq",
599 array($drug_id, $selector)
601 while ($prow = sqlFetchArray($pres)) {
602 $prices[$prow['option_id']] = $prow['pr_price'];
605 writeTemplateLine(
606 $selector,
607 $trow['dosage'],
608 $trow['period'],
609 $trow['quantity'],
610 $trow['refills'],
611 $prices,
612 $trow['taxrates']
617 for ($i = 0; $i < $blank_lines; ++$i) {
618 $selector = $GLOBALS['sell_non_drug_products'] == 2 ? $row['name'] : '';
619 writeTemplateLine($selector, '', '', '', '', $emptyPrices, '');
622 </table>
623 </td>
624 </tr>
626 </table>
629 <input type='submit' name='form_save' value='<?php echo xla('Save'); ?>' />
631 <?php if (acl_check('admin', 'super')) { ?>
632 &nbsp;
633 <input type='submit' name='form_delete' value='<?php echo xla('Delete'); ?>' style='color:red' />
634 <?php } ?>
636 &nbsp;
637 <input type='button' value='<?php echo xla('Cancel'); ?>' onclick='window.close()' />
639 </p>
641 </center>
642 </form>
644 <script language="JavaScript">
645 <?php
646 if ($alertmsg) {
647 echo "alert('" . addslashes($alertmsg) . "');\n";
650 </script>
652 </body>
653 </html>