othr
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
.venv
|
.venv
|
||||||
.idea
|
.idea
|
||||||
__pycache__
|
__pycache__
|
||||||
|
/venv
|
||||||
16
main.py
16
main.py
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
15
models/product.py
Normal 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')
|
||||||
|
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
Reference in New Issue
Block a user