175 lines
5.6 KiB
Python
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))
|