from typing import Optional from fastapi import APIRouter, Depends, Path, Query from fastapi.security import HTTPAuthorizationCredentials from common.models.gmodel import UserInfo from router.v1.validator.dependencies import IsValidAccessToken, RemoveNoneResponse, security from services.negotiation_service import NegotiationService from .protocol import Req_Reject, Res_Participate, Res_Reject, Res_SessionList router = APIRouter(prefix="/v1/negotiation", tags=["Negotiation"], responses={404: {"description": "Not found"}}) @router.get( path="/sessions", response_model=Res_SessionList, summary="협상 세션 목록", description="로그인한 공급사의 협상 세션 목록. 필터(status/qt_type, 정수 코드)·페이지네이션 지원. 기본 정렬(order 미지정)은 '할 일(협상생성·협상중) 우선 + 마감 임박순', 종료(완료·미참여·거부)는 하단·최근순. order 를 주면 그룹 없이 전체 마감순으로 정렬.", ) async def list_sessions( user_info: UserInfo = Depends(IsValidAccessToken), credentials: HTTPAuthorizationCredentials = Depends(security), service: NegotiationService = Depends(), status: Optional[int] = Query(None, description="세션 상태 코드 (SessionStatus)"), qt_type: Optional[int] = Query(None, description="견적 유형 코드 (QtType: 1=재협상, 2=재견적, 3=신규협상, 4=신규견적)"), order: Optional[str] = Query(None, description="마감일 전체 정렬: asc(임박순)/desc(여유순). 미지정 시 기본 그룹 정렬('할 일' 우선 → 종료는 하단·최근순). 지정하면 그룹 없이 전체를 마감 기준으로 정렬."), page: int = Query(1, ge=1, description="페이지 (1부터)"), page_size: int = Query(20, ge=1, le=100, description="페이지당 건수 (1~100)"), ): return RemoveNoneResponse( await service.list_sessions(user_info, credentials.credentials, status, qt_type, order, page, page_size) ) @router.post( path="/sessions/{session_id}/participate", response_model=Res_Participate, summary="협상 참여", description="세션에 참여한다. 소유(공급사)·세션상태·견적마감·마감시간 검증 후 협상생성→협상중, 견적→견적진행중으로 전이.", ) async def participate( session_id: str = Path(description="대상 협상 세션 uuid"), user_info: UserInfo = Depends(IsValidAccessToken), credentials: HTTPAuthorizationCredentials = Depends(security), service: NegotiationService = Depends(), ): return RemoveNoneResponse(await service.participate(user_info, credentials.credentials, session_id)) @router.post( path="/sessions/{session_id}/reject", response_model=Res_Reject, summary="협상 거부", description="세션 참여를 거부한다. 소유(공급사)·세션상태(완료/미참여/거부 불가)·견적마감·마감시간 검증 후 협상거부로 전이하고 사유를 저장.", ) async def reject( session_id: str = Path(description="대상 협상 세션 uuid"), req: Req_Reject = ..., user_info: UserInfo = Depends(IsValidAccessToken), credentials: HTTPAuthorizationCredentials = Depends(security), service: NegotiationService = Depends(), ): return RemoveNoneResponse(await service.reject(user_info, credentials.credentials, session_id, req.reject_reason))