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

6.1 KiB
Raw Permalink Blame History

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 -

请求示例

{
    "printing_job_id": 123,
    "name": "产品A-2026-03",
    "quantity": "150.50",
    "unit": 1,
    "customer_id": 456,
    "remark": "加急订单",
    "position": "A1-01"
}

响应示例

成功响应201 Created

{
    "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_idnull 表示该销售品处于"待分配"状态,尚未关联出货单。

错误响应

400 Bad Request - 缺少必填字段

{
    "printing_job_id": ["此字段为必填项。"],
    "name": ["此字段为必填项。"],
    "quantity": ["此字段为必填项。"],
    "unit": ["此字段为必填项。"]
}

400 Bad Request - 生产任务不存在

{
    "detail": "生产任务 123 不存在或不属于当前商户"
}

400 Bad Request - 单位值无效

{
    "unit": ["单位值无效。可选值:{1: '米', 2: '件', 3: '码', 4: '个'}"]
}

400 Bad Request - 数量格式无效

{
    "detail": "数量 abc 格式无效: invalid literal for int() with base 10: 'abc'"
}

403 Forbidden - 用户未关联商户

{
    "detail": "用户未关联商户,无法创建销售品"
}

401 Unauthorized - 未认证

{
    "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 手动创建:

# 生产任务完成后,手动创建销售品
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 命令

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 示例

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 首次创建,支持手动创建销售品