feat: shipping warehouse and cost

This commit is contained in:
2024-07-18 04:57:05 +03:00
parent ba73d5cb09
commit e7235021f9
18 changed files with 148 additions and 1298 deletions

View File

@@ -31,7 +31,8 @@ routers_list = [
routers.client_router, routers.client_router,
routers.service_router, routers.service_router,
routers.product_router, routers.product_router,
routers.barcode_router routers.barcode_router,
routers.shipping_warehouse_router
] ]
for router in routers_list: for router in routers_list:
app.include_router(router) app.include_router(router)

View File

@@ -7,4 +7,6 @@ from .service import *
from .product import * from .product import *
from .secondary import * from .secondary import *
from .barcode import * from .barcode import *
from .shipping_warehouse import *
configure_mappers() configure_mappers()

View File

@@ -1,4 +1,9 @@
from sqlalchemy.orm import declarative_base from sqlalchemy.ext.asyncio import AsyncAttrs
from sqlalchemy.orm import declarative_base, DeclarativeBase
class BaseModel(DeclarativeBase, AsyncAttrs):
pass
BaseModel = declarative_base()
metadata = BaseModel.metadata metadata = BaseModel.metadata

View File

@@ -1,9 +1,10 @@
from enum import IntEnum, unique from enum import IntEnum, unique
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean
from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import relationship, backref, Mapped, mapped_column
from models.base import BaseModel from models.base import BaseModel
from .shipping_warehouse import ShippingWarehouse
@unique @unique
@@ -32,6 +33,9 @@ class Deal(BaseModel):
is_deleted = Column(Boolean, nullable=False, server_default='0', default=False, comment='Удалена') is_deleted = Column(Boolean, nullable=False, server_default='0', default=False, comment='Удалена')
is_completed = Column(Boolean, nullable=False, server_default='0', default=False, comment='Завершена') is_completed = Column(Boolean, nullable=False, server_default='0', default=False, comment='Завершена')
shipping_warehouse_id: Mapped[int] = mapped_column(ForeignKey('shipping_warehouses.id'), nullable=True)
shipping_warehouse: Mapped["ShippingWarehouse"] = relationship()
services = relationship('DealService', back_populates='deal', cascade="all, delete-orphan") services = relationship('DealService', back_populates='deal', cascade="all, delete-orphan")
products = relationship('DealProduct', back_populates='deal', cascade="all, delete-orphan") products = relationship('DealProduct', back_populates='deal', cascade="all, delete-orphan")

View File

