# 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//` **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