Improvements mostly concerning inventory.
[openemr.git] / interface / drugs / add_edit_lot.php
blobb73165758bfa65a0632a8b391883813cf7f19f4f
1 <?php
3 /**
4 * add and edit lot
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2006-2021 Rod Roark <rod@sunsetsystems.com>
11 * @copyright Copyright (c) 2017 Brady Miller <brady.g.miller@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 // TODO: Replace tables with BS4 grid classes for GSoC
18 require_once("../globals.php");
19 require_once("drugs.inc.php");
20 require_once("$srcdir/options.inc.php");
22 use OpenEMR\Common\Acl\AclMain;
23 use OpenEMR\Common\Csrf\CsrfUtils;
24 use OpenEMR\Core\Header;
26 function checkWarehouseUsed($warehouse_id)
28 global $drug_id;
29 $row = sqlQuery("SELECT count(*) AS count FROM drug_inventory WHERE " .
30 "drug_id = ? AND on_hand != 0 AND " .
31 "destroy_date IS NULL AND warehouse_id = ?", array($drug_id,$warehouse_id));
32 return $row['count'];
35 function areVendorsUsed()
37 $row = sqlQuery(
38 "SELECT COUNT(*) AS count FROM users " .
39 "WHERE active = 1 AND (info IS NULL OR info NOT LIKE '%Inactive%') " .
40 "AND abook_type LIKE 'vendor%'"
42 return $row['count'];
45 // Generate a <select> list of warehouses.
46 // If multiple lots are not allowed for this product, then restrict the
47 // list to warehouses that are unused for the product.
48 // Returns the number of warehouses allowed.
49 // For these purposes the "unassigned" option is considered a warehouse.
51 function genWarehouseList($tag_name, $currvalue, $title, $class = '')
53 global $drug_id, $is_user_restricted;
55 $drow = sqlQuery("SELECT allow_multiple FROM drugs WHERE drug_id = ?", array($drug_id));
56 $allow_multiple = $drow['allow_multiple'];
58 $lres = sqlStatement("SELECT * FROM list_options " .
59 "WHERE list_id = 'warehouse' AND activity = 1 ORDER BY seq, title");
61 echo "<select name='" . attr($tag_name) . "' id='" . attr($tag_name) . "'";
62 if ($class) {
63 echo " class='" . attr($class) . "'";
66 echo " title='" . attr($title) . "'>";
68 $got_selected = false;
69 $count = 0;
71 if ($allow_multiple /* || !checkWarehouseUsed('') */) {
72 echo "<option value=''>" . xlt('Unassigned') . "</option>";
73 ++$count;
76 while ($lrow = sqlFetchArray($lres)) {
77 $whid = $lrow['option_id'];
78 $facid = 0 + $lrow['option_value'];
79 if ($whid != $currvalue) {
80 if (!$allow_multiple && checkWarehouseUsed($whid)) {
81 continue;
83 if ($is_user_restricted && !isWarehouseAllowed($facid, $whid)) {
84 continue;
87 // Value identifies both warehouse and facility to support validation.
88 echo "<option value='" . attr("$whid|$facid") . "'";
90 if (
91 (strlen($currvalue) == 0 && $lrow['is_default']) ||
92 (strlen($currvalue) > 0 && $whid == $currvalue)
93 ) {
94 echo " selected";
95 $got_selected = true;
98 echo ">" . text($lrow['title']) . "</option>\n";
100 ++$count;
103 if (!$got_selected && strlen($currvalue) > 0) {
104 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
105 echo "</select>";
106 echo " <span class='text-danger' title='" .
107 xla('Please choose a valid selection from the list.') . "'>" .
108 xlt('Fix this') . "!</span>";
109 } else {
110 echo "</select>";
113 return $count;
116 $drug_id = $_REQUEST['drug'] + 0;
117 $lot_id = $_REQUEST['lot'] + 0;
118 $info_msg = "";
120 $form_trans_type = intval(isset($_POST['form_trans_type']) ? $_POST['form_trans_type'] : '0');
122 // Check authorizations.
123 $auth_admin = AclMain::aclCheckCore('admin', 'drugs');
124 $auth_lots = $auth_admin ||
125 AclMain::aclCheckCore('inventory', 'lots') ||
126 AclMain::aclCheckCore('inventory', 'purchases') ||
127 AclMain::aclCheckCore('inventory', 'transfers') ||
128 AclMain::aclCheckCore('inventory', 'adjustments') ||
129 AclMain::aclCheckCore('inventory', 'consumption') ||
130 AclMain::aclCheckCore('inventory', 'destruction');
131 if (!$auth_lots) {
132 die(xlt('Not authorized'));
134 // Note if user is restricted to any facilities and/or warehouses.
135 $is_user_restricted = isUserRestricted();
137 if (!$drug_id) {
138 die(xlt('Drug ID missing!'));
141 <html>
142 <head>
143 <title><?php echo $lot_id ? xlt("Edit") : xlt("Add New");
144 echo " " . xlt('Lot'); ?></title>
146 <?php Header::setupHeader(['datetime-picker', 'opener']); ?>
148 <style>
149 td {
150 font-size: 0.8125rem;
152 </style>
154 <script>
156 function validate() {
157 var f = document.forms[0];
158 var trans_type = f.form_trans_type.value;
160 if (trans_type > '0') {
161 // Transaction date validation. Must not be later than today or before 2000.
162 if (f.form_sale_date.value > <?php echo js_escape(date('Y-m-d')) ?> || f.form_sale_date.value < '2000-01-01') {
163 alert(<?php echo xlj('Transaction date must not be in the future or before 2000'); ?>);
164 return false;
166 // Quantity validations.
167 var qty = parseInt(f.form_quantity.value);
168 if (!qty) {
169 alert(<?php echo xlj('A quantity is required'); ?>);
170 return false;
172 if (f.form_trans_type.value != '5' && qty < 0) {
173 alert(<?php echo xlj('Quantity cannot be negative for this transaction type'); ?>);
174 return false;
178 // Get source and target facility IDs.
179 var facfrom = 0;
180 var facto = 0;
181 var a = f.form_source_lot.value.split('|', 2);
182 var lotfrom = parseInt(a[0]);
183 if (a.length > 1) facfrom = parseInt(a[1]);
184 a = f.form_warehouse_id.value.split('|', 2);
185 whid = a[0];
186 if (a.length > 1) facto = parseInt(a[1]);
188 if (lotfrom == '0' && f.form_lot_number.value.search(/\S/) < 0) {
189 alert(<?php echo xlj('A lot number is required'); ?>);
190 return false;
193 // Require warehouse selection.
194 if (whid == '') {
195 alert(<?php echo xlj('A warehouse is required'); ?>);
196 return false;
199 // Require comments for all transactions.
200 if (f.form_trans_type.value > '0' && f.form_notes.value.search(/\S/) < 0) {
201 alert(<?php echo xlj('Comments are required'); ?>);
202 return false;
205 if (f.form_trans_type.value == '4') {
206 // Transfers require a source lot.
207 if (!lotfrom) {
208 alert(<?php echo xlj('A source lot is required'); ?>);
209 return false;
212 // Check the case of a transfer between different facilities.
213 if (facto != facfrom) {
214 if (!confirm(<?php echo xlj('Warning: Source and target facilities differ. Continue anyway?'); ?>))
215 return false;
218 // Check for missing expiration date on a purchase or simple update.
219 if (f.form_expiration.value == '' && f.form_trans_type.value <= '2') {
220 if (!confirm(<?php echo xlj('Warning: Most lots should have an expiration date. Continue anyway?'); ?>)) {
221 return false;
225 return true;
228 function trans_type_changed() {
229 var f = document.forms[0];
230 var sel = f.form_trans_type;
231 var type = sel.options[sel.selectedIndex].value;
232 // display attributes
233 var showQuantity = true;
234 var showOnHand = true;
235 var showSaleDate = true;
236 var showCost = true;
237 var showSourceLot = true;
238 var showNotes = true;
239 var showManufacturer = true;
240 var showLotNumber = true;
241 var showWarehouse = true;
242 var showExpiration = true;
243 var showVendor = <?php echo areVendorsUsed() ? 'true' : 'false'; ?>;
245 // readonly attributes
246 var roManufacturer = true;
247 var roLotNumber = true;
248 var roExpiration = true;
250 labelWarehouse = <?php echo xlj('Warehouse'); ?>;
252 if (type == '2') { // purchase
253 showSourceLot = false;
254 roManufacturer = false;
255 roLotNumber = false;
256 roExpiration = false;
257 <?php if (!$lot_id) { // target lot is not known yet ?>
258 showOnHand = false;
259 <?php } ?>
261 else if (type == '3') { // return
262 showSourceLot = false;
263 showManufacturer = false;
264 showVendor = false;
266 else if (type == '4') { // transfer
267 showCost = false;
268 showManufacturer = false;
269 showVendor = false;
270 showLotNumber = false;
271 showExpiration = false;
272 <?php if ($lot_id) { // disallow warehouse change on xfer to existing lot ?>
273 showWarehouse = false;
274 <?php } else { // target lot is not known yet ?>
275 showOnHand = false;
276 <?php } ?>
277 labelWarehouse = '<?php echo xlt('Destination Warehouse'); ?>';
279 else if (type == '5') { // adjustment
280 showCost = false;
281 showSourceLot = false;
282 showManufacturer = false;
283 showVendor = false;
285 else if (type == '7') { // consumption
286 showCost = false;
287 showSourceLot = false;
288 showManufacturer = false;
289 showVendor = false;
291 else { // Edit Only
292 showQuantity = false;
293 showSaleDate = false;
294 showCost = false;
295 showSourceLot = false;
296 showNotes = false;
297 roManufacturer = false;
298 roLotNumber = false;
299 roExpiration = false;
301 document.getElementById('row_quantity' ).style.display = showQuantity ? '' : 'none';
302 document.getElementById('row_on_hand' ).style.display = showOnHand ? '' : 'none';
303 document.getElementById('row_sale_date' ).style.display = showSaleDate ? '' : 'none';
304 document.getElementById('row_cost' ).style.display = showCost ? '' : 'none';
305 document.getElementById('row_source_lot').style.display = showSourceLot ? '' : 'none';
306 document.getElementById('row_notes' ).style.display = showNotes ? '' : 'none';
307 document.getElementById('row_manufacturer').style.display = showManufacturer ? '' : 'none';
308 document.getElementById('row_vendor' ).style.display = showVendor ? '' : 'none';
309 document.getElementById('row_lot_number' ).style.display = showLotNumber ? '' : 'none';
310 document.getElementById('row_warehouse' ).style.display = showWarehouse ? '' : 'none';
311 document.getElementById('row_expiration' ).style.display = showExpiration ? '' : 'none';
313 f.form_manufacturer.readOnly = roManufacturer;
314 f.form_lot_number.readOnly = roLotNumber;
315 f.form_expiration.readOnly = roExpiration;
316 document.getElementById('img_expiration').style.display = roExpiration ? 'none' : '';
318 document.getElementById('label_warehouse').innerHTML = labelWarehouse;
321 $(function () {
322 $('.datepicker').datetimepicker({
323 <?php $datetimepicker_timepicker = false; ?>
324 <?php $datetimepicker_showseconds = false; ?>
325 <?php $datetimepicker_formatInput = false; ?>
326 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
327 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
330 </script>
332 </head>
334 <body class="body_top">
335 <?php
336 if ($lot_id) {
337 $row = sqlQuery("SELECT * FROM drug_inventory WHERE drug_id = ? " .
338 "AND inventory_id = ?", array($drug_id,$lot_id));
341 // If we are saving, then save and close the window.
343 if (!empty($_POST['form_save'])) {
344 if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) {
345 CsrfUtils::csrfNotVerified();
348 $form_quantity = $_POST['form_quantity'] + 0;
349 $form_cost = sprintf('%0.2f', $_POST['form_cost']);
350 // $form_source_lot = $_POST['form_source_lot'] + 0;
352 list($form_source_lot, $form_source_facility) = explode('|', $_POST['form_source_lot']);
353 $form_source_lot = intval($form_source_lot);
355 list($form_warehouse_id) = explode('|', $_POST['form_warehouse_id']);
357 $form_expiration = $_POST['form_expiration'] ?? '';
358 $form_lot_number = $_POST['form_lot_number'] ?? '';
359 $form_manufacturer = $_POST['form_manufacturer'] ?? '';
360 $form_vendor_id = $_POST['form_vendor_id'] ?? '';
362 if ($form_trans_type < 0 || $form_trans_type > 7) {
363 die(xlt('Internal error!'));
366 if (
367 !$auth_admin && (
368 $form_trans_type == 2 && !AclMain::aclCheckCore('inventory', 'purchases') ||
369 $form_trans_type == 3 && !AclMain::aclCheckCore('inventory', 'purchases') ||
370 $form_trans_type == 4 && !AclMain::aclCheckCore('inventory', 'transfers') ||
371 $form_trans_type == 5 && !AclMain::aclCheckCore('inventory', 'adjustments') ||
372 $form_trans_type == 7 && !AclMain::aclCheckCore('inventory', 'consumption')
375 die(xlt('Not authorized'));
378 // Some fixups depending on transaction type.
379 if ($form_trans_type == 3) { // return
380 $form_quantity = 0 - $form_quantity;
381 $form_cost = 0 - $form_cost;
382 } elseif ($form_trans_type == 5) { // adjustment
383 $form_cost = 0;
384 } elseif ($form_trans_type == 7) { // consumption
385 $form_quantity = 0 - $form_quantity;
386 $form_cost = 0;
387 } elseif ($form_trans_type == 0) { // no transaction
388 $form_quantity = 0;
389 $form_cost = 0;
391 if ($form_trans_type != 4) { // not transfer
392 $form_source_lot = 0;
395 // If a transfer, make sure there is sufficient quantity in the source lot
396 // and apply some default values from it.
397 if ($form_source_lot) {
398 $srow = sqlQuery(
399 "SELECT lot_number, expiration, manufacturer, vendor_id, on_hand " .
400 "FROM drug_inventory WHERE drug_id = ? AND inventory_id = ?",
401 array($drug_id, $form_source_lot)
403 if (empty($form_lot_number)) {
404 $form_lot_number = $srow['lot_number' ];
406 if (empty($form_expiration)) {
407 $form_expiration = $srow['expiration' ];
409 if (empty($form_manufacturer)) {
410 $form_manufacturer = $srow['manufacturer'];
412 if (empty($form_vendor_id)) {
413 $form_vendor_id = $srow['vendor_id' ];
415 if ($form_quantity && $srow['on_hand'] < $form_quantity) {
416 $info_msg = xl('Transfer failed, insufficient quantity in source lot');
420 if (!$info_msg) {
421 // If purchase or transfer with no destination lot specified, see if one already exists.
422 if (!$lot_id && $form_lot_number && ($form_trans_type == 2 || $form_trans_type == 4)) {
423 $erow = sqlQuery(
424 "SELECT * FROM drug_inventory WHERE " .
425 "drug_id = ? AND warehouse_id = ? AND lot_number = ? AND destroy_date IS NULL AND on_hand != 0 " .
426 "ORDER BY inventory_id DESC LIMIT 1",
427 array($drug_id, $form_warehouse_id, $form_lot_number)
429 if (!empty($erow['inventory_id'])) {
430 // Yes a matching lot exists, use it and its values.
431 $lot_id = $erow['inventory_id'];
432 if (empty($form_expiration)) {
433 $form_expiration = $erow['expiration' ];
435 if (empty($form_manufacturer)) {
436 $form_manufacturer = $erow['manufacturer'];
438 if (empty($form_vendor_id)) {
439 $form_vendor_id = $erow['vendor_id' ];
444 // Destination lot already exists.
445 if ($lot_id) {
446 if ($_POST['form_save']) {
447 // Make sure the destination quantity will not end up negative.
448 if (($row['on_hand'] + $form_quantity) < 0) {
449 $info_msg = xl('Transaction failed, insufficient quantity in destination lot');
450 } else {
451 sqlStatement(
452 "UPDATE drug_inventory SET " .
453 "lot_number = ?, " .
454 "manufacturer = ?, " .
455 "expiration = ?, " .
456 "vendor_id = ?, " .
457 "warehouse_id = ?, " .
458 "on_hand = on_hand + ? " .
459 "WHERE drug_id = ? AND inventory_id = ?",
460 array(
461 $form_lot_number,
462 $form_manufacturer,
463 (empty($form_expiration) ? "NULL" : $form_expiration),
464 $form_vendor_id,
465 $form_warehouse_id,
466 $form_quantity,
467 $drug_id,
468 $lot_id
472 } else {
473 sqlStatement("DELETE FROM drug_inventory WHERE drug_id = ? " .
474 "AND inventory_id = ?", array($drug_id,$lot_id));
476 } else { // Destination lot will be created.
477 if ($form_quantity < 0) {
478 $info_msg = xl('Transaction failed, quantity is less than zero');
479 } else {
480 $exptest = $form_expiration ?
481 ("expiration = '" . add_escape_custom($form_expiration) . "'") : "expiration IS NULL";
482 $crow = sqlQuery(
483 "SELECT count(*) AS count from drug_inventory " .
484 "WHERE lot_number = ? " .
485 "AND drug_id = ? " .
486 "AND warehouse_id = ? " .
487 "AND $exptest " .
488 "AND on_hand != 0 " .
489 "AND destroy_date IS NULL",
490 array($form_lot_number, $drug_id, $form_warehouse_id)
492 if ($crow['count']) {
493 $info_msg = xl('Transaction failed, duplicate lot');
494 } else {
495 $lot_id = sqlInsert(
496 "INSERT INTO drug_inventory ( " .
497 "drug_id, lot_number, manufacturer, expiration, " .
498 "vendor_id, warehouse_id, on_hand " .
499 ") VALUES ( " .
500 "?, " .
501 "?, " .
502 "?, " .
503 "?, " .
504 "?, " .
505 "?, " .
506 "? " .
507 ")",
508 array(
509 $drug_id,
510 $form_lot_number,
511 $form_manufacturer,
512 (empty($form_expiration) ? "NULL" : $form_expiration),
513 $form_vendor_id,
514 $form_warehouse_id,
515 $form_quantity
522 // Create the corresponding drug_sales transaction.
523 if ($_POST['form_save'] && $form_quantity && !$info_msg) {
524 $form_notes = $_POST['form_notes'];
525 $form_sale_date = $_POST['form_sale_date'];
526 if (empty($form_sale_date)) {
527 $form_sale_date = date('Y-m-d');
530 sqlStatement(
531 "INSERT INTO drug_sales ( " .
532 "drug_id, inventory_id, prescription_id, pid, encounter, user, sale_date, " .
533 "quantity, fee, xfer_inventory_id, distributor_id, notes, trans_type " .
534 ") VALUES ( " .
535 "?, " .
536 "?, '0', '0', '0', " .
537 "?, " .
538 "?, " .
539 "?, " .
540 "?, " .
541 "?, " .
542 "?, " .
543 "?, " .
544 "? )",
545 array(
546 $drug_id,
547 $lot_id,
548 $_SESSION['authUser'],
549 $form_sale_date,
550 (0 - $form_quantity),
551 (0 - $form_cost),
552 $form_source_lot,
554 $form_notes,
555 $form_trans_type
559 // If this is a transfer then reduce source QOH.
560 if ($form_source_lot) {
561 sqlStatement(
562 "UPDATE drug_inventory SET " .
563 "on_hand = on_hand - ? " .
564 "WHERE inventory_id = ?",
565 array($form_quantity,$form_source_lot)
569 } // end if not $info_msg
571 // Close this window and redisplay the updated list of drugs.
573 echo "<script>\n";
574 if ($info_msg) {
575 echo " alert(" . js_escape($info_msg) . ");\n";
578 echo " window.close();\n";
579 echo " if (opener.refreshme) opener.refreshme();\n";
580 echo "</script></body></html>\n";
581 exit();
583 $title = $lot_id ? xl("Update Lot") : xl("Add Lot");
585 <h3 class="ml-1"><?php echo text($title);?></h3>
586 <form method='post' name='theform' action='add_edit_lot.php?drug=<?php echo attr_url($drug_id); ?>&lot=<?php echo attr_url($lot_id); ?>' onsubmit='return validate()'>
587 <input type="hidden" name="csrf_token_form" value="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
589 <table class="table table-borderless w-100">
591 <tr id='row_sale_date'>
592 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Date'); ?>:</td>
593 <td>
594 <input type='text' class="datepicker" size='10' name='form_sale_date' id='form_sale_date'
595 value='<?php echo attr(date('Y-m-d')) ?>'
596 title='<?php echo xla('yyyy-mm-dd date of purchase or transfer'); ?>' />
597 </td>
598 </tr>
600 <tr>
601 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Transaction Type'); ?>:</td>
602 <td>
603 <select name='form_trans_type' class='form-control' onchange='trans_type_changed()'>
604 <?php
605 foreach (
606 array(
607 '2' => xl('Purchase/Receipt'),
608 '3' => xl('Return'),
609 '4' => xl('Transfer'),
610 '5' => xl('Adjustment'),
611 '7' => xl('Consumption'),
612 '0' => xl('Edit Only'),
613 ) as $key => $value
615 echo "<option value='" . attr($key) . "'";
616 if (
617 !$auth_admin && (
618 $key == 2 && !AclMain::aclCheckCore('inventory', 'purchases') ||
619 $key == 3 && !AclMain::aclCheckCore('inventory', 'purchases') ||
620 $key == 4 && !AclMain::aclCheckCore('inventory', 'transfers') ||
621 $key == 5 && !AclMain::aclCheckCore('inventory', 'adjustments') ||
622 $key == 7 && !AclMain::aclCheckCore('inventory', 'consumption')
625 echo " disabled";
626 } else if (
627 $lot_id && in_array($key, array('2', '4' )) ||
628 // $lot_id && in_array($key, array('2')) ||
629 !$lot_id && in_array($key, array('0', '3', '5', '7'))
631 echo " disabled";
632 } else {
633 if (isset($_POST['form_trans_type']) && $key == $form_trans_type) {
634 echo " selected";
637 echo ">" . text($value) . "</option>\n";
640 </select>
641 </td>
642 </tr>
644 <tr id='row_lot_number'>
645 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Lot Number'); ?>:</td>
646 <td>
647 <input class="form-control w-100" type='text' size='40' name='form_lot_number' maxlength='40' value='<?php echo attr($row['lot_number']) ?>' />
648 </td>
649 </tr>
651 <tr id='row_manufacturer'>
652 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Manufacturer'); ?>:</td>
653 <td>
654 <input class="form-control w-100" type='text' size='40' name='form_manufacturer' maxlength='250' value='<?php echo attr($row['manufacturer']) ?>' />
655 </td>
656 </tr>
658 <tr id='row_expiration'>
659 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Expiration'); ?>:</td>
660 <td>
661 <input type='text' class='datepicker form-control w-50' size='10' name='form_expiration' id='form_expiration'
662 value='<?php echo attr($row['expiration']) ?>'
663 title='<?php echo xla('yyyy-mm-dd date of expiration'); ?>' />
664 </td>
665 </tr>
667 <tr id='row_source_lot'>
668 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Source Lot'); ?>:</td>
669 <td>
670 <select name='form_source_lot' class='form-control'>
671 <option value='0'> </option>
672 <?php
673 $lres = sqlStatement(
674 "SELECT " .
675 "di.inventory_id, di.lot_number, di.on_hand, lo.title, lo.option_value, di.warehouse_id " .
676 "FROM drug_inventory AS di " .
677 "LEFT JOIN list_options AS lo ON lo.list_id = 'warehouse' AND " .
678 "lo.option_id = di.warehouse_id AND lo.activity = 1 " .
679 "WHERE di.drug_id = ? AND di.inventory_id != ? AND " .
680 "di.on_hand > 0 AND di.destroy_date IS NULL " .
681 "ORDER BY di.lot_number, lo.title, di.inventory_id",
682 array ($drug_id,$lot_id)
684 while ($lrow = sqlFetchArray($lres)) {
685 // TBD: For transfer to an existing lot do we want to force the same lot number?
686 // Check clinic/wh permissions.
687 $facid = 0 + $lrow['option_value'];
688 if ($is_user_restricted && !isWarehouseAllowed($facid, $lrow['warehouse_id'])) {
689 continue;
691 echo "<option value='" . attr($lrow['inventory_id']) . '|' . attr($facid) . "'>";
692 echo text($lrow['lot_number']);
693 if (!empty($lrow['title'])) {
694 echo " / " . text($lrow['title']);
696 echo " (" . text($lrow['on_hand']) . ")";
697 echo "</option>\n";
700 </select>
701 </td>
702 </tr>
704 <tr id='row_vendor'>
705 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Vendor'); ?>:</td>
706 <td>
707 <?php
708 // Address book entries for vendors.
709 generate_form_field(
710 array('data_type' => 14, 'field_id' => 'vendor_id',
711 'list_id' => '', 'edit_options' => 'V',
712 'description' => xl('Address book entry for the vendor')),
713 $row['vendor_id']
716 </td>
717 </tr>
719 <tr id='row_warehouse'>
720 <td class="font-weight-bold text-nowrap align-top" id="label_warehouse"><?php echo xlt('Warehouse'); ?>:</td>
721 <td>
722 <?php
723 if (
724 !genWarehouseList(
725 "form_warehouse_id",
726 $row['warehouse_id'],
727 xl('Location of this lot'),
728 "form-control"
731 $info_msg = xl('This product allows only one lot per warehouse.');
734 </td>
735 </tr>
737 <tr id='row_on_hand'>
738 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('On Hand'); ?>:</td>
739 <td>
740 <span><?php echo text($row['on_hand'] + 0); ?></span>
741 </td>
742 </tr>
744 <tr id='row_quantity'>
745 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Quantity'); ?>:</td>
746 <td>
747 <input class="form-control" type='text' size='5' name='form_quantity' maxlength='7' />
748 </td>
749 </tr>
751 <tr id='row_cost'>
752 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Total Cost'); ?>:</td>
753 <td>
754 <input class="form-control" type='text' size='7' name='form_cost' maxlength='12' />
755 </td>
756 </tr>
758 <tr id='row_notes' title='<?php echo xla('Include your initials and details of reason for transaction.'); ?>'>
759 <td class="font-weight-bold text-nowrap align-top"><?php echo xlt('Comments'); ?>:</td>
760 <td>
761 <input class="form-control w-100" type='text' size='40' name='form_notes' maxlength='255' />
762 </td>
763 </tr>
765 </table>
767 <div class="btn-group mt-3">
768 <input type='submit' class="btn btn-primary" name='form_save' value='<?php echo $lot_id ? xla('Update') : xla('Add') ?>' />
770 <?php if ($lot_id && ($auth_admin || AclMain::aclCheckCore('inventory', 'destruction'))) { ?>
771 <input type='button' class="btn btn-danger" value='<?php echo xla('Destroy'); ?>'
772 onclick="window.location.href='destroy_lot.php?drug=<?php echo attr_url($drug_id); ?>&lot=<?php echo attr_url($lot_id); ?>'" />
773 <?php } ?>
775 <input type='button' class="btn btn-primary btn-print" value='<?php echo xla('Print'); ?>' onclick='window.print()' />
777 <input type='button' class="btn btn-warning" value='<?php echo xla('Cancel'); ?>' onclick='window.close()' />
778 </div>
780 </form>
781 <script>
782 <?php
783 if ($info_msg) {
784 echo " alert('" . addslashes($info_msg) . "');\n";
785 echo " window.close();\n";
788 trans_type_changed();
789 </script>
790 </body>
791 </html>