HR-ATS-Portal/backend/reports/app.py

175 lines
5.6 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import JSONResponse, Response
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession
from db_setup import get_session
from reports.views import Report
from users.permissions import PermissionTag, require_permission
router = APIRouter()
class SavedReportCreate(BaseModel):
name: str
report_type: str
description: str | None = None
filters: dict | None = None
class SavedReportUpdate(BaseModel):
name: str | None = None
report_type: str | None = None
description: str | None = None
filters: dict | None = None
class ReportRunRequest(BaseModel):
record_id: str | None = None
report_type: str | None = None
filters: dict | None = None
@router.get("/reports/fetch")
async def fetch_reports(
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_VIEW)),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
data, total = await service.get_reports(current_user)
return JSONResponse(content={"data": data, "total": total, "status_code": 200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/reports/create")
async def create_report(
payload: SavedReportCreate,
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_CREATE)),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
data = await service.create_report(payload.model_dump(exclude_unset=True), current_user)
return JSONResponse(content={"data": data, "status_code": 200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.patch("/reports/update")
async def update_report(
payload: SavedReportUpdate,
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_EDIT)),
record_id: str = Query(...),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
data = await service.update_report(
record_id, payload.model_dump(exclude_unset=True), current_user
)
return JSONResponse(content={"data": data, "status_code": 200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/reports/delete")
async def delete_report(
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_DELETE)),
record_id: str = Query(...),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
data = await service.delete_report(record_id, current_user)
return JSONResponse(content={"data": data, "status_code": 200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/reports/run")
async def run_report(
payload: ReportRunRequest,
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_VIEW)),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
data = await service.run(
current_user,
record_id=payload.record_id,
report_type=payload.report_type,
filters=payload.filters,
)
return JSONResponse(content={"data": data, "total": data["row_count"], "status_code": 200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/reports/export")
async def export_report(
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_EXPORT)),
record_id: str | None = Query(None),
report_type: str | None = Query(None),
from_date: str | None = Query(None),
to_date: str | None = Query(None),
window_days: int | None = Query(None),
department: str | None = Query(None),
recruiter_id: str | None = Query(None),
months: int | None = Query(None),
top: int | None = Query(None),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
filename, body = await service.export_csv(
current_user,
record_id=record_id,
report_type=report_type,
filters={
"from_date": from_date,
"to_date": to_date,
"window_days": window_days,
"department": department,
"recruiter_id": recruiter_id,
"months": months,
"top": top,
},
)
return Response(
content=body,
media_type="text/csv; charset=utf-8",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/reports/runs/fetch")
async def fetch_report_runs(
current_user: dict = Depends(require_permission(PermissionTag.REPORTS_VIEW)),
record_id: str = Query(...),
session: AsyncSession = Depends(get_session),
):
try:
service = Report(session=session)
data = await service.get_runs(record_id, current_user)
return JSONResponse(content={"data": data, "total": len(data), "status_code": 200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))