import uuid from fastapi import APIRouter, Depends, HTTPException, Query from fastapi.responses import JSONResponse from pydantic import BaseModel, Field from sqlalchemy.ext.asyncio import AsyncSession from typing import Optional from db_setup import get_session from department.views import DepartmentService from users.permissions import PermissionTag, require_permission from dotenv import load_dotenv load_dotenv() router = APIRouter() class DepartmentCreate(BaseModel): name: str = Field(min_length=1, max_length=120) short_code: str = Field(min_length=1, max_length=10) subtitle: str | None = Field(default=None, max_length=160) description: str | None = None is_active: bool = True department_head_id: uuid.UUID | None = None parent_department_id: uuid.UUID | None = None location: list[str] = Field(default_factory=list) class DepartmentUpdate(BaseModel): name: str | None = Field(default=None, min_length=1, max_length=120) short_code: str | None = Field(default=None, min_length=1, max_length=10) subtitle: str | None = Field(default=None, max_length=160) description: str | None = None is_active: bool | None = None department_head_id: uuid.UUID | None = None parent_department_id: uuid.UUID | None = None location: list[str] | None = None @router.get("/department/fetch") async def fetch_departments( current_user: dict = Depends(require_permission(PermissionTag.DEPARTMENT_VIEW)), record_id: str | None = Query(None), search: str | None = Query(None), is_active: bool | None = Query(None), top: int | None = Query(None, ge=1), skip: int = Query(0, ge=0), session: AsyncSession = Depends(get_session), ): try: service = DepartmentService(session=session) if record_id is not None: item = await service.get_department(record_id) return JSONResponse(content={"data": item, "total": 1, "status_code": 200}) items, total = await service.get_departments(top, skip, search, is_active) return JSONResponse(content={"data": items, "total": total, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/department/create") async def create_department( body: DepartmentCreate, current_user: dict = Depends(require_permission(PermissionTag.DEPARTMENT_CREATE)), session: AsyncSession = Depends(get_session), ): try: service = DepartmentService(session=session) item = await service.create_department(body.model_dump(), current_user.get("id")) return JSONResponse(status_code=201, content={"data": item, "status_code": 201}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.put("/department/update") async def update_department( body: DepartmentUpdate, record_id: str = Query(...), current_user: dict = Depends(require_permission(PermissionTag.DEPARTMENT_EDIT)), session: AsyncSession = Depends(get_session), ): try: service = DepartmentService(session=session) item = await service.update_department( record_id, body.model_dump(exclude_unset=True), current_user.get("id") ) return JSONResponse(content={"data": item, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/department/heads/fetch") async def fetch_department_heads( role_id:Optional[int] = Query(5), top: Optional[int]=Query(None, ge=1), skip: Optional[int]=Query(0, ge=0), search: Optional[str]=Query(None), current_user: dict = Depends( require_permission( PermissionTag.DEPARTMENT_CREATE, PermissionTag.DEPARTMENT_EDIT, require_all=False, ) ), session: AsyncSession = Depends(get_session), ): try: service = DepartmentService(session=session) items = await service.get_head_options(role_id,top,skip,search) return JSONResponse(content={"data": items, "total": len(items), "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/department/locations/fetch") async def fetch_department_locations( search: Optional[str]=Query(None), current_user: dict = Depends( require_permission( PermissionTag.DEPARTMENT_CREATE, PermissionTag.DEPARTMENT_EDIT, require_all=False, ) ), session: AsyncSession = Depends(get_session), ): try: service = DepartmentService(session=session) items = await service.get_location_options(search) return JSONResponse(content={"data": items, "total": len(items), "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/department/names") async def fetch_department_names( search: Optional[str]=Query(None), current_user: dict = Depends( require_permission( PermissionTag.DEPARTMENT_VIEW, PermissionTag.JOB_BOARD_CREATE, PermissionTag.JOBS_EDIT, require_all=False, ) ), session: AsyncSession = Depends(get_session), ): try: service = DepartmentService(session=session) items = await service.get_department_names(search) return JSONResponse(content={"data": items, "total": len(items), "status_code": 200}) except Exception as e: raise HTTPException(status_code=500, detail=str(e))