import { useEffect, useMemo, useState } from "react"; import { api } from "../api"; import { useAuth } from "../auth"; import { useConfirm } from "../confirm"; import Icon from "../components/Icon"; import { locationOptions, locationPathById } from "../locationPath"; import LocationSelect from "../components/LocationSelect"; import { gruppenOptionen } from "../groupGraph"; import { anzahlWort, fmt, gebinde, grpFactor, grpPkgMode, grpUnit, kindShort } from "../units"; // Anzeigeeinheit eines Produkts: die im Formular gewählte Einheit (Gramm, // Milliliter, Stück) – NICHT die Packung. „1 Packung" ist nichtssagend, weil eine // Packung 500 g, 1 kg oder 25 ml sein kann; deshalb rechnen wir alles in die // echte Einheit um. dispFactor = Basiseinheiten je Anzeigeeinheit. const dispFactor = (p) => (p.unit_factor && p.unit_factor > 0 ? p.unit_factor : 1); const dispLabel = (p) => (p.unit_name || "Stück"); // Mindestbestand gibt es nur bei Charge-Artikeln: Lebensmittel und // Verbrauchsgegenstände (bulk). „Menge je Lagerort" und Einzelstücke nicht. const canHaveMin = (p) => p.tracking !== "object" || p.bulk === true; // Gebinde-Umschaltung: hat das Produkt eine Packungsgröße, lässt sich der // Mindestbestand wahlweise in Packungen (Glas/Dose) statt in g/ml erfassen. const hasPkg = (p) => !!(p.package_size && p.package_size > 0); const pkgMode = (p) => hasPkg(p) && !!p.min_stock_in_packages; // Basiseinheiten je gewählter Erfassungseinheit (Packung ODER Anzeigeeinheit). const effFactor = (p) => (pkgMode(p) ? p.package_size : dispFactor(p)); // Einheitslabel der gewählten Erfassungseinheit, passend zur Menge (1 Glas / 3 Gläser). const effUnit = (p, menge = 1) => (pkgMode(p) ? gebinde(menge, p.package_label || "Packung") : dispLabel(p)); // Gruppen rechnen in ihrer verwalteten Einheit ODER im Gruppen-Gebinde – // grpPkgMode/grpFactor/grpUnit stehen in units.js, weil Groups.jsx sie genauso // braucht (und ohne sie den Bestand falsch beschriftet hat). // „Überall" ist der Ort NULL. Im saveSoll(r, e.target.value)} /> ) : {fmt(r.soll)}} {/* Einheit: bei Packungsartikeln und Gruppen mit Einheit umschaltbar. */} {isAdmin && r.kind === "product" && hasPkg(r.entity) ? ( ) : isAdmin && g && g.min_stock_unit_id ? ( ) : ( {r.unit || "–"} )} {r.bestand != null ? `Bestand ${fmt(r.bestand)} ${r.bestandUnit || ""}` : ""} {isAdmin && ( <> moveRow(r, id)} /> )} {/* Ohne Adminrechte bleiben die letzten beiden Spalten leer, damit die Zeilen trotzdem fluchten. */} {!isAdmin && (<>)} ); } return (

Mindestbestände

Was soll wo immer da sein? „Überall“ heißt: egal wo, Hauptsache im Haus — Käufe für einen Lagerort decken ihn mit ab.
{isAdmin && ( )}
{error &&
{error}
} {isAdmin && draft && (

Mindestbestand hinzufügen

{draft.kind === "product" && draftTarget && hasPkg(draftTarget) && (
)}
)} {isAdmin && gebindeDlg && (

Gruppen-Gebinde festlegen

Wie viel zählt „1 Packung“ dieser Gruppe? Ein Richtwert – die Produkte der Gruppe dürfen unterschiedlich große Packungen haben.

)} {loading &&

Wird geladen…

} {!loading && abschnitte.map((a) => (

{a.label}

{a.zeilen.length} {a.zeilen.length === 1 ? "Eintrag" : "Einträge"}
{a.zeilen.length === 0 && (

Hier ist noch nichts hinterlegt.

)} {a.zeilen.map(zeile)} {isAdmin && (
)}
))}
); }