forked from erp-dev/erp
feat: retry haobuye sync order
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# SalesItem 修改与删除 API 文档
|
||||
|
||||
本文档说明 `SalesItem` 销售品的修改与软删除接口。
|
||||
本文档说明 `SalesItem` 销售品的修改、重建与软删除接口。
|
||||
|
||||
## 修改接口
|
||||
|
||||
@@ -91,6 +91,105 @@
|
||||
}
|
||||
```
|
||||
|
||||
## 重建接口
|
||||
|
||||
### 接口信息
|
||||
|
||||
- URL: `/api/v1/shipment/sales-items/{id}/rebuild/`
|
||||
- Method: `POST`
|
||||
- 认证: 需要登录(JWT Token)
|
||||
|
||||
说明:
|
||||
|
||||
- 该接口本质上等同于“软删除旧销售品 + 基于新的 `printing_job` 重建一个新销售品”
|
||||
- 只有旧销售品的 `created_by` 本人才能执行这个操作
|
||||
- 新销售品会保留旧销售品的 `created_by`
|
||||
- 旧销售品若已关联出货单,则不允许重建
|
||||
|
||||
### 请求体
|
||||
|
||||
```json
|
||||
{
|
||||
"new_printing_job_id": 456,
|
||||
"quantity": "66.50"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
- `new_printing_job_id`: 必填,新的生产任务 ID
|
||||
- `quantity`: 可选,新的数量;未传时沿用旧销售品数量
|
||||
|
||||
### 成功响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "销售品已重建",
|
||||
"old_sales_item_id": 15,
|
||||
"new_sales_item_id": 18,
|
||||
"rebuild_record_id": 3,
|
||||
"data": {
|
||||
"id": 18,
|
||||
"name": "测试销售品",
|
||||
"quantity": "66.50",
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"position": "A3-02",
|
||||
"remark": "补充备注",
|
||||
"printing_job_id": 456,
|
||||
"printing_order_id": 80,
|
||||
"external_order_id": "EXT-2026-010",
|
||||
"customer_id": 8,
|
||||
"customer_name": "客户A",
|
||||
"shipment_id": null,
|
||||
"shipment_date": null,
|
||||
"created_at": "2026-04-06T16:00:00+08:00",
|
||||
"created_by_id": 3,
|
||||
"created_by_name": "测试员工",
|
||||
"product_image_url": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 重建审计记录
|
||||
|
||||
每次成功重建时,会新增一条 `SalesItemRebuildRecord`,记录:
|
||||
|
||||
- `old_sales_item`
|
||||
- `new_sales_item`
|
||||
- `operator`
|
||||
- `rebuilt_at`
|
||||
- `old_printing_job_id`
|
||||
- `new_printing_job_id`
|
||||
- `old_quantity`
|
||||
- `new_quantity`
|
||||
|
||||
### 错误响应示例
|
||||
|
||||
#### 1. 不是原创建者
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "只有销售品创建者才能执行重建"
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 旧销售品已关联出货单
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "已关联出货单的销售品不允许删除"
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 新生产任务无效
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "生产任务 999 不存在或不属于当前商户"
|
||||
}
|
||||
```
|
||||
|
||||
## 删除接口
|
||||
|
||||
### 接口信息
|
||||
|
||||
222
docs/sales_item_merge_remark_api.md
Normal file
222
docs/sales_item_merge_remark_api.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# 销售品合卷备注(merge_remark)API 变更说明
|
||||
|
||||
> 变更日期:2026-04-06
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
`SalesItem`(销售品)模型新增可空 JSON 字段 `merge_remark`,用于记录该销售品由多个生产子单合卷产生时的合卷信息。
|
||||
|
||||
本次变更涉及:
|
||||
- **创建销售品**(POST):新增可选入参 `merge_remark`,传入时进行结构校验
|
||||
- **所有返回销售品对象的接口**:响应体中新增 `merge_remark` 字段
|
||||
- **更新销售品**(PATCH):**不支持**传入 `merge_remark`,不受影响
|
||||
|
||||
---
|
||||
|
||||
## 一、受影响的 API
|
||||
|
||||
### 1. 创建销售品(新增入参)
|
||||
|
||||
```
|
||||
POST /api/v1/shipment/sales-items/
|
||||
```
|
||||
|
||||
请求体新增可选字段 `merge_remark`,不传或传 `null` 均视为无合卷信息。
|
||||
|
||||
#### 完整请求参数
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| printing_job_id | integer | 是 | 生产任务ID |
|
||||
| name | string | 是 | 销售品名称 |
|
||||
| quantity | string | 是 | 数量(支持小数) |
|
||||
| unit | integer | 是 | 单位:1=米, 2=件, 3=码, 4=个 |
|
||||
| customer_id | integer | 否 | 客户ID |
|
||||
| remark | string | 否 | 备注 |
|
||||
| position | string | 否 | 货位 |
|
||||
| **merge_remark** | object \| null | **否** | **合卷备注(见下方结构说明)** |
|
||||
|
||||
#### merge_remark 结构
|
||||
|
||||
传入时必须严格符合以下结构,字段不可多、不可少:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| merge_type | string | 合卷类型标识,固定传 `"combined_jobs"` |
|
||||
| jobs | integer[] | 参与本次合卷的所有子单ID(printing_job_id)列表,至少 2 个元素 |
|
||||
| main_job | integer | 主子单ID,**必须是 jobs 列表中的成员** |
|
||||
| quantity | string | 本次合卷销售品的最终数量,字符串形式 |
|
||||
| unit | string | 数量单位,如 `"meter"` |
|
||||
| job_count | integer | 参与合卷的子单数量,**必须等于 jobs 列表的长度** |
|
||||
|
||||
#### 请求示例(含 merge_remark)
|
||||
|
||||
```json
|
||||
{
|
||||
"printing_job_id": 9777,
|
||||
"name": "某款合卷布料",
|
||||
"quantity": "647",
|
||||
"unit": 1,
|
||||
"merge_remark": {
|
||||
"merge_type": "combined_jobs",
|
||||
"jobs": [9777, 9776],
|
||||
"main_job": 9777,
|
||||
"quantity": "647",
|
||||
"unit": "meter",
|
||||
"job_count": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例(201 Created)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 101,
|
||||
"name": "某款合卷布料",
|
||||
"quantity": "647.00",
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"position": "",
|
||||
"remark": "",
|
||||
"printing_job_id": 9777,
|
||||
"printing_order_id": 55,
|
||||
"external_order_id": null,
|
||||
"customer_id": 12,
|
||||
"customer_name": "某客户",
|
||||
"shipment_id": null,
|
||||
"shipment_date": null,
|
||||
"merge_remark": {
|
||||
"merge_type": "combined_jobs",
|
||||
"jobs": [9777, 9776],
|
||||
"main_job": 9777,
|
||||
"quantity": "647",
|
||||
"unit": "meter",
|
||||
"job_count": 2
|
||||
},
|
||||
"created_at": "2026-04-06T10:00:00Z",
|
||||
"created_by_id": 1,
|
||||
"created_by_name": "张三"
|
||||
}
|
||||
```
|
||||
|
||||
#### merge_remark 校验错误响应(400 Bad Request)
|
||||
|
||||
**缺少必填字段:**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["缺少必填字段: ['job_count', 'main_job']"]
|
||||
}
|
||||
```
|
||||
|
||||
**包含未知字段:**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["包含未知字段: ['extra_field']"]
|
||||
}
|
||||
```
|
||||
|
||||
**字段类型错误(如 main_job 传了字符串):**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["字段 'main_job' 类型错误,期望 int,实际 str"]
|
||||
}
|
||||
```
|
||||
|
||||
**jobs 列表元素不是整数:**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["jobs 列表中的元素必须为整数"]
|
||||
}
|
||||
```
|
||||
|
||||
**jobs 少于 2 个元素:**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["jobs 列表至少需要包含 2 个子单ID"]
|
||||
}
|
||||
```
|
||||
|
||||
**main_job 不在 jobs 中:**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["main_job 必须是 jobs 列表中的一个成员"]
|
||||
}
|
||||
```
|
||||
|
||||
**job_count 与 jobs 长度不一致:**
|
||||
```json
|
||||
{
|
||||
"merge_remark": ["job_count (3) 与 jobs 长度 (2) 不一致"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. 获取销售品详情(新增返回字段)
|
||||
|
||||
```
|
||||
GET /api/v1/shipment/sales-items/<id>/
|
||||
```
|
||||
|
||||
响应体新增 `merge_remark` 字段。无合卷信息时值为 `null`。
|
||||
|
||||
---
|
||||
|
||||
### 3. 按客户查询销售品列表(新增返回字段)
|
||||
|
||||
```
|
||||
GET /api/v1/shipment/sales-items/by-customer/<customer_id>/
|
||||
```
|
||||
|
||||
列表中每条销售品对象新增 `merge_remark` 字段。
|
||||
|
||||
---
|
||||
|
||||
### 4. 按生产订单查询销售品列表(新增返回字段)
|
||||
|
||||
```
|
||||
GET /api/v1/shipment/sales-items/by-printing-order/<printing_order_id>/
|
||||
```
|
||||
|
||||
列表中每条销售品对象新增 `merge_remark` 字段。
|
||||
|
||||
---
|
||||
|
||||
### 5. 出货单详情中的嵌套销售品列表(新增返回字段)
|
||||
|
||||
```
|
||||
GET /api/v1/shipment/shipments/<id>/
|
||||
```
|
||||
|
||||
响应体 `sales_items` 数组中每条销售品对象新增 `merge_remark` 字段。
|
||||
|
||||
---
|
||||
|
||||
## 二、不受影响的 API
|
||||
|
||||
| 端点 | 说明 |
|
||||
|------|------|
|
||||
| `PATCH /api/v1/shipment/sales-items/<id>/` | 更新销售品,**不接受** `merge_remark` 参数,传入会被忽略 |
|
||||
| `POST /api/v1/shipment/sales-items/<id>/rebuild/` | 重建销售品,不涉及 `merge_remark` |
|
||||
| `POST /api/v1/shipment/shipments/` | 创建出货单,不涉及 `merge_remark` |
|
||||
|
||||
---
|
||||
|
||||
## 三、merge_remark 为 null 的情况
|
||||
|
||||
普通销售品(非合卷)创建时不传 `merge_remark`,返回值中该字段为 `null`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 102,
|
||||
"name": "普通布料",
|
||||
"quantity": "200.00",
|
||||
...
|
||||
"merge_remark": null
|
||||
}
|
||||
```
|
||||
|
||||
前端展示时直接判断 `merge_remark !== null` 即可区分是否为合卷销售品。
|
||||
Reference in New Issue
Block a user