Lot, Serial, ExpiryDate

This commit is contained in:
Thanakorn S
2026-04-25 14:37:00 +07:00
parent 92d116fd21
commit 3cc5baba3f
35 changed files with 3518 additions and 1890 deletions
+124 -13
View File
@@ -13,7 +13,7 @@ $(function () {
var $el = $(el);
$el.autocomplete({
// Fetch data from server
source: function (request, response) {
@@ -120,7 +120,7 @@ $(function () {
var $el = $(el);
$el.autocomplete({
// Fetch data from server
source: function (request, response) {
@@ -202,12 +202,12 @@ $(function () {
})
// Allow HTML rendering in dropdown
.data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>")
.append($("<div>").html(item.label))
.appendTo(ul);
};
// Allow HTML rendering in dropdown
.data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>")
.append($("<div>").html(item.label))
.appendTo(ul);
};
// Add this ↓
$el.on('blur', function () {
@@ -220,6 +220,117 @@ $(function () {
});
/** =========================
* LOT SEARCH AUTOCOMPLETE
* ========================= */
$('input.lot_search').each(function (i, el) {
var $el = $(el);
$el.autocomplete({
source: function (request, response) {
if ($el.data('xhr')) {
$el.data('xhr').abort();
}
let q = prepare_form_data(0, true);
q['keyword'] = request.term;
q['product_sku'] = $('input#product_sku').attr('secondary') || $('input#product_sku').val();
let json = JSON.stringify(q);
var xhr = $.ajax({
url: server_url + 'ics/api/engine/retrieve_lot.php',
type: 'POST',
dataType: 'json',
data: { json: json },
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success: function (res) {
var aca = [];
$.each(res.result, function (i, item) {
var temp = "";
temp += "<div class='lot-result-item' style='font-family:\"Poppins\",sans-serif;padding:4px 0;'>";
temp += "<div style='font-size:10px;text-transform:uppercase;color:#E66239;font-weight:600;line-height:1.2;'>";
temp += "Lot: " + item.lot_number;
temp += "</div>";
temp += "<div style='font-size:13px;font-weight:500;color:#171717;margin-top:2px;'>";
temp += "Expiry: " + (item.expiry_date || 'N/A');
temp += "</div>";
temp += "</div>";
aca.push({
label: temp,
value: item.lot_number,
data: item
});
});
response(aca);
}
});
$el.data('xhr', xhr);
},
minLength: 0,
delay: 300,
select: function (e, ui) {
if (ui.item && ui.item.data) {
var lot = ui.item.data;
// Set lot_number value
$(this)
.val(lot.lot_number)
.attr('secondary', lot.lot_number)
.attr('data-existing', '1'); // flag: this is an existing lot
// Populate + lock expiry_date — existing lot, not editable
if (typeof expiryPicker !== 'undefined' && expiryPicker) {
expiryPicker.setDate(lot.expiry_date || '', true, 'Y-m-d');
if (expiryPicker.altInput) { expiryPicker.altInput.disabled = true; }
}
$('#expiry_date').prop('disabled', true)
.attr('title', 'Expiry date is locked for existing lots');
return false;
}
}
})
.data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>")
.append($("<div>").html(item.label))
.appendTo(ul);
};
// On blur — restore value if user didn't pick from dropdown
$el.on('blur', function () {
var secondary = $(this).attr('secondary');
if (secondary) {
$(this).val(secondary);
}
});
// On manual edit — clear existing flag and unlock expiry_date
$el.on('input', function () {
$(this).removeAttr('data-existing');
$('#expiry_date').prop('disabled', false).removeAttr('title');
if (typeof expiryPicker !== 'undefined' && expiryPicker) {
expiryPicker.clear();
if (expiryPicker.altInput) { expiryPicker.altInput.disabled = false; }
}
});
});
});
@@ -306,20 +417,20 @@ function ajax_request(options) {
return Promise.reject("validation_failed");
}
if(options.data){
if (options.data) {
Object.entries(options.data).forEach(([key, value]) => {
payloadJson[key] = value;
});
}
if(options.action){
if (options.action) {
// modify action
if(options.action === 'manage'){
options.action = (payloadJson['id'])?'update':'create';
if (options.action === 'manage') {
options.action = (payloadJson['id']) ? 'update' : 'create';
}
// add action to JSON
payloadJson['action'] = options.action;
}else{
} else {
isAjaxProcessing = false;
return Promise.reject("please_define_action");
}