Web: Mindestbestand je Lagerort + Einkaufsliste je Ort

- Neuer LocationMinStock-Editor (Zeilen: Lagerort + Menge, separat speichern).
- Produktformular: Abschnitt „Mindestbestand je Lagerort" (Menge in Artikel-
  einheit), zusaetzlich zum Gesamt-Mindestbestand.
- Gruppen: je Gruppe ein Editor „Mindestbestand je Lagerort".
- Einkaufsliste: Abschnitt „Bedarf: <Lagerort>" mit Produkten und Gruppen, die
  am Ort unter dem dort hinterlegten Mindestbestand liegen.
- API-Methoden set*LocationMinStock und shoppingByLocation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-27 07:12:59 +02:00
parent 67bc2dd87d
commit dff7677e50
5 changed files with 199 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import { useConfirm } from "../confirm";
import { useAuth } from "../auth";
import BarcodeList from "../components/BarcodeList";
import Icon from "../components/Icon";
import LocationMinStock from "../components/LocationMinStock";
import { fmt } from "../units";
export default function Groups() {
@@ -11,15 +12,19 @@ export default function Groups() {
const { isAdmin } = useAuth();
const [groups, setGroups] = useState([]);
const [units, setUnits] = useState([]);
const [locations, setLocations] = useState([]);
const [form, setForm] = useState({ name: "", min_stock: "", min_stock_unit_id: "" });
const [selectedId, setSelectedId] = useState(null);
const [error, setError] = useState(null);
async function load() {
try {
const [gs, us] = await Promise.all([api.listGroups(), api.listUnits()]);
const [gs, us, ls] = await Promise.all([
api.listGroups(), api.listUnits(), api.listLocations(),
]);
setGroups(gs);
setUnits(us);
setLocations(ls);
} catch (err) {
setError(err.message);
}
@@ -204,6 +209,30 @@ export default function Groups() {
</section>
)}
{selected && isAdmin && (
<section className="card">
<div className="card-head">
<Icon name="location" />
<h2>Mindestbestand je Lagerort</h2>
</div>
<p className="muted small mt-0">
Bedarf dieser Gruppe je Lagerort (z.B. Ferienhaus, Zuhause), zusätzlich zum
Gesamt-Mindestbestand{selected.min_stock_unit_name ? ` (in ${selected.min_stock_unit_name})` : ""}.
</p>
<LocationMinStock
key={selected.id}
locations={locations}
initial={selected.location_min_stocks || []}
unitLabel={selected.min_stock_unit_name || ""}
onError={setError}
onSave={async (list) => {
await api.setGroupLocationMinStock(selected.id, list);
await load();
}}
/>
</section>
)}
{isAdmin && (
<form className="card" onSubmit={add}>
<div className="card-head"><Icon name="tag" /><h2>Neue Gruppe</h2></div>