1
0
forked from erp-dev/erp
Files
erpnew/docs/business_api_reference.md
2026-06-13 11:44:15 +08:00

354 lines
15 KiB
Markdown
Raw 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.
# Business 模块 API 汇总
本文件汇集 `business` 模块及其在 `api_v1` 下的所有接口,前端只需参考本页即可完成对接。所有接口均位于 `/api/v1/`,除明确说明外均需用户已登录且具备员工身份。
---
## 1. 通用约定
| 项 | 说明 |
|----|------|
| 认证 | Session / Token与项目统一。用户必须关联 `Employee` 且属于目标 `Merchant`。 |
| 多租户 | `request.user.employee.merchant` 自动限定数据范围,接口内部已校验,无需额外参数。 |
| 分页 | 列表接口使用 `limit` / `offset`,默认 `limit=20`,最大 `100`。 |
| 状态枚举 | `1=PENDING``2=APPROVED``3=CANCELLED`。审批接口通过 `action=approve/cancel` 修改状态。 |
| 金额字段 | 字符串形式的十进制数(例如 `"123.45"`),与后端 `Decimal` 精度一致。 |
| items 结构 | 受仓库模式影响:<br>• 严进/严进严出:`numbers: [int,…]` 表示条数明细<br>• 宽进宽出:`quantity` + `num_of_rolls`<br>• 严出:`consume_detail_ids: [detail_id,…]` |
| 审批副作用 | 采购/销售审批通过后根据商户设置触发 Celery 入/出库任务;付款/收款审批通过将同步写入余额表。 |
| 余额审计 | 审批成功后会同步写入 `BalanceChangeRecord`,记录来源单据、方向、前后余额与冲抵占位字段,供审计/红冲使用。 |
错误响应统一为 `{"error": "代码", "message": "描述"}`,字段可能因场景扩展(如 `record_id``fields` 等)。
---
## 2. 采购相关:采购单 + 采购退货单
| API | 方法 | 描述 |
|-----|------|------|
| `/purchase-orders/` | GET | 分页列表。 |
| `/purchase-orders/` | POST | 创建采购单。 |
| `/purchase-orders/<id>/` | PUT/PATCH | 编辑采购单(仅限审批中)。 |
| `/purchase-orders/<id>/review/` | POST | 审批或作废。 |
### 2.1 创建请求体
`items` 数组支持以下字段:
| 字段 | 必填 | 说明 |
|------|------|------|
| `product_id` | 是 | 产品 ID |
| `price` | 是 | 单价 |
| `unit` | 否 | 单位,默认使用产品单位 |
| `numbers` / `quantity` + `num_of_rolls` | 仓库模式相关 | 严进提供 `numbers`,宽进提供 `quantity`/`num_of_rolls` |
| `empty_diff_percent` | 否 | **空差百分比**,用于计算实际数量与空差(默认 `0` |
| `color` / `spec` / `batch_number` / `remarks` | 否 | 可选信息 |
```json
{
"supplier": 12,
"warehouse": 8,
"order_date": "2025-11-30",
"items": [
{
"product_id": 1001,
"numbers": [30, 25],
"price": "12.50",
"unit": "米"
}
],
"remarks": "可选"
}
```
宽进仓将 `numbers` 换为 `quantity` + `num_of_rolls`。至少 1 条明细,否则返回 400。
> 创建成功201返回精简体`{"id", "human_id", "status", "message"}`,不包含 `items`、`total_amount` 等明细字段。需要完整结构请通过编辑PUT/PATCH或审批`review`)接口获取,二者返回完整序列化。
### 2.2 审批
`POST /purchase-orders/<id>/review/`,请求体 `{"action": "approve"}``{"action": "cancel"}`
- `approve`:在事务内将状态置为 `APPROVED`、写入供应商余额(正向金额),并在商户开启自动任务时触发 `create_purchase_order_stock_entries`
- `cancel`:若已存在 `StockChangeRecord`source=`PURCHASE`),返回 400否则置为 `CANCELLED`
成功返回最新的采购单序列化(含 `items``total_amount``status_name` 等)。
### 2.3 采购退货单PurchaseReturnOrder
| API | 方法 | 描述 |
|-----|------|------|
| `/purchase-return-orders/` | GET/POST | 与采购单相同的查询/创建接口,字段改为 `return_date`。 |
| `/purchase-return-orders/<id>/` | PUT/PATCH | 编辑采购退货单(仅限审批中)。 |
| `/purchase-return-orders/<id>/review/` | POST | 审批或作废,流程与采购单一致。 |
- **创建字段**`supplier``warehouse``return_date``items`、可选 `purchase_order``items` 结构沿用采购单;当仓库 `mode=RESTRICT_IN_OUT` 时必须提供 `consume_detail_ids`,指明要冲销的入库明细。
- **审批逻辑**
- `approve`:在事务内锁单、构建 `stock_flow_items`,状态置为 `APPROVED`,调用 `StockFlowService.stock_out`source=`PURCHASE_RETURN`),并向 `BalanceService` 写入 **负值** 以减少供应商应付。
- `cancel`:仅允许 `PENDING` 且尚未生成 `StockChangeRecord` 的单据;审批完成后禁止作废。
---
## 3. 销售相关:销售单 + 销售退货单
| API | 方法 | 描述 |
|-----|------|------|
| `/sales-orders/` | GET | 分页列表。 |
| `/sales-orders/` | POST | 创建销售单。 |
| `/sales-orders/<id>/` | PUT/PATCH | 编辑销售单(仅限审批中)。 |
| `/sales-orders/<id>/review/` | POST | 审批或作废。 |
### 3.1 创建请求体
销售单 `items` 字段同样支持 `empty_diff_percent``color``spec``batch_number``remarks` 等信息,用途与采购单一致;仓库模式决定使用 `numbers``quantity + num_of_rolls``consume_detail_ids`
顶层可选字段 `kind`(销售单类型):`1=大货``2=样板`。不传或传空时默认 `1`(大货);传入非法枚举值返回 400。
```json
{
"customer": 6,
"warehouse": 3,
"kind": 1,
"order_date": "2025-11-30",
"items": [
{
"product_id": 1001,
"numbers": [20, 18],
"price": "18.80",
"unit": "米"
}
],
"remarks": ""
}
```
仓库为严出(`RESTRICT_IN_OUT`)时必须改用:
```json
{
"product_id": 1001,
"consume_detail_ids": [321, 322],
"quantity": 200,
"price": "20",
"unit": "米"
}
```
> 创建成功201返回精简体`{"id", "human_id", "status", "message"}`,不包含 `items`、`total_amount` 等明细字段。需要完整结构请通过编辑PUT/PATCH或审批`review`)接口获取,二者返回完整序列化。
### 3.2 审批
与采购单一致,但方向为出库:
- `approve`:写入客户余额(正向欠款),若商户配置自动出库则触发 `create_sales_order_stock_entries`
- `cancel`:如果已存在 `StockChangeRecord`source=`SALES`)则拒绝。
### 3.3 销售退货单SalesReturnOrder
| API | 方法 | 描述 |
|-----|------|------|
| `/sales-return-orders/` | GET/POST | 创建 / 列表接口。 |
| `/sales-return-orders/<id>/` | PUT/PATCH | 编辑销售退货单(仅限审批中)。 |
| `/sales-return-orders/<id>/review/` | POST | 审批或作废。 |
- **创建字段**`customer``warehouse``return_date``items`、可选 `sales_order`。因退货为入库动作,严出仓不再需要 `consume_detail_ids`
- **审批逻辑**
- `approve`:状态置为 `APPROVED`,调用 `StockFlowService.stock_in`source=`SALES_RETURN`),并向 `BalanceService` 写入 **负值** 以冲减客户欠款,同时写 `BalanceChangeRecord`
- `cancel`:仅允许 `PENDING` 且未生成 `StockChangeRecord` 的单据;审批通过后不可作废。
---
## 4. 付款单PaymentOrder
| API | 方法 | 描述 |
|-----|------|------|
| `/payment-orders/` | GET | 分页列表。 |
| `/payment-orders/` | POST | 创建付款单。 |
| `/payment-orders/<id>/review/` | POST | 审批或作废。 |
### 4.1 创建请求体
```json
{
"supplier": 12,
"bank_account": 3,
"payment_date": "2025-11-30",
"amount": "5000.00",
"discount_amount": "120.00",
"remarks": "",
"markup": "审批备注"
}
```
字段说明:
- `bank_account`:可选,引用 `basic_info.BankAccount`,用于记录具体的付款账户。
- `markup`:可选字符串,用于记录票据附言;与 `remarks`(内部备注)区分。
- `discount_amount`:可选,默认 0允许大于 `amount`(表示折扣大于实付);必须 ≥ 0。
- 列表/详情响应额外包含 `is_external_source``external_source_id`,用于标识是否来自外部系统同步以及对应外部记录 ID。
- `settlement_amount = amount + discount_amount`,所有余额、对账及汇总均基于结算金额。
- `amount` 必须大于 0。返回 201 + 创建的记录,响应中会包含 `discount_amount``settlement_amount`
### 4.2 审批逻辑
- `approve`:在事务内锁定单据,防止重复审批;状态改为 `APPROVED`,并将供应商余额 **减少** 对应金额。
- `cancel`:仅允许从 `PENDING` 作废,且若已审批则返回 400。
---
## 5. 收款单ReceiptOrder
| API | 方法 | 描述 |
|-----|------|------|
| `/receipt-orders/` | GET | 列表。 |
| `/receipt-orders/` | POST | 创建收款单。 |
| `/receipt-orders/<id>/review/` | POST | 审批或作废。 |
### 5.1 创建
```json
{
"customer": 6,
"bank_account": 3,
"receipt_date": "2025-11-30",
"amount": "3200.00",
"discount_amount": "50.00",
"remarks": "",
"markup": "回单附言"
}
```
字段说明:
- `bank_account`:可选,引用到账银行账户。
- `discount_amount`:可选,默认 0可大于 `amount`,但必须 ≥ 0。
- `markup`:可选,记录回单附言,默认留空。
- 列表/详情响应额外包含 `is_external_source``external_source_id`,用于外部收款/退款同步关联与审计。
- `settlement_amount` 为响应只读字段(`amount + discount_amount`),对账及余额只会计算结算金额。
### 5.2 审批
- `approve`:状态改为 `APPROVED`,客户余额 **减少** 对应金额(冲减欠款)。若已取消则拒绝再次审批。
- `cancel`:仅允许从 `PENDING` 作废;当单据已审批时返回 400。
---
## 6. 余额表 / 对账接口
余额数据来自 `SupplierBalance` / `CustomerBalance` 表,所有审批通过的单据均在事务内写入,保证与业务状态一致。
### 6.1 客户余额
| API | 方法 | 描述 |
|-----|------|------|
| `/customers/<id>/balance/` | GET | 查询指定客户应收余额。 |
响应示例:
```json
{
"customer": 6,
"customer_name": "杭州零售商",
"balance": "3200.00"
}
```
- 正数表示客户仍欠款;负数表示已收超额。
- 若客户无记录返回 `"0"`
### 6.2 供应商余额
| API | 方法 | 描述 |
|-----|------|------|
| `/suppliers/<id>/balance/` | GET | 查询指定供应商待付余额。 |
响应示例:
```json
{
"supplier": 3,
"supplier_name": "桐乡面料商",
"balance": "1850.00"
}
```
- 正数表示仍需支付给供应商的金额;负数表示预付或多付。
- 若供应商无记录返回 `"0"`
### 6.3 余额变动记录BalanceChangeRecord
- **写入时机**:仅在审批通过瞬间写入;审批成功后禁止作废,若需冲销必须通过红冲/对冲流程生成反向记录。
- **字段概要**
- `target_type`:供应商 / 客户
- `source_type` + `source_id`:关联具体业务对象(采购/销售/付款/收款)
- `delta / balance_before / balance_after / direction`:记录本次增减与余额快照
- `offset_to / offset_id`:预留冲抵链路,与库存 `StockSnapshot` 设计一致
- `request_id / extra_meta`:用于幂等和记录审批上下文(操作者、触发渠道等)
- **用途**:对账、审计和红冲追踪。业务单据红冲会生成反向 `BalanceChangeRecord`,并通过 `offset_to / offset_id / red_flush_id` 与原记录关联。目前余额变动记录仍未开放对外查询 API可在内部管理端或报表服务中直接访问若后续开放请提供分页、时间范围与 `source_type` 过滤能力。
### 6.4 业务单据红冲Red Flush
正式业务单据已开放整单红冲入口,详细说明请参阅独立文档 `docs/2026-06-12_business_red_flush_api.md`
| API | 方法 | 描述 |
|-----|------|------|
| `/purchase-orders/<id>/red-flush/` | POST | 红冲已审批采购单,反向余额和库存影响 |
| `/sales-orders/<id>/red-flush/` | POST | 红冲已审批销售单,反向余额和库存影响 |
| `/purchase-return-orders/<id>/red-flush/` | POST | 红冲已审批采购退货单,反向余额和库存影响 |
| `/sales-return-orders/<id>/red-flush/` | POST | 红冲已审批销售退货单,反向余额和库存影响 |
| `/payment-orders/<id>/red-flush/` | POST | 红冲已审批付款单,反向供应商余额 |
| `/receipt-orders/<id>/red-flush/` | POST | 红冲已审批收款单,反向客户余额 |
请求体:
```json
{
"reason": "录入错误,需要红冲"
}
```
`reason` 必填且不能为空。红冲成功后原单据状态保持已审批,并返回 `is_red_flushed=true``red_flush_id``red_flushed_at`。外部来源付款/收款单不允许红冲。
## 7. 对账单Statements
客户/供应商对账单提供统一的金额视图与余额快照,用于销售/采购结算场景。完整说明(含响应示例、字段定义与业务规则)请参阅 `docs/statements.md`
| API | 方法 | 描述 |
|-----|------|------|
| `/customers/<id>/statements/` | GET | 指定客户的销售 / 销退 / 收款对账单 |
| `/suppliers/<id>/statements/` | GET | 指定供应商的采购 / 采退 / 付款对账单 |
| `/statements/record/` | GET | 通过主体与单据参数获取单条对账记录 |
关键特性:
- 固定按 `occurred_at -> recorded_at -> source_id` 倒序输出,不提供排序参数。
- `positive_amount` / `negative_amount` 统一表示余额增减;`cumulative_amount``current_balance``arrears_amount` 均冗余在每条记录中,前端可直接使用。
- 客户对账单在存在外部 statement-only 业务依据时,可能出现 `external_sales_order` / `external_sales_return_order` 两种新的 `source_type`
- 客户对账单在存在外部 statement-only 业务依据时,`current_balance` / `arrears_amount` 会基于“本地余额 + 外部业务来源净额”做临时展示口径修正;余额接口本身仍返回持久化 `CustomerBalance.balance`
- 单条查询接口需提供 `counterparty_type``counterparty_id``order_type``order_id` 四个 Query 参数,返回 schema 与列表一致,仅 `records` 中包含匹配记录。
---
## 8. 错误码与常见响应
| 场景 | HTTP | 返回 |
|------|------|------|
| 未登录 / 认证失败 | 401 | `{"detail": "Authentication credentials were not provided."}` |
| 非本商户数据 | 403 | `{"error": "forbidden", "message": "无权限访问"}` |
| 单据不存在 | 404 | `{"error": "purchase_order_not_found"}` 等 |
| 审批非法状态 | 400 | 例如 `{"error": "purchase_order_has_stock_records"}``{"error": "receipt_order_already_approved"}` |
| 红冲非法状态 | 400 | 例如未审批、重复红冲、缺少可红冲库存/余额记录、外部来源单据不允许红冲 |
---
## 9. 参考文档
- `docs/2026-06-12_business_red_flush_api.md`:业务单据红冲独立 API 文档。
- `docs/2026-06-12_business_red_flush_design.md`:业务单据红冲 service/API 设计备查。
- `docs/purchase_order_approval_and_red_flush.md`:采购单审批与红冲背景。
- `docs/sales_order_approval_and_red_flush.md`:销售单审批与严出模式说明。
- `docs/payment_receipt_workflow.md`:资金类单据与余额表写入逻辑。
本汇总会随着业务扩展同步更新,如需新增接口请补充到此文件以保持前端“单文档”体验。***