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

486 lines
11 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.
# 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 (合并)
**Outgoing (出库) Sources**:
- `6`: Sales (销售)
- `7`: Purchase Return (采购退货)
- `8`: Transport Out (调出)
- `9`: Recheck Removal (盘亏)
- `10`: Explode (拆卷)
### 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
}
]
}
```
## 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]
}
]
}'
```
## 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