Lot, Serial, ExpiryDate
This commit is contained in:
@@ -44,7 +44,23 @@
|
||||
<input type="number" class="form-control" id="quantity" placeholder="Enter quantity" required>
|
||||
</div>
|
||||
|
||||
<!-- Lot Number -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="lot_number" class="form-label">Lot Number <span class="text-muted fw-normal">(optional)</span></label>
|
||||
<input type="text" class="form-control lot_search" id="lot_number" placeholder="Type to search or enter new lot..." autocomplete="off">
|
||||
</div>
|
||||
|
||||
<!-- Expiry Date (only relevant when lot_number is set) -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="expiry_date" class="form-label">Expiry Date <span class="text-muted fw-normal">(optional)</span></label>
|
||||
<input type="text" class="form-control" id="expiry_date" placeholder="DD/MM/YYYY" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<!-- Serial Number -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="serial_number" class="form-label">Serial Number <span class="text-muted fw-normal">(optional)</span></label>
|
||||
<input type="text" class="form-control" id="serial_number" placeholder="Enter serial number">
|
||||
</div>
|
||||
|
||||
<!-- Warehouse -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
@@ -79,7 +95,6 @@
|
||||
<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>
|
||||
@@ -111,7 +126,10 @@
|
||||
checkRequired: 1,
|
||||
debugMode: 0,
|
||||
data: {
|
||||
"contact_id": $("#contact").attr('data-id')
|
||||
"contact_id": $("#contact").attr('data-id'),
|
||||
"lot_number": $("#lot_number").val(),
|
||||
"expiry_date": $("#expiry_date").val(),
|
||||
"serial_number": $("#serial_number").val()
|
||||
},
|
||||
action: 'manage',
|
||||
onSuccess: function(res) {
|
||||
@@ -271,6 +289,16 @@
|
||||
.attr('data-id', data.contact_id);
|
||||
|
||||
$('#product_name').val(data.product_name);
|
||||
$('#lot_number').val(data.lot_number || '');
|
||||
$('#serial_number').val(data.serial_number || '');
|
||||
if (data.lot_number) {
|
||||
if (expiryPicker) { expiryPicker.setDate(data.expiry_date || '', true, 'Y-m-d'); }
|
||||
$('#expiry_date').prop('disabled', true).attr('title', 'Expiry date is locked for existing lots')
|
||||
.val(data.expiry_date);
|
||||
if (expiryPicker && expiryPicker.altInput) { expiryPicker.altInput.disabled = true; }
|
||||
} else {
|
||||
if (expiryPicker) { expiryPicker.clear(); }
|
||||
}
|
||||
$('#product_sku').attr('secondary', data.product_sku);
|
||||
|
||||
$('#product_sku,#quantity').prop('disabled', true);
|
||||
@@ -291,16 +319,80 @@
|
||||
}
|
||||
|
||||
|
||||
// ── Prefill for restock flow (coming from low-stock-products.php) ────
|
||||
function prefill_from_restock() {
|
||||
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var sku = params.get('sku');
|
||||
var name = params.get('name');
|
||||
var qty = params.get('qty');
|
||||
var wh = params.get('wh');
|
||||
|
||||
// Not a restock flow — nothing to prefill
|
||||
if (!sku) return false;
|
||||
|
||||
// Product fields (locked — the point of restock is this specific SKU)
|
||||
$('#product_sku')
|
||||
.val(sku)
|
||||
.attr('secondary', sku)
|
||||
.prop('disabled', true);
|
||||
|
||||
$('#product_name')
|
||||
.val(name || '')
|
||||
.attr('secondary', name || '');
|
||||
// already disabled in markup
|
||||
|
||||
// Suggested quantity (prefilled value only; user can still edit)
|
||||
if (qty) {
|
||||
$('#quantity').val(qty);
|
||||
}
|
||||
|
||||
// Warehouse: lock it (can't restock to a different warehouse than the one that's low)
|
||||
if (wh) {
|
||||
$('#warehouse').val(wh).prop('disabled', true);
|
||||
|
||||
// Chain-load location selects for the locked warehouse.
|
||||
// Unlike edit mode, we DON'T preselect zone/aisle/rack — the user picks.
|
||||
retrieve_zone('to', function() {
|
||||
retrieve_aisle('to', function() {
|
||||
retrieve_rack('to');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_warehouse('to');
|
||||
await retrieve_for_edit();
|
||||
|
||||
<?php if(!empty($_GET["sku"])){ ?>
|
||||
prefill_from_restock();
|
||||
<?php } ?>
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
// ── Flatpickr: display dd/mm/yyyy, send yyyy-mm-dd to API ──────────
|
||||
var expiryPicker = flatpickr("#expiry_date", {
|
||||
dateFormat: "Y-m-d", // actual value stored in input (sent to API)
|
||||
altInput: true, // show a separate visible input
|
||||
altFormat: "d/m/Y", // visible format: 28/04/2026
|
||||
allowInput: true,
|
||||
onReady: function(_, __, fp) {
|
||||
// Apply Bootstrap form-control class to the alt input
|
||||
fp.altInput.classList.add("form-control");
|
||||
},
|
||||
onChange: function(_, dateStr) {
|
||||
// If lot is new (not existing), keep expiry_date unlocked
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
$("select#warehouse").change(function() {
|
||||
retrieve_zone('to');
|
||||
|
||||
Reference in New Issue
Block a user