Gruppen: Bestand in der richtigen Einheit, Baumansicht, Gruppen-Spalte

Anzeigefehler: die Gruppenliste klebte immer min_stock_unit_name hinter den
Bestand - auch wenn die Gruppe laengst im Gruppen-Gebinde zaehlt. Aus 790 g bei
einem 190-g-Glas wurde so "4,16 Gramm" statt "4,16 Glaeser". Gerechnet war
richtig, beschriftet falsch.

Ursache war doppelte Logik: MinStock.jsx hatte grpPkgMode/grpFactor/grpUnit
lokal, Groups.jsx gar nicht. Die drei stehen jetzt in units.js und werden von
beiden benutzt. Die Einheiten-Spalte sagt ausserdem, wenn eine Gruppe im
Gebinde zaehlt ("zaehlt in Glaeser a 190 g") und bietet den Weg zurueck an.

Gruppenliste als Baum: eine Gruppe mit zwei Obergruppen erscheint unter beiden -
das ist die ehrliche Darstellung eines Graphen. Jede Zeile traegt ihren PFAD als
Schluessel, damit die vorhandene Baumlogik der DataTable unveraendert zurecht
kommt; die kennt nur einen Elternteil je Zeile, und ein Pfad hat genau einen.
Beim Sortieren/Filtern flacht sie wie gewohnt ab.

"1 Untergruppen" heisst jetzt "1 Untergruppe" - an allen vier Stellen ueber
einen gemeinsamen Helfer (anzahlWort), Web und App.

Lebensmittelliste bekommt eine Spalte "Gruppe" mit Filter. Dafuer liefert
ProductOut jetzt group_name, symmetrisch zu category_name, mit joinedload gegen
N+1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-16 09:40:09 +02:00
parent 158175f693
commit 3de168b598
12 changed files with 148 additions and 31 deletions

View File

@@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
import { api } from "../api";
import Icon from "../components/Icon";
import ShoppingNeedText from "../components/ShoppingNeedText";
import { anzahlWort } from "../units";
export default function ShoppingList() {
const [items, setItems] = useState([]);
@@ -50,7 +51,7 @@ export default function ShoppingList() {
<span className="badge accent">Gruppe</span>
{it.subgroup_count > 0 && (
<span className="badge" title="Bestand und Fehlmenge zählen die Untergruppen mit; Käufe für Untergruppen sind bereits abgezogen.">
inkl. {it.subgroup_count} Untergruppen
inkl. {anzahlWort(it.subgroup_count, "Untergruppe", "Untergruppen")}
</span>
)}
<span className="item-name">{it.name}</span>
@@ -95,7 +96,7 @@ export default function ShoppingList() {
<span className="badge accent">Gruppe</span>
{it.subgroup_count > 0 && (
<span className="badge" title="Bestand und Fehlmenge zählen die Untergruppen mit; Käufe für Untergruppen sind bereits abgezogen.">
inkl. {it.subgroup_count} Untergruppen
inkl. {anzahlWort(it.subgroup_count, "Untergruppe", "Untergruppen")}
</span>
)}
<span className="item-name">{it.name}</span>