feat: Fixes #6772 adds twig email templates to emails (#6773)
[openemr.git] / interface / drugs / add_edit_lot.php
blobeb700d21d61f2e6f6dd8595d5b108cf1055fe6a0
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\Common\Twig\TwigContainer;
25 use OpenEMR\Core\Header;
27 // Check authorizations.
28 $auth_admin = AclMain::aclCheckCore('admin', 'drugs');
29 $auth_lots = $auth_admin ||
30 AclMain::aclCheckCore('inventory', 'lots') ||
31 AclMain::aclCheckCore('inventory', 'purchases') ||
32 AclMain::aclCheckCore('inventory', 'transfers') ||
33 AclMain::aclCheckCore('inventory', 'adjustments') ||
34 AclMain::aclCheckCore('inventory', 'consumption') ||
35 AclMain::aclCheckCore('inventory', 'destruction');
36 if (!$auth_lots) {
37 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Edit/Add Lot")]);
38 exit;
41 function checkWarehouseUsed($warehouse_id)
43 global $drug_id;
44 $row = sqlQuery("SELECT count(*) AS count FROM drug_inventory WHERE " .
45 "drug_id = ? AND on_hand != 0 AND " .
46 "destroy_date IS NULL AND warehouse_id = ?", array($drug_id,$warehouse_id));
47 return $row['count'];
50 function areVendorsUsed()
52 $row = sqlQuery(
53 "SELECT COUNT(*) AS count FROM users " .
54 "WHERE active = 1 AND (info IS NULL OR info NOT LIKE '%Inactive%') " .
55 "AND abook_type LIKE 'vendor%'"
57 return $row['count'];
60 // Generate a <select> list of warehouses.
61 // If multiple lots are not allowed for this product, then restrict the
62 // list to warehouses that are unused for the product.
63 // Returns the number of warehouses allowed.
64 // For these purposes the "unassigned" option is considered a warehouse.
66 function genWarehouseList($tag_name, $currvalue, $title, $class = '')
68 global $drug_id, $is_user_restricted;
70 $drow = sqlQuery("SELECT allow_multiple FROM drugs WHERE drug_id = ?", array($drug_id));
71 $allow_multiple = $drow['allow_multiple'];
73 $lres = sqlStatement("SELECT * FROM list_options " .
74 "WHERE list_id = 'warehouse' AND activity = 1 ORDER BY seq, title");
76 echo "<select name='" . attr($tag_name) . "' id='" . attr($tag_name) . "'";
77 if ($class) {
78 echo " class='" . attr($class) . "'";
81 echo " title='" . attr($title) . "'>";
83 $got_selected = false;
84 $count = 0;
86 if ($allow_multiple /* || !checkWarehouseUsed('') */) {
87 echo "<option value=''>" . xlt('Unassigned') . "</option>";
88 ++$count;
91 while ($lrow = sqlFetchArray($lres)) {
92 $whid = $lrow['option_id'];
93 $facid = (int) ($lrow['option_value'] ?? null);
94 if ($whid != $currvalue) {
95 if (!$allow_multiple && checkWarehouseUsed($whid)) {
96 continue;
98 if ($is_user_restricted && !isWarehouseAllowed($facid, $whid)) {
99 continue;
102 // Value identifies both warehouse and facility to support validation.
103 echo "<option value='" . attr("$whid|$facid") . "'";
105 if (
106 (strlen($currvalue) == 0 && $lrow['is_default']) ||
107 (strlen($currvalue) > 0 && $whid == $currvalue)
109 echo " selected";
110 $got_selected = true;
113 echo ">" . text($lrow['title']) . "</option>\n";
115 ++$count;
118 if (!$got_selected && strlen($currvalue) > 0) {
119 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
120 echo "</select>";
121 echo " <span class='text-danger' title='" .
122 xla('Please choose a valid selection from the list.') . "'>" .
123 xlt('Fix this') . "!</span>";
124 } else {
125 echo "</select>";
128 return $count;
131 $drug_id = $_REQUEST['drug'] + 0;
132 $lot_id = $_REQUEST['lot'] + 0;
133 $info_msg = "";
135 $form_trans_type = intval(isset($_POST['form_trans_type']) ? $_POST['form_trans_type'] : '0');
137 // Note if user is restricted to any facilities and/or warehouses.
138 $is_user_restricted = isUserRestricted();
140 if (!$drug_id) {
141 die(xlt('Drug ID missing!'));
144 <html>
145 <head>
146 <title><?php echo $lot_id ? xlt("Edit") : xlt("Add New");
147 echo " " . xlt('Lot'); ?></title>
149 <?php Header::setupHeader(['datetime-picker', 'opener']); ?>
151 <style>
152 td {
153 font-size: 0.8125rem;
155 </style>
157 <script>
159 function validate() {
160 var f = document.forms[0];
161 var trans_type = f.form_trans_type.value;
163 if (trans_type > '0') {
164 // Transaction date validation. Must not be later than today or before 2000.
165 if (f.form_sale_date.value > <?php echo js_escape(date('Y-m-d')) ?> || f.form_sale_date.value < '2000-01-01') {
166 alert(<?php echo xlj('Transaction date must not be in the future or before 2000'); ?>);
167 return false;
169 // Quantity validations.
170 var qty = parseInt(f.form_quantity.value);
171 if (!qty) {
172 alert(<?php echo xlj('A quantity is required'); ?>);
173 return false;
175 if (f.form_trans_type.value != '5' && qty < 0) {
176 alert(<?php echo xlj('Quantity cannot be negative for this transaction type'); ?>);
177 return false;
181 // Get source and target facility IDs.
182 var facfrom = 0;
183 var facto = 0;
184 var a = f.form_source_lot.value.split('|', 2);
185 var lotfrom = parseInt(a[0]);
186 if (a.length > 1) facfrom = parseInt(a[1]);
187 a = f.form_warehouse_id.value.split('|', 2);
188 whid = a[0];
189 if (a.length > 1) facto = parseInt(a[1]);
191 if (lotfrom == '0' && f.form_lot_number.value.search(/\S/) < 0) {
192 alert(<?php echo xlj('A lot number is required'); ?>);
193 return false;
196 // Require warehouse selection.
197 if (whid == '') {
198 alert(<?php echo xlj('A warehouse is required'); ?>);
199 return false;
202 // Require comments for all transactions.
203 if (f.form_trans_type.value > '0' && f.form_notes.value.search(/\S/) < 0) {
204 alert(<?php echo xlj('Comments are required'); ?>);
205 return false;
208 if (f.form_trans_type.value == '4') {
209 // Transfers require a source lot.
210 if (!lotfrom) {
211 alert(<?php echo xlj('A source lot is required'); ?>);
212 return false;
215 // Check the case of a transfer between different facilities.
216 if (facto != facfrom) {
217 if (!confirm(<?php echo xlj('Warning: Source and target facilities differ. Continue anyway?'); ?>))
218 return false;
221 // Check for missing expiration date on a purchase or simple update.
222 if (f.form_expiration.value == '' && f.form_trans_type.value <= '2') {
223 if (!confirm(<?php echo xlj('Warning: Most lots should have an expiration date. Continue anyway?'); ?>)) {
224 return false;
228 return true;
231 function trans_type_changed() {
232 var f = document.forms[0];
233 var sel = f.form_trans_type;
234 var type = sel.options[sel.selectedIndex].value;
235 // display attributes
236 var showQuantity = true;
237 var showOnHand = true;
238 var showSaleDate = true;
239 var showCost = true;
240 var showSourceLot = true;
241 var showNotes = true;
242 var showManufacturer = true;
243 var showLotNumber = true;
244 var showWarehouse = true;
245 var showExpiration = true;
246 var showVendor = <?php echo areVendorsUsed() ? 'true' : 'false'; ?>;
248 // readonly attributes
249 var roManufacturer = true;
250 var roLotNumber = true;
251 var roExpiration = true;
253 labelWarehouse = <?php echo xlj('Warehouse'); ?>;
255 if (type == '2') { // purchase
256 showSourceLot = false;
257 roManufacturer = false;
258 roLotNumber = false;
259 roExpiration = false;
260 <?php if (!$lot_id) { // target lot is not known yet ?>
261 showOnHand = false;
262 <?php } ?>
264 else if (type == '3') { // return
265 showSourceLot = false;
266 showManufacturer = false;
267 showVendor = false;
269 else if (type == '4') { // transfer
270 showCost = false;
271 showManufacturer = false;
272 showVendor = false;
273 showLotNumber = false;
274 showExpiration = false;
275 <?php if ($lot_id) { // disallow warehouse change on xfer to existing lot ?>
276 showWarehouse = false;
277 <?php } else { // target lot is not known yet ?>
278 showOnHand = false;
279 <?php } ?>
280 labelWarehouse = <?php echo xlj('Destination Warehouse'); ?>;
282 else if (type == '5') { // adjustment
283 showCost = false;
284 showSourceLot = false;
285 showManufacturer = false;
286 showVendor = false;
288 else if (type == '7') { // consumption
289 showCost = false;
290 showSourceLot = false;
291 showManufacturer = false;
292 showVendor = false;
294 else { // Edit Only
295 showQuantity = false;
296 showSaleDate = false;
297 showCost = false;
298 showSourceLot = false;
299 showNotes = false;
300 roManufacturer = false;
301 roLotNumber = false;
302 roExpiration = false;
304 document.getElementById('row_quantity' ).style.display = showQuantity ? '' : 'none';
305 document.getElementById('row_on_hand' ).style.display = showOnHand ? '' : 'none';
306 document.getElementById('row_sale_date' ).style.display = showSaleDate ? '' : 'none';
307 document.getElementById('row_cost' ).style.display = showCost ? '' : 'none';
308 document.getElementById('row_source_lot').style.display = showSourceLot ? '' : 'none';
309 document.getElementById('row_notes' ).style.display = showNotes ? '' : 'none';
310 document.getElementById('row_manufacturer').style.display = showManufacturer ? '' : 'none';
311 document.getElementById('row_vendor' ).style.display = showVendor ? '' : 'none';
312 document.getElementById('row_lot_number' ).style.display = showLotNumber ? '' : 'none';
313 document.getElementById('row_warehouse' ).style.display = showWarehouse ? '' : 'none';
314 document.getElementById('row_expiration' ).style.display = showExpiration ? '' : 'none';
316 f.form_manufacturer.readOnly = roManufacturer;
317 f.form_lot_number.readOnly = roLotNumber;
318 f.form_expiration.readOnly = roExpiration;
319 document.getElementById('img_expiration').style.display = roExpiration ? 'none' : '';
321 document.getElementById('label_warehouse').innerHTML = labelWarehouse;
324 $(function () {
325 $('.datepicker').datetimepicker({
326 <?php $datetimepicker_timepicker = false; ?>
327 <?php $datetimepicker_showseconds = false; ?>
328 <?php $datetimepicker_formatInput = false; ?>
329 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
330 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
333 </script>
335 </head>
337 <body class="body_top">
338 <?php
339 if ($lot_id) {
340 $row = sqlQuery("SELECT * FROM drug_inventory WHERE drug_id = ? " .
341 "AND inventory_id = ?", array($drug_id,$lot_id));
344 // If we are saving, then save and close the window.
346 if (!empty($_POST['form_save'])) {
347 if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) {
348 CsrfUtils::csrfNotVerified();
351 $form_quantity = $_POST['form_quantity'] + 0;
352 $form_cost = sprintf('%0.2f', $_POST['form_cost']);
353 // $form_source_lot = $_POST['form_source_lot'] + 0;
355 list($form_source_lot, $form_source_facility) = explode('|', $_POST['form_source_lot']);
356 $form_source_lot = intval($form_source_lot);
358 list($form_warehouse_id) = explode('|', $_POST['form_warehouse_id']);
360 $form_expiration = $_POST['form_expiration'] ?? '';
361 $form_lot_number = $_POST['form_lot_number'] ?? '';
362 $form_manufacturer = $_POST['form_manufacturer'] ?? '';
363 $form_vendor_id = $_POST['form_vendor_id'] ?? '';
365 if ($form_trans_type < 0 || $form_trans_type > 7) {
366 die(xlt('Internal error!'));
369 if (
370 !$auth_admin && (
371 $form_trans_type == 2 && !AclMain::aclCheckCore('inventory', 'purchases') ||
372 $form_trans_type == 3 && !AclMain::aclCheckCore('inventory', 'purchases') ||
373 $form_trans_type == 4 && !AclMain::aclCheckCore('inventory', 'transfers') ||
374 $form_trans_type == 5 && !AclMain::aclCheckCore('inventory', 'adjustments') ||
375 $form_trans_type == 7 && !AclMain::aclCheckCore('inventory', 'consumption')
378 die(xlt('Not authorized'));
381 // Some fixups depending on transaction type.
382 if ($form_trans_type == 3) { // return
383 $form_quantity = 0 - $form_quantity;
384 $form_cost = 0 - $form_cost;
385 } elseif ($form_trans_type == 5) { // adjustment
386 $form_cost = 0;
387 } elseif ($form_trans_type == 7) { // consumption
388 $form_quantity = 0 - $form_quantity;
389 $form_cost = 0;
390 } elseif ($form_trans_type == 0) { // no transaction
391 $form_quantity = 0;
392 $form_cost = 0;
394 if ($form_trans_type != 4) { // not transfer
395 $form_source_lot = 0;
398 // If a transfer, make sure there is sufficient quantity in the source lot
399 // and apply some default values from it.
400 if ($form_source_lot) {
401 $srow = sqlQuery(
402 "SELECT lot_number, expiration, manufacturer, vendor_id, on_hand " .
403 "FROM drug_inventory WHERE drug_id = ? AND inventory_id = ?",
404 array($drug_id, $form_source_lot)
406 if (empty($form_lot_number)) {
407 $form_lot_number = $srow['lot_number' ];
409 if (empty($form_expiration)) {
410 $form_expiration = $srow['expiration' ];
412 if (empty($form_manufacturer)) {
413 $form_manufacturer = $srow['manufacturer'];
415 if (empty($form_vendor_id)) {
416 $form_vendor_id = $srow['vendor_id' ];
418 if ($form_quantity && $srow['on_hand'] < $form_quantity) {
419 $info_msg = xl('Transfer failed, insufficient quantity in source lot');
423 if (!$info_msg) {
424 // If purchase or transfer with no destination lot specified, see if one already exists.
425 if (!$lot_id && $form_lot_number && ($form_trans_type == 2 || $form_trans_type == 4)) {
426 $erow = sqlQuery(
427 "SELECT * FROM drug_inventory WHERE " .
428 "drug_id = ? AND warehouse_id = ? AND lot_number = ? AND destroy_date IS NULL AND on_hand != 0 " .
429 "ORDER BY inventory_id DESC LIMIT 1",
430 array($drug_id, $form_warehouse_id, $form_lot_number)
432 if (!empty($erow['inventory_id'])) {
433 // Yes a matching lot exists, use it and its values.
434 $lot_id = $erow['inventory_id'];
435 if (empty($form_expiration)) {
436 $form_expiration = $erow['expiration' ];
438 if (empty($form_manufacturer)) {
439 $form_manufacturer = $erow['manufacturer'];
441 if (empty($form_vendor_id)) {
442 $form_vendor_id = $erow['vendor_id' ];
447 // Destination lot already exists.
448 if ($lot_id) {
449 if ($_POST['form_save']) {
450 // Make sure the destination quantity will not end up negative.
451 if (($row['on_hand'] + $form_quantity) < 0) {
452 $info_msg = xl('Transaction failed, insufficient quantity in destination lot');
453 } else {
454 sqlStatement(
455 "UPDATE drug_inventory SET " .
456 "lot_number = ?, " .
457 "manufacturer = ?, " .
458 "expiration = ?, " .
459 "vendor_id = ?, " .
460 "warehouse_id = ?, " .
461 "on_hand = on_hand + ? " .
462 "WHERE drug_id = ? AND inventory_id = ?",
463 array(
464 $form_lot_number,
465 $form_manufacturer,
466 (empty($form_expiration) ? "NULL" : $form_expiration),
467 $form_vendor_id,
468 $form_warehouse_id,
469 $form_quantity,
470 $drug_id,
471 $lot_id
475 } else {
476 sqlStatement("DELETE FROM drug_inventory WHERE drug_id = ? " .
477 "AND inventory_id = ?", array($drug_id,$lot_id));
479 } else { // Destination lot will be created.
480 if ($form_quantity < 0) {
481 $info_msg = xl('Transaction failed, quantity is less than zero');
482 } else {
483 $exptest = $form_expiration ?
484 ("expiration = '" . add_escape_custom($form_expiration) . "'") : "expiration IS NULL";
485 $crow = sqlQuery(
486 "SELECT count(*) AS count from drug_inventory " .
487 "WHERE lot_number = ? " .
488 "AND drug_id = ? " .
489 "AND warehouse_id = ? " .
490 "AND $exptest " .
491 "AND on_hand != 0 " .
492 "AND destroy_date IS NULL",
493 array($form_lot_number, $drug_id, $form_warehouse_id)
495 if ($crow['count']) {
496 $info_msg = xl('Transaction failed, duplicate lot');
497 } else {
498 $lot_id = sqlInsert(
499 "INSERT INTO drug_inventory ( " .
500 "drug_id, lot_number, manufacturer, expiration, " .
501 "vendor_id, warehouse_id, on_hand " .
502 ") VALUES ( " .
503 "?, " .
504 "?, " .
505 "?, " .
506 "?, " .
507 "?, " .
508 "?, " .
509 "? " .
510 ")",
511 array(
512 $drug_id,
513 $form_lot_number,
514 $form_manufacturer,
515 (empty($form_expiration) ? "NULL" : $form_expiration),
516 $form_vendor_id,
517 $form_warehouse_id,
518 $form_quantity
525 // Create the corresponding drug_sales transaction.
526 if ($_POST['form_save'] && $form_quantity && !$info_msg) {
527 $form_notes = $_POST['form_notes'];
528 $form_sale_date = $_POST['form_sale_date'];
529 if (empty($form_sale_date)) {
530 $form_sale_date = date('Y-m-d');
533 sqlStatement(
534 "INSERT INTO drug_sales ( " .
535 "drug_id, inventory_id, prescription_id, pid, encounter, user, sale_date, " .
536 "quantity, fee, xfer_inventory_id, distributor_id, notes, trans_type " .
537 ") VALUES ( " .
538 "?, " .
539 "?, '0', '0', '0', " .
540 "?, " .
541 "?, " .
542 "?, " .
543 "?, " .
544 "?, " .
545 "?, " .
546 "?, " .
547 "? )",
548 array(
549 $drug_id,
550 $lot_id,
551 $_SESSION['authUser'],
552 $form_sale_date,
553 (0 - $form_quantity),
554 (0 - $form_cost),
555 $form_source_lot,
557 $form_notes,
558 $form_trans_type
562 // If this is a transfer then reduce source QOH.
563 if ($form_source_lot) {
564 sqlStatement(
565 "UPDATE drug_inventory SET " .
566 "on_hand = on_hand - ? " .
567 "WHERE inventory_id = ?",
568 array($form_quantity,$form_source_lot)
572 } // end if not $info_msg
574 // Close this window and redisplay the updated list of drugs.
576 echo "<script>\n";
577 if ($info_msg) {
578 echo " alert(" . js_escape($info_msg) . ");\n";
581 echo " window.close();\n";
582 echo " if (opener.refreshme) opener.refreshme();\n";
583 echo "</script></body></html>\n";
584 exit();
586 $title = $lot_id ? xl("Update Lot") : xl("Add Lot");
588 <h3 class="ml-1"><?php echo text($title);?></h3>
589 <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()'>
590 <input type="hidden" name="csrf_token_form" value="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
592 <table class="table table-borderless w-100">
594 <tr id='row_sale_date'>
595 <td class="text-nowrap align-top"><?php echo xlt('Date'); ?>:</td>
596 <td>
597 <input type='text' class="datepicker" size='10' name='form_sale_date' id='form_sale_date'
598 value='<?php echo attr(date('Y-m-d')) ?>'
599 title='<?php echo xla('yyyy-mm-dd date of purchase or transfer'); ?>' />
600 </td>
601 </tr>
603 <tr>
604 <td class="text-nowrap align-top"><?php echo xlt('Transaction Type'); ?>:</td>
605 <td>
606 <select name='form_trans_type' class='form-control' onchange='trans_type_changed()'>
607 <?php
608 foreach (
609 array(
610 '2' => xl('Purchase/Receipt'),
611 '3' => xl('Return'),
612 '4' => xl('Transfer'),
613 '5' => xl('Adjustment'),
614 '7' => xl('Consumption'),
615 '0' => xl('Edit Only'),
616 ) as $key => $value
618 echo "<option value='" . attr($key) . "'";
619 if (
620 !$auth_admin && (
621 $key == 2 && !AclMain::aclCheckCore('inventory', 'purchases') ||
622 $key == 3 && !AclMain::aclCheckCore('inventory', 'purchases') ||
623 $key == 4 && !AclMain::aclCheckCore('inventory', 'transfers') ||
624 $key == 5 && !AclMain::aclCheckCore('inventory', 'adjustments') ||
625 $key == 7 && !AclMain::aclCheckCore('inventory', 'consumption')
628 echo " disabled";
629 } else if (
630 $lot_id && in_array($key, array('2', '4' )) ||
631 // $lot_id && in_array($key, array('2')) ||
632 !$lot_id && in_array($key, array('0', '3', '5', '7'))
634 echo " disabled";
635 } else {
636 if (isset($_POST['form_trans_type']) && $key == $form_trans_type) {
637 echo " selected";
640 echo ">" . text($value) . "</option>\n";
643 </select>
644 </td>
645 </tr>
647 <tr id='row_lot_number'>
648 <td class="text-nowrap align-top"><?php echo xlt('Lot Number'); ?>:</td>
649 <td>
650 <input class="form-control w-100" type='text' size='40' name='form_lot_number' maxlength='40' value='<?php echo attr($row['lot_number']) ?>' />
651 </td>
652 </tr>
654 <tr id='row_manufacturer'>
655 <td class="text-nowrap align-top"><?php echo xlt('Manufacturer'); ?>:</td>
656 <td>
657 <input class="form-control w-100" type='text' size='40' name='form_manufacturer' maxlength='250' value='<?php echo attr($row['manufacturer']) ?>' />
658 </td>
659 </tr>
661 <tr id='row_expiration'>
662 <td class="text-nowrap align-top"><?php echo xlt('Expiration'); ?>:</td>
663 <td>
664 <input type='text' class='datepicker form-control w-50' size='10' name='form_expiration' id='form_expiration'
665 value='<?php echo attr($row['expiration']) ?>'
666 title='<?php echo xla('yyyy-mm-dd date of expiration'); ?>' />
667 </td>
668 </tr>
670 <tr id='row_source_lot'>
671 <td class="text-nowrap align-top"><?php echo xlt('Source Lot'); ?>:</td>
672 <td>
673 <select name='form_source_lot' class='form-control'>
674 <option value='0'> </option>
675 <?php
676 $lres = sqlStatement(
677 "SELECT " .
678 "di.inventory_id, di.lot_number, di.on_hand, lo.title, lo.option_value, di.warehouse_id " .
679 "FROM drug_inventory AS di " .
680 "LEFT JOIN list_options AS lo ON lo.list_id = 'warehouse' AND " .
681 "lo.option_id = di.warehouse_id AND lo.activity = 1 " .
682 "WHERE di.drug_id = ? AND di.inventory_id != ? AND " .
683 "di.on_hand > 0 AND di.destroy_date IS NULL " .
684 "ORDER BY di.lot_number, lo.title, di.inventory_id",
685 array ($drug_id,$lot_id)
687 while ($lrow = sqlFetchArray($lres)) {
688 // TBD: For transfer to an existing lot do we want to force the same lot number?
689 // Check clinic/wh permissions.
690 $facid = (int) ($lrow['option_value'] ?? null);
691 if ($is_user_restricted && !isWarehouseAllowed($facid, $lrow['warehouse_id'])) {
692 continue;
694 echo "<option value='" . attr($lrow['inventory_id']) . '|' . attr($facid) . "'>";
695 echo text($lrow['lot_number']);
696 if (!empty($lrow['title'])) {
697 echo " / " . text($lrow['title']);
699 echo " (" . text($lrow['on_hand']) . ")";
700 echo "</option>\n";
703 </select>
704 </td>
705 </tr>
707 <tr id='row_vendor'>
708 <td class="text-nowrap align-top"><?php echo xlt('Vendor'); ?>:</td>
709 <td>
710 <?php
711 // Address book entries for vendors.
712 generate_form_field(
713 array('data_type' => 14, 'field_id' => 'vendor_id',
714 'list_id' => '', 'edit_options' => 'V',
715 'description' => xl('Address book entry for the vendor')),
716 $row['vendor_id']
719 </td>
720 </tr>
722 <tr id='row_warehouse'>
723 <td class="text-nowrap align-top" id="label_warehouse"><?php echo xlt('Warehouse'); ?>:</td>
724 <td>
725 <?php
726 if (
727 !genWarehouseList(
728 "form_warehouse_id",
729 $row['warehouse_id'],
730 xl('Location of this lot'),
731 "form-control"
734 $info_msg = xl('This product allows only one lot per warehouse.');
737 </td>
738 </tr>
740 <tr id='row_on_hand'>
741 <td class="text-nowrap align-top"><?php echo xlt('On Hand'); ?>:</td>
742 <td>
743 <span><?php echo text($row['on_hand'] + 0); ?></span>
744 </td>
745 </tr>
747 <tr id='row_quantity'>
748 <td class="text-nowrap align-top"><?php echo xlt('Quantity'); ?>:</td>
749 <td>
750 <input class="form-control" type='text' size='5' name='form_quantity' maxlength='7' />
751 </td>
752 </tr>
754 <tr id='row_cost'>
755 <td class="text-nowrap align-top"><?php echo xlt('Total Cost'); ?>:</td>
756 <td>
757 <input class="form-control" type='text' size='7' name='form_cost' maxlength='12' />
758 </td>
759 </tr>
761 <tr id='row_notes' title='<?php echo xla('Include your initials and details of reason for transaction.'); ?>'>
762 <td class="text-nowrap align-top"><?php echo xlt('Comments'); ?>:</td>
763 <td>
764 <input class="form-control w-100" type='text' size='40' name='form_notes' maxlength='255' />
765 </td>
766 </tr>
768 </table>
770 <div class="btn-group mt-3">
771 <input type='submit' class="btn btn-primary" name='form_save' value='<?php echo $lot_id ? xla('Update') : xla('Add') ?>' />
773 <?php if ($lot_id && ($auth_admin || AclMain::aclCheckCore('inventory', 'destruction'))) { ?>
774 <input type='button' class="btn btn-danger" value='<?php echo xla('Destroy'); ?>'
775 onclick="window.location.href='destroy_lot.php?drug=<?php echo attr_url($drug_id); ?>&lot=<?php echo attr_url($lot_id); ?>'" />
776 <?php } ?>
778 <input type='button' class="btn btn-primary btn-print" value='<?php echo xla('Print'); ?>' onclick='window.print()' />
780 <input type='button' class="btn btn-warning" value='<?php echo xla('Cancel'); ?>' onclick='window.close()' />
781 </div>
783 </form>
784 <script>
785 <?php
786 if ($info_msg) {
787 echo " alert('" . addslashes($info_msg) . "');\n";
788 echo " window.close();\n";
791 trans_type_changed();
792 </script>
793 </body>
794 </html>