Fix anomaly banner when expected_qty is negative (untracked initial stock)

This commit is contained in:
dadaloop82
2026-04-29 15:26:59 +00:00
parent 22266cb620
commit da46fec174
5 changed files with 17 additions and 1 deletions
+4
View File
@@ -1584,6 +1584,10 @@ function getInventoryAnomalies(PDO $db): void {
if (!empty($dismissed[$key])) 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';
$anomalies[] = [
'inventory_id' => (int)$r['inventory_id'],
'product_id' => (int)$r['product_id'],
+6 -1
View File
@@ -2962,9 +2962,14 @@ 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 (isPhantom) {
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) {
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 {
+3
View File
@@ -128,6 +128,9 @@
"banner_finished_check": "Kannst du nachschauen?",
"banner_anomaly_phantom_title": "mehr Bestand als erwartet",
"banner_anomaly_phantom_detail": "Bestand zeigt {inv_qty} {unit}, aber laut Buchungen solltest du nur {expected_qty} {unit} haben. Hast du Bestand ohne Buchung hinzugefügt?",
"banner_anomaly_untracked_title": "Anfangsbestand nicht als Eingang gebucht",
"banner_anomaly_untracked_detail": "Du hast <strong>{inv_qty} {unit}</strong> im Bestand, aber die gebuchten Abgänge übersteigen die Eingänge — der Anfangsbestand wurde wahrscheinlich nie als \"Eingang\" erfasst. Bitte korrigiere die Menge oder trage die fehlenden Eingänge nach."
,
"banner_anomaly_ghost_title": "weniger Bestand als erwartet",
"banner_anomaly_ghost_detail": "Laut Buchungen solltest du {expected_qty} {unit} von {name} haben, aber der Bestand zeigt nur {inv_qty} {unit}. Hast du etwas ohne Buchung entnommen?",
"consumed": "Verbraucht: {n} ({pct}%)",
+2
View File
@@ -128,6 +128,8 @@
"banner_finished_check": "Can you check?",
"banner_anomaly_phantom_title": "you have more stock than expected",
"banner_anomaly_phantom_detail": "Inventory shows {inv_qty} {unit}, but based on records you should only have {expected_qty} {unit}. Did you add stock without recording it?",
"banner_anomaly_untracked_title": "stock not recorded as an entry",
"banner_anomaly_untracked_detail": "You have <strong>{inv_qty} {unit}</strong> in inventory, but recorded outflows exceed inflows — the initial stock was likely never added as an \"in\" transaction. You can correct the quantity or log the missing entries.",
"banner_anomaly_ghost_title": "you have less stock than expected",
"banner_anomaly_ghost_detail": "Based on recorded operations you should have {expected_qty} {unit} of {name}, but inventory shows only {inv_qty} {unit}. Did you take stock without recording it?",
"consumed": "Consumed: {n} ({pct}%)",
+2
View File
@@ -128,6 +128,8 @@
"banner_finished_check": "Puoi controllare?",
"banner_anomaly_phantom_title": "hai più scorte del previsto",
"banner_anomaly_phantom_detail": "L'inventario segna {inv_qty} {unit}, ma in base alle registrazioni ne dovresti avere solo {expected_qty} {unit}. Hai aggiunto scorte senza registrarle?",
"banner_anomaly_untracked_title": "scorte non registrate come entrata",
"banner_anomaly_untracked_detail": "Hai <strong>{inv_qty} {unit}</strong> in inventario, ma le uscite registrate superano le entrate — le scorte iniziali probabilmente non sono mai state aggiunte come entrata. Puoi correggere la quantità o registrare le entrate mancanti.",
"banner_anomaly_ghost_title": "hai meno scorte del previsto",
"banner_anomaly_ghost_detail": "In base alle operazioni registrate dovresti avere {expected_qty} {unit} di {name}, ma l'inventario mostra solo {inv_qty} {unit}. Hai prelevato senza registrarlo?",
"consumed": "Consumati: {n} ({pct}%)",