@@ -13,12 +13,22 @@ class Service(BaseModel):
category_id = Column(Integer, ForeignKey('service_categories.id'), nullable=False, comment='ID категории услуги') category_id = Column(Integer, ForeignKey('service_categories.id'), nullable=False, comment='ID категории услуги')
category = relationship('ServiceCategory', lazy='joined') category = relationship('ServiceCategory', lazy='joined')
price = Column(Double, nullable=False, comment='Стоимость услуги') price = Column(
Double,
nullable=False,
comment='Стоимость услуги'
)
cost = Column(
Double,
nullable=False,
server_default='0',
comment='Себестоимость услуги'
)
service_type = Column(Integer, service_type = Column(Integer,
server_default=f'{enums.service.ServiceType.DEAL_SERVICE}', server_default=f'{enums.service.ServiceType.DEAL_SERVICE}',
nullable=False, nullable=False,
comment='Тип услуги') comment='Тип услуги')
price_ranges = relationship('ServicePriceRange', price_ranges = relationship('ServicePriceRange',
back_populates='service', back_populates='service',
lazy='selectin', lazy='selectin',

View File

@@ -0,0 +1,9 @@
from sqlalchemy.orm import Mapped, mapped_column
from models import BaseModel
class ShippingWarehouse(BaseModel):
__tablename__ = 'shipping_warehouses'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(nullable=False)

View File

@@ -4,3 +4,4 @@ from .client import client_router
from .service import service_router 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

View File

@@ -0,0 +1,28 @@
from typing import Annotated
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from backend.session import get_session
from schemas.shipping_warehouse import GetAllShippingWarehousesResponse
from services.auth import get_current_user
from services.shipping_warehouse import ShippingWarehouseService
shipping_warehouse_router = APIRouter(
prefix="/shipping-warehouse",
tags=["shipping-warehouse"],
dependencies=[Depends(get_current_user)]
)
@shipping_warehouse_router.get(
'/get-all',
response_model=GetAllShippingWarehousesResponse,
operation_id='get_all_shipping_warehouses'
)
async def get_all(
session: Annotated[AsyncSession, Depends(get_session)]
):
return await ShippingWarehouseService(session).get_all()

View File

@@ -13,6 +13,7 @@ class CustomModelCamel(BaseModel):
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}

View File

@@ -1,10 +1,13 @@
import datetime import datetime
from typing import List from typing import List, Optional
from pydantic import constr
from schemas.base import CustomModelCamel, OkMessageSchema from schemas.base import CustomModelCamel, 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
from schemas.shipping_warehouse import ShippingWarehouseSchema
from schemas.user import UserSchema from schemas.user import UserSchema
@@ -66,6 +69,7 @@ class DealSchema(CustomModelCamel):
is_completed: bool is_completed: bool
client: ClientSchema client: ClientSchema
comment: str comment: str
shipping_warehouse: Optional[ShippingWarehouseSchema] = None
class DealGeneralInfoSchema(CustomModelCamel): class DealGeneralInfoSchema(CustomModelCamel):
@@ -88,10 +92,11 @@ class DealCreateRequest(CustomModelCamel):
class DealQuickCreateRequest(CustomModelCamel): class DealQuickCreateRequest(CustomModelCamel):
name: str name: constr(strip_whitespace=True)
client_name: str client_name: constr(strip_whitespace=True)
comment: str comment: str
acceptance_date: datetime.datetime acceptance_date: datetime.datetime
shipping_warehouse: constr(strip_whitespace=True)
class DealSummaryRequest(CustomModelCamel): class DealSummaryRequest(CustomModelCamel):

View File

@@ -23,6 +23,7 @@ class ServiceSchema(CustomModelCamel):
price: float price: float
service_type: int service_type: int
price_ranges: List[ServicePriceRangeSchema] price_ranges: List[ServicePriceRangeSchema]
cost: Optional[int]
# endregion # endregion

View File

@@ -0,0 +1,12 @@
from typing import List
from schemas.base import CustomModelCamel
class ShippingWarehouseSchema(CustomModelCamel):
id: int
name: str
class GetAllShippingWarehousesResponse(CustomModelCamel):
shipping_warehouses: List[ShippingWarehouseSchema]

View File

@@ -13,6 +13,7 @@ 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
from services.shipping_warehouse import ShippingWarehouseService
class DealService(BaseService): class DealService(BaseService):
@@ -90,6 +91,10 @@ class DealService(BaseService):
request.client_name, request.client_name,
ClientDetailsSchema() ClientDetailsSchema()
) )
shipping_warehouse_service = ShippingWarehouseService(self.session)
shipping_warehouse = await shipping_warehouse_service.get_by_name(name=request.shipping_warehouse)
if not shipping_warehouse:
shipping_warehouse = await shipping_warehouse_service.create_by_name(name=request.shipping_warehouse)
rank = await self._get_rank_for_deal(DealStatus.CREATED) rank = await self._get_rank_for_deal(DealStatus.CREATED)
deal = Deal( deal = Deal(
@@ -97,7 +102,8 @@ class DealService(BaseService):
created_at=datetime.datetime.now(), created_at=datetime.datetime.now(),
client_id=client.id, client_id=client.id,
current_status=DealStatus.CREATED, current_status=DealStatus.CREATED,
lexorank=rank lexorank=rank,
shipping_warehouse_id=shipping_warehouse.id
) )
self.session.add(deal) self.session.add(deal)
await self.session.flush() await self.session.flush()
@@ -167,7 +173,8 @@ class DealService(BaseService):
price_subquery, Deal.id == price_subquery.c.deal_id) price_subquery, Deal.id == price_subquery.c.deal_id)
.where( .where(
Deal.is_deleted == False, Deal.is_deleted == False,
Deal.is_completed == False Deal.is_completed == False,
Deal.current_status != DealStatus.COMPLETED
) )
) )
deals_query = await self.session.execute(q) deals_query = await self.session.execute(q)
@@ -203,7 +210,9 @@ class DealService(BaseService):
deal = await self.session.scalar( deal = await self.session.scalar(
select(Deal) select(Deal)
.options( .options(
joinedload(Deal.client).joinedload(Client.details), joinedload(Deal.shipping_warehouse),
joinedload(Deal.client)
.joinedload(Client.details),
selectinload(Deal.services) selectinload(Deal.services)
.joinedload(models.secondary.DealService.service) .joinedload(models.secondary.DealService.service)
.joinedload(Service.category), .joinedload(Service.category),
@@ -220,6 +229,7 @@ class DealService(BaseService):
.joinedload(DealStatusHistory.user), .joinedload(DealStatusHistory.user),
selectinload(Deal.status_history) selectinload(Deal.status_history)
.noload(DealStatusHistory.deal), .noload(DealStatusHistory.deal),
) )
.where(Deal.id == deal_id) .where(Deal.id == deal_id)
) )

