1
0
forked from erp-dev/erp
Files
erpnew/docs/business_purchase.md

3.2 KiB
Raw Blame History

Business 模块采购单 API

创建采购单并触发入库

  • URL: POST /api/v1/purchase-orders/
  • 权限: 需要登录且具备员工身份
  • 描述: 创建业务模块的 PurchaseOrder,并异步触发库存入库任务(通过 stock.services.StockFlowService.stock_in 实现)。

请求体

{
  "supplier": 1,
  "warehouse_id": 2,
  "order_date": "2025-11-26",
  "remarks": "测试采购单",
  "items": [
    {
      "product_id": 10,
      "quantity": 120,
      "num_of_rolls": 3,
      "price": "12.50",
      "unit": "米",
      "empty_diff_percent": "0"
    }
  ]
}
字段 类型 必填 说明
supplier integer 供应商 ID必须隶属于当前商户
warehouse / warehouse_id integer 入库仓库 ID两字段二选一推荐 warehouse_id
order_date string (date) 订单日期(YYYY-MM-DD
remarks string 备注
items array 入库明细,根据仓库模式提供不同字段

items 结构说明

  • 宽进仓UNRESTRICTED

    • 必填:product_idquantitynum_of_rolls
    • quantity_of_rolls 会自动置空,并以 {value, num_of_rolls} 的形式传递给 StockFlowService.stock_in 的宽松模式。
  • 严进仓RESTRICT_IN / RESTRICT_IN_OUT

    • 必填:product_idnumbers(数组)
    • 后端会以数组长度设置 num_of_rolls,把所有数值拼为 quantity_of_rolls="10,5,8",同时求和得到 quantity,并生成 {'quantities': ['10','5','8']} 传递给严谨模式。

公共可选字段:priceunitcolorempty_diff_percentbatch_numberremarks。缺省时默认使用 0 或产品单位。
⚠️ 当仓库模式与 items 字段不匹配(例如严进仓缺少 numbers、宽进仓提供 numbers)时将返回 400,提示“仓库为 ×× 模式items[n] 需要提供 …”。

响应

{
  "id": 35,
  "message": "采购单创建成功,入库任务已排队"
}

创建成功即刻返回,实际入库明细由后台 Celery 任务生成,可在日志或 stock_change 记录中查看。

错误示例

状态码 示例 说明
400 {"error": "缺少仓库 ID"} 请求缺失关键字段
400 {"error": "仓库为严进模式items[0] 需要提供 numbers 数组"} 参数与仓库模式不匹配
400 {"error": "供应商 99 不存在"} 供应商不属于当前商户
403 {"error": "无权限访问"} 当前用户无员工信息

关联任务business/tasks.py

create_purchase_order_stock_entries 任务会接收 purchase_order_idwarehouse_id、已转换好的 items 信息,并通过 StockFlowService.stock_in 创建入库记录。

  • 任务日志示例:采购单 35 入库任务完成
  • 返回 payload 包含 stock_change_record_idcreated_details_count

测试

api_v1/tests.py 中的 PurchaseOrderAPITestCase 覆盖宽进/严进模式、模式不匹配和未登录场景;
business/tests.py 中的 PurchaseOrderServiceTestCasePurchaseOrderStockTaskTestCase 验证 service 层逻辑与 Celery 任务(通过 mock StockFlowService)。