651 lines
23 KiB
PHP
651 lines
23 KiB
PHP
<?php
|
|
session_start();
|
|
require '../config.php';
|
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin', 'staff'], true)) {
|
|
http_response_code(403);
|
|
exit('Access denied.');
|
|
}
|
|
require '../include_header.php';
|
|
?>
|
|
|
|
<body>
|
|
<?php require '../include_topbar.php';?>
|
|
<?php require '../include_sidebar.php';?>
|
|
|
|
<!-- MAIN CONTENT -->
|
|
<main id="content" class="content py-15">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="mb-6">
|
|
<h1 class="fs-3 mb-0">Stock Out</h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row g">
|
|
<div class="col-lg-8 col-12">
|
|
<div class="card">
|
|
<div class="card-body p-5">
|
|
<h2 class="fs-5 mb-4">Remove Stock</h2>
|
|
<form class="row gx-5">
|
|
|
|
<!-- Step 1: Product -->
|
|
<div class="mb-3 col-lg-3">
|
|
<label for="product_sku" class="form-label">SKU</label>
|
|
<div class="input-group">
|
|
<input type="text" id="product_sku" class="form-control product_search"
|
|
placeholder="Type product sku..." autocomplete="off" required>
|
|
<button class="btn btn-outline-secondary" type="button" onclick="scanner.open_camera()" title="Scan barcode label">
|
|
<i class="ti ti-scan"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3 col-lg-3">
|
|
<label for="product_name" class="form-label">Name</label>
|
|
<input type="text" id="product_name" class="form-control" autocomplete="off" disabled>
|
|
</div>
|
|
|
|
<!-- Step 2: Lot Number (active lots for selected SKU) -->
|
|
<div class="mb-3 col-lg-3">
|
|
<label for="lot_number" class="form-label">Lot Number <span class="text-muted fw-normal">(optional)</span></label>
|
|
<select id="lot_number" class="form-select">
|
|
<option value="">Select lot...</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Step 3: Serial Number (active serials for selected SKU + lot) -->
|
|
<div class="mb-3 col-lg-3">
|
|
<label for="serial_number" class="form-label">Serial Number <span class="text-muted fw-normal">(optional)</span></label>
|
|
<select id="serial_number" class="form-select">
|
|
<option value="">Select serial...</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Step 4: Warehouse -->
|
|
<div class="mb-3 col-lg-6">
|
|
<label for="warehouse" class="form-label">Warehouse</label>
|
|
<select name="warehouse" id="warehouse" class="form-select" required disabled>
|
|
<option value="">Select warehouse...</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Step 5: Zone -->
|
|
<div class="mb-3 col-lg-6" id="group_zone">
|
|
<label for="zone" class="form-label" id="label_zone">Zone</label>
|
|
<select name="zone" id="zone" class="form-select" disabled>
|
|
<option value="">Please select zone</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Step 6: Aisle -->
|
|
<div class="mb-3 col-lg-6" id="group_aisle">
|
|
<label for="aisle" class="form-label" id="label_aisle">Aisle</label>
|
|
<select name="aisle" id="aisle" class="form-select" disabled>
|
|
<option value="">Please select aisle</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Step 7: Rack -->
|
|
<div class="mb-3 col-lg-6" id="group_rack">
|
|
<label for="rack" class="form-label" id="label_rack">Rack</label>
|
|
<select name="rack" id="rack" class="form-select" required disabled>
|
|
<option value="">Please select rack</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Contact -->
|
|
<div class="mb-3 col-lg-6">
|
|
<label for="contact" class="form-label">Contact</label>
|
|
<input type="text" class="form-control contact_search" id="contact" placeholder="Enter contact name">
|
|
</div>
|
|
|
|
<!-- Notes / Description -->
|
|
<div class="mb-3 col-lg-12">
|
|
<label for="description" class="form-label">Notes / Description</label>
|
|
<textarea class="form-control" id="description" rows="3" placeholder="Enter any notes"></textarea>
|
|
</div>
|
|
|
|
<!-- Submit Button -->
|
|
<div class="mb-3 col-lg-12">
|
|
<button type="submit" class="btn btn-primary" data-min-role="staff" onclick="manage_stock_out();">Remove Stock</button>
|
|
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<?php require "../include_ending.php";?>
|
|
|
|
<script>
|
|
|
|
var advanced = false;
|
|
var label_rack = 'Location';
|
|
var label_zone = 'Zone';
|
|
var label_aisle = 'Aisle';
|
|
var scan_sku_ready = false;
|
|
var scan_location_ready = false;
|
|
var pending_scan_lot = '';
|
|
var pending_scan_serial = '';
|
|
|
|
function set_select_value(selector, value, label) {
|
|
if (!value) return;
|
|
var $select = $(selector);
|
|
if (!$select.find(`option[value="${value}"]`).length) {
|
|
$select.append(`<option value="${value}">${label || value}</option>`);
|
|
}
|
|
$select.val(value).prop('disabled', false);
|
|
}
|
|
|
|
function apply_sku_label_scan(data) {
|
|
$('#product_sku').val(data.sku).attr('secondary', data.sku);
|
|
$('#product_name').val(data.product_name || '').attr('secondary', data.product_name || '');
|
|
pending_scan_lot = data.lot_number || '';
|
|
pending_scan_serial = data.serial_number || '';
|
|
set_select_value('#lot_number', data.lot_number, data.lot_number);
|
|
set_select_value('#serial_number', data.serial_number, data.serial_number);
|
|
scan_sku_ready = true;
|
|
scan_location_ready = false;
|
|
reset_location();
|
|
retrieve_active_lot();
|
|
}
|
|
|
|
function apply_location_label_scan(data) {
|
|
if (!scan_sku_ready && !($('#product_sku').attr('secondary') || $('#product_sku').val())) {
|
|
bootbox.alert('Scan the SKU label first, then scan the location label.');
|
|
return;
|
|
}
|
|
validate_scanned_location('out', data, function() {
|
|
set_select_value('#warehouse', data.warehouse_id, data.warehouse_id);
|
|
if (advanced) {
|
|
set_select_value('#zone', data.zone, data.zone);
|
|
set_select_value('#aisle', data.aisle, data.aisle);
|
|
}
|
|
set_select_value('#rack', data.rack, data.rack);
|
|
scan_location_ready = true;
|
|
});
|
|
}
|
|
|
|
function validate_scanned_location(mode, data, onSuccess) {
|
|
ajax_request({
|
|
url: '<?php echo $server_url?>ics/api/engine/validate_scan_location.php',
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
action: 'read',
|
|
queueLock: false,
|
|
noLoading: true,
|
|
data: {
|
|
mode: mode,
|
|
warehouse_id: data.warehouse_id,
|
|
zone: data.zone,
|
|
aisle: data.aisle,
|
|
rack: data.rack,
|
|
product_sku: $('#product_sku').attr('secondary') || $('#product_sku').val(),
|
|
lot_number: $('#lot_number').val(),
|
|
serial_number: $('#serial_number').val()
|
|
},
|
|
onSuccess: onSuccess
|
|
});
|
|
}
|
|
|
|
function reset_stock_out_inputs() {
|
|
$('form')[0].reset();
|
|
$('#product_sku').removeAttr('secondary').prop('disabled', false);
|
|
$('#product_name').removeAttr('secondary').val('');
|
|
$('#lot_number').html('<option value="">Select lot...</option>').prop('disabled', false);
|
|
$('#serial_number').html('<option value="">Select serial...</option>').prop('disabled', false);
|
|
$('#contact').removeAttr('secondary data-id');
|
|
reset_location();
|
|
scan_sku_ready = false;
|
|
scan_location_ready = false;
|
|
pending_scan_lot = '';
|
|
pending_scan_serial = '';
|
|
$('#product_sku').focus();
|
|
}
|
|
|
|
function save_scanned_stock_out() {
|
|
if (!scan_sku_ready && !($('#product_sku').attr('secondary') || $('#product_sku').val())) {
|
|
bootbox.alert('Scan the SKU label first.');
|
|
return;
|
|
}
|
|
if (!scan_location_ready && !$('#rack').val()) {
|
|
bootbox.alert('Scan the location label before saving.');
|
|
return;
|
|
}
|
|
manage_stock_out();
|
|
}
|
|
|
|
function load_location_config(callback) {
|
|
return ajax_request({
|
|
url: server_url + 'setting/api/engine/company_setting.php',
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
action: 'read',
|
|
onSuccess: function(res) {
|
|
var s = res.output;
|
|
advanced = s.advanced_location == 1;
|
|
label_rack = s.location_label_rack || (advanced ? 'Rack' : 'Location');
|
|
label_zone = s.location_label_zone || 'Zone';
|
|
label_aisle = s.location_label_aisle || 'Aisle';
|
|
if (callback) callback();
|
|
}
|
|
});
|
|
}
|
|
|
|
function apply_location_labels() {
|
|
if (advanced) {
|
|
$('#group_zone').show();
|
|
$('#group_aisle').show();
|
|
$('#label_zone').text(label_zone);
|
|
$('#label_aisle').text(label_aisle);
|
|
$('#label_rack').text(label_rack);
|
|
} else {
|
|
$('#group_zone').hide();
|
|
$('#group_aisle').hide();
|
|
$('#label_rack').text(label_rack);
|
|
}
|
|
}
|
|
|
|
function manage_stock_out() {
|
|
var rack_val = $('#rack').val();
|
|
var sku_val = $('#product_sku').attr('secondary') || $('#product_sku').val();
|
|
var wh_val = $('#warehouse').val();
|
|
|
|
if (!advanced) {
|
|
$('#zone').val(rack_val);
|
|
$('#aisle').val(rack_val);
|
|
}
|
|
|
|
return ajax_request({
|
|
url: '<?php echo $server_url?>ics/api/engine/manage_stock_out.php',
|
|
autoPrepare: true,
|
|
checkRequired: 1,
|
|
debugMode: 0,
|
|
data: {
|
|
'contact_id': $('#contact').attr('data-id'),
|
|
'zone': advanced ? $('#zone').val() : rack_val,
|
|
'aisle': advanced ? $('#aisle').val() : rack_val,
|
|
'rack': rack_val,
|
|
'product_sku': sku_val,
|
|
'warehouse': wh_val,
|
|
'lot_number': $('#lot_number').val(),
|
|
'serial_number': $('#serial_number').val(),
|
|
},
|
|
action: 'manage',
|
|
onSuccess: function() {
|
|
<?php if(empty($_GET["id"])){ ?>
|
|
reset_stock_out_inputs();
|
|
<?php } else { ?>
|
|
window.location.href = '<?php echo $server_url?>ics/stock_out.php';
|
|
<?php } ?>
|
|
}
|
|
});
|
|
}
|
|
|
|
function approve_current_stock() {
|
|
bootbox.confirm({
|
|
message: 'Approve this stock-out record?',
|
|
buttons: { confirm: { label: 'Approve', className: 'btn-success' }, cancel: { label: 'Cancel', className: 'btn-secondary' } },
|
|
callback: function(result) {
|
|
if (!result) return;
|
|
ajax_request({
|
|
url: '<?php echo $server_url?>ics/api/engine/approve_stock.php',
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
action: 'update',
|
|
data: {
|
|
id: '<?php echo $_GET["id"] ?? "";?>',
|
|
warehouse: '<?php echo $_GET["wh"] ?? "";?>',
|
|
type: 'out'
|
|
},
|
|
onSuccess: function() {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// ── Step 1: Product selected → load active lots ───────────────────────
|
|
function retrieve_active_lot() {
|
|
|
|
var sku = $('#product_sku').attr('secondary') || $('#product_sku').val();
|
|
if (!sku) return;
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_active_lot.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
noLoading: true,
|
|
queueLock: false,
|
|
action: 'read',
|
|
data: { "product_sku": sku },
|
|
onSuccess: function(res) {
|
|
|
|
var option = '<option value="">Select lot... (optional)</option>';
|
|
$.each(res.output, function(i, item) {
|
|
var label = item.lot_number;
|
|
if (item.expiry_date) label += ' — exp: ' + item.expiry_date;
|
|
option += `<option value="${item.lot_number}">${label}</option>`;
|
|
});
|
|
$('#lot_number').html(option).prop('disabled', false);
|
|
if (pending_scan_lot) {
|
|
set_select_value('#lot_number', pending_scan_lot, pending_scan_lot);
|
|
}
|
|
$('#serial_number').html('<option value="">Select serial... (optional)</option>').prop('disabled', false);
|
|
|
|
// Reset downstream
|
|
if (!scan_location_ready) reset_location();
|
|
if (pending_scan_lot) {
|
|
retrieve_active_serial();
|
|
} else {
|
|
retrieve_warehouse();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// ── Step 2: Lot selected → load active serials ────────────────────────
|
|
function retrieve_active_serial() {
|
|
|
|
var sku = $('#product_sku').attr('secondary') || $('#product_sku').val();
|
|
if (!sku) return;
|
|
|
|
var lot = $('#lot_number').val();
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_active_serial.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
noLoading: true,
|
|
queueLock: false,
|
|
action: 'read',
|
|
data: { "product_sku": sku, "lot_number": lot },
|
|
onSuccess: function(res) {
|
|
|
|
var option = '<option value="">Select serial... (optional)</option>';
|
|
$.each(res.output, function(i, serial) {
|
|
option += `<option value="${serial}">${serial}</option>`;
|
|
});
|
|
$('#serial_number').html(option).prop('disabled', false);
|
|
if (pending_scan_serial) {
|
|
set_select_value('#serial_number', pending_scan_serial, pending_scan_serial);
|
|
pending_scan_serial = '';
|
|
}
|
|
|
|
// Reset downstream
|
|
if (!scan_location_ready) reset_location();
|
|
retrieve_warehouse();
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// ── Step 4: Load warehouse filtered by SKU ────────────────────────────
|
|
function retrieve_warehouse() {
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_warehouse.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
noLoading: true,
|
|
queueLock: false,
|
|
data: {
|
|
"type": 'from',
|
|
"product_sku": $('#product_sku').attr('secondary') || $('#product_sku').val(),
|
|
"lot_number": $('#lot_number').val()
|
|
},
|
|
action: 'read',
|
|
onSuccess: function(res) {
|
|
var current = $('#warehouse').val();
|
|
var option = '<option value="">Select warehouse...</option>';
|
|
$.each(res.output, function(key, item) {
|
|
option += `<option value='${item.id}'>${item.warehouse_name}</option>`;
|
|
});
|
|
$('#warehouse').html(option).prop('disabled', false);
|
|
if (current) set_select_value('#warehouse', current, current);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// ── Steps 5-7: Zone → Aisle → Rack ───────────────────────────────────
|
|
function retrieve_zone(callback) {
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_zone.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
noLoading: true,
|
|
queueLock: false,
|
|
data: {
|
|
"warehouse": $('#warehouse').val(),
|
|
"type": 'from',
|
|
"product_sku": $('#product_sku').attr('secondary') || $('#product_sku').val(),
|
|
"lot_number": $('#lot_number').val(),
|
|
"serial_number": $('#serial_number').val()
|
|
},
|
|
action: 'read',
|
|
onSuccess: function(res) {
|
|
var option = '<option value="">Please select ' + label_zone.toLowerCase() + '</option>';
|
|
$.each(res.output, function(key, item) {
|
|
option += `<option value='${item.zone}'>${item.zone}</option>`;
|
|
});
|
|
$('#zone').html(option).prop('disabled', false);
|
|
if (callback) callback();
|
|
}
|
|
});
|
|
}
|
|
|
|
function retrieve_aisle(callback) {
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_aisle.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
noLoading: true,
|
|
queueLock: false,
|
|
data: {
|
|
"warehouse": $('#warehouse').val(),
|
|
"zone": $('#zone').val(),
|
|
"type": 'from',
|
|
"product_sku": $('#product_sku').attr('secondary') || $('#product_sku').val(),
|
|
"lot_number": $('#lot_number').val(),
|
|
"serial_number": $('#serial_number').val()
|
|
},
|
|
action: 'read',
|
|
onSuccess: function(res) {
|
|
var option = '<option value="">Please select ' + label_aisle.toLowerCase() + '</option>';
|
|
$.each(res.output, function(key, item) {
|
|
option += `<option value='${item}'>${item}</option>`;
|
|
});
|
|
$('#aisle').html(option).prop('disabled', false);
|
|
if (callback) callback();
|
|
}
|
|
});
|
|
}
|
|
|
|
function retrieve_rack(callback) {
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_rack.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
noLoading: true,
|
|
queueLock: false,
|
|
data: {
|
|
"warehouse": $('#warehouse').val(),
|
|
"zone": $('#zone').val(),
|
|
"aisle": $('#aisle').val(),
|
|
"type": 'from',
|
|
"product_sku": $('#product_sku').attr('secondary') || $('#product_sku').val(),
|
|
"lot_number": $('#lot_number').val(),
|
|
"serial_number": $('#serial_number').val()
|
|
},
|
|
action: 'read',
|
|
onSuccess: function(res) {
|
|
var option = '<option value="">Please select ' + label_rack.toLowerCase() + '</option>';
|
|
$.each(res.output, function(key, item) {
|
|
option += `<option value='${item}'>${item}</option>`;
|
|
});
|
|
$('#rack').html(option).prop('disabled', false);
|
|
if (callback) callback();
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// ── Reset location dropdowns ──────────────────────────────────────────
|
|
function reset_location() {
|
|
$('#warehouse').html('<option value="">Select warehouse...</option>').prop('disabled', true);
|
|
$('#zone').html('<option value="">Please select ' + label_zone.toLowerCase() + '</option>').prop('disabled', true);
|
|
$('#aisle').html('<option value="">Please select ' + label_aisle.toLowerCase() + '</option>').prop('disabled', true);
|
|
$('#rack').html('<option value="">Please select ' + label_rack.toLowerCase() + '</option>').prop('disabled', true);
|
|
}
|
|
|
|
|
|
// ── Edit mode ─────────────────────────────────────────────────────────
|
|
function retrieve_for_edit() {
|
|
|
|
<?php if(empty($_GET["id"])){ ?>
|
|
return false;
|
|
<?php } ?>
|
|
|
|
return ajax_request({
|
|
url: "<?php echo $server_url?>ics/api/engine/retrieve_stock_out.php",
|
|
autoPrepare: true,
|
|
checkRequired: 0,
|
|
debugMode: 0,
|
|
action: 'read',
|
|
onSuccess: function(res) {
|
|
|
|
var data = res.output;
|
|
|
|
// Lock lot/serial — not editable in edit mode
|
|
$('#lot_number').html(`<option value="${data.lot_number || ''}">${data.lot_number || '—'}</option>`)
|
|
.val(data.lot_number || '').prop('disabled', true);
|
|
$('#serial_number').html(`<option value="${data.serial_number || ''}">${data.serial_number || '—'}</option>`)
|
|
.val(data.serial_number || '').prop('disabled', true);
|
|
|
|
$('#warehouse').val('<?php echo $_GET["wh"];?>').prop('disabled', true);
|
|
|
|
function populate_fields() {
|
|
$.each(data, function(key, item) {
|
|
if (!['warehouse', 'zone', 'aisle', 'rack', 'lot_number', 'serial_number'].includes(key)) {
|
|
$('#' + key).val(item);
|
|
}
|
|
});
|
|
$('#contact').val(data.contact_name)
|
|
.attr('secondary', data.contact_name)
|
|
.attr('data-id', data.contact_id);
|
|
$('#product_name').val(data.product_name);
|
|
$('#product_sku').attr('secondary', data.product_sku).prop('disabled', true);
|
|
$('button[type=submit]').text('Update');
|
|
$('button[type=reset]').hide();
|
|
if (data.status == 0) {
|
|
$('#approve_stock_btn').removeClass('d-none');
|
|
}
|
|
}
|
|
|
|
if (advanced) {
|
|
retrieve_zone(function() {
|
|
$('#zone').val(data.zone).prop('disabled', true);
|
|
retrieve_aisle(function() {
|
|
$('#aisle').val(data.aisle).prop('disabled', true);
|
|
retrieve_rack(function() {
|
|
$('#rack').val(data.rack).prop('disabled', true);
|
|
populate_fields();
|
|
});
|
|
});
|
|
});
|
|
} else {
|
|
// Simple mode — skip zone/aisle cascade
|
|
retrieve_rack(function() {
|
|
$('#rack').val(data.rack).prop('disabled', true);
|
|
populate_fields();
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// ── Boot ─────────────────────────────────────────────────────────────
|
|
$(async function() {
|
|
try {
|
|
await load_location_config(apply_location_labels);
|
|
await retrieve_warehouse();
|
|
await retrieve_for_edit();
|
|
scanner.init({
|
|
allowRaw: false,
|
|
allowedTypes: ['sku', 'loc'],
|
|
onScan: function(sku, product_name, uom, data) {
|
|
if (data.type === 'sku') apply_sku_label_scan(data);
|
|
if (data.type === 'loc') apply_location_label_scan(data);
|
|
}
|
|
});
|
|
} catch(e) {
|
|
console.log(e);
|
|
}
|
|
});
|
|
|
|
|
|
// ── Change handlers (create mode only) ───────────────────────────────
|
|
<?php if(empty($_GET["id"])){ ?>
|
|
$(document).on('keydown', function(e) {
|
|
if (e.key === 'F2') {
|
|
e.preventDefault();
|
|
save_scanned_stock_out();
|
|
}
|
|
});
|
|
|
|
// SKU selected → load lots
|
|
$('input#product_sku').on('blur', function() {
|
|
var sku = $(this).attr('secondary');
|
|
if (!sku) return;
|
|
retrieve_active_lot();
|
|
retrieve_warehouse();
|
|
});
|
|
|
|
// Lot selected → reload serials + location
|
|
$('#lot_number').on('change', function() {
|
|
retrieve_active_serial();
|
|
retrieve_warehouse();
|
|
});
|
|
|
|
// Serial selected → reload location
|
|
$('#serial_number').on('change', function() {
|
|
retrieve_warehouse();
|
|
});
|
|
|
|
// Warehouse selected → load zone (advanced) or rack directly (simple)
|
|
$('#warehouse').on('change', function() {
|
|
if (advanced) {
|
|
retrieve_zone();
|
|
} else {
|
|
retrieve_rack();
|
|
}
|
|
});
|
|
|
|
// Zone selected → load aisle (advanced only)
|
|
$('#zone').on('change', function() {
|
|
if (advanced) retrieve_aisle();
|
|
});
|
|
|
|
// Aisle selected → load rack (advanced only)
|
|
$('#aisle').on('change', function() {
|
|
if (advanced) retrieve_rack();
|
|
});
|
|
|
|
<?php } ?>
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|