from typing import Any from fastapi import APIRouter, Body, Depends, HTTPException, status from sqlalchemy.orm import Session from app.core.database import get_db from app.dependencies.auth import get_current_admin, get_current_seller from app.models.product import Product from app.models.user import User from app.schemas.product import Product as ProductSchema from app.services.inventory import InventoryService router = APIRouter() @router.put("/products/{product_id}/stock", response_model=ProductSchema) async def update_product_stock( product_id: str, quantity: int = Body(..., ge=0), db: Session = Depends(get_db), current_user: User = Depends(get_current_seller) ): """ Update the stock quantity of a product. Seller can only update their own products. Admin can update any product. """ # Check if product exists and belongs to the current user product = db.query(Product).filter(Product.id == product_id).first() if not product: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" ) # Check ownership if current_user.id != product.seller_id and not any(role.name == "admin" for role in current_user.roles): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions to update this product" ) # Get current stock current_stock = product.stock_quantity # Calculate change if quantity > current_stock: # Add stock quantity_change = quantity - current_stock product = InventoryService.update_stock(db, product_id, quantity_change, "add") elif quantity < current_stock: # Remove stock quantity_change = current_stock - quantity product = InventoryService.update_stock(db, product_id, quantity_change, "subtract") else: # No change return product return product @router.put("/products/{product_id}/stock/add", response_model=ProductSchema) async def add_stock( product_id: str, quantity: int = Body(..., gt=0), db: Session = Depends(get_db), current_user: User = Depends(get_current_seller) ): """ Add stock to a product. """ # Check if product exists and belongs to the current user product = db.query(Product).filter(Product.id == product_id).first() if not product: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" ) # Check ownership if current_user.id != product.seller_id and not any(role.name == "admin" for role in current_user.roles): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions to update this product" ) product = InventoryService.update_stock(db, product_id, quantity, "add") return product @router.put("/products/{product_id}/stock/subtract", response_model=ProductSchema) async def subtract_stock( product_id: str, quantity: int = Body(..., gt=0), db: Session = Depends(get_db), current_user: User = Depends(get_current_seller) ): """ Subtract stock from a product. """ # Check if product exists and belongs to the current user product = db.query(Product).filter(Product.id == product_id).first() if not product: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" ) # Check ownership if current_user.id != product.seller_id and not any(role.name == "admin" for role in current_user.roles): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions to update this product" ) product = InventoryService.update_stock(db, product_id, quantity, "subtract") return product @router.get("/low-stock", response_model=list[ProductSchema]) async def get_low_stock_products( threshold: int = 5, category_id: str | None = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_seller) ): """ Get products with low stock. Seller can only see their own products. Admin can see all products. """ # For sellers, always filter by seller_id seller_id = None if any(role.name == "admin" for role in current_user.roles) else current_user.id products = InventoryService.get_low_stock_products( db, threshold, category_id, seller_id ) return products @router.put("/bulk-update", response_model=list[ProductSchema]) async def bulk_update_stock( updates: list[dict[str, Any]] = Body(...), db: Session = Depends(get_db), current_user: User = Depends(get_current_admin) ): """ Update stock for multiple products at once (admin only). """ products = InventoryService.bulk_update_stock(db, updates) return products