from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List from database import get_db from models.product import Product, Category, ProductOption, ProductIngredient from models.user import User from schemas.product import ( ProductCreate, ProductUpdate, ProductOut, CategoryCreate, CategoryUpdate, CategoryOut, ) from routers.deps import get_current_user, require_manager router = APIRouter() # ── Categories ─────────────────────────────────────────────────────────────── @router.get("/categories", response_model=List[CategoryOut]) def list_categories(db: Session = Depends(get_db), user: User = Depends(get_current_user)): return db.query(Category).order_by(Category.sort_order).all() @router.post("/categories", response_model=CategoryOut, status_code=status.HTTP_201_CREATED) def create_category(body: CategoryCreate, db: Session = Depends(get_db), user: User = Depends(require_manager)): cat = Category(**body.model_dump()) db.add(cat) db.commit() db.refresh(cat) return cat @router.put("/categories/{category_id}", response_model=CategoryOut) def update_category(category_id: int, body: CategoryUpdate, db: Session = Depends(get_db), user: User = Depends(require_manager)): cat = db.query(Category).filter(Category.id == category_id).first() if not cat: raise HTTPException(status_code=404, detail="Category not found") for field, value in body.model_dump(exclude_none=True).items(): setattr(cat, field, value) db.commit() db.refresh(cat) return cat @router.delete("/categories/{category_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_category(category_id: int, db: Session = Depends(get_db), user: User = Depends(require_manager)): cat = db.query(Category).filter(Category.id == category_id).first() if not cat: raise HTTPException(status_code=404, detail="Category not found") db.delete(cat) db.commit() # ── Products ────────────────────────────────────────────────────────────────── @router.get("/", response_model=List[ProductOut]) def list_products(db: Session = Depends(get_db), user: User = Depends(get_current_user)): return db.query(Product).filter(Product.is_available == True).all() @router.post("/", response_model=ProductOut, status_code=status.HTTP_201_CREATED) def create_product(body: ProductCreate, db: Session = Depends(get_db), user: User = Depends(require_manager)): data = body.model_dump(exclude={"options", "ingredients"}) product = Product(**data) db.add(product) db.flush() for opt in body.options: db.add(ProductOption(product_id=product.id, **opt.model_dump())) for ing in body.ingredients: db.add(ProductIngredient(product_id=product.id, **ing.model_dump())) db.commit() db.refresh(product) return product @router.put("/{product_id}", response_model=ProductOut) def update_product(product_id: int, body: ProductUpdate, db: Session = Depends(get_db), user: User = Depends(require_manager)): product = db.query(Product).filter(Product.id == product_id).first() if not product: raise HTTPException(status_code=404, detail="Product not found") for field, value in body.model_dump(exclude_none=True).items(): setattr(product, field, value) db.commit() db.refresh(product) return product @router.delete("/{product_id}", status_code=status.HTTP_204_NO_CONTENT) def deactivate_product(product_id: int, db: Session = Depends(get_db), user: User = Depends(require_manager)): product = db.query(Product).filter(Product.id == product_id).first() if not product: raise HTTPException(status_code=404, detail="Product not found") product.is_available = False db.commit()