699 lines
15 KiB
Markdown
699 lines
15 KiB
Markdown
# Warehouse Material Management System - API Specification
|
|
|
|
**Base URL:** `/api`
|
|
|
|
---
|
|
|
|
## 1. Material APIs
|
|
|
|
### GET /materials
|
|
|
|
List all materials with optional filtering.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|----------------------------------|
|
|
| search | string | No | Search by material code or name |
|
|
| category | string | No | Filter by category |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "10mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"warning_stock": 100,
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z"
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
|
|
---
|
|
|
|
### GET /materials/:id
|
|
|
|
Get a single material by ID.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|---------|----------|------------------|
|
|
| id | integer | Yes | Material ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "10mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"warning_stock": 100,
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z"
|
|
},
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
### POST /materials
|
|
|
|
Create a new material.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "10mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"warning_stock": 100
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|----------------|---------|----------|--------------------------------------|
|
|
| material_code | string | Yes | Unique material code |
|
|
| name | string | Yes | Material name |
|
|
| spec | string | No | Specification |
|
|
| category | string | No | Material category |
|
|
| unit | string | No | Unit of measure (default: pcs) |
|
|
| warning_stock | integer | No | Warning stock threshold (default: 0) |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "10mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"warning_stock": 100,
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z"
|
|
},
|
|
"message": "Material created successfully"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `201 Created` - Material created successfully
|
|
- `400 Bad Request` - Invalid request body or material code already exists
|
|
|
|
---
|
|
|
|
### PUT /materials/:id
|
|
|
|
Update an existing material.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|---------|----------|------------------|
|
|
| id | integer | Yes | Material ID |
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "12mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"warning_stock": 150
|
|
}
|
|
```
|
|
|
|
All fields are optional. Only provided fields will be updated.
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "12mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"warning_stock": 150,
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-02T10:00:00Z"
|
|
},
|
|
"message": "Material updated successfully"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Material updated successfully
|
|
- `400 Bad Request` - Invalid request body
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
### DELETE /materials/:id
|
|
|
|
Delete a material.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|---------|----------|------------------|
|
|
| id | integer | Yes | Material ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": null,
|
|
"message": "Material deleted successfully"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Material deleted successfully
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
## 2. Inbound APIs
|
|
|
|
### GET /inbound
|
|
|
|
List all inbound orders.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|----------------------------------|
|
|
| search | string | No | Search by handler or supplier |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"handler": "John Doe",
|
|
"supplier": "ABC Steel Co.",
|
|
"status": "completed",
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z"
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
|
|
---
|
|
|
|
### GET /inbound/:id
|
|
|
|
Get a single inbound order with its items.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|---------|----------|-------------------|
|
|
| id | integer | Yes | Inbound order ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"handler": "John Doe",
|
|
"supplier": "ABC Steel Co.",
|
|
"status": "completed",
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z",
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"material_id": 1,
|
|
"material_code": "M001",
|
|
"material_name": "Steel Plate",
|
|
"quantity": 500
|
|
}
|
|
]
|
|
},
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Inbound order not found
|
|
|
|
---
|
|
|
|
### POST /inbound
|
|
|
|
Create a new inbound order.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"handler": "John Doe",
|
|
"supplier": "ABC Steel Co.",
|
|
"items": [
|
|
{ "material_id": 1, "quantity": 500 },
|
|
{ "material_id": 2, "quantity": 200 }
|
|
]
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|----------|--------|----------|------------------------|
|
|
| handler | string | Yes | Handler name |
|
|
| supplier | string | Yes | Supplier name |
|
|
| items | array | Yes | List of inbound items |
|
|
|
|
**Items Array Structure:**
|
|
| Field | Type | Required | Description |
|
|
|-------------|---------|----------|--------------------------|
|
|
| material_id | integer | Yes | Material ID |
|
|
| quantity | integer | Yes | Inbound quantity (> 0) |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"handler": "John Doe",
|
|
"supplier": "ABC Steel Co.",
|
|
"status": "completed",
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z",
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"material_id": 1,
|
|
"material_code": "M001",
|
|
"material_name": "Steel Plate",
|
|
"quantity": 500
|
|
}
|
|
]
|
|
},
|
|
"message": "Inbound order created successfully"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `201 Created` - Inbound order created successfully
|
|
- `400 Bad Request` - Invalid request body or material not found
|
|
|
|
---
|
|
|
|
### GET /inbound/materials/:materialId
|
|
|
|
Get inbound records for a specific material.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-------------|---------|----------|-----------------|
|
|
| materialId | integer | Yes | Material ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"inbound_id": 1,
|
|
"handler": "John Doe",
|
|
"supplier": "ABC Steel Co.",
|
|
"quantity": 500,
|
|
"created_at": "2026-01-01T08:00:00Z"
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
## 3. Outbound APIs
|
|
|
|
### GET /outbound
|
|
|
|
List all outbound orders.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|----------------------------------|
|
|
| search | string | No | Search by handler or receiver |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"handler": "Jane Smith",
|
|
"receiver": "XYZ Factory",
|
|
"status": "completed",
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z"
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
|
|
---
|
|
|
|
### GET /outbound/:id
|
|
|
|
Get a single outbound order with its items.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|---------|----------|-------------------|
|
|
| id | integer | Yes | Outbound order ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"handler": "Jane Smith",
|
|
"receiver": "XYZ Factory",
|
|
"status": "completed",
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z",
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"material_id": 1,
|
|
"material_code": "M001",
|
|
"material_name": "Steel Plate",
|
|
"quantity": 100
|
|
}
|
|
]
|
|
},
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Outbound order not found
|
|
|
|
---
|
|
|
|
### POST /outbound
|
|
|
|
Create a new outbound order.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"handler": "Jane Smith",
|
|
"receiver": "XYZ Factory",
|
|
"items": [
|
|
{ "material_id": 1, "quantity": 100 },
|
|
{ "material_id": 2, "quantity": 50 }
|
|
]
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|----------|--------|----------|-------------------------|
|
|
| handler | string | Yes | Handler name |
|
|
| receiver | string | Yes | Receiver name |
|
|
| items | array | Yes | List of outbound items |
|
|
|
|
**Items Array Structure:**
|
|
| Field | Type | Required | Description |
|
|
|-------------|---------|----------|---------------------------|
|
|
| material_id | integer | Yes | Material ID |
|
|
| quantity | integer | Yes | Outbound quantity (> 0) |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"id": 1,
|
|
"handler": "Jane Smith",
|
|
"receiver": "XYZ Factory",
|
|
"status": "completed",
|
|
"created_at": "2026-01-01T08:00:00Z",
|
|
"updated_at": "2026-01-01T08:00:00Z",
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"material_id": 1,
|
|
"material_code": "M001",
|
|
"material_name": "Steel Plate",
|
|
"quantity": 100
|
|
}
|
|
]
|
|
},
|
|
"message": "Outbound order created successfully"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `201 Created` - Outbound order created successfully
|
|
- `400 Bad Request` - Invalid request body, material not found, or insufficient stock
|
|
|
|
---
|
|
|
|
### GET /outbound/materials/:materialId
|
|
|
|
Get outbound records for a specific material.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-------------|---------|----------|-----------------|
|
|
| materialId | integer | Yes | Material ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"outbound_id": 1,
|
|
"handler": "Jane Smith",
|
|
"receiver": "XYZ Factory",
|
|
"quantity": 100,
|
|
"created_at": "2026-01-01T08:00:00Z"
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
## 4. Stock APIs
|
|
|
|
### GET /stock
|
|
|
|
List all stock information with material details.
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"material_id": 1,
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "10mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"total_on_hand": 500,
|
|
"warning_stock": 100
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
|
|
---
|
|
|
|
### GET /stock/:materialId
|
|
|
|
Get stock information for a single material.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-------------|---------|----------|-----------------|
|
|
| materialId | integer | Yes | Material ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {
|
|
"material_id": 1,
|
|
"material_code": "M001",
|
|
"name": "Steel Plate",
|
|
"spec": "10mm x 2000mm x 6000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"total_on_hand": 500,
|
|
"warning_stock": 100
|
|
},
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
### GET /stock/warning
|
|
|
|
List materials where current stock is below warning stock threshold.
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"material_id": 2,
|
|
"material_code": "M002",
|
|
"name": "Aluminum Rod",
|
|
"spec": "20mm x 3000mm",
|
|
"category": "Raw Material",
|
|
"unit": "pcs",
|
|
"total_on_hand": 30,
|
|
"warning_stock": 100
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
|
|
---
|
|
|
|
### GET /stock/logs/:materialId
|
|
|
|
Get stock change logs for a specific material.
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Required | Description |
|
|
|-------------|---------|----------|-----------------|
|
|
| materialId | integer | Yes | Material ID |
|
|
|
|
**Response Body:**
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"material_id": 1,
|
|
"change_type": "inbound",
|
|
"quantity": 500,
|
|
"balance": 500,
|
|
"reference_id": 1,
|
|
"reference_type": "inbound",
|
|
"created_at": "2026-01-01T08:00:00Z"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"material_id": 1,
|
|
"change_type": "outbound",
|
|
"quantity": 100,
|
|
"balance": 400,
|
|
"reference_id": 1,
|
|
"reference_type": "outbound",
|
|
"created_at": "2026-01-01T10:00:00Z"
|
|
}
|
|
],
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
**HTTP Status Codes:**
|
|
- `200 OK` - Success
|
|
- `404 Not Found` - Material not found
|
|
|
|
---
|
|
|
|
## Common Response Structure
|
|
|
|
All API responses follow this structure:
|
|
|
|
```json
|
|
{
|
|
"code": 0,
|
|
"data": {},
|
|
"message": "success"
|
|
}
|
|
```
|
|
|
|
| Field | Type | Description |
|
|
|---------|---------|--------------------------------------------------------|
|
|
| code | integer | Status code (0 = success, non-zero = error) |
|
|
| data | object | Response data (null for delete operations) |
|
|
| message | string | Human-readable message |
|
|
|
|
## HTTP Status Code Summary
|
|
|
|
| Status Code | Description |
|
|
|-------------|--------------------------------------------------|
|
|
| 200 OK | Request succeeded |
|
|
| 201 Created | Resource created successfully |
|
|
| 400 Bad Request | Invalid request body or parameters |
|
|
| 404 Not Found | Resource not found |
|
|
| 500 Internal Server Error | Server-side error |
|