Gruppen-Gebinde: Mindestbestand/Bestand in Packungen (Backend)

Gruppen bekommen ein eigenes Richt-Gebinde (package_size/label) plus
min_stock_in_packages. Weil die Produkte einer Gruppe unterschiedlich
große Packungen haben können (Pesto 99 g vs. 160 g), legt die Gruppe einen
gemeinsamen Richtwert fest (1 Glas ≈ X g).

- Neuer Helfer group_min_context() zentralisiert, in welcher Einheit der
  Gruppen-Mindestbestand zaehlt (Gebinde ODER verwaltete Einheit).
- Einkaufsliste (gesamt + je Ort), Dashboard-Bedarf und GroupOut nutzen ihn;
  need.text kommt so als 'x Glaeser (y g)'.
- update_group rechnet bestehende Werte beim Umschalten der Einheit um, damit
  der physische Bedarf gleich bleibt.
- Migration: groups.package_size/package_label/min_stock_in_packages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-07 18:38:12 +02:00
parent 28785b0a10
commit ecc1570100
8 changed files with 168 additions and 128 deletions

View File

@@ -44,7 +44,7 @@ from ..schemas import (
FlowPoint,
TimelinePoint,
)
from ..services.conversion import article_unit
from ..services.conversion import article_unit, group_min_context
from ..services.stock import current_stock
from .settings import get_expiry_warning_days
@@ -354,12 +354,9 @@ def stats(
if current_stock(db, product.id) < product.min_stock:
bedarf += 1
for group in db.query(Group).filter(Group.min_stock.isnot(None), Group.min_stock > 0):
unit = group.min_stock_unit
produkte = list(group.products)
summe = float(sum(current_stock(db, p.id) for p in produkte))
if unit is not None:
summe /= unit.factor or 1.0
if summe < group.min_stock:
ctx = group_min_context(group)
summe_base = float(sum(current_stock(db, p.id) for p in ctx.matching))
if summe_base < group.min_stock * ctx.divisor:
bedarf += 1
return DashboardStats(