Change 'Rack' to 'Bin'

This commit is contained in:
Thanakorn S
2026-05-27 17:14:53 +07:00
parent b8798bc02d
commit 8f57ab5570
41 changed files with 931 additions and 933 deletions
+4 -4
View File
@@ -6,16 +6,16 @@
(new UsageGuard($pdo1, $company_id, $packages))->assertFeatureAccessible('reports');
require_once '../../../assets/utils/classes/ReportManager.php';
$rack_id = (int)($data['rack_id'] ?? 0);
$bin_id = (int)($data['bin_id'] ?? 0);
if (!$rack_id) {
if (!$bin_id) {
$answer['output'] = [];
$answer['success'] = 1;
exit(json_encode($answer));
}
$report = new ReportManager($pdo2, $company_id, $db_database);
$answer['output'] = $report->getRackLog($rack_id);
$answer['output'] = $report->getBinLog($bin_id);
$answer['success'] = 1;
exit(json_encode($answer));
?>
?>
+6 -6
View File
@@ -194,22 +194,22 @@
var search_term = '';
var filter_status = '';
var advanced = false;
var label_rack = 'Location';
var label_bin = 'Location';
var label_zone = 'Zone';
var label_aisle = 'Aisle';
function apply_location_labels() {
$('.th_location').text(advanced
? label_zone + ' / ' + label_aisle + ' / ' + label_rack
: label_rack
? label_zone + ' / ' + label_aisle + ' / ' + label_bin
: label_bin
);
}
function format_location(item) {
if (advanced) {
return [item.zone, item.aisle, item.rack].filter(Boolean).join('-') || '<span class="text-muted">—</span>';
return [item.zone, item.aisle, item.bin].filter(Boolean).join('-') || '<span class="text-muted">—</span>';
}
return item.rack || '<span class="text-muted">—</span>';
return item.bin || '<span class="text-muted">—</span>';
}
function load_company_setting() {
@@ -221,7 +221,7 @@
onSuccess: function(res) {
var s = res.output || {};
advanced = s.advanced_location == 1;
label_rack = s.location_label_rack || (advanced ? 'Rack' : 'Location');
label_bin = s.location_label_bin || (advanced ? 'Bin' : 'Location');
label_zone = s.location_label_zone || 'Zone';
label_aisle = s.location_label_aisle || 'Aisle';
apply_location_labels();
+50 -50
View File
@@ -18,7 +18,7 @@
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-5 gap-3">
<div>
<h1 class="fs-3 mb-1">Rack Occupancy</h1>
<p class="mb-0">View occupied and available rack positions across all warehouses</p>
<p class="mb-0">View occupied and available bin positions across all warehouses</p>
</div>
</div>
</div>
@@ -112,13 +112,13 @@
<div class="mb-6 d-flex align-items-center justify-content-between">
<div>
<h3 class="mb-1 fs-4">All Racks</h3>
<p class="mb-0">Complete rack list across all warehouses</p>
<p class="mb-0">Complete bin list across all warehouses</p>
</div>
</div>
<div class="col-lg-12 mb-5">
<div class="position-relative">
<input type="search" id="search_all" class="form-control ps-9"
placeholder="Search by warehouse, zone, aisle, rack, or SKU…">
placeholder="Search by warehouse, zone, aisle, bin, or SKU…">
<span class="position-absolute top-25 ms-4">
<i class="ti ti-search text-muted"></i>
</span>
@@ -131,7 +131,7 @@
<th>Warehouse</th>
<th class="th_loc_zone">Zone</th>
<th class="th_loc_aisle">Aisle</th>
<th class="th_loc_rack">Rack</th>
<th class="th_loc_bin">Rack</th>
<th>SKU</th>
<th>Product</th>
<th>Status</th>
@@ -161,7 +161,7 @@
<div class="col-lg-12 mb-5">
<div class="position-relative">
<input type="search" id="search_occupied" class="form-control ps-9"
placeholder="Search by warehouse, zone, aisle, rack, or SKU…">
placeholder="Search by warehouse, zone, aisle, bin, or SKU…">
<span class="position-absolute top-25 ms-4">
<i class="ti ti-search text-muted"></i>
</span>
@@ -174,7 +174,7 @@
<th>Warehouse</th>
<th class="th_loc_zone">Zone</th>
<th class="th_loc_aisle">Aisle</th>
<th class="th_loc_rack">Rack</th>
<th class="th_loc_bin">Rack</th>
<th>SKU</th>
<th>Product</th>
<th>Action</th>
@@ -203,7 +203,7 @@
<div class="col-lg-12 mb-5">
<div class="position-relative">
<input type="search" id="search_empty" class="form-control ps-9"
placeholder="Search by warehouse, zone, aisle, or rack…">
placeholder="Search by warehouse, zone, aisle, or bin…">
<span class="position-absolute top-25 ms-4">
<i class="ti ti-search text-muted"></i>
</span>
@@ -216,7 +216,7 @@
<th>Warehouse</th>
<th class="th_loc_zone">Zone</th>
<th class="th_loc_aisle">Aisle</th>
<th class="th_loc_rack">Rack</th>
<th class="th_loc_bin">Rack</th>
<th>Action</th>
</tr>
</thead>
@@ -231,12 +231,12 @@
</div>
<!-- Rack Log Modal -->
<div class="modal fade" id="rackLogModal" tabindex="-1" aria-labelledby="rackLogModalLabel" aria-hidden="true">
<!-- Bin Log Modal -->
<div class="modal fade" id="binLogModal" tabindex="-1" aria-labelledby="binLogModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="rackLogModalLabel">Rack Log</h5>
<h5 class="modal-title" id="binLogModalLabel">Bin Log</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-0">
@@ -249,7 +249,7 @@
<th>User</th>
</tr>
</thead>
<tbody id="rack_log_body">
<tbody id="bin_log_body">
<tr><td colspan="4" class="text-center py-4 text-muted">Loading...</td></tr>
</tbody>
</table>
@@ -267,7 +267,7 @@
// ── Location config ───────────────────────────────────────────────────────
var advanced = false;
var label_rack = 'Location';
var label_bin = 'Location';
var label_zone = 'Zone';
var label_aisle = 'Aisle';
@@ -276,21 +276,21 @@
if (advanced) {
$('.th_loc_zone').text(label_zone).show();
$('.th_loc_aisle').text(label_aisle).show();
$('.th_loc_rack').text(label_rack);
$('.th_loc_bin').text(label_bin);
} else {
$('.th_loc_zone').hide();
$('.th_loc_aisle').hide();
$('.th_loc_rack').text(label_rack);
$('.th_loc_bin').text(label_bin);
}
var loc_hint = advanced
? label_zone.toLowerCase() + ', ' + label_aisle.toLowerCase() + ', ' + label_rack.toLowerCase()
: label_rack.toLowerCase();
? label_zone.toLowerCase() + ', ' + label_aisle.toLowerCase() + ', ' + label_bin.toLowerCase()
: label_bin.toLowerCase();
$('#search_all, #search_occupied').attr('placeholder',
'Search by warehouse, ' + loc_hint + ', or SKU…');
$('#search_empty').attr('placeholder',
'Search by warehouse or ' + loc_hint + '…');
$('#rackLogModalLabel').text(label_rack + ' Log');
$('#stat_label_racks').text('Total ' + label_rack + 's');
$('#binLogModalLabel').text(label_bin + ' Log');
$('#stat_label_bins').text('Total ' + label_bin + 's');
}
// Returns 1 or 3 <td> cells depending on mode
@@ -298,16 +298,16 @@
if (advanced) {
return '<td class="py-3">' + (item.zone || '—') + '</td>'
+ '<td class="py-3">' + (item.aisle || '—') + '</td>'
+ '<td class="py-3">' + (item.rack || '—') + '</td>';
+ '<td class="py-3">' + (item.bin || '—') + '</td>';
}
return '<td class="py-3">' + (item.rack || '—') + '</td>';
return '<td class="py-3">' + (item.bin || '—') + '</td>';
}
// Rack log modal label
function rack_label(item) {
function bin_label(item) {
return advanced
? item.warehouse_name + ' ' + item.zone + '-' + item.aisle + '-' + item.rack
: item.warehouse_name + ' ' + item.rack;
? item.warehouse_name + ' ' + item.zone + '-' + item.aisle + '-' + item.bin
: item.warehouse_name + ' ' + item.bin;
}
var search_all = '';
@@ -316,10 +316,10 @@
// ── Fetch ─────────────────────────────────────────────────────────────
function retrieve_rack_occupancy() {
function retrieve_bin_occupancy() {
return ajax_request({
url: "<?php echo $server_url?>reports/api/engine_report/rack_occupancy.php",
url: "<?php echo $server_url?>reports/api/engine_report/bin_occupancy.php",
autoPrepare: true,
checkRequired: 0,
action: 'read',
@@ -338,8 +338,8 @@
$('#stat_rate').text(rate + '%');
// Store in alasql
alasql('CREATE TABLE IF NOT EXISTS rack_all');
alasql.tables.rack_all.data = res.output || [];
alasql('CREATE TABLE IF NOT EXISTS bin_all');
alasql.tables.bin_all.data = res.output || [];
change_page_all(1);
change_page_occupied(1);
@@ -356,14 +356,14 @@
var kw = search_all.toLowerCase();
var filtered = kw ? alasql(
`SELECT * FROM rack_all
`SELECT * FROM bin_all
WHERE LOWER(warehouse_name) LIKE '%${kw}%'
OR LOWER(zone) LIKE '%${kw}%'
OR LOWER(aisle) LIKE '%${kw}%'
OR LOWER(rack) LIKE '%${kw}%'
OR LOWER(bin) LIKE '%${kw}%'
OR LOWER(product_sku) LIKE '%${kw}%'
OR LOWER(product_name) LIKE '%${kw}%'`
) : alasql('SELECT * FROM rack_all');
) : alasql('SELECT * FROM bin_all');
$('table#tbl_all tfoot').html(generate_pagination('tbl_all', filtered.length));
@@ -385,7 +385,7 @@
<td class="py-3">${item.product_sku || '<span class="text-muted">—</span>'}</td>
<td class="py-3">${item.product_name || '<span class="text-muted">—</span>'}</td>
<td class="py-3">${badge}</td>
<td class="py-3"><a href="javascript:;" onclick="view_rack_log(${item.id}, '${rack_label(item)}')"><i class="ti ti-history fs-5"></i></a></td>
<td class="py-3"><a href="javascript:;" onclick="view_bin_log(${item.id}, '${bin_label(item)}')"><i class="ti ti-history fs-5"></i></a></td>
</tr>`;
});
$('table#tbl_all > tbody').html(body);
@@ -398,13 +398,13 @@
var offset = (page_num - 1) * prop_limit;
var kw = search_occupied.toLowerCase();
var base = alasql("SELECT * FROM rack_all WHERE status = 'occupied'");
var base = alasql("SELECT * FROM bin_all WHERE status = 'occupied'");
var filtered = kw ? base.filter(function(item) {
return (item.warehouse_name || '').toLowerCase().includes(kw)
|| (item.zone || '').toLowerCase().includes(kw)
|| (item.aisle || '').toLowerCase().includes(kw)
|| (item.rack || '').toLowerCase().includes(kw)
|| (item.bin || '').toLowerCase().includes(kw)
|| (item.product_sku || '').toLowerCase().includes(kw)
|| (item.product_name || '').toLowerCase().includes(kw);
}) : base;
@@ -425,7 +425,7 @@
` + location_cells(item) + `
<td class="py-3">${item.product_sku}</td>
<td class="py-3">${item.product_name || '<span class="text-muted">—</span>'}</td>
<td class="py-3"><a href="javascript:;" onclick="view_rack_log(${item.id}, '${rack_label(item)}')"><i class="ti ti-history fs-5"></i></a></td>
<td class="py-3"><a href="javascript:;" onclick="view_bin_log(${item.id}, '${bin_label(item)}')"><i class="ti ti-history fs-5"></i></a></td>
</tr>`;
});
$('table#tbl_occupied > tbody').html(body);
@@ -438,13 +438,13 @@
var offset = (page_num - 1) * prop_limit;
var kw = search_empty.toLowerCase();
var base = alasql("SELECT * FROM rack_all WHERE status = 'empty'");
var base = alasql("SELECT * FROM bin_all WHERE status = 'empty'");
var filtered = kw ? base.filter(function(item) {
return (item.warehouse_name || '').toLowerCase().includes(kw)
|| (item.zone || '').toLowerCase().includes(kw)
|| (item.aisle || '').toLowerCase().includes(kw)
|| (item.rack || '').toLowerCase().includes(kw);
|| (item.bin || '').toLowerCase().includes(kw);
}) : base;
$('table#tbl_empty tfoot').html(generate_pagination('tbl_empty', filtered.length));
@@ -461,7 +461,7 @@
body += `<tr>
<td class="py-3">${item.warehouse_name}</td>
` + location_cells(item) + `
<td class="py-3"><a href="javascript:;" onclick="view_rack_log(${item.id}, '${rack_label(item)}')"><i class="ti ti-history fs-5"></i></a></td>
<td class="py-3"><a href="javascript:;" onclick="view_bin_log(${item.id}, '${bin_label(item)}')"><i class="ti ti-history fs-5"></i></a></td>
</tr>`;
});
$('table#tbl_empty > tbody').html(body);
@@ -501,30 +501,30 @@
// Remember last active tab
$(document).ready(function() {
$('button.nav-link').on('click', function() {
sessionStorage.setItem('rack_nav_id', $(this).attr('id'));
sessionStorage.setItem('bin_nav_id', $(this).attr('id'));
});
var nav_id = sessionStorage.getItem('rack_nav_id');
var nav_id = sessionStorage.getItem('bin_nav_id');
if (nav_id) $(`button#${nav_id}`).trigger('click');
});
// ── Rack Log ─────────────────────────────────────────────────────────
function view_rack_log(rack_id, label) {
// ── Bin Log ──────────────────────────────────────────────────────────
function view_bin_log(bin_id, label) {
$('#rackLogModalLabel').text('Rack Log — ' + label);
$('#rack_log_body').html('<tr><td colspan="4" class="text-center py-4 text-muted">Loading...</td></tr>');
$('#rackLogModal').modal('show');
$('#binLogModalLabel').text('Bin Log — ' + label);
$('#bin_log_body').html('<tr><td colspan="4" class="text-center py-4 text-muted">Loading...</td></tr>');
$('#binLogModal').modal('show');
ajax_request({
url: "<?php echo $server_url?>reports/api/engine_report/rack_log.php",
url: "<?php echo $server_url?>reports/api/engine_report/bin_log.php",
autoPrepare: true,
checkRequired: 0,
action: 'read',
data: { "rack_id": rack_id },
data: { "bin_id": bin_id },
onSuccess: function(res) {
if (!res.output || res.output.length === 0) {
$('#rack_log_body').html('<tr><td colspan="4" class="text-center py-4 text-muted">No log entries.</td></tr>');
$('#bin_log_body').html('<tr><td colspan="4" class="text-center py-4 text-muted">No log entries.</td></tr>');
return;
}
@@ -544,7 +544,7 @@
<td class="py-3">${row.user_name || '<span class="text-muted">—</span>'}</td>
</tr>`;
});
$('#rack_log_body').html(body);
$('#bin_log_body').html(body);
}
});
}
@@ -554,7 +554,7 @@
$(async function() {
try {
await load_location_config(apply_location_labels);
await retrieve_rack_occupancy();
await retrieve_bin_occupancy();
} catch(e) {
console.log(e);
}
+6 -6
View File
@@ -183,7 +183,7 @@
var lot_log_page = 1;
var lot_log_limit = 10;
var advanced = false;
var label_rack = 'Location';
var label_bin = 'Location';
var label_zone = 'Zone';
var label_aisle = 'Aisle';
@@ -202,16 +202,16 @@
function apply_location_labels() {
$('#th_location').text(advanced
? label_zone + ' / ' + label_aisle + ' / ' + label_rack
: label_rack
? label_zone + ' / ' + label_aisle + ' / ' + label_bin
: label_bin
);
}
function format_location(row) {
if (advanced) {
return [row.zone, row.aisle, row.rack].filter(Boolean).join('-') || '<span class="text-muted">—</span>';
return [row.zone, row.aisle, row.bin].filter(Boolean).join('-') || '<span class="text-muted">—</span>';
}
return row.rack || '<span class="text-muted">—</span>';
return row.bin || '<span class="text-muted">—</span>';
}
function load_company_setting() {
@@ -223,7 +223,7 @@
onSuccess: function(res) {
var s = res.output || {};
advanced = s.advanced_location == 1;
label_rack = s.location_label_rack || (advanced ? 'Rack' : 'Location');
label_bin = s.location_label_bin || (advanced ? 'Bin' : 'Location');
label_zone = s.location_label_zone || 'Zone';
label_aisle = s.location_label_aisle || 'Aisle';
apply_location_labels();
+6 -6
View File
@@ -256,7 +256,7 @@
// Movement Summary running totals (reset on each search)
var run_revenue = 0, run_cogs = 0, run_gp = 0, sum_in = 0, sum_out = 0, sum_txn = 0;
var label_rack = 'Location';
var label_bin = 'Location';
var label_zone = 'Zone';
var label_aisle = 'Aisle';
@@ -268,16 +268,16 @@
function apply_location_labels() {
$('#th_location').text(advanced
? label_zone + ' / ' + label_aisle + ' / ' + label_rack
: label_rack
? label_zone + ' / ' + label_aisle + ' / ' + label_bin
: label_bin
);
}
function format_location(row) {
if (advanced) {
return [row.zone, row.aisle, row.rack].filter(Boolean).join('-');
return [row.zone, row.aisle, row.bin].filter(Boolean).join('-');
}
return row.rack || '';
return row.bin || '';
}
function display_location(row) {
@@ -293,7 +293,7 @@
onSuccess: function(res) {
var s = res.output || {};
advanced = s.advanced_location == 1;
label_rack = s.location_label_rack || (advanced ? 'Rack' : 'Location');
label_bin = s.location_label_bin || (advanced ? 'Bin' : 'Location');
label_zone = s.location_label_zone || 'Zone';
label_aisle = s.location_label_aisle || 'Aisle';
apply_location_labels();