from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, status, Form from sqlalchemy.orm import Session import os import shutil from ..db import get_db from ..models import Grave, GraveStatus, Cemetery, GraveHistory from ..schemas import GraveCreate, GraveOut, GraveUpdate from ..dependencies import get_current_user, require_admin from ..config import settings router = APIRouter() @router.post("/", response_model=GraveOut) def create_grave( payload: GraveCreate, db: Session = Depends(get_db), user=Depends(get_current_user), ): cemetery = db.query(Cemetery).get(payload.cemetery_id) if not cemetery: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cemetery not found") grave = Grave(**payload.dict(), created_by=user.id) db.add(grave) db.commit() db.refresh(grave) db.add(GraveHistory(grave_id=grave.id, action="created", actor_id=user.id)) db.commit() return grave @router.get("/", response_model=list[GraveOut]) def list_graves(cemetery_id: int | None = None, db: Session = Depends(get_db)): q = db.query(Grave) if cemetery_id: q = q.filter(Grave.cemetery_id == cemetery_id) return q.order_by(Grave.id.desc()).all() @router.get("/{grave_id}", response_model=GraveOut) def get_grave(grave_id: int, db: Session = Depends(get_db)): grave = db.query(Grave).get(grave_id) if not grave: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found") return grave @router.patch("/{grave_id}", response_model=GraveOut, dependencies=[Depends(require_admin)]) def update_grave(grave_id: int, payload: GraveUpdate, db: Session = Depends(get_db), user=Depends(get_current_user)): grave = db.query(Grave).get(grave_id) if not grave: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found") before_status = grave.status for k, v in payload.dict(exclude_unset=True).items(): setattr(grave, k, v) db.commit() db.refresh(grave) action = "updated" if before_status != grave.status: action = grave.status.value db.add(GraveHistory(grave_id=grave.id, action=action, actor_id=user.id)) db.commit() return grave @router.delete("/{grave_id}", status_code=204, dependencies=[Depends(require_admin)]) def delete_grave(grave_id: int, db: Session = Depends(get_db), user=Depends(get_current_user)): grave = db.query(Grave).get(grave_id) if not grave: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found") db.add(GraveHistory(grave_id=grave.id, action="deleted", actor_id=user.id)) db.delete(grave) db.commit() return None @router.post("/{grave_id}/upload", response_model=GraveOut) def upload_temp_photo(grave_id: int, file: UploadFile = File(...), db: Session = Depends(get_db), user=Depends(get_current_user)): grave = db.query(Grave).get(grave_id) if not grave: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found") os.makedirs(settings.uploads_temp_dir, exist_ok=True) file_path = os.path.join(settings.uploads_temp_dir, f"grave_{grave_id}_{file.filename}") with open(file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) grave.temp_photo_path = file_path db.commit() db.refresh(grave) return grave