forked from erp-dev/erp
264 lines
4.9 KiB
Markdown
264 lines
4.9 KiB
Markdown
# SalesItem 修改与删除 API 文档
|
||
|
||
本文档说明 `SalesItem` 销售品的修改、重建与软删除接口。
|
||
|
||
## 修改接口
|
||
|
||
### 接口信息
|
||
|
||
- URL: `/api/v1/shipment/sales-items/{id}/`
|
||
- Method: `PATCH`
|
||
- 认证: 需要登录(JWT Token)
|
||
|
||
说明:
|
||
|
||
- 该接口仅允许修改部分非关系字段
|
||
- 当前允许修改的字段只有:
|
||
- `quantity`
|
||
- `remark`
|
||
- `position`
|
||
- 不允许修改 `name`、`unit`、`shipment`、`customer_id`、`printing_job_id` 等字段
|
||
- 成功修改后会自动写入 `SalesItemChangeRecord`
|
||
|
||
### 请求体示例
|
||
|
||
```json
|
||
{
|
||
"quantity": "120.50",
|
||
"remark": "补充备注",
|
||
"position": "A3-02"
|
||
}
|
||
```
|
||
|
||
### 成功响应示例
|
||
|
||
```json
|
||
{
|
||
"id": 15,
|
||
"name": "测试销售品",
|
||
"quantity": "120.50",
|
||
"unit": 1,
|
||
"unit_display": "米",
|
||
"position": "A3-02",
|
||
"remark": "补充备注",
|
||
"printing_job_id": 123,
|
||
"printing_order_id": 45,
|
||
"external_order_id": "EXT-2026-001",
|
||
"customer_id": 8,
|
||
"customer_name": "客户A",
|
||
"shipment_id": null,
|
||
"shipment_date": null,
|
||
"created_at": "2026-04-06T10:00:00+08:00",
|
||
"created_by_id": 3,
|
||
"created_by_name": "测试员工",
|
||
"product_image_url": null
|
||
}
|
||
```
|
||
|
||
### 修改审计记录
|
||
|
||
每次成功修改时,会新增一条 `SalesItemChangeRecord`,记录:
|
||
|
||
- `sales_item`
|
||
- `operator`
|
||
- `operated_at`
|
||
- `before_values`
|
||
- `after_values`
|
||
|
||
### 错误响应示例
|
||
|
||
#### 1. 传入了不允许修改的字段
|
||
|
||
```json
|
||
{
|
||
"detail": "销售品仅允许修改以下字段: position, quantity, remark;不支持字段: customer_id, name"
|
||
}
|
||
```
|
||
|
||
#### 2. 数量格式非法
|
||
|
||
```json
|
||
{
|
||
"detail": "数量 abc 格式无效: [具体异常信息]"
|
||
}
|
||
```
|
||
|
||
#### 3. 对象不存在或无权访问
|
||
|
||
```json
|
||
{
|
||
"detail": "Not found."
|
||
}
|
||
```
|
||
|
||
## 重建接口
|
||
|
||
### 接口信息
|
||
|
||
- 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 不存在或不属于当前商户"
|
||
}
|
||
```
|
||
|
||
## 删除接口
|
||
|
||
### 接口信息
|
||
|
||
- URL: `/api/v1/shipment/sales-items/{id}/`
|
||
- Method: `DELETE`
|
||
- 认证: 需要登录(JWT Token)
|
||
|
||
说明:
|
||
|
||
- 该接口为软删除,不会物理删除数据库记录
|
||
- 删除后销售品会从常规查询接口中隐藏
|
||
- 删除操作需要独立 Django 权限:`shipment.soft_delete_salesitem`
|
||
|
||
### 软删除字段
|
||
|
||
`SalesItem` 通过以下字段记录删除信息:
|
||
|
||
- `delete_at`: 删除时间
|
||
- `delete_by`: 删除人
|
||
|
||
### 权限要求
|
||
|
||
调用方需要具备:
|
||
|
||
- `shipment.soft_delete_salesitem`
|
||
|
||
无该权限时返回 `403 Forbidden`。
|
||
|
||
### 请求示例
|
||
|
||
```http
|
||
DELETE /api/v1/shipment/sales-items/15/
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
### 成功响应
|
||
|
||
```json
|
||
{
|
||
"detail": "销售品已标记为删除"
|
||
}
|
||
```
|
||
|
||
### 行为说明
|
||
|
||
- 软删除后,`SalesItem` 不再出现在以下常规接口结果中:
|
||
- 销售品详情
|
||
- 按客户查询销售品
|
||
- 按生产订单查询销售品
|
||
- 未出货销售品客户反查
|
||
- 出货单详情 / 列表中的嵌套销售品
|
||
- 重复删除当前实现保持幂等;由于对象在常规查询中已隐藏,后续再次调用通常会得到 `404`
|
||
|
||
### 错误响应示例
|
||
|
||
#### 1. 无权限
|
||
|
||
```json
|
||
{
|
||
"detail": "没有权限删除销售品"
|
||
}
|
||
```
|
||
|
||
#### 2. 对象不存在或无权访问
|
||
|
||
```json
|
||
{
|
||
"detail": "Not found."
|
||
}
|
||
```
|