feat: shipping warehouse and cost
This commit is contained in:
3
main.py
3
main.py
@@ -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)
|
||||
|
||||
@@ -7,4 +7,6 @@ from .service import *
|
||||
from .product import *
|
||||
from .secondary import *
|
||||
from .barcode import *
|
||||
from .shipping_warehouse import *
|
||||
|
||||
configure_mappers()
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
|
||||
@@ -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',
|
||||
|
||||
9
models/shipping_warehouse.py
Normal file
9
models/shipping_warehouse.py
Normal 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)
|
||||
@@ -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
|
||||
|
||||
28
routers/shipping_warehouse.py
Normal file
28
routers/shipping_warehouse.py
Normal 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()
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -23,6 +23,7 @@ class ServiceSchema(CustomModelCamel):
|
||||
price: float
|
||||
service_type: int
|
||||
price_ranges: List[ServicePriceRangeSchema]
|
||||
cost: Optional[int]
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
12
schemas/shipping_warehouse.py
Normal file
12
schemas/shipping_warehouse.py
Normal 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]
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
37
services/shipping_warehouse.py
Normal file
37
services/shipping_warehouse.py
Normal 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
9
test.py
Normal 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))))
|
||||
@@ -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)
|
||||
1241
test/test.json
1241
test/test.json
File diff suppressed because it is too large
Load Diff
28
test/test.py
28
test/test.py
@@ -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())
|
||||
Reference in New Issue
Block a user