Kategorien-Anteile: einstellbare Kategorie-Tiefe (Unterkategorien zusammenfassen)
/dashboard/by-category bekommt depth: rollt jede Artikel-Kategorie auf ihren Vorfahren der gewuenschten Stufe hoch (1 = oberste Ebene), ohne depth zaehlt jede zugeordnete Kategorie einzeln (feinste). Neue Karten-Konfig select Kategorie-Tiefe (Feinste / oberste / bis 2. / bis 3. Stufe). KartenConfig zeigt jetzt auch bei select den Hinweis. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -386,17 +386,45 @@ def expiry_split(
|
||||
|
||||
@router.get("/by-category", response_model=list[CategoryShare])
|
||||
def by_category(
|
||||
db: Session = Depends(get_db), _: User = Depends(get_current_user)
|
||||
depth: int | None = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: User = Depends(get_current_user),
|
||||
) -> list[CategoryShare]:
|
||||
"""Artikeleinheiten je Kategorie, zusätzlich nach Ablaufzustand aufgeteilt."""
|
||||
"""Artikeleinheiten je Kategorie, zusätzlich nach Ablaufzustand aufgeteilt.
|
||||
|
||||
``depth`` fasst tiefe Unterkategorien zu ihrer Oberkategorie auf der
|
||||
gewünschten Stufe zusammen (1 = oberste Ebene). Ohne ``depth`` zählt jede
|
||||
Kategorie so, wie sie dem Artikel zugeordnet ist (feinste Auflösung).
|
||||
"""
|
||||
heute = date.today()
|
||||
warnfrist = get_expiry_warning_days(db)
|
||||
namen = {c.id: c.name for c in db.query(Category).all()}
|
||||
kategorien = db.query(Category).all()
|
||||
namen = {c.id: c.name for c in kategorien}
|
||||
eltern = {c.id: c.parent_id for c in kategorien}
|
||||
|
||||
# Kategorie auf die gewünschte Tiefe hochrollen (Vorfahr auf Stufe ``depth``).
|
||||
rollup_cache: dict[int | None, int | None] = {}
|
||||
|
||||
def rollup(cid: int | None) -> int | None:
|
||||
if depth is None or cid is None:
|
||||
return cid
|
||||
if cid in rollup_cache:
|
||||
return rollup_cache[cid]
|
||||
pfad: list[int] = []
|
||||
cur, gesehen = cid, set()
|
||||
while cur is not None and cur not in gesehen:
|
||||
pfad.append(cur)
|
||||
gesehen.add(cur)
|
||||
cur = eltern.get(cur)
|
||||
pfad.reverse() # Wurzel zuerst
|
||||
ziel = pfad[min(max(depth, 1) - 1, len(pfad) - 1)]
|
||||
rollup_cache[cid] = ziel
|
||||
return ziel
|
||||
|
||||
leer = lambda: {"article_units": 0.0, "ok": 0.0, "soon": 0.0, "expired": 0.0, "no_date": 0.0}
|
||||
eimer: dict[int | None, dict] = defaultdict(leer)
|
||||
for product, menge, zustand in _bestand_beitraege(db, heute, warnfrist):
|
||||
topf = eimer[product.category_id]
|
||||
topf = eimer[rollup(product.category_id)]
|
||||
topf["article_units"] += menge
|
||||
topf[zustand] += menge
|
||||
|
||||
|
||||
Reference in New Issue
Block a user