Suggerisci confezione da usare per prima (scad. più vicina)
- Nel form USA, se il prodotto ha >=2 slot in inventario con scadenze
diverse (es. 2 lotti dispensa, o frigo+dispensa), mostra un banner
giallo: '⚠️ Usa prima quella in Frigo — scade il 12/04 (tra 3 giorni)!'
- Logica: filtra item con expiry_date, ordina per scadenza ASC,
mostra hint solo se ci sono almeno 2 scadenze diverse O 2 location diverse
- Nessun hint se tutto ha la stessa scadenza (inutile)
This commit is contained in:
@@ -2352,6 +2352,18 @@ body {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#use-expiry-hint {
|
||||||
|
background: #fef3c7;
|
||||||
|
border: 1.5px solid #f59e0b;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 10px 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #92400e;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
/* ===== EMPTY STATE ===== */
|
/* ===== EMPTY STATE ===== */
|
||||||
.empty-state {
|
.empty-state {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -3971,6 +3971,52 @@ function renderUsePreview() {
|
|||||||
let _useConfMode = null; // null = normal, { packageSize, packageUnit, totalSub, unit } = conf mode active
|
let _useConfMode = null; // null = normal, { packageSize, packageUnit, totalSub, unit } = conf mode active
|
||||||
let _useNormalUnit = 'pz'; // unit when not in conf mode
|
let _useNormalUnit = 'pz'; // unit when not in conf mode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mostra un suggerimento giallo sotto le info inventario quando ci sono più
|
||||||
|
* confezioni con scadenze diverse (o in posti diversi con scadenze diverse).
|
||||||
|
* Es: "⚠️ Usa prima quella in Frigo — scade il 12/04 (tra 3 giorni)!"
|
||||||
|
*/
|
||||||
|
function _renderUseExpiryHint(items) {
|
||||||
|
const hintEl = document.getElementById('use-expiry-hint');
|
||||||
|
|
||||||
|
// Filtra solo item con scadenza e quantità > 0
|
||||||
|
const withExpiry = items.filter(i => i.expiry_date && parseFloat(i.quantity) > 0);
|
||||||
|
|
||||||
|
// Serve almeno 2 item con scadenze diverse (o locazioni diverse con scadenze)
|
||||||
|
if (withExpiry.length < 2) { hintEl.style.display = 'none'; return; }
|
||||||
|
|
||||||
|
const dates = withExpiry.map(i => i.expiry_date);
|
||||||
|
const uniqueDates = new Set(dates);
|
||||||
|
const uniqueLocs = new Set(withExpiry.map(i => i.location));
|
||||||
|
|
||||||
|
// Mostra hint se scadenze diverse OPPURE stessa scadenza ma luoghi diversi
|
||||||
|
if (uniqueDates.size < 2 && uniqueLocs.size < 2) { hintEl.style.display = 'none'; return; }
|
||||||
|
|
||||||
|
// Trova il più vicino alla scadenza
|
||||||
|
withExpiry.sort((a, b) => new Date(a.expiry_date) - new Date(b.expiry_date));
|
||||||
|
const soonest = withExpiry[0];
|
||||||
|
|
||||||
|
const today = new Date(); today.setHours(0,0,0,0);
|
||||||
|
const expDate = new Date(soonest.expiry_date);
|
||||||
|
const diffDays = Math.round((expDate - today) / 86400000);
|
||||||
|
|
||||||
|
const locInfo = LOCATIONS[soonest.location] || { icon: '📦', label: soonest.location };
|
||||||
|
const dateStr = expDate.toLocaleDateString('it-IT', { day: '2-digit', month: '2-digit' });
|
||||||
|
|
||||||
|
let whenStr;
|
||||||
|
if (diffDays < 0) whenStr = `scaduta da ${-diffDays} giorn${-diffDays === 1 ? 'o' : 'i'}`;
|
||||||
|
else if (diffDays === 0) whenStr = 'scade <strong>oggi</strong>';
|
||||||
|
else if (diffDays === 1) whenStr = 'scade <strong>domani</strong>';
|
||||||
|
else whenStr = `scade tra <strong>${diffDays} giorni</strong>`;
|
||||||
|
|
||||||
|
const locLabel = uniqueLocs.size > 1
|
||||||
|
? ` (${locInfo.icon} ${locInfo.label})`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
hintEl.innerHTML = `⚠️ Usa prima quella${locLabel} che scade il <strong>${dateStr}</strong> — ${whenStr}!`;
|
||||||
|
hintEl.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
async function loadUseInventoryInfo() {
|
async function loadUseInventoryInfo() {
|
||||||
try {
|
try {
|
||||||
const data = await api('inventory_list');
|
const data = await api('inventory_list');
|
||||||
@@ -3982,9 +4028,14 @@ async function loadUseInventoryInfo() {
|
|||||||
infoEl.innerHTML = '⚠️ Prodotto non presente nell\'inventario.';
|
infoEl.innerHTML = '⚠️ Prodotto non presente nell\'inventario.';
|
||||||
unitSwitch.style.display = 'none';
|
unitSwitch.style.display = 'none';
|
||||||
_useConfMode = null;
|
_useConfMode = null;
|
||||||
|
document.getElementById('use-expiry-hint').style.display = 'none';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Suggerisci quale confezione usare per prima ──────────────────
|
||||||
|
_renderUseExpiryHint(items);
|
||||||
|
// ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// Auto-select the location with an opened package first (use from opened before sealed)
|
// Auto-select the location with an opened package first (use from opened before sealed)
|
||||||
const openedItem = items.find(i => {
|
const openedItem = items.find(i => {
|
||||||
const q = parseFloat(i.quantity);
|
const q = parseFloat(i.quantity);
|
||||||
|
|||||||
@@ -262,6 +262,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="product-preview-small" id="use-product-preview"></div>
|
<div class="product-preview-small" id="use-product-preview"></div>
|
||||||
<div class="use-inventory-info" id="use-inventory-info"></div>
|
<div class="use-inventory-info" id="use-inventory-info"></div>
|
||||||
|
<div id="use-expiry-hint" style="display:none"></div>
|
||||||
<form class="form" onsubmit="submitUse(event)">
|
<form class="form" onsubmit="submitUse(event)">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>📍 Da dove?</label>
|
<label>📍 Da dove?</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user