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

4.7 KiB
Raw Blame History

Business 模块采购单 API

创建采购单(默认待审批)

  • URL: POST /api/v1/purchase-orders/
  • 权限: 需要登录且具备员工身份
  • 描述: 创建业务模块的 PurchaseOrder,默认状态为 PENDING(审批中)。此时不会立即生成入库记录,需在审批通过后才会触发库存入库任务。

请求体

{
  "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,
  "status": 1,
  "message": "采购单创建成功,等待审批"
}

创建成功即刻返回,状态为 审批中。只有在审批通过后才会调用库存入库任务。

错误示例

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

审批 / 作废采购单API & Service

  • URL: POST /api/v1/purchase-orders/<id>/review/
  • 权限: 登录 + 员工身份
  • 请求体:
{
  "action": "approve"  // 可选: approve / cancel
}

action=approve 时,会调用 business.services.review_purchase_order 将采购单状态更新为 APPROVED,并在商户设置 auto_create_stock_change_tasks=True 时自动触发 create_purchase_order_stock_entries Celery 任务(根据采购单明细重建 StockFlowService.stock_in 所需 payload

action=cancel 时,会尝试将采购单状态改为 CANCELLED。如果该采购单已经生成过出入库记录(source_type=PURCHASEsource_id=采购单ID),接口会返回 400,提示“采购单已生成出入库记录,无法作废”。

响应示例

{
  "id": 12,
  "status": 2,
  "supplier_name": "供应商A",
  "warehouse_name": "严进仓",
  "total_amount": "1500.00",
  "diff_quantity": "0.00",
  "total_quantity": "120.00",
  "items": [
    {
      "id": 33,
      "product": 10,
      "quantity": "120.00",
      "unit": "米",
      "spec": "50D",
      "num_of_rolls": 3
    }
  ]
}

错误示例

状态码 示例 说明
400 {"action": ["This field is required."]} 缺少 action
400 {"error": "采购单已生成出入库记录,无法作废"} 尝试作废但已生成出入库单
404 {"error": "采购单不存在"} ID 不在当前商户下

关联任务business/tasks.py

create_purchase_order_stock_entries 任务会接收 purchase_order_idwarehouse_id、已转换好的 items 信息,并通过 StockFlowService.stock_in 创建入库记录。只有当采购单审批通过且商户开启自动入库设置时才会派发该任务。

测试

  • business/tests.PurchaseOrderServiceTestCase:覆盖创建采购单、审批触发任务、作废校验以及宽/严模式的 payload 生成逻辑。
  • business/tests.PurchaseOrderStockServiceTestCasePurchaseOrderStockTaskTestCase:继续验证 service 层生成入库单及 Celery 任务封装逻辑。