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 {