功能:隔离五类测试业务链路
This commit is contained in:
@@ -7,6 +7,7 @@ from sqlalchemy.orm.attributes import InstrumentedAttribute
|
||||
|
||||
from common.vo import PageModel
|
||||
from module_business.domain.enums import DocumentStatus, PalletFlowState
|
||||
from module_business.domain.test_batch_scope import TestBatchScope, batch_scope_condition
|
||||
from module_business.entity.do.master_do import BizPallet
|
||||
from module_business.entity.do.operation_do import (
|
||||
BizFillingRecord,
|
||||
@@ -56,36 +57,49 @@ class OperationDao:
|
||||
@staticmethod
|
||||
def _inbound_scope_conditions(
|
||||
warehouse_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
) -> list[ColumnElement[bool]]:
|
||||
if warehouse_ids is None:
|
||||
return []
|
||||
return [batch_scope_condition(BizInboundOrder.test_batch_id, scope)]
|
||||
scoped_warehouse_ids = sorted(set(warehouse_ids))
|
||||
return [BizInboundOrder.warehouse_id.in_(scoped_warehouse_ids) if scoped_warehouse_ids else false()]
|
||||
return [
|
||||
batch_scope_condition(BizInboundOrder.test_batch_id, scope),
|
||||
BizInboundOrder.warehouse_id.in_(scoped_warehouse_ids) if scoped_warehouse_ids else false(),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _filling_scope_conditions(
|
||||
warehouse_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
) -> list[ColumnElement[bool]]:
|
||||
if warehouse_ids is None:
|
||||
return []
|
||||
return [batch_scope_condition(BizFillingRecord.test_batch_id, scope)]
|
||||
scoped_warehouse_ids = sorted(set(warehouse_ids))
|
||||
return [BizFillingRecord.warehouse_id.in_(scoped_warehouse_ids) if scoped_warehouse_ids else false()]
|
||||
return [
|
||||
batch_scope_condition(BizFillingRecord.test_batch_id, scope),
|
||||
BizFillingRecord.warehouse_id.in_(scoped_warehouse_ids) if scoped_warehouse_ids else false(),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _usage_scope_conditions(
|
||||
site_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
) -> list[ColumnElement[bool]]:
|
||||
if site_ids is None:
|
||||
return []
|
||||
return [batch_scope_condition(BizUsageRecord.test_batch_id, scope)]
|
||||
scoped_site_ids = sorted(set(site_ids))
|
||||
return [BizUsageRecord.site_id.in_(scoped_site_ids) if scoped_site_ids else false()]
|
||||
return [
|
||||
batch_scope_condition(BizUsageRecord.test_batch_id, scope),
|
||||
BizUsageRecord.site_id.in_(scoped_site_ids) if scoped_site_ids else false(),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _shipment_scope_conditions(
|
||||
warehouse_ids: list[int] | None,
|
||||
site_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
) -> list[ColumnElement[bool]]:
|
||||
conditions = []
|
||||
conditions = [batch_scope_condition(BizShipmentOrder.test_batch_id, scope)]
|
||||
if warehouse_ids is not None:
|
||||
scoped_warehouse_ids = sorted(set(warehouse_ids))
|
||||
conditions.append(
|
||||
@@ -100,9 +114,10 @@ class OperationDao:
|
||||
def _return_scope_conditions(
|
||||
site_ids: list[int] | None,
|
||||
warehouse_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
) -> list[ColumnElement[bool]]:
|
||||
if site_ids is None and warehouse_ids is None:
|
||||
return []
|
||||
return [batch_scope_condition(BizReturnOrder.test_batch_id, scope)]
|
||||
|
||||
visibility_conditions: list[ColumnElement[bool]] = []
|
||||
if site_ids is not None:
|
||||
@@ -115,7 +130,7 @@ class OperationDao:
|
||||
visibility_conditions.append(
|
||||
BizReturnOrder.target_warehouse_id.in_(scoped_warehouse_ids) if scoped_warehouse_ids else false()
|
||||
)
|
||||
return [or_(*visibility_conditions)]
|
||||
return [batch_scope_condition(BizReturnOrder.test_batch_id, scope), or_(*visibility_conditions)]
|
||||
|
||||
@staticmethod
|
||||
async def _paginate(
|
||||
@@ -180,6 +195,7 @@ class OperationDao:
|
||||
item_model: type[Any],
|
||||
item_order_id_column: InstrumentedAttribute,
|
||||
item_id_column: InstrumentedAttribute,
|
||||
scope: TestBatchScope,
|
||||
*order_conditions: ColumnElement[bool],
|
||||
) -> Any | None:
|
||||
order = await cls._get_by_id(
|
||||
@@ -193,7 +209,9 @@ class OperationDao:
|
||||
return None
|
||||
|
||||
item_result = await db.execute(
|
||||
select(item_model).where(item_order_id_column == order_id).order_by(item_id_column)
|
||||
select(item_model)
|
||||
.where(item_order_id_column == order_id, batch_scope_condition(item_model.test_batch_id, scope))
|
||||
.order_by(item_id_column)
|
||||
)
|
||||
order.items = list(item_result.scalars().all())
|
||||
return order
|
||||
@@ -260,6 +278,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
inbound_id: int,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizInboundOrder | None:
|
||||
inbound = await cls._get_for_update(
|
||||
@@ -267,7 +286,7 @@ class OperationDao:
|
||||
BizInboundOrder,
|
||||
BizInboundOrder.inbound_id,
|
||||
inbound_id,
|
||||
*cls._inbound_scope_conditions(warehouse_ids),
|
||||
*cls._inbound_scope_conditions(warehouse_ids, scope),
|
||||
)
|
||||
if inbound is None:
|
||||
return None
|
||||
@@ -275,7 +294,10 @@ class OperationDao:
|
||||
# 父单锁定后用 locking read 获取最新明细,避免 MySQL RR 继续读取确认前的旧快照。
|
||||
item_result = await db.execute(
|
||||
select(BizInboundItem)
|
||||
.where(BizInboundItem.inbound_id == inbound_id)
|
||||
.where(
|
||||
BizInboundItem.inbound_id == inbound_id,
|
||||
batch_scope_condition(BizInboundItem.test_batch_id, scope),
|
||||
)
|
||||
.order_by(BizInboundItem.pallet_id, BizInboundItem.inbound_item_id)
|
||||
.with_for_update()
|
||||
.execution_options(populate_existing=True)
|
||||
@@ -291,6 +313,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
shipment_id: int,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> BizShipmentOrder | None:
|
||||
@@ -299,7 +322,7 @@ class OperationDao:
|
||||
BizShipmentOrder,
|
||||
BizShipmentOrder.shipment_id,
|
||||
shipment_id,
|
||||
*cls._shipment_scope_conditions(warehouse_ids, site_ids),
|
||||
*cls._shipment_scope_conditions(warehouse_ids, site_ids, scope),
|
||||
)
|
||||
if shipment is None:
|
||||
return None
|
||||
@@ -307,7 +330,10 @@ class OperationDao:
|
||||
# 父单锁定后读取当前明细,避免 MySQL RR 沿用确认前的快照。
|
||||
item_result = await db.execute(
|
||||
select(BizShipmentItem)
|
||||
.where(BizShipmentItem.shipment_id == shipment_id)
|
||||
.where(
|
||||
BizShipmentItem.shipment_id == shipment_id,
|
||||
batch_scope_condition(BizShipmentItem.test_batch_id, scope),
|
||||
)
|
||||
.order_by(BizShipmentItem.pallet_id, BizShipmentItem.shipment_item_id)
|
||||
.with_for_update()
|
||||
.execution_options(populate_existing=True)
|
||||
@@ -323,6 +349,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
return_id: int,
|
||||
scope: TestBatchScope,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizReturnOrder | None:
|
||||
@@ -331,7 +358,7 @@ class OperationDao:
|
||||
BizReturnOrder,
|
||||
BizReturnOrder.return_id,
|
||||
return_id,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids),
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids, scope),
|
||||
)
|
||||
if return_order is None:
|
||||
return None
|
||||
@@ -339,7 +366,10 @@ class OperationDao:
|
||||
# 父单锁定后使用 locking read 获取当前明细,避免 MySQL RR 沿用旧快照。
|
||||
item_result = await db.execute(
|
||||
select(BizReturnItem)
|
||||
.where(BizReturnItem.return_id == return_id)
|
||||
.where(
|
||||
BizReturnItem.return_id == return_id,
|
||||
batch_scope_condition(BizReturnItem.test_batch_id, scope),
|
||||
)
|
||||
.order_by(BizReturnItem.pallet_id, BizReturnItem.return_item_id)
|
||||
.with_for_update()
|
||||
.execution_options(populate_existing=True)
|
||||
@@ -355,6 +385,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
filling_id: int,
|
||||
scope: TestBatchScope,
|
||||
) -> BizFillingRecord | None:
|
||||
"""按已锁库存的 active_filling_id 锁定仍处于活动状态的装填周期。"""
|
||||
return await cls._get_for_update(
|
||||
@@ -362,6 +393,7 @@ class OperationDao:
|
||||
BizFillingRecord,
|
||||
BizFillingRecord.filling_id,
|
||||
filling_id,
|
||||
batch_scope_condition(BizFillingRecord.test_batch_id, scope),
|
||||
BizFillingRecord.active_slot == 'ACTIVE',
|
||||
)
|
||||
|
||||
@@ -370,6 +402,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
idempotency_key: str,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizInboundOrder | None:
|
||||
return await cls._get_by_key(
|
||||
@@ -377,7 +410,7 @@ class OperationDao:
|
||||
BizInboundOrder,
|
||||
BizInboundOrder.confirm_idempotency_key,
|
||||
idempotency_key,
|
||||
*cls._inbound_scope_conditions(warehouse_ids),
|
||||
*cls._inbound_scope_conditions(warehouse_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -385,6 +418,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
idempotency_key: str,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> BizShipmentOrder | None:
|
||||
@@ -393,7 +427,7 @@ class OperationDao:
|
||||
BizShipmentOrder,
|
||||
BizShipmentOrder.confirm_idempotency_key,
|
||||
idempotency_key,
|
||||
*cls._shipment_scope_conditions(warehouse_ids, site_ids),
|
||||
*cls._shipment_scope_conditions(warehouse_ids, site_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -401,6 +435,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
idempotency_key: str,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizFillingRecord | None:
|
||||
return await cls._get_by_key(
|
||||
@@ -408,7 +443,7 @@ class OperationDao:
|
||||
BizFillingRecord,
|
||||
BizFillingRecord.idempotency_key,
|
||||
idempotency_key,
|
||||
*cls._filling_scope_conditions(warehouse_ids),
|
||||
*cls._filling_scope_conditions(warehouse_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -416,6 +451,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
idempotency_key: str,
|
||||
scope: TestBatchScope,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> BizUsageRecord | None:
|
||||
return await cls._get_by_key(
|
||||
@@ -423,7 +459,7 @@ class OperationDao:
|
||||
BizUsageRecord,
|
||||
BizUsageRecord.idempotency_key,
|
||||
idempotency_key,
|
||||
*cls._usage_scope_conditions(site_ids),
|
||||
*cls._usage_scope_conditions(site_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -433,6 +469,7 @@ class OperationDao:
|
||||
idempotency_key: str,
|
||||
source_site_id: int,
|
||||
target_warehouse_id: int,
|
||||
scope: TestBatchScope,
|
||||
) -> BizReturnOrder | None:
|
||||
return await cls._get_by_key(
|
||||
db,
|
||||
@@ -441,6 +478,7 @@ class OperationDao:
|
||||
idempotency_key,
|
||||
BizReturnOrder.source_site_id == source_site_id,
|
||||
BizReturnOrder.target_warehouse_id == target_warehouse_id,
|
||||
batch_scope_condition(BizReturnOrder.test_batch_id, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -450,6 +488,7 @@ class OperationDao:
|
||||
idempotency_key: str,
|
||||
source_site_id: int,
|
||||
target_warehouse_id: int,
|
||||
scope: TestBatchScope,
|
||||
) -> BizReturnOrder | None:
|
||||
return await cls._get_by_key(
|
||||
db,
|
||||
@@ -458,6 +497,7 @@ class OperationDao:
|
||||
idempotency_key,
|
||||
BizReturnOrder.source_site_id == source_site_id,
|
||||
BizReturnOrder.target_warehouse_id == target_warehouse_id,
|
||||
batch_scope_condition(BizReturnOrder.test_batch_id, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -465,10 +505,11 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
query_object: InboundPageQueryModel,
|
||||
warehouse_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
is_page: bool = True,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> PageModel | list[dict[str, Any]]:
|
||||
conditions = cls._inbound_scope_conditions(warehouse_ids)
|
||||
conditions = cls._inbound_scope_conditions(warehouse_ids, scope)
|
||||
if query_object.inbound_no:
|
||||
conditions.append(BizInboundOrder.inbound_no.like(f'%{query_object.inbound_no}%'))
|
||||
if query_object.warehouse_id:
|
||||
@@ -490,6 +531,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
inbound_id: int,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizInboundOrder | None:
|
||||
return await cls._get_order_detail(
|
||||
@@ -500,7 +542,8 @@ class OperationDao:
|
||||
BizInboundItem,
|
||||
BizInboundItem.inbound_id,
|
||||
BizInboundItem.inbound_item_id,
|
||||
*cls._inbound_scope_conditions(warehouse_ids),
|
||||
scope,
|
||||
*cls._inbound_scope_conditions(warehouse_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -549,10 +592,11 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
query_object: FillingPageQueryModel,
|
||||
warehouse_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
is_page: bool = True,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> PageModel | list[dict[str, Any]]:
|
||||
conditions = cls._filling_scope_conditions(warehouse_ids)
|
||||
conditions = cls._filling_scope_conditions(warehouse_ids, scope)
|
||||
if query_object.filling_no:
|
||||
conditions.append(BizFillingRecord.filling_no.like(f'%{query_object.filling_no}%'))
|
||||
if query_object.warehouse_id:
|
||||
@@ -584,6 +628,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
filling_id: int,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizFillingRecord | None:
|
||||
return await cls._get_by_id(
|
||||
@@ -591,7 +636,7 @@ class OperationDao:
|
||||
BizFillingRecord,
|
||||
BizFillingRecord.filling_id,
|
||||
filling_id,
|
||||
*cls._filling_scope_conditions(warehouse_ids),
|
||||
*cls._filling_scope_conditions(warehouse_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -620,11 +665,12 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
query_object: ShipmentPageQueryModel,
|
||||
warehouse_ids: list[int] | None,
|
||||
site_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
is_page: bool = True,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> PageModel | list[dict[str, Any]]:
|
||||
conditions = cls._shipment_scope_conditions(warehouse_ids, site_ids)
|
||||
conditions = cls._shipment_scope_conditions(warehouse_ids, site_ids, scope)
|
||||
if query_object.shipment_no:
|
||||
conditions.append(BizShipmentOrder.shipment_no.like(f'%{query_object.shipment_no}%'))
|
||||
if query_object.source_warehouse_id:
|
||||
@@ -648,6 +694,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
shipment_id: int,
|
||||
scope: TestBatchScope,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> BizShipmentOrder | None:
|
||||
@@ -656,7 +703,7 @@ class OperationDao:
|
||||
BizShipmentOrder,
|
||||
BizShipmentOrder.shipment_id,
|
||||
shipment_id,
|
||||
*cls._shipment_scope_conditions(warehouse_ids, site_ids),
|
||||
*cls._shipment_scope_conditions(warehouse_ids, site_ids, scope),
|
||||
)
|
||||
if shipment is None:
|
||||
return None
|
||||
@@ -674,9 +721,13 @@ class OperationDao:
|
||||
BizPalletInventory.current_line_id.is_(None),
|
||||
BizPalletInventory.active_filling_id.is_not(None),
|
||||
BizPalletInventory.remaining_packages > 0,
|
||||
batch_scope_condition(BizPalletInventory.test_batch_id, scope),
|
||||
),
|
||||
)
|
||||
.where(BizShipmentItem.shipment_id == shipment_id)
|
||||
.where(
|
||||
BizShipmentItem.shipment_id == shipment_id,
|
||||
batch_scope_condition(BizShipmentItem.test_batch_id, scope),
|
||||
)
|
||||
.order_by(BizShipmentItem.shipment_item_id)
|
||||
)
|
||||
items = []
|
||||
@@ -686,7 +737,10 @@ class OperationDao:
|
||||
else:
|
||||
item_result = await db.execute(
|
||||
select(BizShipmentItem)
|
||||
.where(BizShipmentItem.shipment_id == shipment_id)
|
||||
.where(
|
||||
BizShipmentItem.shipment_id == shipment_id,
|
||||
batch_scope_condition(BizShipmentItem.test_batch_id, scope),
|
||||
)
|
||||
.order_by(BizShipmentItem.shipment_item_id)
|
||||
)
|
||||
items = list(item_result.scalars().all())
|
||||
@@ -746,10 +800,11 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
query_object: UsagePageQueryModel,
|
||||
site_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
is_page: bool = True,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> PageModel | list[dict[str, Any]]:
|
||||
conditions = cls._usage_scope_conditions(site_ids)
|
||||
conditions = cls._usage_scope_conditions(site_ids, scope)
|
||||
if query_object.usage_no:
|
||||
conditions.append(BizUsageRecord.usage_no.like(f'%{query_object.usage_no}%'))
|
||||
if query_object.site_id:
|
||||
@@ -779,6 +834,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
usage_id: int,
|
||||
scope: TestBatchScope,
|
||||
site_ids: list[int] | None = None,
|
||||
) -> BizUsageRecord | None:
|
||||
return await cls._get_by_id(
|
||||
@@ -786,7 +842,7 @@ class OperationDao:
|
||||
BizUsageRecord,
|
||||
BizUsageRecord.usage_id,
|
||||
usage_id,
|
||||
*cls._usage_scope_conditions(site_ids),
|
||||
*cls._usage_scope_conditions(site_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -802,11 +858,12 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
query_object: ReturnPageQueryModel,
|
||||
site_ids: list[int] | None,
|
||||
warehouse_ids: list[int] | None,
|
||||
scope: TestBatchScope,
|
||||
is_page: bool = True,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> PageModel | list[dict[str, Any]]:
|
||||
conditions = cls._return_scope_conditions(site_ids, warehouse_ids)
|
||||
conditions = cls._return_scope_conditions(site_ids, warehouse_ids, scope)
|
||||
if query_object.return_no:
|
||||
conditions.append(BizReturnOrder.return_no.like(f'%{query_object.return_no}%'))
|
||||
if query_object.source_site_id:
|
||||
@@ -830,6 +887,7 @@ class OperationDao:
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
return_id: int,
|
||||
scope: TestBatchScope,
|
||||
site_ids: list[int] | None = None,
|
||||
warehouse_ids: list[int] | None = None,
|
||||
) -> BizReturnOrder | None:
|
||||
@@ -841,7 +899,8 @@ class OperationDao:
|
||||
BizReturnItem,
|
||||
BizReturnItem.return_id,
|
||||
BizReturnItem.return_item_id,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids),
|
||||
scope,
|
||||
*cls._return_scope_conditions(site_ids, warehouse_ids, scope),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user