Fix smart shopping false positives (prodotti appena comprati/sufficienti)
PHP smartShopping(): - Absolute minimum fallback: requires isRegular + buyCount>=2 + pctLeft<80 (before: ANY product with buyCount>=1 → triggered for newly bought items) - Add justRestocked guard: skip item if bought within 3 days AND pctLeft>=50% and not expiring (prevents items bought yesterday showing as urgent) - Add daysSinceLastBuy calculation JS isLowStock(): - pz threshold: <=1 (was <=2) — 2 pezzi rimasti non è già urgente
This commit is contained in:
+14
-3
@@ -2681,6 +2681,10 @@ function smartShopping(PDO $db): void {
|
|||||||
: ($daysSinceFirst >= 7 ? ($useCount / $daysSinceFirst) * 30 : $useCount * 0.5);
|
: ($daysSinceFirst >= 7 ? ($useCount / $daysSinceFirst) * 30 : $useCount * 0.5);
|
||||||
// Days since last use/purchase — measures recency
|
// Days since last use/purchase — measures recency
|
||||||
$daysSinceLastUse = $lastOut ? ($now - $lastOut) / 86400 : ($lastIn ? ($now - $lastIn) / 86400 : 999);
|
$daysSinceLastUse = $lastOut ? ($now - $lastOut) / 86400 : ($lastIn ? ($now - $lastIn) / 86400 : 999);
|
||||||
|
// Days since last PURCHASE specifically
|
||||||
|
$daysSinceLastBuy = $lastIn ? ($now - $lastIn) / 86400 : 999;
|
||||||
|
// Product was restocked very recently (within 3 days) — suppress non-expiry urgency
|
||||||
|
$justRestocked = $daysSinceLastBuy <= 3;
|
||||||
// Is this a frequently used product? (≥ 1.5 uses/month)
|
// Is this a frequently used product? (≥ 1.5 uses/month)
|
||||||
$isFrequent = $usesPerMonth >= 1.5;
|
$isFrequent = $usesPerMonth >= 1.5;
|
||||||
// Is it a regular product? (≥ 0.5 uses/month = at least once every 2 months)
|
// Is it a regular product? (≥ 0.5 uses/month = at least once every 2 months)
|
||||||
@@ -2766,9 +2770,10 @@ function smartShopping(PDO $db): void {
|
|||||||
$score += 20;
|
$score += 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Absolute minimum stock fallback: flag items with very low stock regardless of usage frequency.
|
// Absolute minimum stock fallback: flag items with critically low stock.
|
||||||
// Applies to products bought at least once, even if rarely used.
|
// Requires: product is regularly consumed (isRegular), bought ≥2 times (proven staple),
|
||||||
if ($urgency === 'none' && $buyCount >= 1 && $qty > 0) {
|
// and stock is clearly depleted relative to normal purchase (pctLeft < 80).
|
||||||
|
if ($urgency === 'none' && $isRegular && $buyCount >= 2 && $qty > 0 && $pctLeft < 80) {
|
||||||
if ($unit === 'conf') {
|
if ($unit === 'conf') {
|
||||||
if ($qty <= 1) {
|
if ($qty <= 1) {
|
||||||
$urgency = 'high';
|
$urgency = 'high';
|
||||||
@@ -2805,6 +2810,12 @@ function smartShopping(PDO $db): void {
|
|||||||
// Is already on Bring? (fuzzy token match — mirrors JS _findSimilarItem logic)
|
// Is already on Bring? (fuzzy token match — mirrors JS _findSimilarItem logic)
|
||||||
$onBring = _productOnBring($p['name'], $bringItems);
|
$onBring = _productOnBring($p['name'], $bringItems);
|
||||||
|
|
||||||
|
// "Just restocked" suppression: if bought in the last 3 days AND stock is above 50%
|
||||||
|
// of reference qty, skip non-expiry urgency flags. The product doesn't need rebuying yet.
|
||||||
|
if ($justRestocked && $pctLeft >= 50 && !$isExpired && !$isExpiringSoon) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'product_id' => $pid,
|
'product_id' => $pid,
|
||||||
'name' => $p['name'],
|
'name' => $p['name'],
|
||||||
|
|||||||
+1
-1
@@ -4075,7 +4075,7 @@ function setPzFraction(frac) {
|
|||||||
// ===== LOW STOCK → BRING! PROMPT =====
|
// ===== LOW STOCK → BRING! PROMPT =====
|
||||||
function isLowStock(totalRemaining, unit, defaultQty) {
|
function isLowStock(totalRemaining, unit, defaultQty) {
|
||||||
if (totalRemaining <= 0) return true; // fully depleted → definitely needs restocking
|
if (totalRemaining <= 0) return true; // fully depleted → definitely needs restocking
|
||||||
if (unit === 'pz') return totalRemaining <= 2;
|
if (unit === 'pz') return totalRemaining <= 1; // only 1 piece left
|
||||||
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
|
||||||
if (defaultQty > 0) return totalRemaining <= defaultQty * 0.25;
|
if (defaultQty > 0) return totalRemaining <= defaultQty * 0.25;
|
||||||
|
|||||||
Reference in New Issue
Block a user