1
0
forked from erp-dev/erp

feat: sales return order and purchase return order

This commit is contained in:
2025-12-01 16:52:59 +08:00
parent a3b4af2602
commit fae33809ac
17 changed files with 1745 additions and 6 deletions

View File

@@ -21,7 +21,7 @@
---
## 2. 采购PurchaseOrder
## 2. 采购相关:采购单 + 采购退货单
| API | 方法 | 描述 |
|-----|------|------|
@@ -59,9 +59,21 @@
成功返回最新的采购单序列化(含 `items``total_amount``status_name` 等)。
### 2.3 采购退货单PurchaseReturnOrder
| API | 方法 | 描述 |
|-----|------|------|
| `/purchase-return-orders/` | GET/POST | 与采购单相同的查询/创建接口,字段改为 `return_date`。 |
| `/purchase-return-orders/<id>/review/` | POST | 审批或作废,流程与采购单一致。 |
- **创建字段**`supplier``warehouse``return_date``items`、可选 `purchase_order``items` 结构沿用采购单;当仓库 `mode=RESTRICT_IN_OUT` 时必须提供 `consume_detail_ids`,指明要冲销的入库明细。
- **审批逻辑**
- `approve`:在事务内锁单、构建 `stock_flow_items`,状态置为 `APPROVED`,调用 `StockFlowService.stock_out`source=`PURCHASE_RETURN`),并向 `BalanceService` 写入 **负值** 以减少供应商应付。
- `cancel`:仅允许 `PENDING` 且尚未生成 `StockChangeRecord` 的单据;审批完成后禁止作废。
---
## 3. 销售SalesOrder
## 3. 销售相关:销售单 + 销售退货单
| API | 方法 | 描述 |
|-----|------|------|
@@ -107,6 +119,18 @@
- `approve`:写入客户余额(正向欠款),若商户配置自动出库则触发 `create_sales_order_stock_entries`
- `cancel`:如果已存在 `StockChangeRecord`source=`SALES`)则拒绝。
### 3.3 销售退货单SalesReturnOrder
| API | 方法 | 描述 |
|-----|------|------|
| `/sales-return-orders/` | GET/POST | 创建 / 列表接口。 |
| `/sales-return-orders/<id>/review/` | POST | 审批或作废。 |
- **创建字段**`customer``warehouse``return_date``items`、可选 `sales_order`。因退货为入库动作,严出仓不再需要 `consume_detail_ids`
- **审批逻辑**
- `approve`:状态置为 `APPROVED`,调用 `StockFlowService.stock_in`source=`SALES_RETURN`),并向 `BalanceService` 写入 **负值** 以冲减客户欠款,同时写 `BalanceChangeRecord`
- `cancel`:仅允许 `PENDING` 且未生成 `StockChangeRecord` 的单据;审批通过后不可作废。
---
## 4. 付款单PaymentOrder

View File

@@ -34,4 +34,4 @@
## 5. 与采购/销售单的关系
- 继承相同的方向抽象(`get_direction()`),可与采购/销售的金额统计组合成统一的应收/应付报表。
- 不触发库存任务,也没有 `items`、仓库等字段;扩展字段(如付款方式、附件)可在此基础上继续添加。
- 采购退货 / 销售退货等复合单据在审批时会**同时**触发库存与余额写入,可视为采购/销售单 + 资金单据的组合;资金类单据仍需保持独立,以便单独统计资金流水。

View File

@@ -45,7 +45,23 @@
- 作废时已有出入库记录:`ValueError('采购单已生成出入库记录,无法作废')` -> API 返回 `400`
- ID 不存在或不属于当前商户API 返回 `404`
## 6. 下一阶段:库存红冲(对冲)方案规划
## 6. 采购退货(采退)流程补充
- API`POST /api/v1/purchase-return-orders/` 创建,`POST /api/v1/purchase-return-orders/<id>/review/` 审批。
- 创建阶段与采购单一致,只是字段改为 `return_date`,并允许传入 `purchase_order` 以关联原单。
- 审批通过:
1. 在事务内锁单、生成 `stock_flow_items`
2. 状态置为 `APPROVED`
3. 调用 `BalanceService.adjust_supplier_balance(delta=-总金额source=PURCHASE_RETURN_ORDER)`,写入 `BalanceChangeRecord`
4. 触发 `create_purchase_return_order_stock_entries`,底层调用 `StockFlowService.stock_out`source=`PURCHASE_RETURN`),受仓库 mode 约束:
- 宽进仓:传递 `value + num_of_rolls`
- 严进仓:传递 `numbers`
- 严进严出:必须提供 `consume_detail_ids`
- 作废逻辑沿用采购单:只有 `PENDING` 且未产生 `StockChangeRecord` 时才允许取消,一旦审批成功便禁止。
---
## 7. 下一阶段:库存红冲(对冲)方案规划
### 6.1 目标与原则

View File

@@ -43,7 +43,20 @@
- 作废时已有出库记录:`ValueError('销售单已生成出入库记录,无法作废')` -> `400`
- ID 不存在或不属于当前商户:`404`
## 6. 创建接口参数约定
## 6. 销售退货(销退)流程补充
- API`/api/v1/sales-return-orders/`(创建、列表)与 `/review/` 审批接口,与销售单保持完全一致的认证/权限。
- 创建时字段改为 `return_date`,其余 `items` 结构与销售单一致(根据仓库 mode 填写 `numbers``quantity` / `num_of_rolls`)。严进严出仓在退货场景下视为“入库”,故无需 `consume_detail_ids`
- 审批通过:
1. 事务锁定单据与明细。
2. 状态置为 `APPROVED`
3. 调用 `BalanceService.adjust_customer_balance(delta=-total_amount, source=SALES_RETURN_ORDER)`,写 `BalanceChangeRecord`,减少客户欠款。
4. 根据商户设置触发 `create_sales_return_order_stock_entries`,底层走 `StockFlowService.stock_in`source=`SALES_RETURN`)。
- 作废:同销售单,只允许 `PENDING` 且未生成 `StockChangeRecord` 的单据作废;审批后不可逆。
---
## 7. 创建接口参数约定
销售单创建接口沿用采购单的参数格式,根据仓库模式填写 `items`
@@ -55,7 +68,7 @@
> 说明:在严出模式下,`consume_detail_ids` 列表中的 ID 必须为同仓库、同商户且未被消耗的入库明细 ID。系统会在审批通过时逐条扣减对应库存。
## 6. 红冲(对冲)规划
## 8. 红冲(对冲)规划
与采购单一致,后续将通过库存红冲入口(`StockFlowService.offset_stock_change` 占位方法)实现销售单出库的反向抵销。关键原则: