kamau1's picture
Fix report endpoints to be async for compatibility with permission decorator
93e3d85
"""
REPORTS Endpoints
Provides structured data generation and CSV exports for:
- SLA Compliance
- User Performance
- Financial Summaries
- Inventory Usage
"""
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session
from datetime import datetime
from typing import Any
from app.api.deps import get_db, get_current_user
from app.models.user import User
from app.schemas.report import (
ReportFilter,
ReportResponse,
ReportMetaData,
ReportFormat
)
from app.services.report_service import ReportService
from app.core.permissions import require_permission
router = APIRouter()
@router.post("/generate", response_model=ReportResponse)
@require_permission("view_reports")
async def generate_report(
filters: ReportFilter,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
) -> Any:
"""
Generate a JSON report for visualization/tables.
**Report Types:**
- `sla_compliance`: Tickets vs Due Dates
- `user_performance`: Aggregated timesheet stats
- `financial_summary`: Revenue & Expenses ledger
- `inventory_usage`: Items installed/consumed
**Performance:**
- Designed for sub-2 second response times.
- Uses aggregated warehouse tables (Timesheets) where possible.
"""
try:
data = ReportService.generate_report_data(db, filters, current_user)
return ReportResponse(
meta=ReportMetaData(
generated_at=datetime.utcnow(),
record_count=len(data),
filters_applied=filters.model_dump(),
report_type=filters.report_type
),
data=data
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Report generation failed: {str(e)}"
)
@router.post("/export")
@require_permission("export_reports")
async def export_report(
filters: ReportFilter,
format: ReportFormat = ReportFormat.CSV,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""
Generate and download a report file (CSV).
Designed to work with the same filters as the `/generate` endpoint.
Returns a File Download stream.
"""
if format != ReportFormat.CSV:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Only CSV export is currently supported."
)
try:
# 1. Generate Data
data = ReportService.generate_report_data(db, filters, current_user)
# 2. Convert to CSV Stream
csv_file = ReportService.generate_csv_export(data)
# 3. Create Filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M")
filename = f"{filters.report_type}_{timestamp}.csv"
return StreamingResponse(
csv_file,
media_type="text/csv",
headers={"Content-Disposition": f"attachment; filename={filename}"}
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Export failed: {str(e)}"
)