148 lines
4.8 KiB
Python

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