View File

@@ -0,0 +1,37 @@
from typing import Union
from sqlalchemy import select
import models
from schemas.shipping_warehouse import GetAllShippingWarehousesResponse, ShippingWarehouseSchema
from services.base import BaseService
class ShippingWarehouseService(BaseService):
async def get_all(self) -> GetAllShippingWarehousesResponse:
stmt = (
select(
models.ShippingWarehouse
)
.order_by(
models.ShippingWarehouse.id
)
)
shipping_warehouses = (await self.session.scalars(stmt)).all()
result = []
for shipping_warehouse in shipping_warehouses:
result.append(ShippingWarehouseSchema.model_validate(shipping_warehouse))
return GetAllShippingWarehousesResponse(shipping_warehouses=result)
async def get_by_name(self, name: str) -> Union[models.ShippingWarehouse, None]:
stmt = select(models.ShippingWarehouse).where(models.ShippingWarehouse.name == name)
shipping_warehouse = await self.session.scalar(stmt)
return shipping_warehouse
async def create_by_name(self, name: str) -> models.ShippingWarehouse:
shipping_warehouse = models.ShippingWarehouse(
name=name
)
self.session.add(shipping_warehouse)
await self.session.flush()
return shipping_warehouse

9
test.py Normal file
View File

@@ -0,0 +1,9 @@
import struct
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:
rf.write(data.to_bytes(length=len(str(data))))

View File

@@ -1,16 +0,0 @@
from pprint import pprint
import lexorank
from lexorank import Bucket, middle
prev = middle(Bucket.BUCEKT_0)
ranks = [prev]
for _ in range(9):
ranks.append(prev.next())
prev = ranks[-1]
middle_ranks = lexorank.between(ranks[1], ranks[2])
pprint(ranks)
print('----------')
ranks.append(middle_ranks)
ranks = sorted(ranks)
pprint(ranks)

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +0,0 @@
import asyncio
from sqlalchemy import select, func, union
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload
from backend.session import session_maker
from external.s3_uploader.uploader import S3Uploader
from models import Deal, DealProduct, Service
import models
import models.secondary
async def main(session: AsyncSession):
file_bytes = open('photo_2024-04-01 10.26.39.jpeg', 'rb').read()
uploader = S3Uploader('1cc46590-4532-4046-97aa-baf3e49f20ad-AUF')
response = await uploader.upload(file_bytes)
print(response)
async def preload():
async with session_maker() as session:
await main(session)
if __name__ == '__main__':
asyncio.run(preload())