[test] contact to setting modules
This commit is contained in:
+96
-28
@@ -31,10 +31,18 @@
|
||||
<div class="mb-3 col-lg-2">
|
||||
<input class="form-control" value='Warehouse' disabled>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-4">
|
||||
<div class="mb-3 col-lg-2">
|
||||
<select name="warehouse" id="warehouse" class="form-select" required></select>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-6">
|
||||
<div class="mb-3 col-lg-2">
|
||||
<input class="form-control" value='Source' disabled>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-2">
|
||||
<select name="source" id="source" class="form-select">
|
||||
<option value="">All Sources</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-2">
|
||||
<button class='btn btn-secondary' onclick='retrieve_stock_in()'>Search</button>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +58,8 @@
|
||||
<th>Product</th>
|
||||
<th>Lot Number</th>
|
||||
<th>Serial Number</th>
|
||||
<th>Quantity</th>
|
||||
<th style="text-align: right;">Quantity</th>
|
||||
<th>Source</th>
|
||||
<th class="th_loc_zone">Zone</th>
|
||||
<th class="th_loc_aisle">Aisle</th>
|
||||
<th class="th_loc_rack">Rack</th>
|
||||
@@ -103,6 +112,70 @@
|
||||
return `<td class="py-3">${item['rack'] || ''}</td>`;
|
||||
}
|
||||
|
||||
function escape_html(value) {
|
||||
return String(value ?? '').replace(/[&<>"']/g, function(char) {
|
||||
return {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
}[char];
|
||||
});
|
||||
}
|
||||
|
||||
function source_label(source) {
|
||||
source = source || '';
|
||||
if (!source) return 'Manual';
|
||||
return source.charAt(0).toUpperCase() + source.slice(1).replace(/_/g, ' ');
|
||||
}
|
||||
|
||||
function source_cell(source) {
|
||||
var label = escape_html(source_label(source));
|
||||
return source
|
||||
? `<span class="badge bg-info-subtle text-info">${label}</span>`
|
||||
: `<span class="badge bg-secondary-subtle text-secondary">${label}</span>`;
|
||||
}
|
||||
|
||||
function populate_source_filter(rows) {
|
||||
var current = $('#source').val() || '';
|
||||
var sources = {};
|
||||
|
||||
$.each(rows, function(_, item) {
|
||||
sources[item.source || '__manual__'] = item.source || '';
|
||||
});
|
||||
|
||||
var option = `<option value="">All Sources</option>`;
|
||||
$.each(Object.keys(sources).sort(), function(_, key) {
|
||||
var value = sources[key];
|
||||
var option_value = value || '__manual__';
|
||||
option += `<option value="${escape_html(option_value)}">${escape_html(source_label(value))}</option>`;
|
||||
});
|
||||
|
||||
$('#source').html(option).val(current);
|
||||
if ($('#source').val() !== current) $('#source').val('');
|
||||
}
|
||||
|
||||
function apply_source_filter() {
|
||||
var selected = $('#source').val() || '';
|
||||
var rows = alasql.tables.stock_in_all ? alasql.tables.stock_in_all.data : [];
|
||||
|
||||
if (!selected) {
|
||||
alasql.tables.stock_in.data = rows;
|
||||
} else {
|
||||
alasql.tables.stock_in.data = rows.filter(function(item) {
|
||||
var source = item.source || '';
|
||||
return selected === '__manual__' ? !source : source === selected;
|
||||
});
|
||||
}
|
||||
|
||||
var table_id = 'stock_in';
|
||||
var total_records = alasql.tables.stock_in.data.length;
|
||||
var page = generate_pagination(table_id, total_records);
|
||||
$(`table#${table_id} tfoot`).html(page);
|
||||
change_page_stock_in(1);
|
||||
}
|
||||
|
||||
function retrieve_stock_in() {
|
||||
|
||||
return ajax_request({
|
||||
@@ -114,22 +187,12 @@
|
||||
onSuccess: function(res) {
|
||||
|
||||
// Register the array as a table name
|
||||
alasql('CREATE TABLE IF NOT EXISTS stock_in_all');
|
||||
alasql('CREATE TABLE IF NOT EXISTS stock_in');
|
||||
alasql.tables.stock_in.data = res.output || [];
|
||||
alasql.tables.stock_in_all.data = res.output || [];
|
||||
|
||||
var total_records = alasql.tables.stock_in.data.length;
|
||||
|
||||
var table_id = 'stock_in';
|
||||
|
||||
var page = generate_pagination(table_id, total_records);
|
||||
$(`table#${table_id} tfoot`).html(page);
|
||||
|
||||
// dynamic function name
|
||||
if (typeof window[`change_page_${table_id}`] === "function") {
|
||||
window[`change_page_${table_id}`](1);
|
||||
} else {
|
||||
console.error(`Function change_page_${table_id} does not exist.`);
|
||||
}
|
||||
populate_source_filter(alasql.tables.stock_in_all.data);
|
||||
apply_source_filter();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -153,19 +216,19 @@
|
||||
<td class="py-3">${item["product_sku"]}: ${item['product_name']}</td>
|
||||
<td class="py-3">${item['lot_number'] || '<span class="text-muted">—</span>'}</td>
|
||||
<td class="py-3">${item['serial_number'] || '<span class="text-muted">—</span>'}</td>
|
||||
<td class="py-3">${item['quantity']}</td>
|
||||
<td class="py-3">
|
||||
<div class="d-flex justify-content-end align-items-baseline gap-1">
|
||||
<span>${format_number(item['quantity'], 2)}</span>
|
||||
<span class="text-muted small" style="min-width:28px;">${item['uom'] || ''}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3">${source_cell(item['source'])}</td>
|
||||
${location_cells(item)}
|
||||
<td class="py-3">
|
||||
${item['status'] == 1 ? '<span class="badge bg-success">Approved</span>' : '<span class="badge bg-warning text-dark">Draft</span>'}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_in.php?id=${item['id']}&wh=${warehouse}" class=""><i class="ti ti-eye fs-5"></i></a>
|
||||
${item['status'] == 0
|
||||
? (auto_approve
|
||||
? '<button class="btn btn-sm btn-outline-secondary ms-2" disabled title="Auto-approved on save — no manual approval needed"><i class=\"ti ti-check\"></i></button>'
|
||||
: '<button class="btn btn-sm btn-outline-success ms-2" onclick=\"approve_stock('+item['id']+', '+item['warehouse_id']+', \'in\')\" title="Approve"><i class=\"ti ti-check\"></i></button>'
|
||||
)
|
||||
: ''}
|
||||
<a href="javascript:void(0);" class="link-danger"
|
||||
onclick="delete_stock_in($(this),${item['id']})">
|
||||
<i class="ti ti-trash ms-2 fs-5"></i>
|
||||
@@ -225,6 +288,9 @@
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', '#source', apply_source_filter);
|
||||
$(document).on('change', '#warehouse', retrieve_stock_in);
|
||||
|
||||
// ── Stock approval ────────────────────────────────────────────────────────
|
||||
var auto_approve = false; // set from company_setting on load
|
||||
@@ -258,11 +324,13 @@
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'update',
|
||||
id: id,
|
||||
warehouse: warehouse_id,
|
||||
type: type,
|
||||
data: {
|
||||
id: id,
|
||||
warehouse: warehouse_id,
|
||||
type: type
|
||||
},
|
||||
onSuccess: function(res) {
|
||||
retrieve_stock_list();
|
||||
retrieve_stock_in();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user