74 lines
2.9 KiB
Python
74 lines
2.9 KiB
Python
"""Endpoints для заявок фрилансеров."""
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, desc
|
|
|
|
from app.core.database import get_db
|
|
from app.core.security import get_current_user
|
|
from app.schemas.proposal import ProposalCreate, ProposalResponse
|
|
from app.models.project import Project
|
|
from app.models.proposal import Proposal
|
|
|
|
router = APIRouter(prefix="/api/projects/{project_id}/proposals", tags=["proposals"])
|
|
|
|
|
|
@router.post("", response_model=ProposalResponse)
|
|
async def create_proposal(
|
|
project_id: str, data: ProposalCreate, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)
|
|
):
|
|
"""Фрилансер подаёт заявку на проект."""
|
|
|
|
result = await db.execute(select(Project).where(Project.id == project_id))
|
|
project = result.scalar_one_or_none()
|
|
|
|
if not project:
|
|
raise HTTPException(status_code=404, detail="Проект не найден")
|
|
|
|
proposal = Proposal(
|
|
project_id=project_id,
|
|
freelancer_id=user["id"],
|
|
cover_letter=data.cover_letter,
|
|
proposed_price=data.proposed_price,
|
|
estimated_days=data.estimated_days,
|
|
)
|
|
db.add(proposal)
|
|
await db.commit()
|
|
await db.refresh(proposal)
|
|
|
|
return ProposalResponse(
|
|
id=str(proposal.id), project_id=project_id, freelancer_id=user["id"],
|
|
cover_letter=proposal.cover_letter, proposed_price=float(proposal.proposed_price) if proposal.proposed_price else None,
|
|
estimated_days=proposal.estimated_days, status=proposal.status, created_at=str(proposal.created_at),
|
|
)
|
|
|
|
|
|
@router.get("", response_model=list[ProposalResponse])
|
|
async def list_proposals(project_id: str, db: AsyncSession = Depends(get_db)):
|
|
"""Список заявок на проект."""
|
|
|
|
result = await db.execute(select(Proposal).where(Proposal.project_id == project_id).order_by(desc(Proposal.created_at)))
|
|
proposals = result.scalars().all()
|
|
|
|
return [ProposalResponse(
|
|
id=str(p.id), project_id=p.project_id, freelancer_id=p.freelancer_id, cover_letter=p.cover_letter,
|
|
proposed_price=float(p.proposed_price) if p.proposed_price else None, estimated_days=p.estimated_days,
|
|
status=p.status, created_at=str(p.created_at),
|
|
) for p in proposals]
|
|
|
|
|
|
@router.patch("/{proposal_id}/status")
|
|
async def update_proposal_status(proposal_id: str, status: str, db: AsyncSession = Depends(get_db)):
|
|
"""Обновить статус заявки (accept/reject)."""
|
|
|
|
result = await db.execute(select(Proposal).where(Proposal.id == proposal_id))
|
|
proposal = result.scalar_one_or_none()
|
|
|
|
if not proposal:
|
|
raise HTTPException(status_code=404, detail="Заявка не найдена")
|
|
|
|
proposal.status = status
|
|
await db.commit()
|
|
|
|
return {"status": "updated", "proposal_id": str(proposal.id)}
|