from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.orm import Session from app.api.deps import current_user, require_home_member, require_home_write from app.db.session import get_db from app.models.entities import Product, ShoppingItem, User from app.schemas.common import Message, ProductIn, ShoppingItemIn, ShoppingItemOut from app.services.audit import audit router = APIRouter() @router.get("", response_model=list[ShoppingItemOut]) def list_items(home_id: str, user: User = Depends(current_user), db: Session = Depends(get_db)) -> list[ShoppingItem]: require_home_member(home_id, db, user) return list(db.scalars(select(ShoppingItem).where(ShoppingItem.home_id == home_id).order_by(ShoppingItem.checked, ShoppingItem.created_at.desc())).all()) @router.post("", response_model=ShoppingItemOut, status_code=201) def create_item(home_id: str, payload: ShoppingItemIn, user: User = Depends(current_user), db: Session = Depends(get_db)) -> ShoppingItem: require_home_write(home_id, db, user) item = ShoppingItem(home_id=home_id, **payload.model_dump()) db.add(item) audit(db, user, "shopping.create", "shopping_item", item.id) db.commit() db.refresh(item) return item @router.patch("/{item_id}", response_model=ShoppingItemOut) def update_item(home_id: str, item_id: str, payload: dict, user: User = Depends(current_user), db: Session = Depends(get_db)) -> ShoppingItem: require_home_write(home_id, db, user) item = db.get(ShoppingItem, item_id) if not item or item.home_id != home_id: raise HTTPException(status_code=404, detail="Item not found") for field in ["name", "category", "quantity", "unit", "checked"]: if field in payload: setattr(item, field, payload[field]) db.commit() return item @router.post("/{item_id}/move-to-inventory", response_model=Message) def move_to_inventory(home_id: str, item_id: str, payload: ProductIn | None = None, user: User = Depends(current_user), db: Session = Depends(get_db)) -> Message: require_home_write(home_id, db, user) item = db.get(ShoppingItem, item_id) if not item or item.home_id != home_id: raise HTTPException(status_code=404, detail="Item not found") data = payload.model_dump() if payload else {"name": item.name, "category": item.category, "quantity": item.quantity, "unit": item.unit} db.add(Product(home_id=home_id, created_by_id=user.id, **data)) item.checked = True audit(db, user, "shopping.move_to_inventory", "shopping_item", item.id) db.commit() return Message(message="Moved to inventory") @router.delete("/{item_id}", response_model=Message) def delete_item(home_id: str, item_id: str, user: User = Depends(current_user), db: Session = Depends(get_db)) -> Message: require_home_write(home_id, db, user) item = db.get(ShoppingItem, item_id) if not item or item.home_id != home_id: raise HTTPException(status_code=404, detail="Item not found") db.delete(item) db.commit() return Message(message="Item deleted")