forked from erp-dev/erp
3.9 KiB
3.9 KiB
销售单审批流程与红冲规划
1. 背景
- 销售单在创建时同样进入
PENDING状态,审批通过后才会触发出库流程。 business.services.review_sales_order统一处理审批通过 (APPROVED) 与作废 (CANCELLED) 的业务规则。api_v1/views/business/sales/views.py暴露POST /api/v1/sales-orders/<id>/review/接口,供前端、自动化和第三方系统一致调用。
2. 审批流程总览
| 步骤 | 说明 |
|---|---|
| 1 | 前端调用 POST /api/v1/sales-orders/<id>/review/, body: {"action": "approve"} 或 {"action": "cancel"} |
| 2 | API 层校验员工身份、订单归属商户、action 可选项 |
| 3 | API 调用 review_sales_order,根据 action 映射到 SalesOrderStatusEnum.APPROVED / CANCELLED |
| 4 | Service 端根据状态调用 _approve_sales_order 或 _cancel_sales_order,并在必要时抛出业务异常(如重复审批、已有出入库记录等) |
| 5 | API 返回最新的 SalesOrderSerializer 数据,供前端刷新详情 |
3. 审批通过触发的事务
_approve_sales_order构建stock_flow_items(结构与采购单一致)。- 在事务内将
sales_order.status更新为APPROVED。 - 读取商户设置
auto_create_stock_change_tasks:- 未配置或为
False时,仅更新状态。 - 为
True时投递business.tasks.create_sales_order_stock_entriesCelery 任务。
- 未配置或为
- Celery 任务执行
StockFlowService.stock_out:- 依据仓库模式创建出库
StockChangeRecord/StockChangeDetail。 stock.services.make_stock_change_completed会在自动完成开启时写入Inventory并生成StockSnapshot。
- 依据仓库模式创建出库
- 任务返回
stock_change_record_id与明细信息,并写日志用于审计。
4. 作废流程约束
- 仍通过
POST /api/v1/sales-orders/<id>/review/, body:{"action": "cancel"}。 _cancel_sales_order会检查source_type = SALES且source_id = 销售单ID的StockChangeRecord是否存在。- 若已经生成出库记录,则抛出
ValueError('销售单已生成出入库记录,无法作废'),API 返回400提示前端。 - 若未生成记录,则在事务内将状态更新为
CANCELLED,且不会触发 Celery 任务。
5. 常见异常与返回
- 缺少
customer字段:400+{"error": "缺少客户 ID"}。 - 审批重复:保持幂等,直接返回当前状态。
- 已作废单据审批:
ValueError('作废状态的销售单无法再次审批')->400。 - 作废时已有出库记录:
ValueError('销售单已生成出入库记录,无法作废')->400。 - ID 不存在或不属于当前商户:
404。
6. 创建接口参数约定
销售单创建接口沿用采购单的参数格式,根据仓库模式填写 items:
| 仓库模式 | 出库模式 | items 必填字段 |
|---|---|---|
UNRESTRICTED(宽出) |
无需指定入库明细 | product_id, quantity, num_of_rolls, price, unit |
RESTRICT_IN(严进宽出) |
无需指定入库明细 | product_id, numbers (list[int]), price, unit |
RESTRICT_IN_OUT(严出) |
必须指定要消耗的入库明细 | product_id, consume_detail_ids (list[int]), quantity, price, unit |
说明:在严出模式下,
consume_detail_ids列表中的 ID 必须为同仓库、同商户且未被消耗的入库明细 ID。系统会在审批通过时逐条扣减对应库存。
6. 红冲(对冲)规划
与采购单一致,后续将通过库存红冲入口(StockFlowService.offset_stock_change 占位方法)实现销售单出库的反向抵销。关键原则:
- 采用新增反向记录的方式,保留所有历史变动。
- 红冲记录需要指向原
StockChangeRecord/StockSnapshot,保证审计可追溯。 - 红冲需与业务对象绑定,避免孤立库存操作。
文档与测试应在红冲能力落地时同步更新,确保审批、出库、红冲形成闭环。