forked from erp-dev/erp
feat: statement for supplier and customer
This commit is contained in:
676
docs/stock_api_overview.md
Normal file
676
docs/stock_api_overview.md
Normal file
@@ -0,0 +1,676 @@
|
||||
# Stock Management API Documentation
|
||||
|
||||
This document provides detailed documentation for the stock management module APIs, focusing on the three main stock change creation modes: Full, Relaxed, and Restricted.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Stock Models](#stock-models)
|
||||
3. [Stock Change Modes](#stock-change-modes)
|
||||
4. [API Endpoints](#api-endpoints)
|
||||
5. [Examples](#examples)
|
||||
6. [Error Handling](#error-handling)
|
||||
|
||||
## Overview
|
||||
|
||||
The stock management system handles all inventory movement operations including stock-in (入库) and stock-out (出库) transactions. The system supports three different modes of operation:
|
||||
|
||||
1. **Full Mode**: Standard operation with explicit quantity lists
|
||||
2. **Relaxed Mode**: Automatically splits quantities based on total and unit count
|
||||
3. **Restricted Mode**: Strict "restricted-in/out" mode for warehouse operations
|
||||
|
||||
## Stock Models
|
||||
|
||||
### StockChangeRecord
|
||||
Represents a stock change record (either stock-in or stock-out).
|
||||
|
||||
**Fields**:
|
||||
- `id`: Record ID
|
||||
- `type`: Change type (1=Stock-in, 2=Stock-out)
|
||||
- `warehouse`: Associated warehouse
|
||||
- `source_type`: Source of the change (1=Purchase, 6=Sales, etc.)
|
||||
- `source_id`: ID of the source document (optional)
|
||||
- `created_by`: User who created the record
|
||||
- `is_finished`: Whether the stock change is completed
|
||||
- `finished_at`: When the record was completed
|
||||
- `remarks`: Additional notes
|
||||
|
||||
### StockChangeDetail
|
||||
Represents detailed items within a stock change record.
|
||||
|
||||
**Fields**:
|
||||
- `id`: Detail ID
|
||||
- `product`: Associated product
|
||||
- `stock_change_record`: Parent stock change record
|
||||
- `quantity`: Quantity of the product
|
||||
- `unit`: Unit of measurement
|
||||
- `is_consumed`: Whether this detail has been consumed (for restricted mode)
|
||||
- `consume_with`: Reference to the inbound detail being consumed (for restricted mode)
|
||||
|
||||
### Inventory
|
||||
Represents current inventory levels for a product in a warehouse.
|
||||
|
||||
**Fields**:
|
||||
- `id`: Inventory ID
|
||||
- `product`: Associated product
|
||||
- `warehouse`: Warehouse location
|
||||
- `quantity`: Current quantity
|
||||
- `num_of_rolls`: Number of rolls
|
||||
- `spec`: Product specification
|
||||
- `description`: Additional notes
|
||||
|
||||
## Stock Change Modes
|
||||
|
||||
### Source Types
|
||||
|
||||
The system supports various source types for stock changes:
|
||||
|
||||
**Incoming (入库) Sources**:
|
||||
- `1`: Purchase (采购)
|
||||
- `2`: Sales Return (销退)
|
||||
- `3`: Transport In (调入)
|
||||
- `4`: Recheck Addition (盘盈)
|
||||
- `5`: Combine (合并)
|
||||
- `11`: Offset (红冲,反向抵销入库)
|
||||
|
||||
**Outgoing (出库) Sources**:
|
||||
- `6`: Sales (销售)
|
||||
- `7`: Purchase Return (采购退货)
|
||||
- `8`: Transport Out (调出)
|
||||
- `9`: Recheck Removal (盘亏)
|
||||
- `10`: Explode (拆卷)
|
||||
- `11`: Offset (红冲,反向抵销出库)
|
||||
|
||||
### Warehouse Modes
|
||||
|
||||
Warehouses can operate in different modes:
|
||||
- `1`: Restricted In (严进) - Strict control on stock-in
|
||||
- `2`: Restricted In/Out (严进严出) - Strict control on both stock-in and stock-out
|
||||
- `3`: Unrestricted (宽进宽出) - Relaxed controls for both directions
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. Full Mode Stock Change
|
||||
|
||||
**URL**: `POST /api/v1/stock-change/`
|
||||
|
||||
**Description**: Creates a stock change record with explicit quantity lists for each product.
|
||||
|
||||
**Request Parameters**:
|
||||
```json
|
||||
{
|
||||
"type": 1, // 1=入库, 2=出库
|
||||
"warehouse": 1, // 仓库ID
|
||||
"source_type": 1, // 来源类型,见上文说明
|
||||
"source_id": 123, // 可选,来源单据ID
|
||||
"products": [
|
||||
{
|
||||
"product": 1, // 产品ID
|
||||
"quantity": [85.5, 75.2, 90.0] // 数量列表,每个值对应一条明细
|
||||
},
|
||||
{
|
||||
"product": 2,
|
||||
"quantity": [120.0]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"stock_change_record": {
|
||||
"id": 15,
|
||||
"type": 1,
|
||||
"warehouse": 1,
|
||||
"source_type": 1,
|
||||
"source_id": 123,
|
||||
"is_finished": false,
|
||||
"created_at": "2025-11-25T10:30:00Z",
|
||||
"updated_at": "2025-11-25T10:30:00Z"
|
||||
},
|
||||
"details": [
|
||||
{
|
||||
"id": 45,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 85.5,
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 15,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": null
|
||||
},
|
||||
{
|
||||
"id": 46,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 75.2,
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 15,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": null
|
||||
}
|
||||
// ... 更多明细
|
||||
],
|
||||
"message": "成功创建库存变动记录及 3 条明细",
|
||||
"created_details_count": 3
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Relaxed Mode Stock Change
|
||||
|
||||
**URL**: `POST /api/v1/stock-change/relaxed/`
|
||||
|
||||
**Description**: Creates a stock change record using total quantity and unit count to automatically split into details.
|
||||
|
||||
**Request Parameters**:
|
||||
```json
|
||||
{
|
||||
"type": 1, // 1=入库, 2=出库
|
||||
"warehouse": 1, // 仓库ID
|
||||
"source_type": 1, // 来源类型
|
||||
"source_id": 123, // 可选,来源单据ID
|
||||
"products": [
|
||||
{
|
||||
"product": 1, // 产品ID
|
||||
"quantity": {
|
||||
"value": 250.8, // 总数量
|
||||
"unit_count": 2.5 // 单条数量,默认为1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"stock_change_record": {
|
||||
"id": 16,
|
||||
"type": 1,
|
||||
"warehouse": 1,
|
||||
"source_type": 1,
|
||||
"source_id": 123,
|
||||
"is_finished": false,
|
||||
"created_at": "2025-11-25T11:00:00Z",
|
||||
"updated_at": "2025-11-25T11:00:00Z"
|
||||
},
|
||||
"details": [
|
||||
{
|
||||
"id": 48,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 100.0, // 自动拆分
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 16,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": null
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 100.0, // 自动拆分
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 16,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": null
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 50.8, // 剩余数量
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 16,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": null
|
||||
}
|
||||
],
|
||||
"message": "成功创建库存变动记录及 3 条明细",
|
||||
"created_details_count": 3
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Restricted Mode Stock Change
|
||||
|
||||
**URL**: `POST /api/v1/stock-change/restrict/`
|
||||
|
||||
**Description**: Creates a stock change record in "restricted-in-out" mode where outbound details must reference existing inbound details.
|
||||
|
||||
**Request Parameters**:
|
||||
```json
|
||||
{
|
||||
"type": 2, // 1=入库, 2=出库
|
||||
"warehouse": 1, // 仓库ID,必须为严进严出模式
|
||||
"source_type": 6, // 来源类型
|
||||
"source_id": 123, // 可选,来源单据ID
|
||||
"products": [
|
||||
{
|
||||
"product": 1, // 产品ID
|
||||
"quantity": [150.5], // 数量列表
|
||||
"consume_with": [23, 24] // 必须指定消耗的入库明细ID列表
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"stock_change_record": {
|
||||
"id": 17,
|
||||
"type": 2,
|
||||
"warehouse": 1,
|
||||
"source_type": 6,
|
||||
"source_id": 123,
|
||||
"is_finished": false,
|
||||
"created_at": "2025-11-25T11:15:00Z",
|
||||
"updated_at": "2025-11-25T11:15:00Z"
|
||||
},
|
||||
"details": [
|
||||
{
|
||||
"id": 51,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 75.25,
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 17,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": 23 // 消耗的入库明细ID
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 75.25,
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"stock_change_record": 17,
|
||||
"is_consumed": false,
|
||||
"consume_with_id": 24 // 消耗的入库明细ID
|
||||
}
|
||||
],
|
||||
"message": "成功创建库存变动记录及 2 条明细",
|
||||
"created_details_count": 2
|
||||
}
|
||||
```
|
||||
|
||||
### Other Related Endpoints
|
||||
|
||||
#### List Stock Changes
|
||||
**URL**: `GET /api/v1/stock-changes/`
|
||||
|
||||
**Response**: List of stock change records with pagination
|
||||
```json
|
||||
{
|
||||
"count": 100,
|
||||
"next": "http://example.com/api/v1/stock-changes/?page=2",
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 15,
|
||||
"type": 1,
|
||||
"type_display": "入库",
|
||||
"warehouse": 1,
|
||||
"source_type": 1,
|
||||
"source_type_display": "采购",
|
||||
"is_finished": true,
|
||||
"finished_at": "2025-11-25T12:00:00Z",
|
||||
"created_at": "2025-11-25T10:30:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Get Stock Change Details
|
||||
**URL**: `GET /api/v1/stock-change/<id>/`
|
||||
|
||||
**Response**: Detailed view of a specific stock change record with its details
|
||||
```json
|
||||
{
|
||||
"stock_change_record": {
|
||||
"id": 15,
|
||||
"type": 1,
|
||||
"type_display": "入库",
|
||||
"warehouse": 1,
|
||||
"source_type": 1,
|
||||
"source_type_display": "采购",
|
||||
"is_finished": true,
|
||||
"finished_at": "2025-11-25T12:00:00Z",
|
||||
"created_at": "2025-11-25T10:30:00Z"
|
||||
},
|
||||
"details": [
|
||||
{
|
||||
"id": 45,
|
||||
"product": 1,
|
||||
"product_name": "纯棉印花布",
|
||||
"quantity": 85.5,
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"is_consumed": false,
|
||||
"consume_with_id": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 库存红冲(Stock Change Offset)
|
||||
|
||||
- **URL**: `POST /api/v1/stock-change/<id>/offset/`
|
||||
- **权限**:登录员工,且仓库必须属于当前商户。
|
||||
- **描述**:针对已完成的库存变动记录生成反向库存记录,恢复库存数量并标记原快照 `cancelled=true`。
|
||||
|
||||
**Request Body**
|
||||
```json
|
||||
{
|
||||
"reason": "采购单作废,冲销库存",
|
||||
"request_id": "rcf-20251201-0001", // 可选,幂等键
|
||||
"extra_meta": { "source": "purchase_order", "operator": 18 }
|
||||
}
|
||||
```
|
||||
|
||||
> **注意**:当前版本仅支持“全量红冲”,`items` 字段请留空;未来版本会按需要开放部分明细红冲能力。
|
||||
|
||||
**Response**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "红冲记录已创建",
|
||||
"stock_change_record": {
|
||||
"id": 602,
|
||||
"type": 2,
|
||||
"source_type": 11,
|
||||
"source_id": 498,
|
||||
"warehouse": 3,
|
||||
"is_finished": true
|
||||
},
|
||||
"details": [
|
||||
{
|
||||
"id": 1880,
|
||||
"product": 15,
|
||||
"quantity": "100.00",
|
||||
"unit": 1
|
||||
}
|
||||
],
|
||||
"created_details_count": 1
|
||||
}
|
||||
```
|
||||
|
||||
**错误返回**
|
||||
|
||||
| HTTP | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| 400 | `{"error": "仅允许对已完成的库存变动执行红冲"}` | 原记录未完成或仍在处理中 |
|
||||
| 400 | `{"error": "该库存变动记录已执行红冲"}` | 阻止重复红冲 |
|
||||
| 403 | `{"error": "无权访问该库存变动记录"}` | 仓库不属于当前商户 |
|
||||
| 404 | `{"error": "库存变动记录ID xxx 不存在"}` | 记录不存在 |
|
||||
|
||||
红冲成功后,会生成 `source_type=OFFSET` 的库存记录,`source_id` 指向原库存记录 ID;原 `StockSnapshot` 会设置 `cancelled=true`、`offset_id=<新快照ID>`,便于审计追踪。
|
||||
|
||||
---
|
||||
|
||||
### 5. Stock Snapshot List
|
||||
|
||||
- **URL**: `GET /api/v1/stock-snapshots/`
|
||||
- **Description**: Read-only list of `StockSnapshot` entries. Supports `limit/offset` pagination,搜索与过滤。
|
||||
- **Query Parameters**:
|
||||
| 参数 | 说明 |
|
||||
|------|------|
|
||||
| `product` / `product_name` / `product_code` | 指定产品或模糊搜索 |
|
||||
| `warehouse` / `warehouse_name` | 指定仓库或模糊搜索 |
|
||||
| `stock_change_record` | 关联的出入库记录 ID |
|
||||
| `unit` | 单位过滤 |
|
||||
| `cancelled` | `true/false`,是否被标记取消 |
|
||||
| `has_offset` | `true/false`,筛选是否存在冲抵记录 |
|
||||
| `date_from` / `date_to` | 创建时间范围(`YYYY-MM-DD`) |
|
||||
| `search` | 针对产品名、产品编码、仓库名的全文搜索 |
|
||||
| `ordering` | 排序字段,默认 `-created_at` |
|
||||
|
||||
**Response 示例**:
|
||||
```json
|
||||
{
|
||||
"count": 2,
|
||||
"results": [
|
||||
{
|
||||
"id": 901,
|
||||
"product": 15,
|
||||
"product_name": "纯棉印花布",
|
||||
"warehouse": 3,
|
||||
"warehouse_name": "严进仓",
|
||||
"delta": "120.00",
|
||||
"quantity_before": "80.00",
|
||||
"quantity_after": "200.00",
|
||||
"stock_change_record": 456,
|
||||
"stock_change_record_type": "入库",
|
||||
"stock_change_record_source": "采购",
|
||||
"unit": 1,
|
||||
"unit_display": "米",
|
||||
"num_of_rolls": 3,
|
||||
"offset_to": null,
|
||||
"cancelled": false,
|
||||
"created_at": "2025-11-25T12:05:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Merchant Auto Complete Setting
|
||||
|
||||
- **URL**: `POST /api/v1/set-merchant-auto-complete-stock-change/`
|
||||
- **Description**: 为当前商户开启 / 关闭“创建出入库记录后自动完成”功能。开启后,`create_*` 接口在事务内会立即调用 `stock.services.make_stock_change_completed`,自动写入库存与快照。
|
||||
- **Request**:
|
||||
```json
|
||||
{
|
||||
"auto_complete": true
|
||||
}
|
||||
```
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"status": "success"
|
||||
}
|
||||
```
|
||||
|
||||
只有具备员工身份的登录用户才可调用该接口。
|
||||
|
||||
### 6. Stock Change Completion Behavior
|
||||
|
||||
- **自动完成**:当商户开启 `auto_complete_stock_change` 时,任意模式的创建接口都会立即调用 `make_stock_change_completed`,更新 `Inventory` 并生成 `StockSnapshot`。
|
||||
- **手动完成**:当需要补处理或未开启自动完成时,可调用 `POST /api/v1/stock-change/<id>/finish/` 手动触发 `make_stock_change_completed`,也可直接在后台脚本里调用服务函数。
|
||||
- **状态字段**:`StockChangeRecord.is_finished` / `finished_at` 会在完成时标记,用于列表和详情接口判断记录是否已经生效。
|
||||
|
||||
### 7. Finish Stock Change Record (Manual)
|
||||
|
||||
- **URL**: `POST /api/v1/stock-change/<id>/finish/`
|
||||
- **Description**: 手动触发指定出入库记录的库存扣减与快照写入,适用于未开启自动完成或需要补处理的场景。仅当前商户下且仓库可见的员工可调用。
|
||||
- **Request**: 无需请求体,只需保证 URL 中的 `<id>` 为目标 `StockChangeRecord` 的 ID。
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "库存变动记录已标记为完成",
|
||||
"stock_change_record": {
|
||||
"id": 17,
|
||||
"type": 1,
|
||||
"warehouse": 1,
|
||||
"warehouse_name": "严谨仓",
|
||||
"source_type": 1,
|
||||
"source_type_display": "采购",
|
||||
"source_id": 123,
|
||||
"is_finished": true,
|
||||
"finished_at": "2025-11-25T12:30:00Z",
|
||||
"created_at": "2025-11-25T11:50:00Z",
|
||||
"created_by": "stock_admin",
|
||||
"remarks": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. Stock Change Offset (Red Flush Placeholder)
|
||||
|
||||
- **URL**: `POST /api/v1/stock-change/<id>/offset/`
|
||||
- **Description**: 面向未来的库存红冲入口。当前仅提供占位实现,用于锁定最终接口形态;实际红冲逻辑尚未上线,因此调用会返回 `501 Not Implemented`,方便前端或上游业务在流程编排中预留节点。
|
||||
- **Request**:
|
||||
```json
|
||||
{
|
||||
"reason": "审批错误,需要冲销",
|
||||
"items": [
|
||||
{
|
||||
"product_id": 1,
|
||||
"quantities": ["50.00"]
|
||||
}
|
||||
],
|
||||
"request_id": "po-123-offset",
|
||||
"extra_meta": {
|
||||
"source": "purchase_order",
|
||||
"operator": "warehouse_admin"
|
||||
}
|
||||
}
|
||||
```
|
||||
- **Response(当前占位行为)**:
|
||||
```json
|
||||
{
|
||||
"error": "stock_offset_not_ready",
|
||||
"message": "库存红冲功能尚未实现",
|
||||
"record_id": 25
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Creating a Stock-in Record (Full Mode)
|
||||
```bash
|
||||
curl -X POST http://example.com/api/v1/stock-change/ \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer your_token" \
|
||||
-d '{
|
||||
"type": 1,
|
||||
"warehouse": 1,
|
||||
"source_type": 1,
|
||||
"products": [
|
||||
{
|
||||
"product": 1,
|
||||
"quantity": [100.5, 75.3, 120.0]
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Example 2: Creating a Stock-out Record (Relaxed Mode)
|
||||
```bash
|
||||
curl -X POST http://example.com/api/v1/stock-change/relaxed/ \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer your_token" \
|
||||
-d '{
|
||||
"type": 2,
|
||||
"warehouse": 1,
|
||||
"source_type": 6,
|
||||
"products": [
|
||||
{
|
||||
"product": 2,
|
||||
"quantity": {
|
||||
"value": 250.8,
|
||||
"unit_count": 2.5
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Example 3: Creating a Stock-out Record (Restricted Mode)
|
||||
```bash
|
||||
curl -X POST http://example.com/api/v1/stock-change/restrict/ \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer your_token" \
|
||||
-d '{
|
||||
"type": 2,
|
||||
"warehouse": 1,
|
||||
"source_type": 6,
|
||||
"products": [
|
||||
{
|
||||
"product": 3,
|
||||
"quantity": [100.0, 50.0],
|
||||
"consume_with": [45, 46]
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Example 4: Finish a Stock Change Record Manually
|
||||
```bash
|
||||
curl -X POST http://example.com/api/v1/stock-change/17/finish/ \
|
||||
-H "Authorization: Bearer your_token"
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Common Error Responses
|
||||
|
||||
#### Authentication Error
|
||||
```json
|
||||
{
|
||||
"error": "无权限访问"
|
||||
}
|
||||
```
|
||||
|
||||
#### Missing Required Parameters
|
||||
```json
|
||||
{
|
||||
"error": "缺少必要参数",
|
||||
"message": "请提供 type, warehouse, source_type"
|
||||
}
|
||||
```
|
||||
|
||||
#### Validation Error
|
||||
```json
|
||||
{
|
||||
"error": "产品数据验证失败",
|
||||
"details": {
|
||||
"products": [
|
||||
"产品列表中存在重复的产品ID"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Warehouse/Product Visibility Error
|
||||
```json
|
||||
{
|
||||
"error": "仓库ID 1 对当前用户不可见"
|
||||
}
|
||||
```
|
||||
|
||||
#### Business Logic Error
|
||||
```json
|
||||
{
|
||||
"error": "仓库出入库模式为【严进严出】,该模式暂未支持当前操作"
|
||||
}
|
||||
```
|
||||
|
||||
## Business Rules
|
||||
|
||||
1. **Warehouse Mode Restrictions**:
|
||||
- Full mode works with all warehouse modes
|
||||
- Relaxed mode requires "unrestricted" (宽进宽出) or "restricted-in" (严进) warehouses
|
||||
- Restricted mode requires "restricted-in-out" (严进严出) warehouses
|
||||
|
||||
2. **Stock Change Validation**:
|
||||
- Stock-in can only use incoming source types (1, 2, 3, 4, 5)
|
||||
- Stock-out can only use outgoing source types (6, 7, 8, 9, 10)
|
||||
|
||||
3. **Restricted Mode Specific Rules**:
|
||||
- Outbound details must reference existing inbound details
|
||||
- Referenced details must belong to the same warehouse
|
||||
- Referenced details must not already be consumed
|
||||
|
||||
4. **Permission Checks**:
|
||||
- Users can only access warehouses they have permission to see
|
||||
- Users can only access products they have permission to see
|
||||
- All stock change operations require proper authentication
|
||||
Reference in New Issue
Block a user