diff --git a/web/src/pages/MinStock.jsx b/web/src/pages/MinStock.jsx index 989b15d..4d91c41 100644 --- a/web/src/pages/MinStock.jsx +++ b/web/src/pages/MinStock.jsx @@ -1,6 +1,7 @@ import { useEffect, useMemo, useState } from "react"; import { api } from "../api"; import { useAuth } from "../auth"; +import { useConfirm } from "../confirm"; import Icon from "../components/Icon"; import DataTable from "../components/DataTable"; import CategoryPathLabel, { pathParts } from "../components/CategoryPathLabel"; @@ -30,6 +31,7 @@ const EMPTY_DRAFT = { kind: "product", targetId: "", scope: "global", locId: "", export default function MinStock() { const { isAdmin } = useAuth(); + const confirm = useConfirm(); const [products, setProducts] = useState([]); const [groups, setGroups] = useState([]); const [locations, setLocations] = useState([]); @@ -132,6 +134,35 @@ export default function MinStock() { } catch (err) { setError(err.message); } } + // Mindestbestand ganz entfernen: Gesamt-Wert auf NULL, je-Lagerort-Eintrag raus. + // Das Feld leeren tut dasselbe – aber ein eigener Knopf macht das Löschen + // eindeutig (und bei Gesamt-Werten sichtbar, da die Zeile sonst bestehen bleibt). + async function deleteRow(row) { + const ziel = row.kind === "group" ? `Gruppe „${row.name}"` : `„${row.name}"`; + const wo = row.scope === "loc" ? ` am Lagerort „${row.ort}"` : ""; + if (!(await confirm({ + title: "Mindestbestand löschen?", + message: `Mindestbestand von ${ziel}${wo} entfernen?`, + confirmLabel: "Löschen", danger: true, + }))) return; + setError(null); + try { + if (row.kind === "product" && row.scope === "global") { + await api.updateProduct(row.entity.id, { + min_stock: null, min_stock_in_packages: false, + min_stock_unit_id: row.entity.display_unit_id ?? null, + }); + } else if (row.kind === "product" && row.scope === "loc") { + await api.setProductLocationMinStock(row.entity.id, mergeLoc(row.entity.location_min_stocks, row.locId, null)); + } else if (row.kind === "group" && row.scope === "global") { + await api.updateGroup(row.entity.id, { min_stock: null }); + } else if (row.kind === "group" && row.scope === "loc") { + await api.setGroupLocationMinStock(row.entity.id, mergeLoc(row.entity.location_min_stocks, row.locId, null)); + } + await load(); + } catch (err) { setError(err.message); } + } + // Ausgewähltes Ziel des Dialogs + dessen Einheit (Menge wird darin erfasst). const draftTarget = draft.kind === "product" ? products.find((p) => String(p.id) === String(draft.targetId)) @@ -195,12 +226,18 @@ export default function MinStock() { : ) }, { key: "ort", header: "Ort", width: 220, filterText: (r) => r.ort, sortValue: (r) => r.ort, render: (r) => (r.scope === "global" ? {r.ort} : r.ort) }, - { key: "soll", header: "Mindestbestand", width: 150, + { key: "soll", header: "Mindestbestand", width: 190, sortValue: (r) => r.soll ?? -1, render: (r) => (isAdmin ? ( - saveSoll(r, e.target.value)} /> +
+ saveSoll(r, e.target.value)} /> + {r.soll != null && ( + + )} +
) : (r.soll != null ? fmt(r.soll) : "–")) }, { key: "unit", header: "Einheit", width: 120, filterText: (r) => r.unit || "", render: (r) => {r.unit || "–"} },