Files
shanxia2.0/backend/app/services/db/weighing_logic.py
T
2026-06-10 22:59:34 +08:00

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)