"""Einkaufsliste: Fehlmenge als Gebinde-Leitangabe (auf ganze Packungen 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() def user(db): person = User(username="tester", password_hash="x", role=Role.admin) db.add(person) db.commit() db.refresh(person) return person def _gramm(db) -> Unit: return db.query(Unit).filter(Unit.name == "Gramm").one() def test_produkt_bedarf_in_ganzen_gebinden(db, user): """500 g fehlen bei 195-g-Gläsern -> 3 Gläser (aufgerundet), 500 g als Hinweis.""" db.add(PackageType(singular="Glas", plural="Gläser")) db.add(Product(name="Pesto", base_unit=BaseUnit.gram, package_size=195, package_label="Glas", min_stock=500)) db.commit() # kein Bestand -> es fehlt der volle Mindestbestand (item,) = shopping_list(db=db, _=user) assert item.need is not None assert item.need.is_package is True assert item.need.count == 3 # ceil(500 / 195) assert item.need.text == "3 Gläser" assert item.need.hint == "500 g" 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=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=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 == "450 g" # 3 * 150 g def test_gruppe_ohne_gebinde_bleibt_basiseinheit(db, user): """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, group=gruppe)) db.commit() (item,) = group_shopping_list(db=db, _=user) assert item.need is not None 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