from typing import Any, List from fastapi import APIRouter, Body, Depends, HTTPException, Path, Query from sqlalchemy.orm import Session from app import crud, models, schemas from app.api import deps router = APIRouter() @router.get("/", response_model=List[schemas.Inventory]) def list_inventory( db: Session = Depends(deps.get_db), skip: int = Query(0, description="Skip first N items"), limit: int = Query(100, description="Limit the number of items returned"), low_stock_only: bool = Query(False, description="Only return low stock items"), low_stock_threshold: int = Query(10, description="Threshold for low stock"), current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Retrieve inventory items with optional filtering """ if low_stock_only: items = crud.inventory.get_low_stock( db, threshold=low_stock_threshold, skip=skip, limit=limit ) else: items = crud.inventory.get_multi(db, skip=skip, limit=limit) return items @router.get("/{product_id}", response_model=schemas.Inventory) def get_product_inventory( *, db: Session = Depends(deps.get_db), product_id: int = Path(..., description="The ID of the product"), current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Get inventory for a specific product """ # Verify product exists product = crud.product.get(db, id=product_id) if not product: raise HTTPException(status_code=404, detail="Product not found") inventory = crud.inventory.get_by_product_id(db, product_id=product_id) if not inventory: raise HTTPException(status_code=404, detail="Inventory not found for this product") return inventory @router.post("/", response_model=schemas.Inventory) def create_inventory( *, db: Session = Depends(deps.get_db), inventory_in: schemas.InventoryCreate, current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Create inventory record for a product """ # Verify product exists product = crud.product.get(db, id=inventory_in.product_id) if not product: raise HTTPException(status_code=404, detail="Product not found") # Check if inventory already exists for this product existing = crud.inventory.get_by_product_id(db, product_id=inventory_in.product_id) if existing: raise HTTPException( status_code=400, detail="Inventory already exists for this product", ) inventory = crud.inventory.create(db, obj_in=inventory_in) return inventory @router.put("/{inventory_id}", response_model=schemas.Inventory) def update_inventory( *, db: Session = Depends(deps.get_db), inventory_id: int = Path(..., description="The ID of the inventory record to update"), inventory_in: schemas.InventoryUpdate, current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Update an inventory record """ inventory = crud.inventory.get(db, id=inventory_id) if not inventory: raise HTTPException(status_code=404, detail="Inventory not found") inventory = crud.inventory.update(db, db_obj=inventory, obj_in=inventory_in) return inventory @router.put("/{inventory_id}/adjust", response_model=schemas.Inventory) def adjust_inventory( *, db: Session = Depends(deps.get_db), inventory_id: int = Path(..., description="The ID of the inventory record to adjust"), quantity_change: int = Body(..., description="Amount to adjust (positive to add, negative to subtract)"), current_user: models.User = Depends(deps.get_current_active_superuser), ) -> Any: """ Adjust inventory quantity """ inventory = crud.inventory.get(db, id=inventory_id) if not inventory: raise HTTPException(status_code=404, detail="Inventory not found") # Check if adjustment would result in negative quantity if inventory.quantity + quantity_change < 0: raise HTTPException( status_code=400, detail="Adjustment would result in negative inventory", ) inventory = crud.inventory.update_quantity( db, inventory_id=inventory_id, quantity_change=quantity_change ) return inventory