| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- """地磅单联动业务逻辑 — 迁移自 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)
|