Backend: Mindestbestand je Lagerort für Produkte und Gruppen
Zusaetzlich zum globalen Mindestbestand: je Produkt und je Gruppe laesst sich pro
Lagerort ein Mindestbestand (in Artikeleinheiten) hinterlegen.
- Neue Tabellen product_location_min_stock / group_location_min_stock.
- PUT /products/{id}/location-min-stock und /groups/{id}/location-min-stock
ersetzen die Eintraege; Produkt-/Gruppen-Ausgabe liefert sie mit.
- Neue Einkaufsliste GET /shopping-list/by-location: Bedarfe je Ort (Produkte +
Gruppen), Bestand-am-Ort gegen Mindestbestand-am-Ort.
- Helfer location_stock_base (Bestand je Ort). 4 neue Tests, Suite 144 gruen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -131,6 +131,9 @@ class Group(Base):
|
||||
|
||||
products: Mapped[list[Product]] = relationship(back_populates="group")
|
||||
min_stock_unit: Mapped[Unit | None] = relationship()
|
||||
location_min_stocks: Mapped[list["GroupLocationMinStock"]] = relationship(
|
||||
cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class Location(Base):
|
||||
@@ -247,6 +250,9 @@ class Product(Base):
|
||||
field_values: Mapped[list[ProductFieldValue]] = relationship(
|
||||
back_populates="product", cascade="all, delete-orphan"
|
||||
)
|
||||
location_min_stocks: Mapped[list["ProductLocationMinStock"]] = relationship(
|
||||
cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class ApiToken(Base):
|
||||
@@ -562,3 +568,46 @@ class ItemDocument(Base):
|
||||
# Nur bei Bedarf laden (Download): sonst zoege jede Item-Liste die Belege mit.
|
||||
data: Mapped[bytes] = mapped_column(LargeBinary, nullable=False, deferred=True)
|
||||
uploaded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
|
||||
|
||||
|
||||
class ProductLocationMinStock(Base):
|
||||
"""Mindestbestand eines Produkts an EINEM Lagerort (in Artikeleinheiten).
|
||||
|
||||
Zusätzlich zum globalen ``Product.min_stock``: so laesst sich derselbe Artikel
|
||||
an mehreren Orten getrennt fuehren (z.B. 5 zuhause, 3 im Ferienhaus).
|
||||
"""
|
||||
|
||||
__tablename__ = "product_location_min_stock"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
product_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("products.id", ondelete="CASCADE"), nullable=False, index=True
|
||||
)
|
||||
location_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("locations.id", ondelete="CASCADE"), nullable=False
|
||||
)
|
||||
# In Artikeleinheiten (Packungen/Stueck), wie in der Produktliste gezaehlt.
|
||||
min_stock: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
|
||||
location: Mapped[Location] = relationship()
|
||||
|
||||
__table_args__ = (UniqueConstraint("product_id", "location_id", name="uq_prod_loc_min"),)
|
||||
|
||||
|
||||
class GroupLocationMinStock(Base):
|
||||
"""Mindestbestand einer Gruppe an EINEM Lagerort (in der Gruppen-Einheit)."""
|
||||
|
||||
__tablename__ = "group_location_min_stock"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
group_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("groups.id", ondelete="CASCADE"), nullable=False, index=True
|
||||
)
|
||||
location_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("locations.id", ondelete="CASCADE"), nullable=False
|
||||
)
|
||||
min_stock: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
|
||||
location: Mapped[Location] = relationship()
|
||||
|
||||
__table_args__ = (UniqueConstraint("group_id", "location_id", name="uq_group_loc_min"),)
|
||||
|
||||
Reference in New Issue
Block a user