from typing import Any, List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app import crud from app.api import deps from app.models.user import User from app.schemas.category import Category, CategoryCreate, CategoryUpdate router = APIRouter() @router.get("/", response_model=List[Category]) def read_categories( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, current_user: User = Depends(deps.get_current_user), ) -> Any: """ Retrieve categories. """ categories = crud.category.get_multi(db, skip=skip, limit=limit) return categories @router.post("/", response_model=Category, status_code=status.HTTP_201_CREATED) def create_category( *, db: Session = Depends(deps.get_db), category_in: CategoryCreate, current_user: User = Depends(deps.get_current_user), ) -> Any: """ Create new category. """ # Check if category with the same name already exists category = crud.category.get_by_name(db, name=category_in.name) if category: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Category with this name already exists", ) category = crud.category.create(db, obj_in=category_in) return category @router.get("/{category_id}", response_model=Category) def read_category( *, db: Session = Depends(deps.get_db), category_id: int, current_user: User = Depends(deps.get_current_user), ) -> Any: """ Get category by ID. """ category = crud.category.get(db, id=category_id) if not category: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Category not found", ) return category @router.put("/{category_id}", response_model=Category) def update_category( *, db: Session = Depends(deps.get_db), category_id: int, category_in: CategoryUpdate, current_user: User = Depends(deps.get_current_user), ) -> Any: """ Update a category. """ category = crud.category.get(db, id=category_id) if not category: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Category not found", ) # Check if name is being changed and if it already exists if category_in.name and category_in.name != category.name: existing_category = crud.category.get_by_name(db, name=category_in.name) if existing_category and existing_category.id != category_id: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Category with this name already exists", ) category = crud.category.update(db, db_obj=category, obj_in=category_in) return category @router.delete("/{category_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None) def delete_category( *, db: Session = Depends(deps.get_db), category_id: int, current_user: User = Depends(deps.get_current_user), ) -> Any: """ Delete a category. """ category = crud.category.get(db, id=category_id) if not category: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Category not found", ) # Check if any items are using this category items = crud.item.get_by_category(db, category_id=category_id, skip=0, limit=1) if items: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot delete category with associated items", ) crud.category.remove(db, id=category_id) return None