# services/procurement/app/api/analytics.py """ Procurement Analytics API - Reporting, statistics, and insights Professional+ tier subscription required """ from fastapi import APIRouter, Depends, HTTPException, Query, Path from typing import Optional, Dict, Any from uuid import UUID from datetime import datetime import structlog from app.services.procurement_service import ProcurementService from shared.routing import RouteBuilder from shared.auth.access_control import analytics_tier_required from shared.auth.decorators import get_current_user_dep from app.core.database import get_db from app.core.config import settings from sqlalchemy.ext.asyncio import AsyncSession route_builder = RouteBuilder('procurement') router = APIRouter(tags=["procurement-analytics"]) logger = structlog.get_logger() def get_procurement_service(db: AsyncSession = Depends(get_db)) -> ProcurementService: """Dependency injection for ProcurementService""" return ProcurementService(db, settings) @router.get( route_builder.build_analytics_route("procurement") ) @analytics_tier_required async def get_procurement_analytics( tenant_id: UUID = Path(..., description="Tenant ID"), start_date: Optional[datetime] = Query(None, description="Start date filter"), end_date: Optional[datetime] = Query(None, description="End date filter"), current_user: Dict[str, Any] = Depends(get_current_user_dep), procurement_service: ProcurementService = Depends(get_procurement_service) ): """Get procurement analytics dashboard for a tenant (Professional+ tier required)""" try: # Call the service method to get actual analytics data analytics_data = await procurement_service.get_procurement_analytics( tenant_id=tenant_id, start_date=start_date, end_date=end_date ) logger.info("Retrieved procurement analytics", tenant_id=tenant_id) return analytics_data except Exception as e: logger.error("Failed to get procurement analytics", error=str(e), tenant_id=tenant_id) raise HTTPException(status_code=500, detail=f"Failed to get procurement analytics: {str(e)}") @router.get( route_builder.build_analytics_route("procurement/trends") ) @analytics_tier_required async def get_procurement_trends( tenant_id: UUID = Path(..., description="Tenant ID"), days: int = Query(7, description="Number of days to retrieve trends for", ge=1, le=90), current_user: Dict[str, Any] = Depends(get_current_user_dep), procurement_service: ProcurementService = Depends(get_procurement_service) ): """Get procurement time-series trends for charts (Professional+ tier required)""" try: # Call the service method to get trends data trends_data = await procurement_service.get_procurement_trends( tenant_id=tenant_id, days=days ) logger.info("Retrieved procurement trends", tenant_id=tenant_id, days=days) return trends_data except Exception as e: logger.error("Failed to get procurement trends", error=str(e), tenant_id=tenant_id) raise HTTPException(status_code=500, detail=f"Failed to get procurement trends: {str(e)}")