FEFO: angebrochene Packung immer zuerst
Ich hatte das nach dem frueheren wirksamen Datum sortiert, sodass eine ungeoeffnete Packung mit knappem MHD vor einer offenen drankam. Das ist falsch herum: Das MHD einer geschlossenen Packung ist konservativ und wird real meist ueberlebt, eine offene verdirbt dagegen tatsaechlich. Und wer die zweite aufmacht, waehrend die erste offen steht, hat am Ende zwei angebrochene. Angebrochenes kommt also immer zuerst; innerhalb beider Gruppen gilt weiter FEFO ueber das naehere von MHD und Verbrauchsdatum. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fa5a2bc4fa
commit
afacf01f11
@@ -634,13 +634,16 @@ def verbrauchen(
|
|||||||
|
|
||||||
|
|
||||||
def _fefo_lots(db: Session, product_id: int) -> list[Lot]:
|
def _fefo_lots(db: Session, product_id: int) -> list[Lot]:
|
||||||
"""Lots eines Produkts, sortiert nach dem WIRKSAMEN Datum (NULL zuletzt).
|
"""Lots eines Produkts: Angebrochenes zuerst, dann nach dem wirksamen Datum.
|
||||||
|
|
||||||
Wirksam ist das frühere aus MHD und Verbrauchsdatum (``Lot.faellig_am``).
|
Eine offene Packung wird immer vor einer geschlossenen geleert, auch wenn
|
||||||
Eine angebrochene Packung kommt damit meist von selbst zuerst, weil ihr
|
die geschlossene früher datiert ist. Das aufgedruckte MHD einer
|
||||||
Verbrauchsdatum näher liegt – aber eine ungeöffnete Charge, die morgen
|
ungeöffneten Packung ist konservativ und wird real meist überlebt – eine
|
||||||
abläuft, geht vor. Erst bei gleichem Datum wird das Angebrochene vorgezogen,
|
offene verdirbt dagegen tatsächlich. Und wer eine zweite Packung aufmacht,
|
||||||
damit nicht eine zweite Packung aufgeht, während eine offen ist.
|
während die erste offen steht, hat am Ende zwei angebrochene.
|
||||||
|
|
||||||
|
Innerhalb beider Gruppen gilt weiter FEFO über das nähere von MHD und
|
||||||
|
Verbrauchsdatum (``Lot.faellig_am``), NULL zuletzt.
|
||||||
"""
|
"""
|
||||||
lots = (
|
lots = (
|
||||||
db.query(Lot)
|
db.query(Lot)
|
||||||
@@ -652,9 +655,9 @@ def _fefo_lots(db: Session, product_id: int) -> list[Lot]:
|
|||||||
return sorted(
|
return sorted(
|
||||||
lots,
|
lots,
|
||||||
key=lambda lot: (
|
key=lambda lot: (
|
||||||
|
lot.opened_on is None,
|
||||||
lot.faellig_am is None,
|
lot.faellig_am is None,
|
||||||
lot.faellig_am or date.max,
|
lot.faellig_am or date.max,
|
||||||
lot.opened_on is None,
|
|
||||||
lot.id,
|
lot.id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ def test_zustand_ohne_daten_bleibt_no_date(db):
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# FEFO
|
# FEFO
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
def test_fefo_nimmt_das_fruehere_wirksame_datum(db, milch):
|
def test_angebrochenes_wird_zuerst_geleert(db, milch):
|
||||||
spaet = _lot(db, milch, 1000, best_before=date.today() + timedelta(days=30))
|
spaet = _lot(db, milch, 1000, best_before=date.today() + timedelta(days=30))
|
||||||
offen = _lot(db, milch, 500, best_before=date.today() + timedelta(days=30),
|
offen = _lot(db, milch, 500, best_before=date.today() + timedelta(days=30),
|
||||||
opened_on=date.today(), consume_by=date.today() + timedelta(days=2))
|
opened_on=date.today(), consume_by=date.today() + timedelta(days=2))
|
||||||
@@ -152,22 +152,28 @@ def test_fefo_nimmt_das_fruehere_wirksame_datum(db, milch):
|
|||||||
assert reihenfolge == [offen.id, spaet.id]
|
assert reihenfolge == [offen.id, spaet.id]
|
||||||
|
|
||||||
|
|
||||||
def test_knappes_mhd_geht_vor_der_offenen_packung(db, milch):
|
def test_angebrochenes_geht_auch_vor_knappem_mhd(db, milch):
|
||||||
"""Verderb schlägt Bequemlichkeit: Was morgen abläuft, kommt zuerst."""
|
"""Offen zuerst, selbst wenn eine geschlossene Packung früher datiert ist.
|
||||||
|
|
||||||
|
Das MHD einer ungeöffneten Packung ist konservativ und wird real meist
|
||||||
|
überlebt; eine offene verdirbt dagegen tatsächlich. Und wer die zweite
|
||||||
|
aufmacht, während die erste offen steht, hat am Ende zwei angebrochene.
|
||||||
|
"""
|
||||||
morgen = _lot(db, milch, 1000, best_before=date.today() + timedelta(days=1))
|
morgen = _lot(db, milch, 1000, best_before=date.today() + timedelta(days=1))
|
||||||
offen = _lot(db, milch, 500, opened_on=date.today(),
|
offen = _lot(db, milch, 500, opened_on=date.today(),
|
||||||
consume_by=date.today() + timedelta(days=5))
|
consume_by=date.today() + timedelta(days=5))
|
||||||
|
|
||||||
reihenfolge = [lot.id for lot in _fefo_lots(db, milch.id)]
|
reihenfolge = [lot.id for lot in _fefo_lots(db, milch.id)]
|
||||||
|
|
||||||
assert reihenfolge == [morgen.id, offen.id]
|
assert reihenfolge == [offen.id, morgen.id]
|
||||||
|
|
||||||
|
|
||||||
def test_bei_gleichem_datum_gewinnt_das_angebrochene(db, milch):
|
def test_unter_den_angebrochenen_gilt_weiter_fefo(db, milch):
|
||||||
gleich = date.today() + timedelta(days=3)
|
spaet = _lot(db, milch, 500, opened_on=date.today(),
|
||||||
zu = _lot(db, milch, 1000, best_before=gleich)
|
consume_by=date.today() + timedelta(days=5))
|
||||||
offen = _lot(db, milch, 500, opened_on=date.today(), consume_by=gleich)
|
frueh = _lot(db, milch, 500, opened_on=date.today(),
|
||||||
|
consume_by=date.today() + timedelta(days=1))
|
||||||
|
|
||||||
reihenfolge = [lot.id for lot in _fefo_lots(db, milch.id)]
|
reihenfolge = [lot.id for lot in _fefo_lots(db, milch.id)]
|
||||||
|
|
||||||
assert reihenfolge == [offen.id, zu.id]
|
assert reihenfolge == [frueh.id, spaet.id]
|
||||||
|
|||||||
Reference in New Issue
Block a user