From b954be4cac53f5d42fce50f5283bd6e776acddb3 Mon Sep 17 00:00:00 2001 From: dadaloop82 Date: Sun, 29 Mar 2026 19:58:43 +0000 Subject: [PATCH] Fix smart shopping: skip one-time purchases, better frequency for short history - Products bought only once (buy_count=1) and out of stock are skipped entirely (not enough history to predict repurchase need, e.g. piadelle) - usesPerMonth for items tracked 7-30 days now normalized instead of using raw count - usesPerMonth for items tracked <7 days halved to avoid inflation - Critical urgency now requires buy_count >= 2 --- api/index.php | 12 +++++++++--- data/dispensa.db | Bin 266240 -> 266240 bytes 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/api/index.php b/api/index.php index 3a0da9a..e66016c 100644 --- a/api/index.php +++ b/api/index.php @@ -2308,7 +2308,10 @@ function smartShopping(PDO $db): void { // --- Frequency & recency metrics --- // Uses per month (30 days) — measures how frequently the product is actually used - $usesPerMonth = $daysSinceFirst >= 30 ? ($useCount / $daysSinceFirst) * 30 : $useCount; + // For items tracked < 30 days, normalize over at least 14 days to avoid inflation + $usesPerMonth = $daysSinceFirst >= 30 + ? ($useCount / $daysSinceFirst) * 30 + : ($daysSinceFirst >= 7 ? ($useCount / $daysSinceFirst) * 30 : $useCount * 0.5); // Days since last use/purchase — measures recency $daysSinceLastUse = $lastOut ? ($now - $lastOut) / 86400 : ($lastIn ? ($now - $lastIn) / 86400 : 999); // Is this a frequently used product? (≥ 1.5 uses/month) @@ -2325,12 +2328,15 @@ function smartShopping(PDO $db): void { // Out of stock if ($qty <= 0) { - if ($isFrequent && $isRecent) { - // Frequently used AND recently active → critical + if ($isFrequent && $isRecent && $buyCount >= 2) { + // Frequently used, recently active, AND bought multiple times → critical $urgency = 'critical'; $reasons[] = 'Esaurito'; $score += 100; if ($useCount >= 5) { $score += 20; $reasons[] = "Uso frequente ({$useCount}x)"; } + } elseif ($isFrequent && $isRecent && $buyCount == 1) { + // Frequent use but only bought once — not yet a proven staple → skip + continue; } elseif ($isRegular && $isRecent && ($useCount >= 4 || $buyCount >= 3)) { // Regularly used, recently active → high $urgency = 'high'; diff --git a/data/dispensa.db b/data/dispensa.db index acd7412f6215b02773a06d4d433dfc8d8391400f..09223b11bead085e6d0f68d149ec52519b698d7c 100644 GIT binary patch delta 101 zcmZozAkY9rEsR^37!`OKw=ys@$}{jTV+>}LpWMi4yWLxXDT|SXfr0zuW<`Uy+!8I} z%&giSxyHpA`2_`;dFk;5MVZN|#nsy%YBK3DO@E`$#KmQ)U}$M&YGP$%)Mmi6%z*g; E0IOOZbpQYW delta 1862 zcma)+L66%+6o5Cgv|_7PLPDxqA+&?J6zZ|xj5DzvwSqL8(ulTMvPlosR>Rr>1Lru{Yk&x7v5w z4GiS>X?5Fhi|<=uG8uZ0%c1^At8-~My7qYx4i3})I85=5M+5b|=RfiW!B&v?v4%kj zKvjIti~VR{W#NDY(h&fz;I-_TLEJO$t_ij5Z-ZQH&QfNajl6Ko1PBQ(NCu8{WzBdv zQFkT7=>RWUmdsSi5yRX^p(nBrO>*hd%H78%F<0;YZjyK2%dgWZmoU(25{!>LI*Eqi zL6jVLX{ddrYX{*t^8Lf?4@UG)xK&+3zS+LpX*O@Q%XF7qg;6~LwiHujahdHI#ClC# zn|*JPYv-%T$JsT7*fn|fuR-4AYOe%IAWWNaTT0-^Ar*;+*#{=M{Q6?`g-Kw!`pqQT zrl6A}ogT#a&mHD99!;^rAdaX!TI}tIb6Fm6kZ3^Bk=@2tJC}uGYwmRD?f%`5$`s4uI4==r5u1tQ z6yo4dOKq0XaNsTjm%Bn9S48E>yge_SaX436tD?(mRpEJ+^%PqwNbw0(-;*k!r^|tH zqubxXChGNCN`gC$E)I}VttT7FJs|=Zi@bA{eI?SNu=>H&ny&Q&RQ>)fsbd<*19 HSpVlg1&}g>