Skip to content

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

FieldTypeDescription
idbigintPrimary key
company_idbigintFK to companies
codestring(20)Auto-generated unique code
namestringEnglish name
name_arstring?Arabic name
typeenummain, sub, transit, damaged, returns
parent_warehouse_idbigint?FK to warehouses (parent)
branch_idbigint?FK to branches
manager_idbigint?FK to users
account_idbigint?FK to accounts (linked GL account)
addresstext?Physical address
phonestring?Contact phone
emailstring?Contact email
allow_negative_stockbooleanAllow stock to go below zero (default: false)
is_activebooleanActive status (default: true)
notestext?Additional notes
created_attimestampCreation timestamp
updated_attimestampLast update timestamp
deleted_attimestamp?Soft-delete timestamp

Indexes:

  • UNIQUE (company_id, code)
  • INDEX (parent_warehouse_id)
  • INDEX (branch_id)
  • INDEX (type)

Relationships

API Endpoints

MethodPathDescription
GET/api/inventory/warehousesList warehouses (paginated, filterable)
GET/api/inventory/warehouses/treeGet warehouses as a hierarchical tree
POST/api/inventory/warehousesCreate 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)

ParameterTypeDescription
pageintegerPage number (default: 1)
typestringFilter by warehouse type
branch_idintegerFilter by branch
is_activebooleanFilter by active status
searchstringSearch 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

  1. Auto-generated code — The code is automatically generated via the Sequence system (e.g., WH-000001). Do not pass it in the request.
  2. Hierarchy — A warehouse can have a parent_warehouse_id to form a tree. Use the /tree endpoint to get the full hierarchy.
  3. Type classification — Each warehouse must have a type: main (primary storage), sub (secondary), transit (in-transit), damaged (defective goods), or returns (customer returns).
  4. Negative stock control — When allow_negative_stock is false (default), issue approvals will fail if stock is insufficient.
  5. Delete protection — A warehouse cannot be deleted if it has child warehouses.
  6. Soft delete — Deletion is a soft delete; the record is retained for audit purposes.
  7. Branch assignment — Warehouses can be assigned to a branch for multi-location filtering.
  8. GL account link — The optional account_id links the warehouse to a GL account for accounting integration.

Warehouse Types

TypeValueUsage
MainmainPrimary storage location
SubsubSecondary or overflow storage
TransittransitGoods in transit between locations
DamageddamagedStorage for defective goods
ReturnsreturnsStorage for customer returns

Moon ERP API Documentation