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.service_router,
routers.product_router,
routers.barcode_router
routers.barcode_router,
routers.shipping_warehouse_router
]
for router in routers_list:
app.include_router(router)

View File

@@ -7,4 +7,6 @@ from .service import *
from .product import *
from .secondary import *
from .barcode import *
from .shipping_warehouse import *
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

View File

@@ -1,9 +1,10 @@
from enum import IntEnum, unique
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 .shipping_warehouse import ShippingWarehouse
@unique
@@ -32,6 +33,9 @@ class Deal(BaseModel):
is_deleted = 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")
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 = 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,
server_default=f'{enums.service.ServiceType.DEAL_SERVICE}',
nullable=False,
comment='Тип услуги')
price_ranges = relationship('ServicePriceRange',
back_populates='service',
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 .product import product_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
populate_by_name = True
@classmethod
def from_sql_model(cls, model, fields: dict):
model_dict = {c.name: getattr(model, c.name) for c in model.__table__.columns}

View File

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

View File

@@ -23,6 +23,7 @@ class ServiceSchema(CustomModelCamel):
price: float
service_type: int
price_ranges: List[ServicePriceRangeSchema]
cost: Optional[int]
# 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 services.base import BaseService
from services.client import ClientService
from services.shipping_warehouse import ShippingWarehouseService
class DealService(BaseService):
@@ -90,6 +91,10 @@ class DealService(BaseService):
request.client_name,
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)
deal = Deal(
@@ -97,7 +102,8 @@ class DealService(BaseService):
created_at=datetime.datetime.now(),
client_id=client.id,
current_status=DealStatus.CREATED,
lexorank=rank
lexorank=rank,
shipping_warehouse_id=shipping_warehouse.id
)
self.session.add(deal)
await self.session.flush()
@@ -167,7 +173,8 @@ class DealService(BaseService):
price_subquery, Deal.id == price_subquery.c.deal_id)
.where(
Deal.is_deleted == False,
Deal.is_completed == False
Deal.is_completed == False,
Deal.current_status != DealStatus.COMPLETED
)
)
deals_query = await self.session.execute(q)
@@ -203,7 +210,9 @@ class DealService(BaseService):
deal = await self.session.scalar(
select(Deal)
.options(
joinedload(Deal.client).joinedload(Client.details),
joinedload(Deal.shipping_warehouse),
joinedload(Deal.client)
.joinedload(Client.details),
selectinload(Deal.services)
.joinedload(models.secondary.DealService.service)
.joinedload(Service.category),
@@ -220,6 +229,7 @@ class DealService(BaseService):
.joinedload(DealStatusHistory.user),
selectinload(Deal.status_history)
.noload(DealStatusHistory.deal),
)
.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())