from typing import Any, List from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app import crud, models, schemas from app.api import deps from app.models.stock_movement import MovementType router = APIRouter() @router.get("/", response_model=List[schemas.StockMovement]) def read_stock_movements( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Retrieve stock movements. """ stock_movements = crud.stock_movement.get_multi(db, skip=skip, limit=limit) return stock_movements @router.post("/", response_model=schemas.StockMovement) def create_stock_movement( *, db: Session = Depends(deps.get_db), stock_movement_in: schemas.StockMovementCreate, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Create new stock movement and update product stock levels. """ # Check if product exists product = crud.product.get(db, id=stock_movement_in.product_id) if not product: raise HTTPException(status_code=404, detail="Product not found") # For outgoing stock, make sure we have enough if stock_movement_in.movement_type in [MovementType.SALE, MovementType.ADJUSTMENT] and stock_movement_in.quantity > 0: if product.current_stock < stock_movement_in.quantity: raise HTTPException( status_code=400, detail=f"Not enough stock available. Current stock: {product.current_stock}", ) # Create stock movement and update product stock level stock_movement = crud.stock_movement.create_with_product_update( db, obj_in=stock_movement_in, created_by=current_user.id ) return stock_movement @router.get("/{stock_movement_id}", response_model=schemas.StockMovement) def read_stock_movement( *, db: Session = Depends(deps.get_db), stock_movement_id: str, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Get stock movement by ID. """ stock_movement = crud.stock_movement.get(db, id=stock_movement_id) if not stock_movement: raise HTTPException(status_code=404, detail="Stock movement not found") return stock_movement @router.get("/by-product/{product_id}", response_model=List[schemas.StockMovement]) def read_stock_movements_by_product( *, db: Session = Depends(deps.get_db), product_id: str, skip: int = 0, limit: int = 100, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Get stock movements by product. """ stock_movements = crud.stock_movement.get_by_product( db, product_id=product_id, skip=skip, limit=limit ) return stock_movements @router.get("/by-type/{movement_type}", response_model=List[schemas.StockMovement]) def read_stock_movements_by_type( *, db: Session = Depends(deps.get_db), movement_type: MovementType, skip: int = 0, limit: int = 100, current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: """ Get stock movements by movement type. """ stock_movements = crud.stock_movement.get_by_movement_type( db, movement_type=movement_type, skip=skip, limit=limit ) return stock_movements