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

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@
.venv
.idea
__pycache__
/venv

16
main.py
View File

@@ -1,8 +1,21 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import routers
origins = [
'http://localhost:5173'
]
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
routers_list = [
routers.auth_router,
routers.deal_router,
@@ -10,6 +23,3 @@ routers_list = [
]
for router in routers_list:
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
@@ -7,5 +8,23 @@ 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='Дата создания')
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 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
client_router = APIRouter(
@@ -19,3 +22,25 @@ async def search_clients(
session: Annotated[AsyncSession, Depends(get_session)]
):
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
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):
name: str
@@ -19,3 +28,16 @@ class ClientCreateRequest(CustomModel):
class ClientSearchResponse(CustomModel):
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
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 schemas.client import *
@@ -14,10 +16,51 @@ class ClientService(BaseService):
client = await self.session.scalar(select(Client).where(Client.name == name))
return client
async def create_client_raw(self, name: str, address: str) -> Client:
client = Client(name=name, address=address, created_at=datetime.datetime.now())
async def get_by_id(self, client_id: int) -> Union[Client, None]:
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)
await self.session.flush()
await self.update_details(user, client, details_schema)
return client
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.deal import *
from schemas.client import ClientDetailsSchema
from schemas.deal import *
from services.base import BaseService
from services.client import ClientService
@@ -49,7 +50,11 @@ class DealService(BaseService):
client_service = ClientService(self.session)
client = await client_service.get_by_name(request.client_name)
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(
name=request.name,
created_at=datetime.datetime.now(),