from uuid import UUID from fastapi import APIRouter, Depends, Query, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.middleware.auth import get_current_user, RoleChecker from app.schemas.leave import LeaveCreate, LeaveUpdate from app.services import leaves as leave_service router = APIRouter(prefix="/leaves", tags=["Leaves"]) @router.get("") async def list_leaves( manager_id: str | None = Query(None), status: str | None = Query(None), page: int = Query(1, ge=1), page_size: int = Query(25, ge=1, le=100), db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """List leave records. Managers see only their own.""" return await leave_service.get_leaves( db=db, user_id=current_user["user_id"], role=current_user["role"], manager_id=manager_id, status=status, page=page, page_size=page_size, ) @router.post("") async def create_leave( data: LeaveCreate, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Create a leave record. Director can create for anyone; manager only for self.""" try: leave = await leave_service.create_leave( db=db, data=data.model_dump(), submitted_by=UUID(current_user["user_id"]), role=current_user["role"], ) return { "id": str(leave.id), "manager_id": str(leave.manager_id), "leave_type": leave.leave_type, "start_date": str(leave.start_date), "end_date": str(leave.end_date), "reason": leave.reason, "submitted_by": str(leave.submitted_by), } except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) @router.put("/{leave_id}") async def update_leave( leave_id: UUID, data: LeaveUpdate, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Update a leave record.""" try: leave = await leave_service.update_leave( db=db, leave_id=leave_id, data=data.model_dump(exclude_none=True), user_id=UUID(current_user["user_id"]), role=current_user["role"], ) return { "id": str(leave.id), "manager_id": str(leave.manager_id), "leave_type": leave.leave_type, "start_date": str(leave.start_date), "end_date": str(leave.end_date), "reason": leave.reason, } except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) except ValueError as e: raise HTTPException(status_code=404 if "不存在" in str(e) else 400, detail=str(e)) @router.delete("/{leave_id}") async def delete_leave( leave_id: UUID, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Delete a leave record.""" try: ok = await leave_service.delete_leave( db=db, leave_id=leave_id, user_id=UUID(current_user["user_id"]), role=current_user["role"], ) if not ok: raise HTTPException(status_code=404, detail="请假记录不存在") return {"status": "deleted"} except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) @router.get("/overview") async def leave_overview( reference_date: str | None = Query(None), db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Get weekly leave overview for dashboard card.""" from datetime import date ref = date.fromisoformat(reference_date) if reference_date else None return await leave_service.get_leave_overview( db=db, user_id=current_user["user_id"], role=current_user["role"], reference_date=ref, )