diff --git a/web/src/pages/MinStock.jsx b/web/src/pages/MinStock.jsx index f337ffa..ed1c0d9 100644 --- a/web/src/pages/MinStock.jsx +++ b/web/src/pages/MinStock.jsx @@ -17,6 +17,8 @@ const articleLabel = (p) => p.package_label || p.unit_name || "Stück"; * Bedarfe je Lagerort, inline editierbar. Ergänzt die einzelnen Produkt-/Gruppen- * Formulare um einen Überblick an einem Ort. */ +const EMPTY_DRAFT = { kind: "product", targetId: "", scope: "global", locId: "", menge: "" }; + export default function MinStock() { const { isAdmin } = useAuth(); const [products, setProducts] = useState([]); @@ -24,6 +26,9 @@ export default function MinStock() { const [locations, setLocations] = useState([]); const [categories, setCategories] = useState([]); const [error, setError] = useState(null); + // „+ hinzufügen"-Dialog: Ziel (Produkt/Gruppe) → Geltung (Gesamt/Lagerort) → Menge. + const [showAdd, setShowAdd] = useState(false); + const [draft, setDraft] = useState(EMPTY_DRAFT); async function load() { try { @@ -109,6 +114,53 @@ export default function MinStock() { } 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)) + : groups.find((g) => String(g.id) === String(draft.targetId)); + const draftUnit = draft.kind === "product" + ? (draftTarget ? articleLabel(draftTarget) : "") + : (draftTarget ? (draftTarget.min_stock_unit_name || "Stück") : ""); + + function resetAdd() { + setShowAdd(false); + setDraft(EMPTY_DRAFT); + } + + async function saveNew() { + setError(null); + const roh = String(draft.menge).trim().replace(",", "."); + const num = roh === "" ? null : Number(roh); + if (!draft.targetId) { setError("Bitte ein Ziel wählen."); return; } + if (num == null || Number.isNaN(num) || num <= 0) { setError("Bitte eine Menge größer 0 angeben."); return; } + if (draft.scope === "loc" && !draft.locId) { setError("Bitte einen Lagerort wählen."); return; } + try { + if (draft.kind === "product") { + const p = draftTarget; + if (draft.scope === "global") { + // Menge in der Artikeleinheit erfasst → in Basiseinheiten speichern, + // wie beim Inline-Editieren ohne bestehenden Wert. + await api.updateProduct(p.id, { + min_stock: Math.round(num * articleUnit(p)), + min_stock_in_packages: (p.package_size || 0) > 0, + min_stock_unit_id: null, + }); + } else { + await api.setProductLocationMinStock(p.id, mergeLoc(p.location_min_stocks, draft.locId, num)); + } + } else { + const g = draftTarget; + if (draft.scope === "global") { + await api.updateGroup(g.id, { min_stock: num }); + } else { + await api.setGroupLocationMinStock(g.id, mergeLoc(g.location_min_stocks, draft.locId, num)); + } + } + resetAdd(); + await load(); + } catch (err) { setError(err.message); } + } + const columns = [ { key: "art", header: "Art", width: 96, filterText: (r) => (r.kind === "group" ? "Gruppe" : "Produkt"), render: (r) => {r.kind === "group" ? "Gruppe" : "Produkt"} }, @@ -146,8 +198,81 @@ export default function MinStock() { Gesamt- und Lagerort-Bedarfe von Produkten und Gruppen an einem Ort{isAdmin ? " – Werte direkt editierbar" : ""}. + {isAdmin && ( + + )} {error &&