forked from erp-dev/erp
feat: transfer api for stock module
This commit is contained in:
@@ -302,6 +302,89 @@ Warehouses can operate in different modes:
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Stock Transfer (调拨)
|
||||
|
||||
**URL**: `POST /api/v1/stock-change/transfer/`
|
||||
|
||||
**Description**: Performs an in-transaction transfer between two warehouses that share the same warehouse **mode** (可以跨类型,例如整件仓 → 散件仓)。一次调用会同步创建调出与调入的 `StockChangeRecord` 并立即完成库存扣加,确保库存一致性。
|
||||
|
||||
**Business Constraints**:
|
||||
- `from_warehouse` 与 `to_warehouse` 必须属于当前商户,且不可相同。
|
||||
- 两个仓库的 `mode` 必须一致(RESTRICT_IN、UNRESTRICTED 均可)。目前不支持 `RESTRICT_IN_OUT`(严进严出)的调拨。
|
||||
- 请求在数据库事务内完成,不能依赖异步任务;支持 `request_id` 幂等重试。
|
||||
- `products` 列表沿用原出入库的 payload 结构,允许:
|
||||
- `quantities`: 严谨/严进模式的显式数量数组;
|
||||
- `value + unit_count/num_of_rolls`: 宽松模式的拆分定义;
|
||||
- `consume_detail_ids`: 若未来开放严进严出调拨,可在此补充(当前会拒绝)。
|
||||
|
||||
**Request Parameters**:
|
||||
```json
|
||||
{
|
||||
"from_warehouse": 3,
|
||||
"to_warehouse": 5,
|
||||
"transfer_date": "2025-12-02", // 可选,默认当天
|
||||
"remarks": "整件仓调拨到散件仓", // 可选
|
||||
"request_id": "transfer-20251202-001", // 可选幂等键
|
||||
"products": [
|
||||
{ "product_id": 12, "quantities": ["10.50", "5.25"] },
|
||||
{ "product_id": 27, "value": "120.0", "unit_count": "30" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"id": 88,
|
||||
"merchant": 6,
|
||||
"from_warehouse": 3,
|
||||
"from_warehouse_name": "整件一号仓",
|
||||
"to_warehouse": 5,
|
||||
"to_warehouse_name": "散件贵宾仓",
|
||||
"mode": 1,
|
||||
"mode_display": "严进宽出",
|
||||
"operator": 24,
|
||||
"transfer_date": "2025-12-02",
|
||||
"status": 2,
|
||||
"status_display": "已完成",
|
||||
"remarks": "整件仓调拨到散件仓",
|
||||
"request_id": "transfer-20251202-001",
|
||||
"outgoing_record_id": 512,
|
||||
"incoming_record_id": 513,
|
||||
"items": [
|
||||
{
|
||||
"id": 143,
|
||||
"product": 12,
|
||||
"product_name": "贡缎白坯布",
|
||||
"total_quantity": "15.75",
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"num_of_rolls": 2
|
||||
},
|
||||
{
|
||||
"id": 144,
|
||||
"product": 27,
|
||||
"product_name": "彩纱混纺",
|
||||
"total_quantity": "120.00",
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"num_of_rolls": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Error Cases**:
|
||||
| HTTP | Payload 示例 | 说明 |
|
||||
|------|--------------|------|
|
||||
| 400 | `{ "error": "调拨要求调出仓与调入仓的出入库模式一致" }` | 两仓 mode 不同 |
|
||||
| 400 | `{ "error": "调入仓与调出仓不能相同" }` | 相同仓库 |
|
||||
| 400 | `{ "error": "调出仓不存在或不属于当前商户" }` | 仓库不属于当前商户 |
|
||||
| 400 | `{ "error": "调拨产品明细不能为空" }` | products 为空 |
|
||||
| 409 | `{ "error": "请求重复" }` *(未来可扩展)* | 同一 `request_id` 重复提交(当前直接返回已存在记录) |
|
||||
|
||||
> **提示**:响应中附带 `outgoing_record_id` 与 `incoming_record_id`,可继续使用既有的 `GET /api/v1/stock-change/<id>/` 接口查看具体的明细与快照。
|
||||
|
||||
### Other Related Endpoints
|
||||
|
||||
#### List Stock Changes
|
||||
|
||||
Reference in New Issue
Block a user