crappy
This commit is contained in:
		
							
								
								
									
										3
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								main.py
									
									
									
									
									
								
							@@ -5,7 +5,8 @@ import routers
 | 
				
			|||||||
app = FastAPI()
 | 
					app = FastAPI()
 | 
				
			||||||
routers_list = [
 | 
					routers_list = [
 | 
				
			||||||
    routers.auth_router,
 | 
					    routers.auth_router,
 | 
				
			||||||
    routers.deal_router
 | 
					    routers.deal_router,
 | 
				
			||||||
 | 
					    routers.client_router
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
for router in routers_list:
 | 
					for router in routers_list:
 | 
				
			||||||
    app.include_router(router)
 | 
					    app.include_router(router)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,3 @@
 | 
				
			|||||||
from .auth import *
 | 
					from .auth import *
 | 
				
			||||||
from .deal import *
 | 
					from .deal import *
 | 
				
			||||||
 | 
					from .client import *
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								models/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								models/client.py
									
									
									
									
									
										Normal file
									
								
							@@ -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='Дата создания')
 | 
				
			||||||
@@ -8,12 +8,13 @@ from models.base import BaseModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@unique
 | 
					@unique
 | 
				
			||||||
class DealStatus(IntEnum):
 | 
					class DealStatus(IntEnum):
 | 
				
			||||||
    AWAITING_ACCEPTANCE = 0
 | 
					    CREATED = 0
 | 
				
			||||||
    PACKAGING = 1
 | 
					    AWAITING_ACCEPTANCE = 1
 | 
				
			||||||
    AWAITING_SHIPMENT = 2
 | 
					    PACKAGING = 2
 | 
				
			||||||
    AWAITING_PAYMENT = 3
 | 
					    AWAITING_SHIPMENT = 3
 | 
				
			||||||
    COMPLETED = 4
 | 
					    AWAITING_PAYMENT = 4
 | 
				
			||||||
    CANCELLED = 5
 | 
					    COMPLETED = 5
 | 
				
			||||||
 | 
					    CANCELLED = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Deal(BaseModel):
 | 
					class Deal(BaseModel):
 | 
				
			||||||
@@ -23,7 +24,10 @@ class Deal(BaseModel):
 | 
				
			|||||||
    created_at = Column(DateTime, nullable=False, comment='Дата создания')
 | 
					    created_at = Column(DateTime, nullable=False, comment='Дата создания')
 | 
				
			||||||
    current_status = Column(Integer, 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):
 | 
					class DealStatusHistory(BaseModel):
 | 
				
			||||||
@@ -39,3 +43,6 @@ class DealStatusHistory(BaseModel):
 | 
				
			|||||||
    changed_at = Column(DateTime, nullable=False, comment='Дата и время когда произошла смена статуса')
 | 
					    changed_at = Column(DateTime, nullable=False, comment='Дата и время когда произошла смена статуса')
 | 
				
			||||||
    from_status = Column(Integer, nullable=False, comment='Предыдущий статус')
 | 
					    from_status = Column(Integer, nullable=False, comment='Предыдущий статус')
 | 
				
			||||||
    to_status = Column(Integer, nullable=False, comment='Новый статус')
 | 
					    to_status = Column(Integer, nullable=False, comment='Новый статус')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    next_status_deadline = Column(DateTime,
 | 
				
			||||||
 | 
					                                  comment='Дедлайн до которого сделку нужно перевести на следующий этап')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
from .auth import auth_router
 | 
					from .auth import auth_router
 | 
				
			||||||
from .deal import deal_router
 | 
					from .deal import deal_router
 | 
				
			||||||
 | 
					from .client import client_router
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								routers/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								routers/client.py
									
									
									
									
									
										Normal file
									
								
							@@ -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))
 | 
				
			||||||
@@ -18,9 +18,10 @@ deal_router = APIRouter(
 | 
				
			|||||||
@deal_router.post('/create')
 | 
					@deal_router.post('/create')
 | 
				
			||||||
async def create(
 | 
					async def create(
 | 
				
			||||||
        request: DealCreateRequest,
 | 
					        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)
 | 
					@deal_router.post('/changeStatus', response_model=DealChangeStatusResponse)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,12 @@
 | 
				
			|||||||
from pydantic import BaseModel
 | 
					from pydantic import BaseModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CustomConfig:
 | 
				
			||||||
 | 
					    populate_by_name = True
 | 
				
			||||||
 | 
					    from_attributes = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CustomModel(BaseModel):
 | 
					class CustomModel(BaseModel):
 | 
				
			||||||
    pass
 | 
					    class Config:
 | 
				
			||||||
 | 
					        from_attributes = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								schemas/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								schemas/client.py
									
									
									
									
									
										Normal file
									
								
							@@ -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]
 | 
				
			||||||
@@ -1,4 +1,7 @@
 | 
				
			|||||||
 | 
					import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from schemas.base import CustomModel
 | 
					from schemas.base import CustomModel
 | 
				
			||||||
 | 
					from schemas.client import ClientSchema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DealChangeStatusRequest(CustomModel):
 | 
					class DealChangeStatusRequest(CustomModel):
 | 
				
			||||||
@@ -16,3 +19,10 @@ class DealCreateRequest(CustomModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class DealCreateResponse(CustomModel):
 | 
					class DealCreateResponse(CustomModel):
 | 
				
			||||||
    ok: bool
 | 
					    ok: bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FastDeal(CustomModel):
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					    client: ClientSchema
 | 
				
			||||||
 | 
					    comment: str
 | 
				
			||||||
 | 
					    acceptance_date: datetime.datetime
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								services/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								services/client.py
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
@@ -13,13 +13,25 @@ class DealService(BaseService):
 | 
				
			|||||||
    async def _get_deal_by_id(self, deal_id) -> Deal:
 | 
					    async def _get_deal_by_id(self, deal_id) -> Deal:
 | 
				
			||||||
        return await self.session.get(Deal, deal_id)
 | 
					        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(
 | 
					        deal = Deal(
 | 
				
			||||||
            name=request.name,
 | 
					            name=request.name,
 | 
				
			||||||
            created_at=datetime.datetime.now(),
 | 
					            created_at=datetime.datetime.now(),
 | 
				
			||||||
            current_status=DealStatus.AWAITING_ACCEPTANCE
 | 
					            current_status=DealStatus.CREATED
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.session.add(deal)
 | 
					        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()
 | 
					        await self.session.commit()
 | 
				
			||||||
        return DealCreateResponse(ok=True)
 | 
					        return DealCreateResponse(ok=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user