fix: low stock detection for rarely-used items
- PHP smart_shopping: add absolute stock fallback that flags conf/pz items with <=2 units (medium) or <=1 unit (high) and g/ml at <=20% of default, regardless of usage frequency. Fixes products like Panna da cucina that are rarely used but running low and were invisible to the frequency-based urgency logic (pctLeft was 66% since last purchase was 3 at once). - JS isLowStock(): return true (not false) when totalRemaining <= 0. A fully depleted item is definitely low-stock; the Bring! add prompt should fire when you use the very last unit.
This commit is contained in:
@@ -2734,6 +2734,36 @@ function smartShopping(PDO $db): void {
|
||||
$score += 20;
|
||||
}
|
||||
|
||||
// Absolute minimum stock fallback: flag items with very low stock regardless of usage frequency.
|
||||
// Applies to products bought at least once, even if rarely used.
|
||||
if ($urgency === 'none' && $buyCount >= 1 && $qty > 0) {
|
||||
if ($unit === 'conf') {
|
||||
if ($qty <= 1) {
|
||||
$urgency = 'high';
|
||||
$reasons[] = 'Solo 1 confezione rimasta';
|
||||
$score += 60;
|
||||
} elseif ($qty <= 2) {
|
||||
$urgency = 'medium';
|
||||
$reasons[] = 'Solo 2 confezioni rimaste';
|
||||
$score += 40;
|
||||
}
|
||||
} elseif ($unit === 'pz') {
|
||||
if ($qty <= 1) {
|
||||
$urgency = 'high';
|
||||
$reasons[] = 'Solo 1 pezzo rimasto';
|
||||
$score += 60;
|
||||
} elseif ($qty <= 2) {
|
||||
$urgency = 'medium';
|
||||
$reasons[] = 'Solo 2 pezzi rimasti';
|
||||
$score += 40;
|
||||
}
|
||||
} elseif (($unit === 'g' || $unit === 'ml') && $defQty > 0 && $qty <= $defQty * 0.20) {
|
||||
$urgency = 'medium';
|
||||
$reasons[] = 'Scorta minima (' . round($qty) . $unit . ')';
|
||||
$score += 40;
|
||||
}
|
||||
}
|
||||
|
||||
if ($urgency === 'none') continue;
|
||||
|
||||
// Boost score for very frequent items
|
||||
|
||||
+1
-1
@@ -3781,7 +3781,7 @@ function selectUseLocation(btn, loc) {
|
||||
|
||||
// ===== LOW STOCK → BRING! PROMPT =====
|
||||
function isLowStock(totalRemaining, unit, defaultQty) {
|
||||
if (totalRemaining <= 0) return false; // already fully depleted → auto-added
|
||||
if (totalRemaining <= 0) return true; // fully depleted → definitely needs restocking
|
||||
if (unit === 'pz') return totalRemaining <= 2;
|
||||
if (unit === 'conf') return totalRemaining <= 1;
|
||||
// Weight/volume: use percentage of default_qty or fixed threshold
|
||||
|
||||
Reference in New Issue
Block a user