ipns-poc-eval / src /controllers /_rfp_controller.py
Aryan Jain
update column name
9b0a6de
from fastapi import Path
from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel, Field, field_validator
from typing import List, Optional
from uuid import UUID
from src.config import logger
from src.services import RFPService
from datetime import datetime
from src.models import RFPStatus
class RFP(BaseModel):
id: UUID
rfp_number: str
name: str
received_proposals: int
evaluated_count: int
awaiting_evaluation: int
target_award_date: Optional[datetime] = None
ko_name: Optional[str] = None
award_type: Optional[str] = None
google_drive_id: Optional[str] = None
status: RFPStatus
comparative_weights_locked: Optional[bool] = False
created_at: datetime
updated_at: datetime
class ResponseRFP(BaseModel):
status: str
data: Optional[List[RFP]]
class RFPRequest(BaseModel):
rfp_number: str
name: str
received_proposals: int
evaluated_count: int
target_award_date: Optional[datetime] = None
ko_name: Optional[str] = None
award_type: Optional[str] = None
google_drive_id: Optional[str] = None
status: RFPStatus
comparative_weights_locked: Optional[bool] = False
awaiting_evaluation: int
class RFPUpdateRequest(BaseModel):
rfp_number: Optional[str] = None
name: Optional[str] = None
received_proposals: Optional[int] = None
evaluated_count: Optional[int] = None
target_award_date: Optional[datetime] = None
ko_name: Optional[str] = None
award_type: Optional[str] = None
google_drive_id: Optional[str] = None
status: Optional[RFPStatus] = None
comparative_weights_locked: Optional[bool] = None
awaiting_evaluation: Optional[int] = None
class RFPDeleteResponse(BaseModel):
status: str
class RFPController:
def __init__(self):
self.__rfp_service = RFPService
self.router = APIRouter()
self.router.add_api_route(
"/rfps",
self.get_rfps,
methods=["GET"],
response_model=ResponseRFP,
tags=["RFPs"],
)
self.router.add_api_route(
"/rfps/{rfp_id}",
self.get_rfps_by_id,
methods=["GET"],
response_model=ResponseRFP,
tags=["RFPs by ID"],
)
self.router.add_api_route(
"/rfps",
self.create_rfp,
methods=["POST"],
response_model=ResponseRFP,
tags=["RFPs"],
)
self.router.add_api_route(
"/rfps/{rfp_id}",
self.update_rfp,
methods=["PUT"],
response_model=ResponseRFP,
tags=["RFPs by ID"],
)
self.router.add_api_route(
"/rfps/{rfp_id}",
self.delete_rfp,
methods=["DELETE"],
response_model=RFPDeleteResponse,
tags=["RFPs by ID"],
)
async def get_rfps(self, status: Optional[RFPStatus] = Query(None)):
async with self.__rfp_service() as service:
try:
rfps = await service.get_rfps(status=status)
return ResponseRFP(status="success", data=[RFP(**rfp) for rfp in rfps])
except HTTPException as e:
logger.warning(e)
raise e
except Exception as e:
logger.exception(e)
raise HTTPException(status_code=500, detail="Failed to retrieve RFPs.")
async def get_rfps_by_id(self, rfp_id: str = Path(...)):
async with self.__rfp_service() as service:
try:
rfps = await service.get_rfps(rfp_id=rfp_id)
return ResponseRFP(status="success", data=[RFP(**rfp) for rfp in rfps])
except HTTPException as e:
logger.warning(e)
raise e
except Exception as e:
logger.exception(e)
raise HTTPException(status_code=500, detail="Failed to retrieve RFPs.")
async def create_rfp(self, rfp: RFPRequest):
async with self.__rfp_service() as service:
try:
rfp = await service.create_rfp(rfp.model_dump(exclude_unset=True))
return ResponseRFP(status="success", data=[RFP(**rfp)])
except HTTPException as e:
logger.warning(e)
raise e
except Exception as e:
logger.exception(e)
raise HTTPException(status_code=500, detail="Failed to create RFP.")
async def update_rfp(self, rfp: RFPUpdateRequest, rfp_id: str = Path(...)):
async with self.__rfp_service() as service:
try:
rfp = await service.update_rfp(
rfp_id=rfp_id, rfp=rfp.model_dump(exclude_unset=True)
)
return ResponseRFP(status="success", data=[RFP(**rfp)])
except HTTPException as e:
logger.warning(e)
raise e
except Exception as e:
logger.exception(e)
raise HTTPException(status_code=500, detail="Failed to update RFP.")
async def delete_rfp(self, rfp_id: str = Path(...)):
async with self.__rfp_service() as service:
try:
status = await service.delete_rfp(rfp_id)
if not status:
raise HTTPException(status_code=404, detail="RFP not found.")
return RFPDeleteResponse(status="success")
except HTTPException as e:
logger.warning(e)
raise e
except Exception as e:
logger.exception(e)
raise HTTPException(status_code=500, detail="Failed to delete RFP.")