Warehouses
Warehouses are the physical or logical storage locations for inventory. They support a hierarchical parent/child structure, branch assignment, manager tracking, and optional GL account linkage for accounting integration.
Purpose
- Define storage locations with type classification (main, sub, transit, damaged, returns)
- Build hierarchical warehouse trees (parent → children)
- Assign warehouses to branches for multi-location operations
- Link warehouses to GL accounts for automatic accounting entries
- Control whether negative stock is allowed per warehouse
- Generate warehouse codes automatically via the Sequence system
Entity Attributes
| Field | Type | Description |
|---|---|---|
id | bigint | Primary key |
company_id | bigint | FK to companies |
code | string(20) | Auto-generated unique code |
name | string | English name |
name_ar | string? | Arabic name |
type | enum | main, sub, transit, damaged, returns |
parent_warehouse_id | bigint? | FK to warehouses (parent) |
branch_id | bigint? | FK to branches |
manager_id | bigint? | FK to users |
account_id | bigint? | FK to accounts (linked GL account) |
address | text? | Physical address |
phone | string? | Contact phone |
email | string? | Contact email |
allow_negative_stock | boolean | Allow stock to go below zero (default: false) |
is_active | boolean | Active status (default: true) |
notes | text? | Additional notes |
created_at | timestamp | Creation timestamp |
updated_at | timestamp | Last update timestamp |
deleted_at | timestamp? | Soft-delete timestamp |
Indexes:
UNIQUE (company_id, code)INDEX (parent_warehouse_id)INDEX (branch_id)INDEX (type)
Relationships
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/inventory/warehouses | List warehouses (paginated, filterable) |
GET | /api/inventory/warehouses/tree | Get warehouses as a hierarchical tree |
POST | /api/inventory/warehouses | Create a new warehouse |
GET | /api/inventory/warehouses/{id} | Get warehouse details |
PUT | /api/inventory/warehouses/{id} | Update a warehouse |
DELETE | /api/inventory/warehouses/{id} | Soft-delete a warehouse |
Query Parameters (List)
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
type | string | Filter by warehouse type |
branch_id | integer | Filter by branch |
is_active | boolean | Filter by active status |
search | string | Search by name, name_ar, or code |
Request/Response Examples
Create Warehouse
Request POST /api/inventory/warehouses
bash
curl -X POST https://moon-erp.test/api/inventory/warehouses \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Main Warehouse",
"name_ar": "المستودع الرئيسي",
"type": "main",
"branch_id": 1,
"manager_id": 1,
"address": "123 Industrial Zone",
"phone": "+965-12345678",
"allow_negative_stock": false,
"is_active": true
}'dart
final response = await http.post(
Uri.parse('https://moon-erp.test/api/inventory/warehouses'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: jsonEncode({
'name': 'Main Warehouse',
'name_ar': 'المستودع الرئيسي',
'type': 'main',
'branch_id': 1,
'manager_id': 1,
'address': '123 Industrial Zone',
'phone': '+965-12345678',
'allow_negative_stock': false,
'is_active': true,
}),
);Response 201 Created
json
{
"data": {
"id": 1,
"company_id": 1,
"code": "WH-000001",
"name": "Main Warehouse",
"name_ar": "المستودع الرئيسي",
"type": "main",
"type_label": "Main",
"parent_warehouse_id": null,
"branch_id": 1,
"manager_id": 1,
"account_id": null,
"address": "123 Industrial Zone",
"phone": "+965-12345678",
"email": null,
"allow_negative_stock": false,
"is_active": true,
"notes": null,
"branch": { "id": 1, "name": "Head Office" },
"manager": { "id": 1, "name": "Admin" },
"children": [],
"created_at": "2026-02-22T10:00:00.000000Z",
"updated_at": "2026-02-22T10:00:00.000000Z"
}
}Get Warehouse Tree
Request GET /api/inventory/warehouses/tree
Response 200 OK
json
{
"data": [
{
"id": 1,
"code": "WH-000001",
"name": "Main Warehouse",
"type": "main",
"is_active": true,
"children": [
{
"id": 2,
"code": "WH-000002",
"name": "Sub Warehouse A",
"type": "sub",
"is_active": true,
"children": []
}
]
}
]
}Business Rules
- Auto-generated code — The
codeis automatically generated via the Sequence system (e.g.,WH-000001). Do not pass it in the request. - Hierarchy — A warehouse can have a
parent_warehouse_idto form a tree. Use the/treeendpoint to get the full hierarchy. - Type classification — Each warehouse must have a type:
main(primary storage),sub(secondary),transit(in-transit),damaged(defective goods), orreturns(customer returns). - Negative stock control — When
allow_negative_stockisfalse(default), issue approvals will fail if stock is insufficient. - Delete protection — A warehouse cannot be deleted if it has child warehouses.
- Soft delete — Deletion is a soft delete; the record is retained for audit purposes.
- Branch assignment — Warehouses can be assigned to a branch for multi-location filtering.
- GL account link — The optional
account_idlinks the warehouse to a GL account for accounting integration.
Warehouse Types
| Type | Value | Usage |
|---|---|---|
| Main | main | Primary storage location |
| Sub | sub | Secondary or overflow storage |
| Transit | transit | Goods in transit between locations |
| Damaged | damaged | Storage for defective goods |
| Returns | returns | Storage for customer returns |