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:
dadaloop82
2026-04-06 10:53:15 +00:00
parent 6424f381af
commit 5be62cfbfd
2 changed files with 31 additions and 1 deletions
+30
View File
@@ -2734,6 +2734,36 @@ function smartShopping(PDO $db): void {
$score += 20; $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; if ($urgency === 'none') continue;
// Boost score for very frequent items // Boost score for very frequent items
+1 -1
View File
@@ -3781,7 +3781,7 @@ function selectUseLocation(btn, loc) {
// ===== LOW STOCK → BRING! PROMPT ===== // ===== LOW STOCK → BRING! PROMPT =====
function isLowStock(totalRemaining, unit, defaultQty) { 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 === 'pz') return totalRemaining <= 2;
if (unit === 'conf') return totalRemaining <= 1; if (unit === 'conf') return totalRemaining <= 1;
// Weight/volume: use percentage of default_qty or fixed threshold // Weight/volume: use percentage of default_qty or fixed threshold