feat: вфыв
This commit is contained in:
8
backend/dependecies.py
Normal file
8
backend/dependecies.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from typing import Annotated
|
||||||
|
|
||||||
|
from fastapi import Depends
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from backend.session import get_session
|
||||||
|
|
||||||
|
SessionDependency = Annotated[AsyncSession, Depends(get_session)]
|
||||||
8
enums/user.py
Normal file
8
enums/user.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from enum import StrEnum
|
||||||
|
|
||||||
|
|
||||||
|
class UserRole(StrEnum):
|
||||||
|
user = 'user'
|
||||||
|
employee = 'employee'
|
||||||
|
manager = 'manager'
|
||||||
|
admin = 'admin'
|
||||||
5
main.py
5
main.py
@@ -32,7 +32,10 @@ routers_list = [
|
|||||||
routers.service_router,
|
routers.service_router,
|
||||||
routers.product_router,
|
routers.product_router,
|
||||||
routers.barcode_router,
|
routers.barcode_router,
|
||||||
routers.shipping_warehouse_router
|
routers.shipping_warehouse_router,
|
||||||
|
routers.position_router,
|
||||||
|
routers.user_router,
|
||||||
|
routers.role_router,
|
||||||
]
|
]
|
||||||
for router in routers_list:
|
for router in routers_list:
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
|
|||||||
@@ -1,12 +1,83 @@
|
|||||||
from sqlalchemy import Column, Integer, BigInteger, String, Boolean
|
from sqlalchemy import BigInteger, Table, ForeignKey, Column
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from models.base import BaseModel
|
from models.base import BaseModel
|
||||||
|
|
||||||
|
role_permissions = Table(
|
||||||
|
'role_permissions',
|
||||||
|
BaseModel.metadata,
|
||||||
|
Column('role_key', ForeignKey('roles.key'), primary_key=True),
|
||||||
|
Column('permission_key', ForeignKey('permissions.key'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
user_position = Table(
|
||||||
|
'user_position',
|
||||||
|
BaseModel.metadata,
|
||||||
|
Column('position_key', ForeignKey('positions.key'), primary_key=True),
|
||||||
|
Column('user_id', ForeignKey('users.id'), primary_key=True, unique=True)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Permission(BaseModel):
|
||||||
|
__tablename__ = 'permissions'
|
||||||
|
key: Mapped[str] = mapped_column(primary_key=True)
|
||||||
|
name: Mapped[str] = mapped_column()
|
||||||
|
|
||||||
|
roles: Mapped[list["Role"]] = relationship('Role',
|
||||||
|
secondary=role_permissions,
|
||||||
|
back_populates='permissions')
|
||||||
|
|
||||||
|
|
||||||
|
class Role(BaseModel):
|
||||||
|
__tablename__ = 'roles'
|
||||||
|
key: Mapped[str] = mapped_column(primary_key=True)
|
||||||
|
name: Mapped[str] = mapped_column()
|
||||||
|
permissions: Mapped[list["Permission"]] = relationship('Permission',
|
||||||
|
secondary=role_permissions,
|
||||||
|
back_populates='roles',
|
||||||
|
lazy='selectin')
|
||||||
|
# users: Mapped[list["User"]] = relationship("User", back_populates="users")
|
||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
class User(BaseModel):
|
||||||
__tablename__ = 'users'
|
__tablename__ = 'users'
|
||||||
id = Column(Integer, autoincrement=True, primary_key=True, index=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
telegram_id = Column(BigInteger, nullable=False, index=True)
|
|
||||||
phone_number = Column(String)
|
|
||||||
|
|
||||||
is_admin = Column(Boolean, nullable=False, default=False)
|
first_name: Mapped[str] = mapped_column(nullable=False, server_default='')
|
||||||
|
second_name: Mapped[str] = mapped_column(nullable=False, server_default='')
|
||||||
|
comment: Mapped[str] = mapped_column(nullable=False, server_default='')
|
||||||
|
telegram_id: Mapped[int] = mapped_column(BigInteger,
|
||||||
|
nullable=False,
|
||||||
|
index=True)
|
||||||
|
phone_number: Mapped[str] = mapped_column(nullable=True)
|
||||||
|
is_admin: Mapped[bool] = mapped_column(nullable=False, default=False)
|
||||||
|
is_blocked: Mapped[bool] = mapped_column(nullable=False, server_default='0')
|
||||||
|
is_deleted: Mapped[bool] = mapped_column(nullable=False, server_default='0')
|
||||||
|
|
||||||
|
role_key: Mapped[int] = mapped_column(ForeignKey('roles.key'))
|
||||||
|
role: Mapped["Role"] = relationship(
|
||||||
|
'Role',
|
||||||
|
lazy='joined'
|
||||||
|
)
|
||||||
|
|
||||||
|
position: Mapped["Position"] = relationship(
|
||||||
|
'Position',
|
||||||
|
secondary=user_position,
|
||||||
|
uselist=False,
|
||||||
|
back_populates='users',
|
||||||
|
lazy="joined"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Position(BaseModel):
|
||||||
|
__tablename__ = 'positions'
|
||||||
|
key: Mapped[str] = mapped_column(primary_key=True)
|
||||||
|
name: Mapped[str] = mapped_column()
|
||||||
|
|
||||||
|
users: Mapped["User"] = relationship(
|
||||||
|
'User',
|
||||||
|
secondary=user_position,
|
||||||
|
uselist=False,
|
||||||
|
back_populates='position'
|
||||||
|
)
|
||||||
|
|||||||
@@ -5,3 +5,6 @@ from .service import service_router
|
|||||||
from .product import product_router
|
from .product import product_router
|
||||||
from .barcode import barcode_router
|
from .barcode import barcode_router
|
||||||
from .shipping_warehouse import shipping_warehouse_router
|
from .shipping_warehouse import shipping_warehouse_router
|
||||||
|
from .position import position_router
|
||||||
|
from .user import user_router
|
||||||
|
from .role import role_router
|
||||||
|
|||||||
33
routers/position.py
Normal file
33
routers/position.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
from backend.dependecies import SessionDependency
|
||||||
|
from schemas.position import *
|
||||||
|
from services.position import PositionService
|
||||||
|
|
||||||
|
position_router = APIRouter(
|
||||||
|
prefix="/position",
|
||||||
|
tags=["position"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@position_router.get(
|
||||||
|
'/get-all',
|
||||||
|
operation_id='get_all_positions',
|
||||||
|
response_model=GetAllPositionsResponse
|
||||||
|
)
|
||||||
|
async def get_all(
|
||||||
|
session: SessionDependency
|
||||||
|
):
|
||||||
|
return await PositionService(session).get_all()
|
||||||
|
|
||||||
|
|
||||||
|
@position_router.post(
|
||||||
|
'/create',
|
||||||
|
operation_id='create_position',
|
||||||
|
response_model=CreatePositionResponse
|
||||||
|
)
|
||||||
|
async def create(
|
||||||
|
session: SessionDependency,
|
||||||
|
request: CreatePositionRequest
|
||||||
|
):
|
||||||
|
return await PositionService(session).create(request)
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
import base64
|
import base64
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Annotated, Union
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, UploadFile
|
from fastapi import APIRouter, Depends, UploadFile
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from starlette.responses import StreamingResponse
|
|
||||||
from fastapi.responses import FileResponse
|
|
||||||
import utils.dependecies
|
import utils.dependecies
|
||||||
from backend.session import get_session
|
from backend.session import get_session
|
||||||
from schemas.barcode import GetProductBarcodeResponse, GetProductBarcodeRequest, GetProductBarcodePdfResponse, \
|
from schemas.barcode import GetProductBarcodeResponse, GetProductBarcodeRequest, GetProductBarcodePdfResponse, \
|
||||||
GetProductBarcodePdfRequest
|
GetProductBarcodePdfRequest
|
||||||
from schemas.base import PaginationSchema
|
from schemas.base import PaginationSchema
|
||||||
from schemas.product import *
|
from schemas.product import *
|
||||||
from services.auth import get_current_user
|
|
||||||
from services.barcode import BarcodeService
|
from services.barcode import BarcodeService
|
||||||
from services.product import ProductService
|
from services.product import ProductService
|
||||||
|
|
||||||
|
|||||||
21
routers/role.py
Normal file
21
routers/role.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
from backend.dependecies import SessionDependency
|
||||||
|
from schemas.role import *
|
||||||
|
from services.role import RoleService
|
||||||
|
|
||||||
|
role_router = APIRouter(
|
||||||
|
prefix='/role',
|
||||||
|
tags=['role']
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@role_router.get(
|
||||||
|
'/get-all',
|
||||||
|
response_model=GetAllRolesResponse,
|
||||||
|
operation_id='get_all_roles'
|
||||||
|
)
|
||||||
|
async def get_all(
|
||||||
|
session: SessionDependency
|
||||||
|
):
|
||||||
|
return await RoleService(session).get_all()
|
||||||
33
routers/user.py
Normal file
33
routers/user.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
from backend.dependecies import SessionDependency
|
||||||
|
from schemas.user import *
|
||||||
|
from services.user import UserService
|
||||||
|
|
||||||
|
user_router = APIRouter(
|
||||||
|
prefix="/user",
|
||||||
|
tags=["user"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@user_router.get(
|
||||||
|
'/get-all',
|
||||||
|
response_model=GetAllUsersResponse,
|
||||||
|
operation_id='get_all_users'
|
||||||
|
)
|
||||||
|
async def get_all(
|
||||||
|
session: SessionDependency
|
||||||
|
):
|
||||||
|
return await UserService(session).get_all()
|
||||||
|
|
||||||
|
|
||||||
|
@user_router.post(
|
||||||
|
'/update',
|
||||||
|
response_model=UpdateUserResponse,
|
||||||
|
operation_id='update_user'
|
||||||
|
)
|
||||||
|
async def update(
|
||||||
|
session: SessionDependency,
|
||||||
|
request: UpdateUserRequest
|
||||||
|
):
|
||||||
|
return await UserService(session).update(request)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
from schemas.base import CustomModelCamel, CustomModelSnake
|
from schemas.base import BaseSchema, CustomModelSnake
|
||||||
|
|
||||||
|
|
||||||
class AuthLoginRequest(CustomModelSnake):
|
class AuthLoginRequest(CustomModelSnake):
|
||||||
@@ -9,5 +9,5 @@ class AuthLoginRequest(CustomModelSnake):
|
|||||||
photo_url: str
|
photo_url: str
|
||||||
|
|
||||||
|
|
||||||
class AuthLoginResponse(CustomModelCamel):
|
class AuthLoginResponse(BaseSchema):
|
||||||
access_token: str
|
access_token: str
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from schemas.base import CustomModelCamel, OkMessageSchema
|
from schemas.base import BaseSchema, OkMessageSchema
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class BarcodeTemplateAttributeSchema(CustomModelCamel):
|
class BarcodeTemplateAttributeSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
key: str
|
key: str
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class BarcodeTemplateSizeSchema(CustomModelCamel):
|
class BarcodeTemplateSizeSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
key: str
|
key: str
|
||||||
@@ -18,12 +18,12 @@ class BarcodeTemplateSizeSchema(CustomModelCamel):
|
|||||||
height: int
|
height: int
|
||||||
|
|
||||||
|
|
||||||
class BarcodeTemplateAdditionalAttributeSchema(CustomModelCamel):
|
class BarcodeTemplateAdditionalAttributeSchema(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
value: str
|
value: str
|
||||||
|
|
||||||
|
|
||||||
class BaseBarcodeTemplateSchema(CustomModelCamel):
|
class BaseBarcodeTemplateSchema(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
is_default: bool
|
is_default: bool
|
||||||
size: BarcodeTemplateSizeSchema
|
size: BarcodeTemplateSizeSchema
|
||||||
@@ -36,12 +36,12 @@ class BarcodeTemplateSchema(BaseBarcodeTemplateSchema):
|
|||||||
attributes: list[BarcodeTemplateAttributeSchema]
|
attributes: list[BarcodeTemplateAttributeSchema]
|
||||||
|
|
||||||
|
|
||||||
class BarcodeAttributeSchema(CustomModelCamel):
|
class BarcodeAttributeSchema(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
value: str
|
value: str
|
||||||
|
|
||||||
|
|
||||||
class BarcodeSchema(CustomModelCamel):
|
class BarcodeSchema(BaseSchema):
|
||||||
barcode: str
|
barcode: str
|
||||||
attributes: List[BarcodeAttributeSchema]
|
attributes: List[BarcodeAttributeSchema]
|
||||||
additional_field: str | None = None
|
additional_field: str | None = None
|
||||||
@@ -50,7 +50,7 @@ class BarcodeSchema(CustomModelCamel):
|
|||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class GetBarcodeTemplateByIdRequest(CustomModelCamel):
|
class GetBarcodeTemplateByIdRequest(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
|
|
||||||
|
|
||||||
@@ -62,16 +62,16 @@ class BarcodeTemplateUpdateResponse(OkMessageSchema):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CreateBarcodeTemplateAttributeRequest(CustomModelCamel):
|
class CreateBarcodeTemplateAttributeRequest(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
label: str
|
label: str
|
||||||
|
|
||||||
|
|
||||||
class BarcodeTemplateDeleteRequest(CustomModelCamel):
|
class BarcodeTemplateDeleteRequest(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
|
|
||||||
|
|
||||||
class GetProductBarcodeRequest(CustomModelCamel):
|
class GetProductBarcodeRequest(BaseSchema):
|
||||||
product_id: int
|
product_id: int
|
||||||
barcode: str
|
barcode: str
|
||||||
barcode_template_id: int | None = None
|
barcode_template_id: int | None = None
|
||||||
@@ -84,7 +84,7 @@ class GetProductBarcodePdfRequest(GetProductBarcodeRequest):
|
|||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Responses
|
# region Responses
|
||||||
class GetBarcodeTemplateByIdResponse(CustomModelCamel):
|
class GetBarcodeTemplateByIdResponse(BaseSchema):
|
||||||
barcode_template: BarcodeTemplateSchema
|
barcode_template: BarcodeTemplateSchema
|
||||||
|
|
||||||
|
|
||||||
@@ -101,11 +101,11 @@ class CreateBarcodeTemplateAttributeResponse(OkMessageSchema):
|
|||||||
id: int
|
id: int
|
||||||
|
|
||||||
|
|
||||||
class GetAllBarcodeTemplatesResponse(CustomModelCamel):
|
class GetAllBarcodeTemplatesResponse(BaseSchema):
|
||||||
templates: list[BarcodeTemplateSchema]
|
templates: list[BarcodeTemplateSchema]
|
||||||
|
|
||||||
|
|
||||||
class GetAllBarcodeTemplateAttributesResponse(CustomModelCamel):
|
class GetAllBarcodeTemplateAttributesResponse(BaseSchema):
|
||||||
attributes: list[BarcodeTemplateAttributeSchema]
|
attributes: list[BarcodeTemplateAttributeSchema]
|
||||||
|
|
||||||
|
|
||||||
@@ -113,15 +113,15 @@ class BarcodeTemplateDeleteResponse(OkMessageSchema):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GetProductBarcodeResponse(CustomModelCamel):
|
class GetProductBarcodeResponse(BaseSchema):
|
||||||
barcode: BarcodeSchema
|
barcode: BarcodeSchema
|
||||||
|
|
||||||
|
|
||||||
class GetAllBarcodeTemplateSizesResponse(CustomModelCamel):
|
class GetAllBarcodeTemplateSizesResponse(BaseSchema):
|
||||||
sizes: list[BarcodeTemplateSizeSchema]
|
sizes: list[BarcodeTemplateSizeSchema]
|
||||||
|
|
||||||
|
|
||||||
class GetProductBarcodePdfResponse(CustomModelCamel):
|
class GetProductBarcodePdfResponse(BaseSchema):
|
||||||
base64_string: str
|
base64_string: str
|
||||||
filename: str
|
filename: str
|
||||||
mime_type: str
|
mime_type: str
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from typing import Self
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic.alias_generators import to_camel
|
from pydantic.alias_generators import to_camel
|
||||||
|
|
||||||
@@ -7,44 +9,52 @@ class CustomConfig:
|
|||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class CustomModelCamel(BaseModel):
|
class BaseSchema(BaseModel):
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
alias_generator = to_camel
|
alias_generator = to_camel
|
||||||
populate_by_name = True
|
populate_by_name = True
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_sql_model(cls, model, fields: dict):
|
def from_sql_model(cls, model, fields: dict):
|
||||||
model_dict = {c.name: getattr(model, c.name) for c in model.__table__.columns}
|
model_dict = {c.name: getattr(model, c.name) for c in model.__table__.columns}
|
||||||
model_dict.update(fields)
|
model_dict.update(fields)
|
||||||
return cls(**model_dict)
|
return cls(**model_dict)
|
||||||
|
|
||||||
|
def model_dump_parent(self):
|
||||||
|
parent_class: BaseModel = self.__class__.__bases__[0]
|
||||||
|
parent_fields = set(parent_class.model_fields.keys())
|
||||||
|
return self.model_dump(include=parent_fields)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_orm_list(cls, sql_models) -> list[Self]:
|
||||||
|
return [cls.model_validate(model) for model in sql_models]
|
||||||
|
|
||||||
|
|
||||||
class CustomModelSnake(BaseModel):
|
class CustomModelSnake(BaseModel):
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class OkMessageSchema(CustomModelCamel):
|
class OkMessageSchema(BaseSchema):
|
||||||
ok: bool
|
ok: bool
|
||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
class PaginationSchema(CustomModelCamel):
|
class PaginationSchema(BaseSchema):
|
||||||
page: int | None = None
|
page: int | None = None
|
||||||
items_per_page: int | None = None
|
items_per_page: int | None = None
|
||||||
|
|
||||||
|
|
||||||
class PaginationInfoSchema(CustomModelCamel):
|
class PaginationInfoSchema(BaseSchema):
|
||||||
total_pages: int
|
total_pages: int
|
||||||
total_items: int
|
total_items: int
|
||||||
|
|
||||||
|
|
||||||
class BaseEnumSchema(CustomModelCamel):
|
class BaseEnumSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class BaseEnumListSchema(CustomModelCamel):
|
class BaseEnumListSchema(BaseSchema):
|
||||||
items: list[BaseEnumSchema]
|
items: list[BaseEnumSchema]
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ from typing import List
|
|||||||
from pydantic import field_validator
|
from pydantic import field_validator
|
||||||
|
|
||||||
from schemas.barcode import BarcodeTemplateSchema
|
from schemas.barcode import BarcodeTemplateSchema
|
||||||
from schemas.base import CustomModelCamel, OkMessageSchema
|
from schemas.base import BaseSchema, OkMessageSchema
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class ClientDetailsSchema(CustomModelCamel):
|
class ClientDetailsSchema(BaseSchema):
|
||||||
telegram: str | None = None
|
telegram: str | None = None
|
||||||
phone_number: str | None = None
|
phone_number: str | None = None
|
||||||
inn: str | None = None
|
inn: str | None = None
|
||||||
@@ -18,7 +18,7 @@ class ClientDetailsSchema(CustomModelCamel):
|
|||||||
return '' if v is None else v
|
return '' if v is None else v
|
||||||
|
|
||||||
|
|
||||||
class ClientSchema(CustomModelCamel):
|
class ClientSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
company_name: str
|
company_name: str
|
||||||
@@ -29,39 +29,39 @@ class ClientSchema(CustomModelCamel):
|
|||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class ClientSearchRequest(CustomModelCamel):
|
class ClientSearchRequest(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class ClientUpdateDetailsRequest(CustomModelCamel):
|
class ClientUpdateDetailsRequest(BaseSchema):
|
||||||
client_id: int
|
client_id: int
|
||||||
details: ClientDetailsSchema
|
details: ClientDetailsSchema
|
||||||
|
|
||||||
|
|
||||||
class ClientCreateRequest(CustomModelCamel):
|
class ClientCreateRequest(BaseSchema):
|
||||||
data: ClientSchema
|
data: ClientSchema
|
||||||
|
|
||||||
|
|
||||||
class ClientUpdateRequest(CustomModelCamel):
|
class ClientUpdateRequest(BaseSchema):
|
||||||
data: ClientSchema
|
data: ClientSchema
|
||||||
|
|
||||||
|
|
||||||
class ClientDeleteRequest(CustomModelCamel):
|
class ClientDeleteRequest(BaseSchema):
|
||||||
client_id: int
|
client_id: int
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Responses
|
# region Responses
|
||||||
class ClientSearchResponse(CustomModelCamel):
|
class ClientSearchResponse(BaseSchema):
|
||||||
clients: List[ClientSchema]
|
clients: List[ClientSchema]
|
||||||
|
|
||||||
|
|
||||||
class ClientUpdateDetailsResponse(CustomModelCamel):
|
class ClientUpdateDetailsResponse(BaseSchema):
|
||||||
ok: bool
|
ok: bool
|
||||||
|
|
||||||
|
|
||||||
class ClientGetAllResponse(CustomModelCamel):
|
class ClientGetAllResponse(BaseSchema):
|
||||||
clients: List[ClientSchema]
|
clients: List[ClientSchema]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
from pydantic import constr
|
from pydantic import constr, field_validator
|
||||||
|
|
||||||
from schemas.base import CustomModelCamel, OkMessageSchema
|
from schemas.base import BaseSchema, OkMessageSchema
|
||||||
from schemas.client import ClientSchema
|
from schemas.client import ClientSchema
|
||||||
from schemas.product import ProductSchema
|
from schemas.product import ProductSchema
|
||||||
from schemas.service import ServiceSchema
|
from schemas.service import ServiceSchema
|
||||||
@@ -12,14 +12,14 @@ from schemas.user import UserSchema
|
|||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class FastDeal(CustomModelCamel):
|
class FastDeal(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
client: ClientSchema
|
client: ClientSchema
|
||||||
comment: str
|
comment: str
|
||||||
acceptance_date: datetime.datetime
|
acceptance_date: datetime.datetime
|
||||||
|
|
||||||
|
|
||||||
class DealSummary(CustomModelCamel):
|
class DealSummary(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
client_name: str
|
client_name: str
|
||||||
@@ -30,24 +30,24 @@ class DealSummary(CustomModelCamel):
|
|||||||
rank: int
|
rank: int
|
||||||
|
|
||||||
|
|
||||||
class DealServiceSchema(CustomModelCamel):
|
class DealServiceSchema(BaseSchema):
|
||||||
service: ServiceSchema
|
service: ServiceSchema
|
||||||
quantity: int
|
quantity: int
|
||||||
price: int
|
price: int
|
||||||
|
|
||||||
|
|
||||||
class DealProductServiceSchema(CustomModelCamel):
|
class DealProductServiceSchema(BaseSchema):
|
||||||
service: ServiceSchema
|
service: ServiceSchema
|
||||||
price: int
|
price: int
|
||||||
|
|
||||||
|
|
||||||
class DealProductSchema(CustomModelCamel):
|
class DealProductSchema(BaseSchema):
|
||||||
product: ProductSchema
|
product: ProductSchema
|
||||||
services: List[DealProductServiceSchema]
|
services: List[DealProductServiceSchema]
|
||||||
quantity: int
|
quantity: int
|
||||||
|
|
||||||
|
|
||||||
class DealStatusHistorySchema(CustomModelCamel):
|
class DealStatusHistorySchema(BaseSchema):
|
||||||
user: UserSchema
|
user: UserSchema
|
||||||
changed_at: datetime.datetime
|
changed_at: datetime.datetime
|
||||||
from_status: int
|
from_status: int
|
||||||
@@ -56,7 +56,7 @@ class DealStatusHistorySchema(CustomModelCamel):
|
|||||||
comment: str | None = None
|
comment: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class DealSchema(CustomModelCamel):
|
class DealSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
client_id: int
|
client_id: int
|
||||||
@@ -69,29 +69,30 @@ class DealSchema(CustomModelCamel):
|
|||||||
is_completed: bool
|
is_completed: bool
|
||||||
client: ClientSchema
|
client: ClientSchema
|
||||||
comment: str
|
comment: str
|
||||||
shipping_warehouse: Optional[ShippingWarehouseSchema] = None
|
shipping_warehouse: Optional[Union[ShippingWarehouseSchema, str]] = None
|
||||||
|
|
||||||
|
|
||||||
class DealGeneralInfoSchema(CustomModelCamel):
|
class DealGeneralInfoSchema(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
is_deleted: bool
|
is_deleted: bool
|
||||||
is_completed: bool
|
is_completed: bool
|
||||||
comment: str
|
comment: str
|
||||||
|
shipping_warehouse: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
# endregion Entities
|
# endregion Entities
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class DealChangeStatusRequest(CustomModelCamel):
|
class DealChangeStatusRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
new_status: int
|
new_status: int
|
||||||
|
|
||||||
|
|
||||||
class DealCreateRequest(CustomModelCamel):
|
class DealCreateRequest(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class DealQuickCreateRequest(CustomModelCamel):
|
class DealQuickCreateRequest(BaseSchema):
|
||||||
name: constr(strip_whitespace=True)
|
name: constr(strip_whitespace=True)
|
||||||
client_name: constr(strip_whitespace=True)
|
client_name: constr(strip_whitespace=True)
|
||||||
comment: str
|
comment: str
|
||||||
@@ -99,70 +100,70 @@ class DealQuickCreateRequest(CustomModelCamel):
|
|||||||
shipping_warehouse: constr(strip_whitespace=True)
|
shipping_warehouse: constr(strip_whitespace=True)
|
||||||
|
|
||||||
|
|
||||||
class DealSummaryRequest(CustomModelCamel):
|
class DealSummaryRequest(BaseSchema):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DealAddServicesRequest(CustomModelCamel):
|
class DealAddServicesRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
services: list[DealServiceSchema]
|
services: list[DealServiceSchema]
|
||||||
|
|
||||||
|
|
||||||
class DealUpdateServiceQuantityRequest(CustomModelCamel):
|
class DealUpdateServiceQuantityRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
service_id: int
|
service_id: int
|
||||||
quantity: int
|
quantity: int
|
||||||
|
|
||||||
|
|
||||||
class DealUpdateServiceRequest(CustomModelCamel):
|
class DealUpdateServiceRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
service: DealServiceSchema
|
service: DealServiceSchema
|
||||||
|
|
||||||
|
|
||||||
class DealAddServiceRequest(CustomModelCamel):
|
class DealAddServiceRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
service_id: int
|
service_id: int
|
||||||
quantity: int
|
quantity: int
|
||||||
price: int
|
price: int
|
||||||
|
|
||||||
|
|
||||||
class DealDeleteServiceRequest(CustomModelCamel):
|
class DealDeleteServiceRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
service_id: int
|
service_id: int
|
||||||
|
|
||||||
|
|
||||||
class DealDeleteServicesRequest(CustomModelCamel):
|
class DealDeleteServicesRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
service_ids: List[int]
|
service_ids: List[int]
|
||||||
|
|
||||||
|
|
||||||
class DealUpdateProductQuantityRequest(CustomModelCamel):
|
class DealUpdateProductQuantityRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
product_id: int
|
product_id: int
|
||||||
quantity: int
|
quantity: int
|
||||||
|
|
||||||
|
|
||||||
class DealAddProductRequest(CustomModelCamel):
|
class DealAddProductRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
product: DealProductSchema
|
product: DealProductSchema
|
||||||
|
|
||||||
|
|
||||||
class DealDeleteProductRequest(CustomModelCamel):
|
class DealDeleteProductRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
product_id: int
|
product_id: int
|
||||||
|
|
||||||
|
|
||||||
class DealDeleteProductsRequest(CustomModelCamel):
|
class DealDeleteProductsRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
product_ids: List[int]
|
product_ids: List[int]
|
||||||
|
|
||||||
|
|
||||||
class DealUpdateGeneralInfoRequest(CustomModelCamel):
|
class DealUpdateGeneralInfoRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
data: DealGeneralInfoSchema
|
data: DealGeneralInfoSchema
|
||||||
|
|
||||||
|
|
||||||
class DealSummaryReorderRequest(CustomModelCamel):
|
class DealSummaryReorderRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
status: int
|
status: int
|
||||||
index: int
|
index: int
|
||||||
@@ -170,11 +171,11 @@ class DealSummaryReorderRequest(CustomModelCamel):
|
|||||||
comment: str | None = None
|
comment: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class DealDeleteRequest(CustomModelCamel):
|
class DealDeleteRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
|
|
||||||
|
|
||||||
class DealUpdateProductRequest(CustomModelCamel):
|
class DealUpdateProductRequest(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
product: DealProductSchema
|
product: DealProductSchema
|
||||||
|
|
||||||
@@ -190,32 +191,32 @@ class DealDeleteServicesResponse(OkMessageSchema):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DealGetAllResponse(CustomModelCamel):
|
class DealGetAllResponse(BaseSchema):
|
||||||
deals: List[DealSchema]
|
deals: List[DealSchema]
|
||||||
|
|
||||||
|
|
||||||
class DealChangeStatusResponse(CustomModelCamel):
|
class DealChangeStatusResponse(BaseSchema):
|
||||||
ok: bool
|
ok: bool
|
||||||
|
|
||||||
|
|
||||||
class DealCreateResponse(CustomModelCamel):
|
class DealCreateResponse(BaseSchema):
|
||||||
ok: bool
|
ok: bool
|
||||||
|
|
||||||
|
|
||||||
class DealQuickCreateResponse(CustomModelCamel):
|
class DealQuickCreateResponse(BaseSchema):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
|
|
||||||
|
|
||||||
class DealSummaryResponse(CustomModelCamel):
|
class DealSummaryResponse(BaseSchema):
|
||||||
summaries: List[DealSummary]
|
summaries: List[DealSummary]
|
||||||
|
|
||||||
|
|
||||||
class DealAddServicesResponse(CustomModelCamel):
|
class DealAddServicesResponse(BaseSchema):
|
||||||
ok: bool
|
ok: bool
|
||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
class DealUpdateServiceQuantityResponse(CustomModelCamel):
|
class DealUpdateServiceQuantityResponse(BaseSchema):
|
||||||
ok: bool
|
ok: bool
|
||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|||||||
20
schemas/position.py
Normal file
20
schemas/position.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
from schemas.base import BaseSchema, OkMessageSchema
|
||||||
|
|
||||||
|
|
||||||
|
class PositionSchema(BaseSchema):
|
||||||
|
name: str
|
||||||
|
key: str
|
||||||
|
|
||||||
|
|
||||||
|
class CreatePositionRequest(BaseSchema):
|
||||||
|
data: PositionSchema
|
||||||
|
|
||||||
|
|
||||||
|
class GetAllPositionsResponse(BaseSchema):
|
||||||
|
positions: List[PositionSchema]
|
||||||
|
|
||||||
|
|
||||||
|
class CreatePositionResponse(OkMessageSchema):
|
||||||
|
pass
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
from schemas.barcode import BarcodeTemplateSchema
|
from schemas.barcode import BarcodeTemplateSchema
|
||||||
from schemas.base import CustomModelCamel, PaginationInfoSchema, OkMessageSchema
|
from schemas.base import BaseSchema, PaginationInfoSchema, OkMessageSchema
|
||||||
from pydantic import field_validator, model_validator
|
from pydantic import field_validator, model_validator
|
||||||
from models import ProductBarcode
|
from models import ProductBarcode
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class ProductImageSchema(CustomModelCamel):
|
class ProductImageSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
product_id: int
|
product_id: int
|
||||||
image_url: str
|
image_url: str
|
||||||
|
|
||||||
|
|
||||||
class BaseProductSchema(CustomModelCamel):
|
class BaseProductSchema(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
article: str | None = ''
|
article: str | None = ''
|
||||||
client_id: int
|
client_id: int
|
||||||
@@ -55,25 +55,25 @@ class ProductCreateRequest(BaseProductSchema):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProductDeleteRequest(CustomModelCamel):
|
class ProductDeleteRequest(BaseSchema):
|
||||||
product_id: int
|
product_id: int
|
||||||
|
|
||||||
|
|
||||||
class ProductUpdateRequest(CustomModelCamel):
|
class ProductUpdateRequest(BaseSchema):
|
||||||
product: ProductSchema
|
product: ProductSchema
|
||||||
|
|
||||||
|
|
||||||
class ProductAddBarcodeRequest(CustomModelCamel):
|
class ProductAddBarcodeRequest(BaseSchema):
|
||||||
product_id: int
|
product_id: int
|
||||||
barcode: str
|
barcode: str
|
||||||
|
|
||||||
|
|
||||||
class ProductDeleteBarcodeRequest(CustomModelCamel):
|
class ProductDeleteBarcodeRequest(BaseSchema):
|
||||||
product_id: int
|
product_id: int
|
||||||
barcode: str
|
barcode: str
|
||||||
|
|
||||||
|
|
||||||
class ProductGenerateBarcodeRequest(CustomModelCamel):
|
class ProductGenerateBarcodeRequest(BaseSchema):
|
||||||
product_id: int
|
product_id: int
|
||||||
|
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class ProductCreateResponse(OkMessageSchema):
|
|||||||
product_id: int | None = None
|
product_id: int | None = None
|
||||||
|
|
||||||
|
|
||||||
class ProductGetResponse(CustomModelCamel):
|
class ProductGetResponse(BaseSchema):
|
||||||
products: List[ProductSchema]
|
products: List[ProductSchema]
|
||||||
pagination_info: PaginationInfoSchema
|
pagination_info: PaginationInfoSchema
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ class ProductGenerateBarcodeResponse(OkMessageSchema):
|
|||||||
barcode: str
|
barcode: str
|
||||||
|
|
||||||
|
|
||||||
class ProductExistsBarcodeResponse(CustomModelCamel):
|
class ProductExistsBarcodeResponse(BaseSchema):
|
||||||
exists: bool
|
exists: bool
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
26
schemas/role.py
Normal file
26
schemas/role.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
from schemas.base import BaseSchema
|
||||||
|
|
||||||
|
|
||||||
|
# region Entities
|
||||||
|
class PermissionSchema(BaseSchema):
|
||||||
|
key: str
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
class RoleSchema(BaseSchema):
|
||||||
|
key: str
|
||||||
|
name: str
|
||||||
|
permissions: List[PermissionSchema]
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Requests
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Responses
|
||||||
|
class GetAllRolesResponse(BaseSchema):
|
||||||
|
roles: List[RoleSchema]
|
||||||
|
# endregion
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from schemas.base import CustomModelCamel, OkMessageSchema, BaseEnumSchema
|
from schemas.base import BaseSchema, OkMessageSchema, BaseEnumSchema
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class ServicePriceRangeSchema(CustomModelCamel):
|
class ServicePriceRangeSchema(BaseSchema):
|
||||||
id: int | None
|
id: int | None
|
||||||
from_quantity: int
|
from_quantity: int
|
||||||
to_quantity: int
|
to_quantity: int
|
||||||
price: float
|
price: float
|
||||||
|
|
||||||
|
|
||||||
class ServiceCategorySchema(CustomModelCamel):
|
class ServiceCategorySchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class ServiceSchema(CustomModelCamel):
|
class ServiceSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
category: ServiceCategorySchema
|
category: ServiceCategorySchema
|
||||||
@@ -30,19 +30,19 @@ class ServiceSchema(CustomModelCamel):
|
|||||||
|
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class ServiceCreateRequest(CustomModelCamel):
|
class ServiceCreateRequest(BaseSchema):
|
||||||
service: ServiceSchema
|
service: ServiceSchema
|
||||||
|
|
||||||
|
|
||||||
class ServiceCreateCategoryRequest(CustomModelCamel):
|
class ServiceCreateCategoryRequest(BaseSchema):
|
||||||
category: ServiceCategorySchema
|
category: ServiceCategorySchema
|
||||||
|
|
||||||
|
|
||||||
class ServiceUpdateRequest(CustomModelCamel):
|
class ServiceUpdateRequest(BaseSchema):
|
||||||
data: ServiceSchema
|
data: ServiceSchema
|
||||||
|
|
||||||
|
|
||||||
class ServiceDeleteRequest(CustomModelCamel):
|
class ServiceDeleteRequest(BaseSchema):
|
||||||
service_id: int
|
service_id: int
|
||||||
|
|
||||||
|
|
||||||
@@ -50,11 +50,11 @@ class ServiceDeleteRequest(CustomModelCamel):
|
|||||||
|
|
||||||
|
|
||||||
# region Responses
|
# region Responses
|
||||||
class ServiceGetAllResponse(CustomModelCamel):
|
class ServiceGetAllResponse(BaseSchema):
|
||||||
services: List[ServiceSchema]
|
services: List[ServiceSchema]
|
||||||
|
|
||||||
|
|
||||||
class ServiceGetAllCategoriesResponse(CustomModelCamel):
|
class ServiceGetAllCategoriesResponse(BaseSchema):
|
||||||
categories: List[ServiceCategorySchema]
|
categories: List[ServiceCategorySchema]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from schemas.base import CustomModelCamel
|
from schemas.base import BaseSchema
|
||||||
|
|
||||||
|
|
||||||
class ShippingWarehouseSchema(CustomModelCamel):
|
class ShippingWarehouseSchema(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class GetAllShippingWarehousesResponse(CustomModelCamel):
|
class GetAllShippingWarehousesResponse(BaseSchema):
|
||||||
shipping_warehouses: List[ShippingWarehouseSchema]
|
shipping_warehouses: List[ShippingWarehouseSchema]
|
||||||
|
|||||||
@@ -1,8 +1,50 @@
|
|||||||
from schemas.base import CustomModelCamel
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from schemas.base import BaseSchema, OkMessageSchema
|
||||||
|
from schemas.position import PositionSchema
|
||||||
|
from schemas.role import RoleSchema
|
||||||
|
|
||||||
|
|
||||||
class UserSchema(CustomModelCamel):
|
# region Entities
|
||||||
|
|
||||||
|
|
||||||
|
class BaseUser(BaseSchema):
|
||||||
id: int
|
id: int
|
||||||
telegram_id: int
|
telegram_id: int
|
||||||
phone_number: str | None = None
|
phone_number: str | None = None
|
||||||
|
first_name: str
|
||||||
|
second_name: str
|
||||||
|
comment: str
|
||||||
|
|
||||||
is_admin: bool
|
is_admin: bool
|
||||||
|
is_blocked: bool
|
||||||
|
is_deleted: bool
|
||||||
|
|
||||||
|
|
||||||
|
class UserSchema(BaseUser):
|
||||||
|
role_key: str
|
||||||
|
role: RoleSchema
|
||||||
|
position: Optional[PositionSchema] = None
|
||||||
|
|
||||||
|
|
||||||
|
class UserUpdate(BaseUser):
|
||||||
|
position_key: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Requests
|
||||||
|
class UpdateUserRequest(BaseSchema):
|
||||||
|
data: UserUpdate
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Responses
|
||||||
|
class GetAllUsersResponse(BaseSchema):
|
||||||
|
users: List[UserSchema]
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateUserResponse(OkMessageSchema):
|
||||||
|
pass
|
||||||
|
# endregion
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from starlette import status
|
|||||||
import backend.config
|
import backend.config
|
||||||
import constants
|
import constants
|
||||||
from backend.session import get_session
|
from backend.session import get_session
|
||||||
|
from enums.user import UserRole
|
||||||
from models import User
|
from models import User
|
||||||
from schemas.auth import *
|
from schemas.auth import *
|
||||||
from services.base import BaseService
|
from services.base import BaseService
|
||||||
@@ -52,8 +53,11 @@ class AuthService(BaseService):
|
|||||||
|
|
||||||
user: Union[User, None] = await self.session.scalar(select(User).where(User.telegram_id == request.id))
|
user: Union[User, None] = await self.session.scalar(select(User).where(User.telegram_id == request.id))
|
||||||
if not user:
|
if not user:
|
||||||
user = User(telegram_id=request.id,
|
user = User(
|
||||||
is_admin=False)
|
telegram_id=request.id,
|
||||||
|
is_admin=False,
|
||||||
|
role_key=UserRole.user
|
||||||
|
)
|
||||||
self.session.add(user)
|
self.session.add(user)
|
||||||
await self.session.commit()
|
await self.session.commit()
|
||||||
access_token = self._generate_jwt_token(user)
|
access_token = self._generate_jwt_token(user)
|
||||||
|
|||||||
@@ -240,13 +240,21 @@ class DealService(BaseService):
|
|||||||
|
|
||||||
async def update_general_info(self, request: DealUpdateGeneralInfoRequest) -> DealUpdateGeneralInfoResponse:
|
async def update_general_info(self, request: DealUpdateGeneralInfoRequest) -> DealUpdateGeneralInfoResponse:
|
||||||
try:
|
try:
|
||||||
deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
|
deal: Deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
|
||||||
if not deal:
|
if not deal:
|
||||||
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
||||||
deal.name = request.data.name
|
deal.name = request.data.name
|
||||||
deal.comment = request.data.comment
|
deal.comment = request.data.comment
|
||||||
deal.is_deleted = request.data.is_deleted
|
deal.is_deleted = request.data.is_deleted
|
||||||
deal.is_completed = request.data.is_completed
|
deal.is_completed = request.data.is_completed
|
||||||
|
|
||||||
|
# Updating shipping warehouse
|
||||||
|
shipping_warehouse_service = ShippingWarehouseService(self.session)
|
||||||
|
shipping_warehouse = await shipping_warehouse_service.get_by_name(request.data.shipping_warehouse)
|
||||||
|
if not shipping_warehouse and request.data.shipping_warehouse:
|
||||||
|
shipping_warehouse = await shipping_warehouse_service.create_by_name(request.data.shipping_warehouse)
|
||||||
|
|
||||||
|
deal.shipping_warehouse = shipping_warehouse
|
||||||
await self.session.commit()
|
await self.session.commit()
|
||||||
return DealUpdateGeneralInfoResponse(ok=True, message='Данные о сделке успешно обновлены')
|
return DealUpdateGeneralInfoResponse(ok=True, message='Данные о сделке успешно обновлены')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
32
services/position.py
Normal file
32
services/position.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from sqlalchemy import select, insert
|
||||||
|
|
||||||
|
from models import Position
|
||||||
|
from schemas.position import *
|
||||||
|
from services.base import BaseService
|
||||||
|
|
||||||
|
|
||||||
|
class PositionService(BaseService):
|
||||||
|
async def get_all(self) -> GetAllPositionsResponse:
|
||||||
|
stmt = select(Position).order_by(Position.key)
|
||||||
|
positions = (await self.session.scalars(stmt)).all()
|
||||||
|
positions_schemas = [PositionSchema.model_validate(position) for position in positions]
|
||||||
|
response = GetAllPositionsResponse(positions=positions_schemas)
|
||||||
|
return response
|
||||||
|
|
||||||
|
async def get_by_key(self, key: str) -> Union[Position, None]:
|
||||||
|
stmt = select(Position).where(Position.key == key)
|
||||||
|
return await self.session.scalar(stmt)
|
||||||
|
|
||||||
|
|
||||||
|
async def create(self, request: CreatePositionRequest) -> CreatePositionResponse:
|
||||||
|
try:
|
||||||
|
if await self.get_by_key(request.data.key):
|
||||||
|
return CreatePositionResponse(ok=False, message='Должность с таким ключом уже существует')
|
||||||
|
stmt = insert(Position).values(request.data.model_dump())
|
||||||
|
await self.session.execute(stmt)
|
||||||
|
await self.session.commit()
|
||||||
|
return CreatePositionResponse(ok=True, message='Должность успешно создана')
|
||||||
|
except Exception as e:
|
||||||
|
return CreatePositionResponse(ok=False, message=str(e))
|
||||||
14
services/role.py
Normal file
14
services/role.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from sqlalchemy import select
|
||||||
|
|
||||||
|
from models import Role
|
||||||
|
from schemas.role import *
|
||||||
|
from services.base import BaseService
|
||||||
|
|
||||||
|
|
||||||
|
class RoleService(BaseService):
|
||||||
|
async def get_all(self) -> GetAllRolesResponse:
|
||||||
|
stmt = (select(Role).order_by(Role.key))
|
||||||
|
roles = (await self.session.scalars(stmt)).all()
|
||||||
|
return GetAllRolesResponse(
|
||||||
|
roles=RoleSchema.from_orm_list(roles)
|
||||||
|
)
|
||||||
47
services/user.py
Normal file
47
services/user.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
from sqlalchemy import select, update, delete, insert
|
||||||
|
|
||||||
|
from models import User, user_position
|
||||||
|
from services.base import BaseService
|
||||||
|
from schemas.user import *
|
||||||
|
|
||||||
|
|
||||||
|
class UserService(BaseService):
|
||||||
|
async def get_all(self) -> GetAllUsersResponse:
|
||||||
|
stmt = (
|
||||||
|
select(User)
|
||||||
|
.order_by(User.id.desc())
|
||||||
|
# .where(User.is_deleted == False)
|
||||||
|
)
|
||||||
|
users = (await self.session.scalars(stmt)).all()
|
||||||
|
users_schemas = [UserSchema.model_validate(user) for user in users]
|
||||||
|
return GetAllUsersResponse(users=users_schemas)
|
||||||
|
|
||||||
|
async def get_by_id(self, user_id: int) -> Optional[User]:
|
||||||
|
return await self.session.scalar(select(User).where(User.id == user_id))
|
||||||
|
|
||||||
|
async def update(self, request: UpdateUserRequest) -> UpdateUserResponse:
|
||||||
|
try:
|
||||||
|
if not self.get_by_id(request.data.id):
|
||||||
|
return UpdateUserResponse(ok=False, message='Указанный пользователь не найден')
|
||||||
|
base_fields = request.data.model_dump_parent()
|
||||||
|
stmt = update(User).values(**base_fields).where(User.id == request.data.id)
|
||||||
|
await self.session.execute(stmt)
|
||||||
|
await self.session.flush()
|
||||||
|
|
||||||
|
# Updating position
|
||||||
|
stmt = delete(user_position).where(user_position.c.user_id == request.data.id)
|
||||||
|
await self.session.execute(stmt)
|
||||||
|
await self.session.flush()
|
||||||
|
|
||||||
|
if not request.data.position_key:
|
||||||
|
await self.session.commit()
|
||||||
|
return UpdateUserResponse(ok=True, message='Пользователь успешно обновлен')
|
||||||
|
stmt = insert(user_position).values(**{
|
||||||
|
'user_id': request.data.id,
|
||||||
|
'position_key': request.data.position_key
|
||||||
|
})
|
||||||
|
await self.session.execute(stmt)
|
||||||
|
await self.session.commit()
|
||||||
|
return UpdateUserResponse(ok=True, message='Пользователь успешно обновлен')
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
19
test.py
19
test.py
@@ -1,9 +1,14 @@
|
|||||||
import struct
|
from typing import Self
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.set_int_max_str_digits(-0)
|
|
||||||
with open('Дизайн.jpg', 'rb') as rf:
|
|
||||||
data = int.from_bytes(rf.read())
|
|
||||||
|
|
||||||
with open('result', 'wb') as rf:
|
class A:
|
||||||
rf.write(data.to_bytes(length=len(str(data))))
|
@classmethod
|
||||||
|
def test(cls) -> Self:
|
||||||
|
return cls()
|
||||||
|
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
a = B.test()
|
||||||
|
|||||||
30
utils/init_roles.py
Normal file
30
utils/init_roles.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from backend.session import session_maker
|
||||||
|
from enums.user import UserRole
|
||||||
|
from models import Role
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
role_name_dictionary = {
|
||||||
|
UserRole.admin: "Админ",
|
||||||
|
UserRole.user: "Базовый пользователь",
|
||||||
|
UserRole.manager: "Менеджер",
|
||||||
|
UserRole.employee: "Сотрудник",
|
||||||
|
}
|
||||||
|
session: AsyncSession = session_maker()
|
||||||
|
for key, name in role_name_dictionary.items():
|
||||||
|
role = Role(
|
||||||
|
key=key,
|
||||||
|
name=name
|
||||||
|
)
|
||||||
|
session.add(role)
|
||||||
|
await session.commit()
|
||||||
|
await session.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
loop.run_until_complete(main())
|
||||||
Reference in New Issue
Block a user