This commit is contained in:
2024-03-17 00:22:05 +03:00
parent f5b7420fac
commit aafa1050a7
8 changed files with 153 additions and 13 deletions

3
.gitignore vendored
View File

@@ -2,4 +2,5 @@
.env .env
.venv .venv
.idea .idea
__pycache__ __pycache__
/venv

16
main.py
View File

@@ -1,8 +1,21 @@
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import routers import routers
origins = [
'http://localhost:5173'
]
app = FastAPI() app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
routers_list = [ routers_list = [
routers.auth_router, routers.auth_router,
routers.deal_router, routers.deal_router,
@@ -10,6 +23,3 @@ routers_list = [
] ]
for router in routers_list: for router in routers_list:
app.include_router(router) app.include_router(router)

View File

@@ -1,4 +1,5 @@
from sqlalchemy import Column, Integer, String, DateTime from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, BigInteger
from sqlalchemy.orm import relationship
from models import BaseModel from models import BaseModel
@@ -7,5 +8,23 @@ class Client(BaseModel):
__tablename__ = 'clients' __tablename__ = 'clients'
id = Column(Integer, autoincrement=True, primary_key=True, index=True) id = Column(Integer, autoincrement=True, primary_key=True, index=True)
name = Column(String, nullable=False, unique=True, comment='Название клиента') name = Column(String, nullable=False, unique=True, comment='Название клиента')
address = Column(String)
created_at = Column(DateTime, nullable=False, comment='Дата создания') created_at = Column(DateTime, nullable=False, comment='Дата создания')
class ClientDetails(BaseModel):
__tablename__ = 'client_details'
id = Column(Integer, autoincrement=True, primary_key=True, index=True)
client_id = Column(Integer, ForeignKey('clients.id'), unique=True, nullable=False, comment='ID клиента')
client = relationship('Client', backref='details', uselist=False)
address = Column(String)
phone_number = Column(String)
inn = Column(BigInteger)
email = Column(String)
last_modified_at = Column(DateTime, nullable=False)
modified_by_user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
modified_by_user = relationship('User')

15
models/product.py Normal file
View File

@@ -0,0 +1,15 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from models import BaseModel
class Product(BaseModel):
__tablename__ = 'products'
id = Column(Integer, autoincrement=True, primary_key=True, index=True)
name = Column(String, nullable=False, index=True)
article = Column(String, nullable=False, index=True)
client_id = Column(Integer, ForeignKey('clients.id'), nullable=False, comment='ID сделки')
client = relationship('Client', back_populates='status_history')

View File

@@ -4,7 +4,10 @@ from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from backend.session import get_session from backend.session import get_session
from schemas.client import ClientSearchRequest from models import User
from schemas.client import ClientSearchRequest, ClientUpdateDetailsRequest, ClientUpdateDetailsResponse, \
ClientGetAllResponse
from services.auth import get_current_user
from services.client import ClientService from services.client import ClientService
client_router = APIRouter( client_router = APIRouter(
@@ -19,3 +22,25 @@ async def search_clients(
session: Annotated[AsyncSession, Depends(get_session)] session: Annotated[AsyncSession, Depends(get_session)]
): ):
return await ClientService(session).search_clients(ClientSearchRequest(name=name)) return await ClientService(session).search_clients(ClientSearchRequest(name=name))
@client_router.post('/update-details')
async def update_client_details(
session: Annotated[AsyncSession, Depends(get_session)],
user: Annotated[User, Depends(get_current_user)],
request: ClientUpdateDetailsRequest,
):
service = ClientService(session)
client = await service.get_by_id(request.client_id)
if not client:
return ClientUpdateDetailsResponse(ok=False)
await service.update_details(user, client, request.details)
await session.commit()
return ClientUpdateDetailsResponse(ok=True)
@client_router.get('/get-all', operation_id='get_all_clients', response_model=ClientGetAllResponse)
async def get_all_clients(
session: Annotated[AsyncSession, Depends(get_session)],
):
return await ClientService(session).get_all()

View File

@@ -8,6 +8,15 @@ class ClientSchema(CustomModel):
name: str name: str
class ClientDetailsSchema(CustomModel):
address: str | None = None
phone_number: str | None = None
inn: int | None = None
email: str | None = None
# TODO add email validation
class ClientSearchRequest(CustomModel): class ClientSearchRequest(CustomModel):
name: str name: str
@@ -19,3 +28,16 @@ class ClientCreateRequest(CustomModel):
class ClientSearchResponse(CustomModel): class ClientSearchResponse(CustomModel):
clients: List[ClientSchema] clients: List[ClientSchema]
class ClientUpdateDetailsRequest(CustomModel):
client_id: int
details: ClientDetailsSchema
class ClientUpdateDetailsResponse(CustomModel):
ok: bool
class ClientGetAllResponse(CustomModel):
clients: List[ClientSchema]

View File

@@ -1,9 +1,11 @@
import datetime import datetime
from typing import Union from typing import Union, Annotated
from sqlalchemy import select from fastapi import Depends
from sqlalchemy import select, update
from models import Client from models import Client, ClientDetails, User
from services.auth import get_current_user
from services.base import BaseService from services.base import BaseService
from schemas.client import * from schemas.client import *
@@ -14,10 +16,51 @@ class ClientService(BaseService):
client = await self.session.scalar(select(Client).where(Client.name == name)) client = await self.session.scalar(select(Client).where(Client.name == name))
return client return client
async def create_client_raw(self, name: str, address: str) -> Client: async def get_by_id(self, client_id: int) -> Union[Client, None]:
client = Client(name=name, address=address, created_at=datetime.datetime.now()) return await self.session.get(Client, client_id)
async def get_details_by_client_id(self, client_id: int) -> Union[ClientDetails, None]:
details = await self.session.scalar(select(ClientDetails).where(ClientDetails.client_id == client_id))
return details
async def get_all(self) -> ClientGetAllResponse:
clients_query = await self.session.scalars(select(Client))
clients = clients_query.all()
result = []
for client in clients:
result.append(ClientSchema.model_validate(client))
return ClientGetAllResponse(clients=result)
async def create_details(self, user, client: Client, request: ClientDetailsSchema):
dict_data = request.dict()
dict_data['client_id'] = client.id
dict_data['last_modified_at'] = datetime.datetime.now()
dict_data['modified_by_user_id'] = user.id
details = ClientDetails(**dict_data)
self.session.add(details)
await self.session.flush()
return details
async def update_details(self, user: User, client: Client, request: ClientDetailsSchema) -> ClientDetails:
details = await self.get_details_by_client_id(client_id=client.id)
if not details:
details = await self.create_details(user, client, request)
dict_data = request.dict()
dict_data['last_modified_at'] = datetime.datetime.now()
dict_data['modified_by_user_id'] = user.id
await self.session.execute(update(ClientDetails).where(ClientDetails.id == details.id).values(**dict_data))
await self.session.flush()
async def create_client_raw(self,
user: User,
client_name: str,
details_schema: ClientDetailsSchema) -> Client:
client = Client(name=client_name, created_at=datetime.datetime.now())
self.session.add(client) self.session.add(client)
await self.session.flush() await self.session.flush()
await self.update_details(user, client, details_schema)
return client return client
async def search_clients(self, request: ClientSearchRequest) -> ClientSearchResponse: async def search_clients(self, request: ClientSearchRequest) -> ClientSearchResponse:

View File

@@ -5,6 +5,7 @@ from sqlalchemy import select
from models import User, Deal from models import User, Deal
from models.deal import * from models.deal import *
from schemas.client import ClientDetailsSchema
from schemas.deal import * from schemas.deal import *
from services.base import BaseService from services.base import BaseService
from services.client import ClientService from services.client import ClientService
@@ -49,7 +50,11 @@ class DealService(BaseService):
client_service = ClientService(self.session) client_service = ClientService(self.session)
client = await client_service.get_by_name(request.client_name) client = await client_service.get_by_name(request.client_name)
if not client: if not client:
client = await client_service.create_client_raw(request.client_name, request.client_address) client = await client_service.create_client_raw(
user,
request.client_name,
ClientDetailsSchema(address=request.client_address))
await client_service.update_details(user, client, ClientDetailsSchema(address=request.client_address))
deal = Deal( deal = Deal(
name=request.name, name=request.name,
created_at=datetime.datetime.now(), created_at=datetime.datetime.now(),