MHD wahlweise nur mit Monat und Jahr (Backend)

Auf vielen Verpackungen steht nur "09/2026". Bisher liess sich ausschliesslich
ein Tagesdatum erfassen, was zu erfundener Genauigkeit fuehrte.

Entwurf: best_before bleibt ein echtes DATE, damit FEFO, die Ablauf-Abfragen
und alle bestehenden Sortierungen unveraendert weiterlaufen. Eine Monatsangabe
wird auf den Monatsletzten gelegt - die uebliche Lesart bei Lebensmitteln, und
die sichere Richtung, weil nicht zu frueh aussortiert wird. Zusaetzlich merkt
sich jede Charge in best_before_precision, wie genau die Angabe war; davon
haengt allein die Anzeige ab. Am Produkt steht in date_precision, welche
Genauigkeit dort ueblich ist (Voreinstellung der Eingabe, z.B. Konserven).

Bewusst als VARCHAR statt als DB-Enum gespeichert: So laesst sich die Spalte
auf bestehenden Tabellen per ADD COLUMN IF NOT EXISTS nachziehen, ohne vorher
einen neuen Postgres-Typ anzulegen. Beide Spalten haben ein Server-Default
'day', damit vorhandene Chargen unveraendert gueltig bleiben.

Export/Import bleiben verlustfrei: Das JSON-Backup fuehrt beide Felder mit. Die
CSV bekommt bewusst keine neue Spalte, damit die Datei in Excel unveraendert
bedienbar bleibt - stattdessen wird eine Monatsangabe als "09/2026" geschrieben
und beim Import an der Schreibweise wieder erkannt ("09/2026", "2026-09",
"09.2026"); tagesgenaue Formate werden weiterhin gelesen.

Beim Korrigieren einer Charge werden MHD und Genauigkeit gemeinsam ausgewertet,
sonst bliebe ein auf Monat umgestellter Wert auf dem alten Tag stehen.

Getestet: 40 pytest-Tests gruen (17 neue zu Monatsletztem, Schaltjahr,
Einlagern, Export-Schreibweise und Import-Erkennung). Zusaetzlich ein
Durchlauf ueber die echte API: Produkt mit Monatsvorgabe anlegen und aendern,
Sammel-Einlagern mit gemischten Genauigkeiten, Chargen wieder auslesen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-22 17:48:11 +02:00
parent d680aeff0e
commit eed7c9e1de
11 changed files with 247 additions and 7 deletions

View File

@@ -16,6 +16,7 @@ from ..schemas import (
LotUpdate,
)
from ..services.conversion import ConversionError
from ..services.dates import clean_precision, normalize_best_before
from ..services.stock import (
StockError,
check_in,
@@ -41,6 +42,7 @@ def stock_checkin(
quantity=payload.quantity,
unit=payload.unit,
best_before=payload.best_before,
best_before_precision=payload.best_before_precision.value,
location_id=payload.location_id,
user=user,
note=payload.note,
@@ -76,6 +78,7 @@ def stock_checkin_batch(
quantity=line.quantity,
unit=payload.unit,
best_before=line.best_before,
best_before_precision=line.best_before_precision.value,
location_id=line.location_id,
user=user,
note=payload.note,
@@ -160,6 +163,19 @@ def update_lot(
raise HTTPException(status.HTTP_404_NOT_FOUND, "Charge nicht gefunden")
data = payload.model_dump(exclude_unset=True)
# MHD und Genauigkeit hängen zusammen: Wird eines von beiden angefasst, muss
# der gespeicherte Tag neu bestimmt werden (Monatsangabe = Monatsletzter).
if "best_before" in data or "best_before_precision" in data:
precision = (
clean_precision(data["best_before_precision"])
if "best_before_precision" in data
else lot.best_before_precision
)
best_before = data["best_before"] if "best_before" in data else lot.best_before
data["best_before"] = normalize_best_before(best_before, precision)
data["best_before_precision"] = precision
old_quantity = lot.quantity
for field, value in data.items():
setattr(lot, field, value)