from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.deps import get_current_active_admin from app.db.session import get_db from app.models.product import Product from app.models.user import User from app.schemas.product import Product as ProductSchema from app.schemas.product import ProductCreate, ProductUpdate router = APIRouter() @router.get("/", response_model=List[ProductSchema]) def read_products( db: Session = Depends(get_db), skip: int = 0, limit: int = 100, category_id: Optional[str] = None, name: Optional[str] = None, min_price: Optional[float] = None, max_price: Optional[float] = None, ) -> Any: """ Retrieve products with optional filtering. """ query = db.query(Product) # Apply filters if provided if category_id: query = query.filter(Product.category_id == category_id) if name: query = query.filter(Product.name.ilike(f"%{name}%")) if min_price is not None: query = query.filter(Product.price >= min_price) if max_price is not None: query = query.filter(Product.price <= max_price) # Only show active products query = query.filter(Product.is_active.is_(True)) products = query.offset(skip).limit(limit).all() return products @router.post("/", response_model=ProductSchema) def create_product( *, db: Session = Depends(get_db), product_in: ProductCreate, current_user: User = Depends(get_current_active_admin), ) -> Any: """ Create new product. Only admin users can create products. """ product = Product(**product_in.dict()) db.add(product) db.commit() db.refresh(product) return product @router.get("/{product_id}", response_model=ProductSchema) def read_product( *, db: Session = Depends(get_db), product_id: str, ) -> Any: """ Get product by ID. """ 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", ) if not product.is_active: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found", ) return product @router.put("/{product_id}", response_model=ProductSchema) def update_product( *, db: Session = Depends(get_db), product_id: str, product_in: ProductUpdate, current_user: User = Depends(get_current_active_admin), ) -> Any: """ Update a product. Only admin users can update products. """ 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", ) update_data = product_in.dict(exclude_unset=True) for field, value in update_data.items(): setattr(product, field, value) db.add(product) db.commit() db.refresh(product) return product @router.delete("/{product_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def delete_product( *, db: Session = Depends(get_db), product_id: str, current_user: User = Depends(get_current_active_admin), ) -> Any: """ Delete a product. Only admin users can delete products. """ 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", ) # Soft delete by setting is_active to False product.is_active = False db.add(product) db.commit() return None