功能:实现托盘两阶段退回
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from datetime import datetime, time, timedelta
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy import ColumnElement, Select, delete, false, select, update
|
||||
from sqlalchemy import ColumnElement, Select, delete, false, or_, select, update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
||||
|
||||
@@ -94,6 +94,27 @@ class OperationDao:
|
||||
conditions.append(BizShipmentOrder.target_site_id.in_(scoped_site_ids) if scoped_site_ids else false())
|
||||
return conditions
|
||||
|
||||
@staticmethod
|
||||
def _return_scope_conditions(
|
||||
site_ids: list[int] | None,
|
||||
warehouse_ids: list[int] | None,
|
||||
) -> list[ColumnElement[bool]]:
|
||||
if site_ids is None and warehouse_ids is None:
|
||||
return []
|
||||
|
||||
visibility_conditions: list[ColumnElement[bool]] = []
|
||||
if site_ids is not None:
|
||||
scoped_site_ids = sorted(set(site_ids))
|
||||
visibility_conditions.append(
|
||||
BizReturnOrder.source_site_id.in_(scoped_site_ids) if scoped_site_ids else false()
|
||||
)
|
||||
if warehouse_ids is not None:
|
||||
scoped_warehouse_ids = sorted(set(warehouse_ids))
|
||||
visibility_conditions.append(
|
||||
BizReturnOrder.target_warehouse_id.in_(scoped_warehouse_ids) if scoped_warehouse_ids else false()
|
||||
)
|
||||
return [or_(*visibility_conditions)]
|
||||
|
||||
@staticmethod
|
||||
async def _paginate(
|
||||
db: AsyncSession,
|
||||
@@ -300,13 +321,32 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
return_id: int,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizReturnOrder | None:
|
||||
return await cls._get_for_update(
|
||||
return_order = await cls._get_for_update(
|
||||
db,
|
||||
BizReturnOrder,
|
||||
BizReturnOrder.return_id,
|
||||
return_id,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids),
|
||||
)
|
||||
if return_order is None:
|
||||
return None
|
||||
|
||||
# 父单锁定后使用 locking read 获取当前明细,避免 MySQL RR 沿用旧快照。
|
||||
item_result = await db.execute(
|
||||
select(BizReturnItem)
|
||||
.where(BizReturnItem.return_id == return_id)
|
||||
.order_by(BizReturnItem.pallet_id, BizReturnItem.return_item_id)
|
||||
.with_for_update()
|
||||
.execution_options(populate_existing=True)
|
||||
)
|
||||
return_order.items = sorted(
|
||||
item_result.scalars().all(),
|
||||
key=lambda item: (item.pallet_id, item.return_item_id),
|
||||
)
|
||||
return return_order
|
||||
|
||||
@classmethod
|
||||
async def get_active_filling_for_update(
|
||||
@@ -387,12 +427,15 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
idempotency_key: str,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizReturnOrder | None:
|
||||
return await cls._get_by_key(
|
||||
db,
|
||||
BizReturnOrder,
|
||||
BizReturnOrder.request_idempotency_key,
|
||||
idempotency_key,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -400,12 +443,15 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
idempotency_key: str,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizReturnOrder | None:
|
||||
return await cls._get_by_key(
|
||||
db,
|
||||
BizReturnOrder,
|
||||
BizReturnOrder.confirm_idempotency_key,
|
||||
idempotency_key,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -718,8 +764,10 @@ class OperationDao:
|
||||
db: AsyncSession,
|
||||
query_object: ReturnPageQueryModel,
|
||||
is_page: bool = True,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> PageModel | list[dict[str, Any]]:
|
||||
conditions = []
|
||||
conditions = cls._return_scope_conditions(site_ids, warehouse_ids)
|
||||
if query_object.return_no:
|
||||
conditions.append(BizReturnOrder.return_no.like(f'%{query_object.return_no}%'))
|
||||
if query_object.source_site_id:
|
||||
@@ -743,6 +791,8 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
return_id: int,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizReturnOrder | None:
|
||||
return await cls._get_order_detail(
|
||||
db,
|
||||
@@ -752,6 +802,7 @@ class OperationDao:
|
||||
BizReturnItem,
|
||||
BizReturnItem.return_id,
|
||||
BizReturnItem.return_item_id,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user