x
This commit is contained in:
@@ -44,10 +44,26 @@ from .schemas import (
|
||||
from .utils import generate_order_no
|
||||
|
||||
router = APIRouter(prefix="/sales-orders", tags=["销售订单"])
|
||||
VALID_ORDER_STATUSES = {"draft", "manufacturing", "delivered", "paid"}
|
||||
VALID_ORDER_STATUSES = {"manufacturing", "delivered", "paid", "cancelled"}
|
||||
PRODUCTION_STATUSES = {"not_started", "bom_missing", "material_issued", "completed"}
|
||||
|
||||
|
||||
def _compute_delivery_status(order: SalesOrder) -> str:
|
||||
"""物流状态:制造中 / 已交付 / 已作废"""
|
||||
if order.status == "cancelled":
|
||||
return "cancelled"
|
||||
if order.status in ("delivered", "paid") or order.actual_delivery_date:
|
||||
return "delivered"
|
||||
return "manufacturing"
|
||||
|
||||
|
||||
def _compute_payment_status(order: SalesOrder) -> str:
|
||||
"""收款状态:未收款 / 已收款"""
|
||||
if order.status == "paid" or order.actual_payment_date:
|
||||
return "paid"
|
||||
return "unpaid"
|
||||
|
||||
|
||||
def _build_sales_order_response(order: SalesOrder, customer_name: str) -> SalesOrderResponse:
|
||||
return SalesOrderResponse(
|
||||
id=order.id,
|
||||
@@ -59,6 +75,8 @@ def _build_sales_order_response(order: SalesOrder, customer_name: str) -> SalesO
|
||||
actual_delivery_date=order.actual_delivery_date,
|
||||
actual_payment_date=order.actual_payment_date,
|
||||
status=order.status,
|
||||
delivery_status=_compute_delivery_status(order),
|
||||
payment_status=_compute_payment_status(order),
|
||||
production_status=order.production_status or "not_started",
|
||||
production_no=order.production_no,
|
||||
planned_material_cost=Decimal(str(order.planned_material_cost or 0)),
|
||||
@@ -90,6 +108,8 @@ async def _build_sales_order_detail_response(
|
||||
actual_delivery_date=order.actual_delivery_date,
|
||||
actual_payment_date=order.actual_payment_date,
|
||||
status=order.status,
|
||||
delivery_status=_compute_delivery_status(order),
|
||||
payment_status=_compute_payment_status(order),
|
||||
production_status=order.production_status or "not_started",
|
||||
production_no=order.production_no,
|
||||
planned_material_cost=Decimal(str(order.planned_material_cost or 0)),
|
||||
@@ -508,16 +528,27 @@ async def update_sales_order_status(
|
||||
raise HTTPException(status_code=400, detail="订单状态必须为 manufacturing、delivered、paid")
|
||||
|
||||
order, customer = await _get_sales_order_with_customer(db_session, order_id)
|
||||
# 只禁止从已交付状态改为非已收款状态
|
||||
if order.status == "delivered" and payload.status != "paid":
|
||||
raise HTTPException(status_code=400, detail="已交付的销售订单只能修改为已收款状态")
|
||||
|
||||
|
||||
# 状态转换守卫
|
||||
if order.status == "paid":
|
||||
raise HTTPException(status_code=400, detail="已收款的销售订单禁止修改状态")
|
||||
if order.status == "cancelled":
|
||||
raise HTTPException(status_code=400, detail="已作废的销售订单禁止修改状态")
|
||||
if order.status == "manufacturing" and payload.status == "paid":
|
||||
raise HTTPException(status_code=400, detail="制造中的订单不能直接标记为已收款,请先标记为已交付")
|
||||
if order.status == "delivered" and payload.status not in ("paid", "cancelled"):
|
||||
raise HTTPException(status_code=400, detail="已交付的销售订单只能修改为已收款或已作废")
|
||||
if payload.status == "cancelled" and order.status == "paid":
|
||||
raise HTTPException(status_code=400, detail="已收款的订单不能作废,请联系管理员")
|
||||
|
||||
# 根据状态更新相应的日期字段
|
||||
from datetime import datetime
|
||||
if payload.status == "delivered" and not order.actual_delivery_date:
|
||||
order.actual_delivery_date = datetime.now()
|
||||
elif payload.status == "paid" and not order.actual_payment_date:
|
||||
order.actual_payment_date = datetime.now()
|
||||
elif payload.status == "cancelled" and not order.actual_delivery_date:
|
||||
order.actual_delivery_date = datetime.now()
|
||||
|
||||
order.status = payload.status
|
||||
await db_session.commit()
|
||||
|
||||
Reference in New Issue
Block a user