Verwaltbare Einheiten mit Umrechnung + Chargen bearbeiten + gezieltes Auslagern
Einheiten (neu):
- Tabelle units (name, kind=count|weight|volume, factor, is_builtin); eingebaut
Stueck/Gramm/Kilogramm/Milliliter/Liter, Admin kann eigene anlegen (z.B. Pfund=500g).
- Bestaende bleiben intern in kanonischer Basis (Stueck/Gramm/Milliliter);
Product.display_unit_id und Group.min_stock_unit_id als nullable FKs.
- Neuer Umrechnungs-Service (services/conversion.py) ersetzt die feste Einheitenlogik;
Ein-/Auslagern und Gruppen-Mindestbestand rechnen ueber den Faktor.
- Gruppen-Mindestbestand mit Einheit; Gruppenbestand summiert nur Produkte
passender Art. Neue Verwaltungsseite "Einheiten" (Admin).
- Schonende Migration beim Start: ADD COLUMN IF NOT EXISTS (Postgres), damit
bestehende Installationen ihre Daten behalten.
Chargen:
- PATCH /lots/{id} und DELETE /lots/{id}: Menge/MHD korrigieren, Charge loeschen
(wird als Korrektur-Bewegung protokolliert). Bearbeitung im Produktdetail.
Auslagern:
- Optionales lot_id: gezielt aus einer bestimmten Charge/MHD abbuchen statt FEFO;
Auswahl-Dropdown in der Auslagern-Seite.
Sonstiges: Roadmap aktualisiert, Tests fuer die Umrechnung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ from sqlalchemy.pool import StaticPool
|
||||
|
||||
from app.database import Base
|
||||
from app.models import BaseUnit, Product
|
||||
from app.seed import ensure_builtin_units
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@@ -17,6 +18,7 @@ def db():
|
||||
Base.metadata.create_all(bind=engine)
|
||||
TestingSession = sessionmaker(bind=engine, autoflush=False, autocommit=False)
|
||||
session = TestingSession()
|
||||
ensure_builtin_units(session) # Einheiten (Gramm, Kilogramm, …) für Umrechnung
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
|
||||
43
backend/tests/test_conversion.py
Normal file
43
backend/tests/test_conversion.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import pytest
|
||||
|
||||
from app.models import BaseUnit, Product
|
||||
from app.services.conversion import ConversionError, to_base
|
||||
|
||||
|
||||
def test_base_unit(db, rice):
|
||||
assert to_base(db, rice, 200, "Gramm") == 200
|
||||
assert to_base(db, rice, 200, "g") == 200 # Kürzel-Alias
|
||||
|
||||
|
||||
def test_kilogram_converts_to_grams(db, rice):
|
||||
assert to_base(db, rice, 1, "Kilogramm") == 1000
|
||||
assert to_base(db, rice, 2.5, "kg") == 2500
|
||||
|
||||
|
||||
def test_package_uses_package_size(db, rice):
|
||||
# rice: package_size = 500 g
|
||||
assert to_base(db, rice, 3, "package") == 1500
|
||||
|
||||
|
||||
def test_wrong_kind_rejected(db, rice):
|
||||
# rice ist ein Gewichts-Produkt -> Volumeneinheit passt nicht
|
||||
with pytest.raises(ConversionError):
|
||||
to_base(db, rice, 1, "Liter")
|
||||
|
||||
|
||||
def test_unknown_unit_rejected(db, rice):
|
||||
with pytest.raises(ConversionError):
|
||||
to_base(db, rice, 1, "Eimer")
|
||||
|
||||
|
||||
def test_volume_product(db):
|
||||
milk = Product(name="Milch", base_unit=BaseUnit.milliliter, package_size=1000)
|
||||
db.add(milk)
|
||||
db.commit()
|
||||
assert to_base(db, milk, 1, "Liter") == 1000
|
||||
assert to_base(db, milk, 500, "ml") == 500
|
||||
|
||||
|
||||
def test_non_positive_quantity_rejected(db, rice):
|
||||
with pytest.raises(ConversionError):
|
||||
to_base(db, rice, 0, "Gramm")
|
||||
Reference in New Issue
Block a user