/
FlysAt
/
DataFoundry
Обзор
Документация
Войти
/
FlysAt
/
DataFoundry
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/src/api/services/assignment.py
116 строк
5 KB
AlexanderShmygol
add download labeling .zip
09 апр 2026, 15:14
09 апр 2026, 15:14
9c3192f
Код
Авторство
О чём код?
from fastapi import HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from src.api.repositories.assignment import AssignmentRepository from src.api.repositories.order import OrderRepository from src.models.assignment import AssignmentStatus, OrderAssignment from src.models.order import Order, OrderStatus from src.models.user import User from src.schemas.assignment import AssignmentCreateSchema, AssignmentStatusUpdateSchema class AssignmentService: def __init__(self, db: AsyncSession) -> None: self.assignments = AssignmentRepository(db) self.orders = OrderRepository(db) @staticmethod def _ensure_executor(user: User) -> None: if "executor" not in user.roles: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Only executor can create assignment", ) async def _get_order(self, order_id: int) -> Order: order = await self.orders.get_by_id(order_id) if not order: raise HTTPException(status_code=404, detail="Order not found") return order async def _get_assignment(self, assignment_id: int, order_id: int) -> OrderAssignment: assignment = await self.assignments.get_by_id_and_order(assignment_id, order_id) if not assignment: raise HTTPException(status_code=404, detail="Assignment not found") return assignment async def create_assignment( self, order_id: int, payload: AssignmentCreateSchema, current_user: User, ) -> OrderAssignment: self._ensure_executor(current_user) order = await self._get_order(order_id) if order.status != OrderStatus.PENDING: raise HTTPException(status_code=400, detail="You can respond only to pending orders") # if order.customer_id == current_user.id: # raise HTTPException(status_code=400, detail="You cannot respond to your own order") existing_assignment = await self.assignments.get_by_order_and_executor(order_id, current_user.id) if existing_assignment: raise HTTPException(status_code=400, detail="You already responded to this order") assignment = OrderAssignment( order_id=order_id, executor_id=current_user.id, proposal=payload.proposal, price=payload.price, execution_days=payload.execution_days, status=AssignmentStatus.PENDING, ) return await self.assignments.create(assignment) async def list_assignments(self, order_id: int, current_user: User) -> list[OrderAssignment]: order = await self._get_order(order_id) if order.customer_id != current_user.id and order.current_executor_id != current_user.id: raise HTTPException(status_code=403, detail="No access to order assignments") return await self.assignments.list_by_order(order_id) async def update_assignment_status( self, order_id: int, assignment_id: int, payload: AssignmentStatusUpdateSchema, current_user: User, ) -> OrderAssignment: assignment = await self._get_assignment(assignment_id, order_id) order = await self._get_order(order_id) if current_user.id != order.customer_id: raise HTTPException( status_code=403, detail="Only order owner can manage assignment status", ) assignment.status = payload.status if payload.status == AssignmentStatus.ACCEPTED: order.current_executor_id = assignment.executor_id order.status = OrderStatus.IN_PROGRESS other_assignments = await self.assignments.list_pending_excluding(order_id, assignment.id) #отклоняем остальные для текущего заказа for other in other_assignments: other.status = AssignmentStatus.REJECTED elif payload.status == AssignmentStatus.REJECTED: if order.current_executor_id == assignment.executor_id: order.current_executor_id = None if order.status == OrderStatus.IN_PROGRESS: order.status = OrderStatus.PENDING return await self.assignments.save(assignment) async def delete_assignment( self, order_id: int, assignment_id: int, current_user: User, ) -> None: assignment = await self._get_assignment(assignment_id, order_id) if assignment.executor_id != current_user.id: raise HTTPException(status_code=403, detail="You can delete only your assignment") if assignment.status == AssignmentStatus.ACCEPTED: raise HTTPException(status_code=400, detail="Accepted assignment cannot be deleted") await self.assignments.delete(assignment)