# app/modules/inventory/models/inventory.py """ Inventory model for tracking stock at warehouse/bin locations. Each entry represents a quantity of a product at a specific bin location within a warehouse. Products can be scattered across multiple bins. Example: Warehouse: "strassen" Bin: "SA-10-02" Product: GTIN 4007817144145 Quantity: 3 """ from sqlalchemy import Column, ForeignKey, Index, Integer, String, UniqueConstraint from sqlalchemy.orm import relationship from app.core.database import Base from models.database.base import TimestampMixin class Inventory(Base, TimestampMixin): __tablename__ = "inventory" id = Column(Integer, primary_key=True, index=True) product_id = Column(Integer, ForeignKey("products.id"), nullable=False, index=True) store_id = Column(Integer, ForeignKey("stores.id"), nullable=False, index=True) # Location: warehouse + bin warehouse = Column(String, nullable=False, default="strassen", index=True) bin_location = Column(String, nullable=False, index=True) # e.g., "SA-10-02" quantity = Column(Integer, nullable=False, default=0) reserved_quantity = Column(Integer, default=0) # Keep GTIN for reference/reporting (matches Product.gtin) gtin = Column(String, index=True) # Relationships product = relationship("Product", back_populates="inventory_entries") store = relationship("Store") # Constraints __table_args__ = ( UniqueConstraint( "product_id", "warehouse", "bin_location", name="uq_inventory_product_warehouse_bin" ), Index("idx_inventory_store_product", "store_id", "product_id"), Index("idx_inventory_warehouse_bin", "warehouse", "bin_location"), ) def __repr__(self): return f"" @property def available_quantity(self): """Calculate available quantity (total - reserved).""" return max(0, self.quantity - self.reserved_quantity)