148 lines
4.8 KiB
Python
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
|