Mindestbestand in jeder angelegten Einheit erfassbar (und gemerkt)
- Produktformular: Auswahl aller verwalteten Einheiten passender Art (plus Packungen), inkl. Umrechnung beim Wechsel. - Die gewaehlte Erfassungseinheit wird gespeichert (products.min_stock_unit_id / min_stock_in_packages) und exakt so wieder angezeigt - vorher wurde sie aus der Produkteinheit abgeleitet. - ProductOut liefert min_stock_display + min_stock_unit_label; Produkttabelle zeigt den Mindestbestand damit in der erfassten Einheit mit Einheit dahinter. - Migration: ADD COLUMN IF NOT EXISTS fuer die zwei neuen Spalten. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -29,8 +29,8 @@ export default function ProductForm() {
|
||||
const [error, setError] = useState(null);
|
||||
const [info, setInfo] = useState(null);
|
||||
const [busy, setBusy] = useState(false);
|
||||
// Einheit für die Mindestbestand-Eingabe: "unit" (gewählte Einheit) oder "package".
|
||||
const [minUnit, setMinUnit] = useState("unit");
|
||||
// Einheit für die Mindestbestand-Eingabe: "package" oder die ID einer Einheit.
|
||||
const [minUnit, setMinUnit] = useState("");
|
||||
const [warnDays, setWarnDays] = useState(7);
|
||||
|
||||
const selectedUnit = units.find((u) => String(u.id) === String(form.unit_id)) || null;
|
||||
@@ -48,19 +48,20 @@ export default function ProductForm() {
|
||||
}
|
||||
|
||||
// Faktor, mit dem der angezeigte Mindestbestand in Basiseinheiten umgerechnet wird.
|
||||
function minFactor(mode, pkgSize, uFactor) {
|
||||
if (mode === "package") return Number(pkgSize) > 0 ? Number(pkgSize) : 1;
|
||||
return uFactor || 1;
|
||||
// sel ist "package" oder die ID einer verwalteten Einheit.
|
||||
function minFactor(sel, pkgSize, unitList) {
|
||||
if (sel === "package") return Number(pkgSize) > 0 ? Number(pkgSize) : 1;
|
||||
const u = unitList.find((x) => String(x.id) === String(sel));
|
||||
return u ? u.factor : 1;
|
||||
}
|
||||
|
||||
function changeMinUnit(newUnit) {
|
||||
if (form.min_stock !== "" && newUnit !== minUnit) {
|
||||
const oldF = minFactor(minUnit, form.package_size, unitFactor);
|
||||
const newF = minFactor(newUnit, form.package_size, unitFactor);
|
||||
const base = Number(form.min_stock) * oldF;
|
||||
set("min_stock", String(base / newF));
|
||||
function changeMinUnit(newSel) {
|
||||
if (form.min_stock !== "" && newSel !== minUnit) {
|
||||
const oldF = minFactor(minUnit, form.package_size, units);
|
||||
const newF = minFactor(newSel, form.package_size, units);
|
||||
set("min_stock", String((Number(form.min_stock) * oldF) / newF));
|
||||
}
|
||||
setMinUnit(newUnit);
|
||||
setMinUnit(newSel);
|
||||
}
|
||||
|
||||
function applySuggestion(s, groupsList, unitList) {
|
||||
@@ -120,9 +121,13 @@ export default function ProductForm() {
|
||||
const uid = p.display_unit_id
|
||||
? String(p.display_unit_id)
|
||||
: canonicalUnitId(us, p.base_unit);
|
||||
const uf = us.find((u) => String(u.id) === uid)?.factor || 1;
|
||||
const mode = p.package_size && p.package_size > 0 ? "package" : "unit";
|
||||
const f = mode === "package" ? p.package_size : uf;
|
||||
// Erfassungseinheit des Mindestbestands wiederherstellen.
|
||||
const mode = p.min_stock_in_packages
|
||||
? "package"
|
||||
: p.min_stock_unit_id
|
||||
? String(p.min_stock_unit_id)
|
||||
: uid;
|
||||
const f = minFactor(mode, p.package_size, us);
|
||||
setMinUnit(mode);
|
||||
setForm({
|
||||
barcode: p.barcode || "", name: p.name, brand: p.brand || "",
|
||||
@@ -148,9 +153,10 @@ export default function ProductForm() {
|
||||
}, [id]);
|
||||
|
||||
function buildPayload() {
|
||||
const sel = minUnit || form.unit_id;
|
||||
let minBase = null;
|
||||
if (form.min_stock !== "") {
|
||||
minBase = Number(form.min_stock) * minFactor(minUnit, form.package_size, unitFactor);
|
||||
minBase = Number(form.min_stock) * minFactor(sel, form.package_size, units);
|
||||
}
|
||||
return {
|
||||
barcode: form.barcode || null,
|
||||
@@ -160,6 +166,8 @@ export default function ProductForm() {
|
||||
unit_id: form.unit_id === "" ? null : Number(form.unit_id),
|
||||
package_size: form.package_size === "" ? null : Number(form.package_size),
|
||||
min_stock: minBase,
|
||||
min_stock_unit_id: sel === "package" || sel === "" ? null : Number(sel),
|
||||
min_stock_in_packages: sel === "package",
|
||||
group_id: form.group_id === "" ? null : Number(form.group_id),
|
||||
};
|
||||
}
|
||||
@@ -257,9 +265,11 @@ export default function ProductForm() {
|
||||
<div className="field-inline">
|
||||
<input type="number" step="any" value={form.min_stock}
|
||||
onChange={(e) => set("min_stock", e.target.value)} disabled={readOnly} placeholder="z.B. 2" />
|
||||
<select value={minUnit} onChange={(e) => changeMinUnit(e.target.value)}
|
||||
disabled={readOnly} style={{ maxWidth: 150, marginTop: 0 }}>
|
||||
<option value="unit">{unitName || "Einheit"}</option>
|
||||
<select value={minUnit || form.unit_id} onChange={(e) => changeMinUnit(e.target.value)}
|
||||
disabled={readOnly} style={{ maxWidth: 160, marginTop: 0 }}>
|
||||
{units
|
||||
.filter((u) => !selectedUnit || u.kind === selectedUnit.kind)
|
||||
.map((u) => <option key={u.id} value={u.id}>{u.name}</option>)}
|
||||
{form.package_size && <option value="package">Packung(en)</option>}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user