125 lines
4.0 KiB
Python
125 lines
4.0 KiB
Python
"""地磅单联动业务逻辑 — 迁移自 simple-dibang-xiaoshou weighing._process_weighing_business_logic。"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import or_
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.db_models import DbInboundOutbound, DbPurchasePlan, DbWeighingSlip
|
|
|
|
|
|
def _has_weight_time(value: datetime | str | None) -> bool:
|
|
if value is None:
|
|
return False
|
|
if isinstance(value, datetime):
|
|
return True
|
|
return bool(str(value).strip())
|
|
|
|
|
|
def process_weighing_business_logic(db: Session, weighing: DbWeighingSlip) -> None:
|
|
"""
|
|
处理地磅单的业务逻辑:
|
|
1. 更新计划单的已执行量(单位:kg)
|
|
2. 更新出入库单的状态
|
|
3. 重新计算地磅单的 executed_quantity(按创建时间顺序累计)
|
|
"""
|
|
plan_ids_to_process: set[str] = set()
|
|
inventory_ids_to_process: set[str] = set()
|
|
|
|
if weighing.purchase_plan_id:
|
|
plan_ids_to_process.add(weighing.purchase_plan_id)
|
|
|
|
if weighing.inbound_outbound_id:
|
|
inventory_ids_to_process.add(weighing.inbound_outbound_id)
|
|
|
|
if weighing.plan_no:
|
|
plans = (
|
|
db.query(DbPurchasePlan)
|
|
.filter(
|
|
DbPurchasePlan.plan_no == weighing.plan_no,
|
|
DbPurchasePlan.del_flag == 0,
|
|
DbPurchasePlan.tenant_no == weighing.tenant_no,
|
|
)
|
|
.all()
|
|
)
|
|
for plan in plans:
|
|
plan_ids_to_process.add(plan.id)
|
|
|
|
for plan_id in plan_ids_to_process:
|
|
plan = db.query(DbPurchasePlan).filter(DbPurchasePlan.id == plan_id).one_or_none()
|
|
if not plan:
|
|
continue
|
|
|
|
plan_weighings = (
|
|
db.query(DbWeighingSlip)
|
|
.filter(
|
|
DbWeighingSlip.is_voided == 0,
|
|
DbWeighingSlip.del_flag == 0,
|
|
DbWeighingSlip.tenant_no == plan.tenant_no,
|
|
or_(
|
|
DbWeighingSlip.plan_no == plan.plan_no,
|
|
DbWeighingSlip.purchase_plan_id == plan.id,
|
|
),
|
|
)
|
|
.order_by(DbWeighingSlip.create_time.asc())
|
|
.all()
|
|
)
|
|
|
|
total_executed = sum(w.net_weight for w in plan_weighings if w.net_weight)
|
|
plan.executed_quantity = total_executed
|
|
|
|
planned_quantity_kg = plan.planned_quantity * 1000
|
|
if total_executed >= planned_quantity_kg:
|
|
plan.execution_status = "已入库" if plan.business_type == "入库" else "已出库"
|
|
elif total_executed > 0:
|
|
plan.execution_status = "入库中" if plan.business_type == "入库" else "出库中"
|
|
else:
|
|
plan.execution_status = "待入库" if plan.business_type == "入库" else "待出库"
|
|
|
|
db.commit()
|
|
db.refresh(plan)
|
|
|
|
cumulative_executed = 0.0
|
|
for slip in plan_weighings:
|
|
cumulative_executed += slip.net_weight if slip.net_weight else 0.0
|
|
slip.executed_quantity = cumulative_executed
|
|
db.commit()
|
|
|
|
for inventory_id in inventory_ids_to_process:
|
|
inventory = (
|
|
db.query(DbInboundOutbound)
|
|
.filter(DbInboundOutbound.id == inventory_id)
|
|
.one_or_none()
|
|
)
|
|
if not inventory:
|
|
continue
|
|
|
|
related_weighings = (
|
|
db.query(DbWeighingSlip)
|
|
.filter(
|
|
DbWeighingSlip.inbound_outbound_id == inventory_id,
|
|
DbWeighingSlip.is_voided == 0,
|
|
DbWeighingSlip.del_flag == 0,
|
|
)
|
|
.all()
|
|
)
|
|
|
|
all_complete = (
|
|
len(related_weighings) > 0
|
|
and all(
|
|
_has_weight_time(w.gross_weight_time) and _has_weight_time(w.tare_weight_time)
|
|
for w in related_weighings
|
|
)
|
|
)
|
|
|
|
if all_complete:
|
|
inventory.status = "已完成"
|
|
else:
|
|
inventory.status = (
|
|
"待入库" if inventory.business_type == "入库" else "待出库"
|
|
)
|
|
|
|
db.commit()
|
|
db.refresh(inventory)
|