Merge pull request #1154 for user interface improvements of left nav and main title
[openemr.git] / interface / drugs / add_edit_lot.php
blob753c41755c1710e631bcb77ef0f4c96c6153d0a2
1 <?php
2 /**
3 * add and edit lot
5 * @package OpenEMR
6 * @link http://www.open-emr.org
7 * @author Rod Roark <rod@sunsetsystems.com>
8 * @author Brady Miller <brady.g.miller@gmail.com>
9 * @copyright Copyright (c) 2006-2016 Rod Roark <rod@sunsetsystems.com>
10 * @copyright Copyright (c) 2017 Brady Miller <brady.g.miller@gmail.com>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 require_once("../globals.php");
16 require_once("$srcdir/acl.inc");
17 require_once("drugs.inc.php");
18 require_once("$srcdir/options.inc.php");
20 function QuotedOrNull($fld)
22 if ($fld) {
23 return "'".add_escape_custom($fld)."'";
26 return "NULL";
29 function checkWarehouseUsed($warehouse_id)
31 global $drug_id;
32 $row = sqlQuery("SELECT count(*) AS count FROM drug_inventory WHERE " .
33 "drug_id = ? AND " .
34 "destroy_date IS NULL AND warehouse_id = ?", array($drug_id,$warehouse_id));
35 return $row['count'];
38 // Generate a <select> list of warehouses.
39 // If multiple lots are not allowed for this product, then restrict the
40 // list to warehouses that are unused for the product.
41 // Returns the number of warehouses allowed.
42 // For these purposes the "unassigned" option is considered a warehouse.
44 function genWarehouseList($tag_name, $currvalue, $title, $class = '')
46 global $drug_id;
48 $drow = sqlQuery("SELECT allow_multiple FROM drugs WHERE drug_id = ?", array($drug_id));
49 $allow_multiple = $drow['allow_multiple'];
51 $lres = sqlStatement("SELECT * FROM list_options " .
52 "WHERE list_id = 'warehouse' AND activity = 1 ORDER BY seq, title");
54 echo "<select name='".attr($tag_name)."' id='".attr($tag_name)."'";
55 if ($class) {
56 echo " class='".attr($class)."'";
59 echo " title='".attr($title)."'>";
61 $got_selected = false;
62 $count = 0;
64 if ($allow_multiple /* || !checkWarehouseUsed('') */) {
65 echo "<option value=''>" . xlt('Unassigned') . "</option>";
66 ++$count;
69 while ($lrow = sqlFetchArray($lres)) {
70 $whid = $lrow['option_id'];
71 if ($whid != $currvalue && !$allow_multiple && checkWarehouseUsed($whid)) {
72 continue;
75 echo "<option value='".attr($whid)."'";
76 if ((strlen($currvalue) == 0 && $lrow['is_default']) ||
77 (strlen($currvalue) > 0 && $whid == $currvalue)) {
78 echo " selected";
79 $got_selected = true;
82 echo ">" . text($lrow['title']) . "</option>\n";
84 ++$count;
87 if (!$got_selected && strlen($currvalue) > 0) {
88 echo "<option value='".attr($currvalue)."' selected>* ".text($currvalue)." *</option>";
89 echo "</select>";
90 echo " <font color='red' title='" .
91 xla('Please choose a valid selection from the list.') . "'>" .
92 xlt('Fix this') . "!</font>";
93 } else {
94 echo "</select>";
97 return $count;
100 $drug_id = $_REQUEST['drug'] + 0;
101 $lot_id = $_REQUEST['lot'] + 0;
102 $info_msg = "";
104 $form_trans_type = isset($_POST['form_trans_type']) ? $_POST['form_trans_type'] : '0';
106 if (!acl_check('admin', 'drugs')) {
107 die(xlt('Not authorized'));
110 if (!$drug_id) {
111 die(xlt('Drug ID missing!'));
114 <html>
115 <head>
116 <?php html_header_show();?>
117 <title><?php echo $lot_id ? xlt("Edit") : xlt("Add New");
118 xlt('Lot', 'e', ' '); ?></title>
119 <link rel="stylesheet" href='<?php echo $css_header ?>' type='text/css'>
120 <link rel="stylesheet" href="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker-2-5-4/build/jquery.datetimepicker.min.css">
122 <style>
123 td { font-size:10pt; }
124 </style>
126 <script type="text/javascript" src="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-min-3-1-1/index.js"></script>
127 <script type="text/javascript" src="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker-2-5-4/build/jquery.datetimepicker.full.min.js"></script>
128 <script type="text/javascript" src="<?php echo $webroot ?>/interface/main/tabs/js/include_opener.js?v=<?php echo $v_js_includes; ?>"></script>
129 <script type="text/javascript" src="../../library/textformat.js?v=<?php echo $v_js_includes; ?>"></script>
131 <script language="JavaScript">
133 function validate() {
134 var f = document.forms[0];
135 if (f.form_source_lot.value == '0' && f.form_lot_number.value.search(/\S/) < 0) {
136 alert('<?php echo addslashes(xl('A lot number is required')); ?>');
137 return false;
139 if (f.form_trans_type.value == '6' && f.form_distributor_id.value == '') {
140 alert('<?php echo addslashes(xl('A distributor is required')); ?>');
141 return false;
143 return true;
146 function trans_type_changed() {
147 var f = document.forms[0];
148 var sel = f.form_trans_type;
149 var type = sel.options[sel.selectedIndex].value;
150 var showQuantity = true;
151 var showSaleDate = true;
152 var showCost = true;
153 var showSourceLot = true;
154 var showNotes = true;
155 var showDistributor = false;
156 if (type == '2') { // purchase
157 showSourceLot = false;
159 else if (type == '3') { // return
160 showSourceLot = false;
162 else if (type == '6') { // distribution
163 showSourceLot = false;
164 showDistributor = true;
166 else if (type == '4') { // transfer
167 showCost = false;
169 else if (type == '5') { // adjustment
170 showCost = false;
171 showSourceLot = false;
173 else {
174 showQuantity = false;
175 showSaleDate = false;
176 showCost = false;
177 showSourceLot = false;
178 showNotes = false;
180 document.getElementById('row_quantity' ).style.display = showQuantity ? '' : 'none';
181 document.getElementById('row_sale_date' ).style.display = showSaleDate ? '' : 'none';
182 document.getElementById('row_cost' ).style.display = showCost ? '' : 'none';
183 document.getElementById('row_source_lot').style.display = showSourceLot ? '' : 'none';
184 document.getElementById('row_notes' ).style.display = showNotes ? '' : 'none';
185 document.getElementById('row_distributor').style.display = showDistributor ? '' : 'none';
188 $(document).ready(function(){
189 $('.datepicker').datetimepicker({
190 <?php $datetimepicker_timepicker = false; ?>
191 <?php $datetimepicker_showseconds = false; ?>
192 <?php $datetimepicker_formatInput = false; ?>
193 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
194 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
197 </script>
199 </head>
201 <body class="body_top">
202 <?php
203 if ($lot_id) {
204 $row = sqlQuery("SELECT * FROM drug_inventory WHERE drug_id = ? " .
205 "AND inventory_id = ?", array($drug_id,$lot_id));
208 // If we are saving, then save and close the window.
210 if ($_POST['form_save'] || $_POST['form_delete']) {
211 $form_quantity = $_POST['form_quantity'] + 0;
212 $form_cost = sprintf('%0.2f', $_POST['form_cost']);
213 $form_source_lot = $_POST['form_source_lot'] + 0;
214 $form_distributor_id = $_POST['form_distributor_id'] + 0;
216 // Some fixups depending on transaction type.
217 if ($form_trans_type == '3') { // return
218 $form_quantity = 0 - $form_quantity;
219 $form_cost = 0 - $form_cost;
220 } else if ($form_trans_type == '5') { // adjustment
221 $form_cost = 0;
222 } else if ($form_trans_type == '0') { // no transaction
223 $form_quantity = 0;
224 $form_cost = 0;
225 } else if ($form_trans_type == '6') { // distribution
226 $form_quantity = 0 - $form_quantity;
227 $form_cost = 0 - $form_cost;
230 if ($form_trans_type != '4') { // not transfer
231 $form_source_lot = 0;
234 if ($form_trans_type != '6') { // not distribution
235 $form_distributor_id = '0';
238 // If a transfer, make sure there is sufficient quantity in the source lot.
239 if ($_POST['form_save'] && $form_source_lot && $form_quantity) {
240 $srow = sqlQuery("SELECT on_hand FROM drug_inventory WHERE " .
241 "drug_id = ? AND inventory_id = ?", array($drug_id,$form_source_lot));
242 if ($srow['on_hand'] < $form_quantity) {
243 $info_msg = xl('Transfer failed, insufficient quantity in source lot');
247 if (!$info_msg) {
248 // Destination lot already exists.
249 if ($lot_id) {
250 if ($_POST['form_save']) {
251 // Make sure the destination quantity will not end up negative.
252 if (($row['on_hand'] + $form_quantity) < 0) {
253 $info_msg = xl('Transaction failed, insufficient quantity in destination lot');
254 } else {
255 sqlStatement("UPDATE drug_inventory SET " .
256 "lot_number = '" . add_escape_custom($_POST['form_lot_number']) . "', " .
257 "manufacturer = '" . add_escape_custom($_POST['form_manufacturer']) . "', " .
258 "expiration = " . QuotedOrNull($_POST['form_expiration']) . ", " .
259 "vendor_id = '" . add_escape_custom($_POST['form_vendor_id']) . "', " .
260 "warehouse_id = '" . add_escape_custom($_POST['form_warehouse_id']) . "', " .
261 "on_hand = on_hand + '" . add_escape_custom($form_quantity) . "' " .
262 "WHERE drug_id = ? AND inventory_id = ?", array($drug_id,$lot_id));
264 } else {
265 sqlStatement("DELETE FROM drug_inventory WHERE drug_id = ? " .
266 "AND inventory_id = ?", array($drug_id,$lot_id));
268 } // Destination lot will be created.
269 else {
270 if ($form_quantity < 0) {
271 $info_msg = xl('Transaction failed, quantity is less than zero');
272 } else {
273 $lot_id = sqlInsert("INSERT INTO drug_inventory ( " .
274 "drug_id, lot_number, manufacturer, expiration, " .
275 "vendor_id, warehouse_id, on_hand " .
276 ") VALUES ( " .
277 "'" . add_escape_custom($drug_id) . "', " .
278 "'" . add_escape_custom($_POST['form_lot_number']) . "', " .
279 "'" . add_escape_custom($_POST['form_manufacturer']) . "', " .
280 QuotedOrNull($_POST['form_expiration']) . ", " .
281 "'" . add_escape_custom($_POST['form_vendor_id']) . "', " .
282 "'" . add_escape_custom($_POST['form_warehouse_id']) . "', " .
283 "'" . add_escape_custom($form_quantity) . "' " .
284 ")");
288 // Create the corresponding drug_sales transaction.
289 if ($_POST['form_save'] && $form_quantity) {
290 $form_notes = $_POST['form_notes'];
291 $form_sale_date = $_POST['form_sale_date'];
292 if (empty($form_sale_date)) {
293 $form_sale_date = date('Y-m-d');
296 sqlInsert("INSERT INTO drug_sales ( " .
297 "drug_id, inventory_id, prescription_id, pid, encounter, user, " .
298 "sale_date, quantity, fee, xfer_inventory_id, distributor_id, notes " .
299 ") VALUES ( " .
300 "'" . add_escape_custom($drug_id) . "', " .
301 "'" . add_escape_custom($lot_id) . "', '0', '0', '0', " .
302 "'" . add_escape_custom($_SESSION['authUser']) . "', " .
303 "'" . add_escape_custom($form_sale_date) . "', " .
304 "'" . add_escape_custom(0 - $form_quantity) . "', " .
305 "'" . add_escape_custom(0 - $form_cost) . "', " .
306 "'" . add_escape_custom($form_source_lot) . "', " .
307 "'" . add_escape_custom($form_distributor_id) . "', " .
308 "'" . add_escape_custom($form_notes) . "' )");
310 // If this is a transfer then reduce source QOH, and also copy some
311 // fields from the source when they are missing.
312 if ($form_source_lot) {
313 sqlStatement("UPDATE drug_inventory SET " .
314 "on_hand = on_hand - ? " .
315 "WHERE inventory_id = ?", array($form_quantity,$form_source_lot));
317 foreach (array('lot_number', 'manufacturer', 'expiration', 'vendor_id') as $item) {
318 sqlStatement("UPDATE drug_inventory AS di1, drug_inventory AS di2 " .
319 "SET di1.".add_escape_custom($item)." = di2.".add_escape_custom($item)." " .
320 "WHERE di1.inventory_id = ? AND " .
321 "di2.inventory_id = ? AND " .
322 "( di1.".add_escape_custom($item)." IS NULL OR di1.".add_escape_custom($item)." = '' OR di1.".add_escape_custom($item)." = '0' )", array($lot_id,$form_source_lot));
326 } // end if not $info_msg
328 // Close this window and redisplay the updated list of drugs.
330 echo "<script language='JavaScript'>\n";
331 if ($info_msg) {
332 echo " alert('".addslashes($info_msg)."');\n";
335 echo " window.close();\n";
336 echo " if (opener.refreshme) opener.refreshme();\n";
337 echo "</script></body></html>\n";
338 exit();
342 <form method='post' name='theform' action='add_edit_lot.php?drug=<?php echo attr($drug_id) ?>&lot=<?php echo attr($lot_id) ?>'
343 onsubmit='return validate()'>
344 <center>
346 <table border='0' width='100%'>
348 <tr>
349 <td valign='top' width='1%' nowrap><b><?php echo xlt('Lot Number'); ?>:</b></td>
350 <td>
351 <input type='text' size='40' name='form_lot_number' maxlength='40' value='<?php echo attr($row['lot_number']) ?>' style='width:100%' />
352 </td>
353 </tr>
355 <tr>
356 <td valign='top' nowrap><b><?php echo xlt('Manufacturer'); ?>:</b></td>
357 <td>
358 <input type='text' size='40' name='form_manufacturer' maxlength='250' value='<?php echo attr($row['manufacturer']) ?>' style='width:100%' />
359 </td>
360 </tr>
362 <tr>
363 <td valign='top' nowrap><b><?php echo xlt('Expiration'); ?>:</b></td>
364 <td>
365 <input type='text' class='datepicker' size='10' name='form_expiration' id='form_expiration'
366 value='<?php echo attr($row['expiration']) ?>'
367 title='<?php echo xla('yyyy-mm-dd date of expiration'); ?>' />
368 </td>
369 </tr>
371 <tr>
372 <td valign='top' nowrap><b><?php echo xlt('Vendor'); ?>:</b></td>
373 <td>
374 <?php
375 // Address book entries for vendors.
376 generate_form_field(
377 array('data_type' => 14, 'field_id' => 'vendor_id',
378 'list_id' => '', 'edit_options' => 'V',
379 'description' => xl('Address book entry for the vendor')),
380 $row['vendor_id']
383 </td>
384 </tr>
386 <tr>
387 <td valign='top' nowrap><b><?php echo xlt('Warehouse'); ?>:</b></td>
388 <td>
389 <?php
390 // generate_select_list("form_warehouse_id", 'warehouse',
391 // $row['warehouse_id'], xl('Location of this lot'), xl('Unassigned'));
392 if (!genWarehouseList(
393 "form_warehouse_id",
394 $row['warehouse_id'],
395 xl('Location of this lot')
396 )) {
397 $info_msg = xl('This product allows only one lot per warehouse.');
400 </td>
401 </tr>
403 <tr>
404 <td valign='top' nowrap><b><?php echo xlt('On Hand'); ?>:</b></td>
405 <td>
406 <?php echo text($row['on_hand'] + 0); ?>
407 </td>
408 </tr>
410 <tr>
411 <td valign='top' nowrap><b><?php echo xlt('Transaction'); ?>:</b></td>
412 <td>
413 <select name='form_trans_type' onchange='trans_type_changed()'>
414 <?php
415 foreach (array(
416 '0' => xl('None'),
417 '2' => xl('Purchase'),
418 '3' => xl('Return'),
419 '6' => xl('Distribution'),
420 '4' => xl('Transfer'),
421 '5' => xl('Adjustment'),
422 ) as $key => $value) {
423 echo "<option value='" . attr($key) . "'";
424 if ($key == $form_trans_type) {
425 echo " selected";
428 echo ">" . text($value) . "</option>\n";
431 </select>
432 </td>
433 </tr>
435 <tr id='row_distributor'>
436 <td valign='top' nowrap><b><?php echo xlt('Distributor'); ?>:</b></td>
437 <td>
438 <?php
439 // Address book entries for distributors.
440 generate_form_field(array('data_type' => 14, 'field_id' => 'distributor_id',
441 'list_id' => '', 'edit_options' => 'R',
442 'description' => xl('Address book entry for the distributor')), '');
444 </td>
445 </tr>
447 <tr id='row_sale_date'>
448 <td valign='top' nowrap><b><?php echo xlt('Date'); ?>:</b></td>
449 <td>
450 <input type='text' class='datepicker' size='10' name='form_sale_date' id='form_sale_date'
451 value='<?php echo attr(date('Y-m-d')) ?>'
452 title='<?php echo xla('yyyy-mm-dd date of purchase or transfer'); ?>' />
453 </td>
454 </tr>
456 <tr id='row_quantity'>
457 <td valign='top' nowrap><b><?php echo xlt('Quantity'); ?>:</b></td>
458 <td>
459 <input type='text' size='5' name='form_quantity' maxlength='7' />
460 </td>
461 </tr>
463 <tr id='row_cost'>
464 <td valign='top' nowrap><b><?php echo xlt('Total Cost'); ?>:</b></td>
465 <td>
466 <input type='text' size='7' name='form_cost' maxlength='12' />
467 </td>
468 </tr>
470 <tr id='row_source_lot'>
471 <td valign='top' nowrap><b><?php echo xlt('Source Lot'); ?>:</b></td>
472 <td>
473 <select name='form_source_lot'>
474 <option value='0'> </option>
475 <?php
476 $lres = sqlStatement("SELECT " .
477 "di.inventory_id, di.lot_number, di.on_hand, lo.title " .
478 "FROM drug_inventory AS di " .
479 "LEFT JOIN list_options AS lo ON lo.list_id = 'warehouse' AND " .
480 "lo.option_id = di.warehouse_id AND lo.activity = 1 " .
481 "WHERE di.drug_id = ? AND di.inventory_id != ? AND " .
482 "di.on_hand > 0 AND di.destroy_date IS NULL " .
483 "ORDER BY di.lot_number, lo.title, di.inventory_id", array ($drug_id,$lot_id));
484 while ($lrow = sqlFetchArray($lres)) {
485 echo "<option value='" . attr($lrow['inventory_id']) . "'>";
486 echo text($lrow['lot_number']);
487 if (!empty($lrow['title'])) {
488 echo " / " . text($lrow['title']);
491 echo " (" . text($lrow['on_hand']) . ")";
492 echo "</option>\n";
495 </select>
496 </td>
497 </tr>
499 <tr id='row_notes'>
500 <td valign='top' nowrap><b><?php echo xlt('Comments'); ?>:</b></td>
501 <td>
502 <input type='text' size='40' name='form_notes' maxlength='255' style='width:100%' />
503 </td>
504 </tr>
506 </table>
509 <input type='submit' name='form_save' value='<?php echo xla('Save'); ?>' />
511 <?php if ($lot_id) { ?>
512 &nbsp;
513 <input type='button' value='<?php echo xla('Destroy...'); ?>'
514 onclick="window.location.href='destroy_lot.php?drug=<?php echo attr($drug_id) ?>&lot=<?php echo attr($lot_id) ?>'" />
515 <?php } ?>
517 &nbsp;
518 <input type='button' value='<?php echo xla('Cancel'); ?>' onclick='window.close()' />
519 </p>
521 </center>
522 </form>
523 <script language='JavaScript'>
524 <?php
525 if ($info_msg) {
526 echo " alert('".addslashes($info_msg)."');\n";
527 echo " window.close();\n";
530 trans_type_changed();
531 </script>
532 </body>
533 </html>