From bf24c791fc68c30058ca0483ac6b97a84f64bbc9 Mon Sep 17 00:00:00 2001 From: fakz9 Date: Mon, 4 Mar 2024 04:15:01 +0300 Subject: [PATCH] crappy --- main.py | 3 ++- models/__init__.py | 1 + models/client.py | 11 +++++++++++ models/deal.py | 21 ++++++++++++++------- routers/__init__.py | 1 + routers/client.py | 21 +++++++++++++++++++++ routers/deal.py | 5 +++-- schemas/base.py | 9 ++++++++- schemas/client.py | 16 ++++++++++++++++ schemas/deal.py | 10 ++++++++++ services/client.py | 15 +++++++++++++++ services/deal.py | 16 ++++++++++++++-- 12 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 models/client.py create mode 100644 routers/client.py create mode 100644 schemas/client.py create mode 100644 services/client.py diff --git a/main.py b/main.py index cce9b2b..5608dbf 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,8 @@ import routers app = FastAPI() routers_list = [ routers.auth_router, - routers.deal_router + routers.deal_router, + routers.client_router ] for router in routers_list: app.include_router(router) diff --git a/models/__init__.py b/models/__init__.py index d83de2e..dbd6ad6 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,2 +1,3 @@ from .auth import * from .deal import * +from .client import * diff --git a/models/client.py b/models/client.py new file mode 100644 index 0000000..59872dd --- /dev/null +++ b/models/client.py @@ -0,0 +1,11 @@ +from sqlalchemy import Column, Integer, String, DateTime + +from models import BaseModel + + +class Client(BaseModel): + __tablename__ = 'clients' + id = Column(Integer, autoincrement=True, primary_key=True, index=True) + name = Column(String, nullable=False, unique=True, comment='Название клиента') + address = Column(String) + created_at = Column(DateTime, nullable=False, comment='Дата создания') diff --git a/models/deal.py b/models/deal.py index ece109c..ae05d42 100644 --- a/models/deal.py +++ b/models/deal.py @@ -8,12 +8,13 @@ from models.base import BaseModel @unique class DealStatus(IntEnum): - AWAITING_ACCEPTANCE = 0 - PACKAGING = 1 - AWAITING_SHIPMENT = 2 - AWAITING_PAYMENT = 3 - COMPLETED = 4 - CANCELLED = 5 + CREATED = 0 + AWAITING_ACCEPTANCE = 1 + PACKAGING = 2 + AWAITING_SHIPMENT = 3 + AWAITING_PAYMENT = 4 + COMPLETED = 5 + CANCELLED = 6 class Deal(BaseModel): @@ -23,7 +24,10 @@ class Deal(BaseModel): created_at = Column(DateTime, nullable=False, comment='Дата создания') current_status = Column(Integer, nullable=False, comment='Текущий статус') - status_history = relationship('DealStatusHistory', back_populates='deal') + client_id = Column(Integer, ForeignKey('clients.id'), nullable=False, comment='ID клиента') + client = relationship('Client', backref='deals') + + status_history = relationship('DealStatusHistory', back_populates='deal', cascade="all, delete-orphan") class DealStatusHistory(BaseModel): @@ -39,3 +43,6 @@ class DealStatusHistory(BaseModel): changed_at = Column(DateTime, nullable=False, comment='Дата и время когда произошла смена статуса') from_status = Column(Integer, nullable=False, comment='Предыдущий статус') to_status = Column(Integer, nullable=False, comment='Новый статус') + + next_status_deadline = Column(DateTime, + comment='Дедлайн до которого сделку нужно перевести на следующий этап') diff --git a/routers/__init__.py b/routers/__init__.py index cec341a..43c00c0 100644 --- a/routers/__init__.py +++ b/routers/__init__.py @@ -1,3 +1,4 @@ from .auth import auth_router from .deal import deal_router +from .client import client_router diff --git a/routers/client.py b/routers/client.py new file mode 100644 index 0000000..1c9bba3 --- /dev/null +++ b/routers/client.py @@ -0,0 +1,21 @@ +from typing import Annotated + +from fastapi import APIRouter, Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from backend.session import get_session +from schemas.client import ClientSearchRequest +from services.client import ClientService + +client_router = APIRouter( + prefix="/client", + tags=['client'] +) + + +@client_router.get('/search', operation_id='search_clients') +async def search_clients( + name: str, + session: Annotated[AsyncSession, Depends(get_session)] +): + return await ClientService(session).search_clients(ClientSearchRequest(name=name)) diff --git a/routers/deal.py b/routers/deal.py index b781dde..817b399 100644 --- a/routers/deal.py +++ b/routers/deal.py @@ -18,9 +18,10 @@ deal_router = APIRouter( @deal_router.post('/create') async def create( request: DealCreateRequest, - session: Annotated[AsyncSession, Depends(get_session)] + session: Annotated[AsyncSession, Depends(get_session)], + user: Annotated[User, Depends(get_current_user)] ): - return await DealService(session).create(request) + return await DealService(session).create(request, user) @deal_router.post('/changeStatus', response_model=DealChangeStatusResponse) diff --git a/schemas/base.py b/schemas/base.py index e125939..43250b7 100644 --- a/schemas/base.py +++ b/schemas/base.py @@ -1,5 +1,12 @@ from pydantic import BaseModel +class CustomConfig: + populate_by_name = True + from_attributes = True + + class CustomModel(BaseModel): - pass + class Config: + from_attributes = True + diff --git a/schemas/client.py b/schemas/client.py new file mode 100644 index 0000000..9b8f7ad --- /dev/null +++ b/schemas/client.py @@ -0,0 +1,16 @@ +from typing import List + +from schemas.base import CustomModel + + +class ClientSchema(CustomModel): + id: int + name: str + + +class ClientSearchRequest(CustomModel): + name: str + + +class ClientSearchResponse(CustomModel): + clients: List[ClientSchema] diff --git a/schemas/deal.py b/schemas/deal.py index f053b2b..423d9cf 100644 --- a/schemas/deal.py +++ b/schemas/deal.py @@ -1,4 +1,7 @@ +import datetime + from schemas.base import CustomModel +from schemas.client import ClientSchema class DealChangeStatusRequest(CustomModel): @@ -16,3 +19,10 @@ class DealCreateRequest(CustomModel): class DealCreateResponse(CustomModel): ok: bool + + +class FastDeal(CustomModel): + name: str + client: ClientSchema + comment: str + acceptance_date: datetime.datetime diff --git a/services/client.py b/services/client.py new file mode 100644 index 0000000..77b9432 --- /dev/null +++ b/services/client.py @@ -0,0 +1,15 @@ +from sqlalchemy import select + +from models import Client +from services.base import BaseService +from schemas.client import * + + +class ClientService(BaseService): + async def search_clients(self, request: ClientSearchRequest) -> ClientSearchResponse: + query = await self.session.scalars(select(Client) + .where(Client.name.ilike(f'%{request.name}%'))) + clients = [] + for client in query.all(): + clients.append(ClientSchema.model_validate(client)) + return ClientSearchResponse(clients=clients) diff --git a/services/deal.py b/services/deal.py index 4f145c6..e4d28ca 100644 --- a/services/deal.py +++ b/services/deal.py @@ -13,13 +13,25 @@ class DealService(BaseService): async def _get_deal_by_id(self, deal_id) -> Deal: return await self.session.get(Deal, deal_id) - async def create(self, request: DealCreateRequest) -> DealCreateResponse: + async def create(self, request: DealCreateRequest, user: User) -> DealCreateResponse: deal = Deal( name=request.name, created_at=datetime.datetime.now(), - current_status=DealStatus.AWAITING_ACCEPTANCE + current_status=DealStatus.CREATED ) self.session.add(deal) + await self.session.flush() + + # Append status history + status_change = DealStatusHistory( + deal_id=request.deal_id, + user_id=user.id, + changed_at=datetime.datetime.now(), + from_status=deal.current_status, + to_status=DealStatus.CREATED.AWAITING_ACCEPTANCE + ) + self.session.add(status_change) + await self.session.commit() return DealCreateResponse(ok=True)