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:
@@ -1,11 +1,17 @@
|
||||
"""Einkaufsliste: Fehlmenge als Gebinde-Leitangabe (auf ganze Packungen
|
||||
aufgerundet) mit der Basiseinheit als kleinem Hinweis – „3 Gläser (500 g)".
|
||||
aufgerundet) mit der Basiseinheit als kleinem Hinweis – „3 Gläser (450 g)".
|
||||
|
||||
Produkte tragen ihre eigene Packungsgröße; Gruppen legen ein eigenes
|
||||
Gruppen-Gebinde als Richtwert fest (weil ihre Produkte unterschiedlich große
|
||||
Packungen haben können).
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from app.models import BaseUnit, Group, PackageType, Product, Role, Unit, User
|
||||
from app.routers.groups import update_group
|
||||
from app.routers.views import group_shopping_list, shopping_list
|
||||
from app.schemas import GroupUpdate
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@@ -36,27 +42,28 @@ def test_produkt_bedarf_in_ganzen_gebinden(db, user):
|
||||
assert item.need.hint == "500 g"
|
||||
|
||||
|
||||
def test_gruppe_mit_einheitlichem_gebinde(db, user):
|
||||
"""Eine Gruppe, deren Produkte alle dasselbe Gebinde haben, zeigt es auch."""
|
||||
def test_gruppe_mit_gruppen_gebinde(db, user):
|
||||
"""Gruppe mit eigenem Richt-Gebinde (1 Glas ≈ 150 g), Mindestbestand 3 Gläser."""
|
||||
db.add(PackageType(singular="Glas", plural="Gläser"))
|
||||
gruppe = Group(name="Pesto alla Genovese", min_stock=500, min_stock_unit=_gramm(db))
|
||||
gruppe = Group(name="Pesto alla Genovese", min_stock=3, min_stock_unit=_gramm(db),
|
||||
package_size=150, package_label="Glas", min_stock_in_packages=True)
|
||||
db.add(gruppe)
|
||||
db.add(Product(name="Pesto Barilla", base_unit=BaseUnit.gram, package_size=195,
|
||||
package_label="Glas", group=gruppe))
|
||||
db.commit()
|
||||
db.add(Product(name="Pesto Barilla", base_unit=BaseUnit.gram, package_size=99, group=gruppe))
|
||||
db.commit() # kein Bestand -> es fehlen 3 Gläser (450 g)
|
||||
|
||||
(item,) = group_shopping_list(db=db, _=user)
|
||||
assert item.need is not None
|
||||
assert item.need.is_package is True
|
||||
assert item.need.count == 3
|
||||
assert item.need.text == "3 Gläser"
|
||||
assert item.need.hint == "500 g"
|
||||
assert item.need.hint == "450 g" # 3 * 150 g
|
||||
|
||||
|
||||
def test_gruppe_ohne_gebinde_bleibt_basiseinheit(db, user):
|
||||
"""Ohne (einheitliches) Gebinde bleibt es bei der Basiseinheit – kein Rateraten."""
|
||||
"""Ohne aktives Gruppen-Gebinde bleibt es bei der verwalteten Einheit."""
|
||||
gruppe = Group(name="Mehl", min_stock=500, min_stock_unit=_gramm(db))
|
||||
db.add(gruppe)
|
||||
db.add(Product(name="Mehl 405", base_unit=BaseUnit.gram, package_size=None, group=gruppe))
|
||||
db.add(Product(name="Mehl 405", base_unit=BaseUnit.gram, group=gruppe))
|
||||
db.commit()
|
||||
|
||||
(item,) = group_shopping_list(db=db, _=user)
|
||||
@@ -64,3 +71,20 @@ def test_gruppe_ohne_gebinde_bleibt_basiseinheit(db, user):
|
||||
assert item.need.is_package is False
|
||||
assert item.need.text == "500 Gramm"
|
||||
assert item.need.hint == ""
|
||||
|
||||
|
||||
def test_gruppe_umschalten_haelt_physischen_bedarf(db, user):
|
||||
"""Umschalten g -> Gebinde rechnet den gespeicherten Wert um (500 g / 150 = 3,33 Glas)."""
|
||||
gruppe = Group(name="Pesto", min_stock=500, min_stock_unit=_gramm(db))
|
||||
db.add(gruppe)
|
||||
db.add(Product(name="Pesto Barilla", base_unit=BaseUnit.gram, group=gruppe))
|
||||
db.commit()
|
||||
|
||||
update_group(
|
||||
group_id=gruppe.id,
|
||||
payload=GroupUpdate(min_stock_in_packages=True, package_size=150, package_label="Glas"),
|
||||
db=db, _=user,
|
||||
)
|
||||
db.refresh(gruppe)
|
||||
assert gruppe.min_stock_in_packages is True
|
||||
assert gruppe.min_stock == pytest.approx(500 / 150, abs=0.01) # ~3,33 Gläser
|
||||
|
||||
Reference in New Issue
Block a user