1
0
forked from erp-dev/erp
Files
erpnew/docs/api_v1_sales_item_create.md
2026-03-10 19:30:48 +08:00

264 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SalesItem 创建 API 文档
## 概述
当自动转化销售品开关(`AUTO_CREATE_SALESITEM_FROM_PRINT_ORDER`)关闭时,通过此 API 手动创建销售品。
## API 端点
```
POST /api/v1/shipment/sales-items/
```
## 请求头
```
Authorization: Bearer <token>
Content-Type: application/json
```
## 请求参数
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| printing_job_id | integer | 是 | 生产任务ID |
| name | string | 是 | 销售品名称最大200字符 |
| quantity | string | 是 | 数量(支持小数,如:"100.50" |
| unit | integer | 是 | 单位(见下方单位可选值) |
| customer_id | integer | 否 | 客户ID默认从生产订单获取 |
| remark | string | 否 | 备注最大200字符 |
| position | string | 否 | 货位最大200字符 |
## 单位可选值
| 值 | 单位 | 说明 |
|----|------|------|
| 1 | 米 | 默认单位 |
| 2 | 件 | - |
| 3 | 码 | - |
| 4 | 个 | - |
## 请求示例
```json
{
"printing_job_id": 123,
"name": "产品A-2026-03",
"quantity": "150.50",
"unit": 1,
"customer_id": 456,
"remark": "加急订单",
"position": "A1-01"
}
```
## 响应示例
### 成功响应201 Created
```json
{
"id": 1,
"name": "产品A-2026-03",
"quantity": "150.50",
"unit": 1,
"unit_display": "米",
"position": "A1-01",
"remark": "加急订单",
"printing_job_id": 123,
"customer_id": 456,
"shipment_id": null,
"shipment_date": null,
"created_at": "2026-03-05T10:30:00Z",
"created_by_id": 1,
"created_by_name": "张三"
}
```
**注意**`shipment_id``null` 表示该销售品处于"待分配"状态,尚未关联出货单。
### 错误响应
#### 400 Bad Request - 缺少必填字段
```json
{
"printing_job_id": ["此字段为必填项。"],
"name": ["此字段为必填项。"],
"quantity": ["此字段为必填项。"],
"unit": ["此字段为必填项。"]
}
```
#### 400 Bad Request - 生产任务不存在
```json
{
"detail": "生产任务 123 不存在或不属于当前商户"
}
```
#### 400 Bad Request - 单位值无效
```json
{
"unit": ["单位值无效。可选值:{1: '米', 2: '件', 3: '码', 4: '个'}"]
}
```
#### 400 Bad Request - 数量格式无效
```json
{
"detail": "数量 abc 格式无效: invalid literal for int() with base 10: 'abc'"
}
```
#### 403 Forbidden - 用户未关联商户
```json
{
"detail": "用户未关联商户,无法创建销售品"
}
```
#### 401 Unauthorized - 未认证
```json
{
"detail": "身份认证信息未提供。"
}
```
## 权限说明
- **认证要求**:需要登录用户(`IsAuthenticated`
- **商户隔离**:自动从当前用户的 `employee.merchant` 获取商户信息
- **Django权限**:需要 `shipment.add_salesitem` 权限遵循Django表级权限
- **生产任务验证**:必须验证生产任务属于当前商户
## 业务逻辑
### 创建流程
1. **验证用户商户**:从 `request.user.employee.merchant` 获取当前商户
2. **验证生产任务**:确认生产任务存在且属于当前商户
3. **数据转换**:将数量字符串转换为 Decimal
4. **获取客户ID**:如果未提供,自动从生产订单获取
5. **创建销售品**
- `shipment = null`(待分配状态)
- `printing_job_id` 关联生产任务
- `merchant` 设置为当前商户
### 状态说明
销售品没有独立的状态字段,通过 `shipment` 字段判断:
- **待分配**`shipment = null`
- **已关联出货单**`shipment != null`
创建后的销售品处于"待分配"状态,可通过出货单 API 关联到出货单。
## 使用场景
### 场景1自动转化开关关闭时
`AUTO_CREATE_SALESITEM_FROM_PRINT_ORDER = False` 时,系统不会自动创建销售品。此时需要通过此 API 手动创建:
```python
# 生产任务完成后,手动创建销售品
POST /api/v1/shipment/sales-items/
{
"printing_job_id": 123,
"name": "产品A",
"quantity": "100",
"unit": 1
}
```
### 场景2补充创建销售品
即使自动转化开关开启,也可以通过此 API 手动创建额外的销售品(用于特殊情况)。
### 场景3修正销售品
如果自动创建的销售品信息有误,可以:
1. 删除自动创建的销售品
2. 使用此 API 手动创建正确的销售品
## 相关 API
### 查询销售品
```
GET /api/v1/shipment/sales-items/by-printing-order/<printing_order_id>/?include_already_has_shipment=false
```
### 创建出货单并关联销售品
```
POST /api/v1/shipment/shipments/
{
"customer": 1,
"shipment_date": "2026-03-05",
"sales_items": [1, 2, 3]
}
```
## 注意事项
1. **商户隔离**:只能为当前用户所属商户创建销售品
2. **生产任务验证**必须提供有效的生产任务ID且该任务必须属于当前商户
3. **数量格式**:支持小数,使用字符串传递避免精度丢失
4. **单位验证**必须提供有效的单位值1/2/3/4
5. **重复创建**:同一个生产任务可以创建多个销售品(如果业务需要)
## 测试示例
### curl 命令
```bash
curl -X POST http://localhost:8000/api/v1/shipment/sales-items/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"printing_job_id": 123,
"name": "测试产品",
"quantity": "100.50",
"unit": 1,
"remark": "测试备注"
}'
```
### Python 示例
```python
import requests
data = {
"printing_job_id": 123,
"name": "产品A-2026-03",
"quantity": "150.50",
"unit": 1, # 米
"customer_id": 456,
"remark": "加急订单",
"position": "A1-01"
}
response = requests.post(
"http://localhost:8000/api/v1/shipment/sales-items/",
json=data,
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
if response.status_code == 201:
sales_item = response.json()
print(f"创建成功:{sales_item['name']} x {sales_item['quantity']} {sales_item['unit_display']}")
else:
print(f"错误:{response.json()}")
```
## 更新日志
- **2026-03-05**: API 首次创建,支持手动创建销售品