From 2c34387592a67f70af18f840eeee441355d43164 Mon Sep 17 00:00:00 2001 From: dadaloop82 Date: Tue, 12 May 2026 05:52:09 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20remove=20'untracked'=20anomaly=20directi?= =?UTF-8?q?on=20=E2=80=94=20incomplete=20purchase=20history=20is=20normal,?= =?UTF-8?q?=20not=20an=20anomaly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/index.php | 9 +++++---- assets/js/app.js | 7 +------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/api/index.php b/api/index.php index 6006566..9cb5d4d 100644 --- a/api/index.php +++ b/api/index.php @@ -1807,11 +1807,12 @@ function getInventoryAnomalies(PDO $db): void { // so it stays dismissed until the user explicitly resets or the direction changes. // An inventory correction (bringing qty closer to expected) will flip the direction // or drop below threshold — naturally clearing the dismissed state. + // If expected <= 0 it means more consumption recorded than purchases — the + // transaction history is simply incomplete (very common: users track consumption + // but not always purchases). Showing an anomaly here is just noise, skip it. + if ($expected <= 0) continue; + $direction = $diff > 0 ? 'phantom' : 'missing'; - // Special case: expected is negative — more consumption recorded than entries. - // The real qty vs tx comparison is meaningless; what we actually know is that - // "initial stock was never formally registered as an 'in' transaction". - if ($expected <= 0) $direction = 'untracked'; $key = 'a_' . $r['product_id'] . '_' . $direction; if (!empty($dismissed[$key])) continue; $anomalies[] = [ diff --git a/assets/js/app.js b/assets/js/app.js index f6a108b..c08face 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -3897,14 +3897,9 @@ function renderBannerItem() { } else if (entry.type === 'anomaly') { const an = entry.data; const isPhantom = an.direction === 'phantom'; - const isUntracked = an.direction === 'untracked'; banner.className = 'alert-banner banner-anomaly'; iconEl.textContent = '🔍'; - if (isUntracked) { - // More consumption recorded than entries — initial stock was never registered - titleEl.textContent = `${an.name} — ${t('dashboard.banner_anomaly_untracked_title')}`; - detailEl.innerHTML = t('dashboard.banner_anomaly_untracked_detail', { inv_qty: an.inv_qty, unit: an.unit }); - } else if (isPhantom) { + if (isPhantom) { titleEl.textContent = `${an.name} — ${t('dashboard.banner_anomaly_phantom_title')}`; detailEl.innerHTML = t('dashboard.banner_anomaly_phantom_detail', { inv_qty: an.inv_qty, unit: an.unit, expected_qty: an.expected_qty }); } else {