from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy.orm import Session from app.db.database import get_db from app.models.product import Product as ProductModel from app.schemas.product import Product, ProductCreate, ProductUpdate from app.crud import product as product_crud router = APIRouter() @router.get("/", response_model=List[Product]) def get_products( category: Optional[str] = None, skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=100), db: Session = Depends(get_db), ): """ Retrieve all products with optional filtering by category. """ products = product_crud.get_products(db, skip=skip, limit=limit, category=category) return products @router.post("/", response_model=Product, status_code=status.HTTP_201_CREATED) def create_product( product: ProductCreate, db: Session = Depends(get_db), ): """ Create a new product. """ db_product = product_crud.get_product_by_sku(db, sku=product.sku) if db_product: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Product with SKU {product.sku} already exists", ) return product_crud.create_product(db=db, product=product) @router.get("/{product_id}", response_model=Product) def get_product( product_id: int, db: Session = Depends(get_db), ): """ Get a specific product by ID. """ db_product = product_crud.get_product(db, product_id=product_id) if db_product is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Product with ID {product_id} not found", ) return db_product @router.put("/{product_id}", response_model=Product) def update_product( product_id: int, product_update: ProductUpdate, db: Session = Depends(get_db), ): """ Update a product. """ db_product = product_crud.get_product(db, product_id=product_id) if db_product is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Product with ID {product_id} not found", ) # If SKU is being updated, check if it already exists if product_update.sku is not None and product_update.sku != db_product.sku: existing_product = product_crud.get_product_by_sku(db, sku=product_update.sku) if existing_product: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Product with SKU {product_update.sku} already exists", ) return product_crud.update_product(db=db, db_product=db_product, product_update=product_update) @router.delete("/{product_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_product( product_id: int, db: Session = Depends(get_db), ): """ Delete a product. """ db_product = product_crud.get_product(db, product_id=product_id) if db_product is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Product with ID {product_id} not found", ) product_crud.delete_product(db=db, db_product=db_product) return None