Skip to content

Multi-Warehouse Inventory Guide

Overview

The Multi-Warehouse Inventory system provides comprehensive stock tracking across unlimited warehouse locations. It supports available vs reserved stock calculations, reorder point monitoring, stock reservations for orders, physical count reconciliation, and inter-warehouse transfers. Built with CQRS patterns and immutable audit trails for regulatory compliance.

Table of Contents

Core Concepts

Inventory Record

Each product-warehouse combination has an inventory record:

php
[
    'id' => 1,
    'product_id' => 42,
    'warehouse_id' => 1,
    'stock_quantity' => 100,        // Total stock
    'reserved_quantity' => 10,      // Reserved for orders
    'available_quantity' => 90,     // Available = stock - reserved
    'reorder_point' => 20,          // Low stock threshold
    'reorder_quantity' => 50,       // Auto-reorder amount
    'location' => 'A-12-3',         // Bin location
    'last_counted_at' => '2025-01-10',
    'last_count_quantity' => 98,
]

Stock Calculations

Available Quantity = Stock Quantity - Reserved Quantity

Stock: 100 units
Reserved: 10 units (for pending orders)
Available: 90 units (can be sold)

Multi-Warehouse Structure

Products can exist in multiple warehouses:

Product: Laptop - Dell XPS 13

Warehouse: Main DC (Chicago)
- Stock: 100
- Reserved: 10
- Available: 90

Warehouse: West Coast (LA)
- Stock: 75
- Reserved: 5
- Available: 70

Warehouse: East Coast (NYC)
- Stock: 50
- Reserved: 8
- Available: 42

Total Across All Warehouses:
- Stock: 225
- Reserved: 23
- Available: 202

Inventory Tracking

View Inventory by Warehouse

Get inventory for a specific warehouse:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory?warehouse_id=1" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": [
    {
      "id": 1,
      "product": {
        "id": 42,
        "name": "Laptop - Dell XPS 13",
        "sku": "DELL-XPS13-001"
      },
      "warehouse": {
        "id": 1,
        "name": "Main Distribution Center",
        "code": "MDC"
      },
      "stock_quantity": 100,
      "reserved_quantity": 10,
      "available_quantity": 90,
      "reorder_point": 20,
      "location": "A-12-3",
      "status": "adequate"
    }
  ]
}

View Inventory for Product

Get all warehouse inventory for a product:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/show?product_id=42" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": {
    "product": {
      "id": 42,
      "name": "Laptop - Dell XPS 13",
      "sku": "DELL-XPS13-001"
    },
    "warehouses": [
      {
        "warehouse_id": 1,
        "warehouse_name": "Main DC",
        "stock_quantity": 100,
        "reserved_quantity": 10,
        "available_quantity": 90,
        "reorder_point": 20
      },
      {
        "warehouse_id": 2,
        "warehouse_name": "West Coast",
        "stock_quantity": 75,
        "reserved_quantity": 5,
        "available_quantity": 70,
        "reorder_point": 15
      }
    ],
    "totals": {
      "total_stock": 175,
      "total_reserved": 15,
      "total_available": 160
    }
  }
}

Inventory Summary

Get aggregated inventory statistics:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/summary" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": {
    "total_products": 450,
    "total_stock_value": 2450000.00,
    "total_warehouses": 5,
    "low_stock_items": 23,
    "out_of_stock_items": 8,
    "overstock_items": 12,
    "total_reservations": 145,
    "inventory_turnover": 4.2,
    "by_warehouse": [
      {
        "warehouse_id": 1,
        "warehouse_name": "Main DC",
        "total_products": 380,
        "total_stock": 12450,
        "stock_value": 1850000.00
      }
    ]
  }
}

Stock Levels

Stock Status

Inventory records have calculated status:

Adequate: Stock > Reorder Point

Stock: 100, Reorder Point: 20
Status: adequate (plenty in stock)

Low: Stock ≤ Reorder Point but > 0

Stock: 15, Reorder Point: 20
Status: low (needs reorder)

Out of Stock: Stock = 0

Stock: 0
Status: out_of_stock (no inventory)

Overstock: Stock > 3× Reorder Point (configurable)

Stock: 200, Reorder Point: 20
Status: overstock (excess inventory)

Low Stock Report

Get products below reorder point:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/low-stock" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": [
    {
      "product_id": 42,
      "product_name": "Laptop - Dell XPS 13",
      "sku": "DELL-XPS13-001",
      "warehouse_id": 1,
      "warehouse_name": "Main DC",
      "stock_quantity": 15,
      "reorder_point": 20,
      "reorder_quantity": 50,
      "shortage": 5,
      "days_until_stockout": 12,
      "suggested_order_quantity": 50,
      "supplier": {
        "id": 2,
        "name": "Tech Supplies Inc"
      }
    }
  ],
  "meta": {
    "total_low_stock_items": 23,
    "total_suggested_order_value": 125000.00
  }
}

Out of Stock Report

Get completely depleted items:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/out-of-stock" \
  -H "Authorization: Bearer {token}"

Stock Reservations

Reserve Stock

Reserve inventory for pending orders:

bash
curl -X POST "https://api.crm.test/api/v1/operations/inventory/reserve" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 42,
    "warehouse_id": 1,
    "quantity": 5,
    "reason": "Sales Order #12345",
    "reference_type": "sales_order",
    "reference_id": 12345
  }'

Effect:

  • reserved_quantity increases by 5
  • available_quantity decreases by 5
  • stock_quantity unchanged
  • Stock movement recorded

Response:

json
{
  "message": "Reserved 5 unit(s) successfully",
  "data": {
    "product_id": 42,
    "warehouse_id": 1,
    "stock_quantity": 100,
    "reserved_quantity": 15,
    "available_quantity": 85,
    "reservation_id": 456
  }
}

Release Reservation

Release reserved stock when order is cancelled:

bash
curl -X POST "https://api.crm.test/api/v1/operations/inventory/release" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 42,
    "warehouse_id": 1,
    "quantity": 5,
    "reason": "Order cancelled",
    "reference_type": "sales_order",
    "reference_id": 12345
  }'

Effect:

  • reserved_quantity decreases by 5
  • available_quantity increases by 5
  • stock_quantity unchanged
  • Stock movement recorded

Reservation Workflow

mermaid
graph LR
    A[Order Created] --> B[Reserve Stock]
    B --> C{Order Status}
    C -->|Shipped| D[Decrease Stock]
    C -->|Cancelled| E[Release Reservation]
    D --> F[Stock Reduced]
    E --> G[Stock Available Again]

States:

  1. Order Created: Reserve stock (available ↓)
  2. Order Shipped: Decrease stock (stock ↓, reserved ↓)
  3. Order Cancelled: Release reservation (available ↑, reserved ↓)

Inventory Adjustments

Adjust Stock Manually

Increase or decrease stock with reason:

bash
curl -X POST "https://api.crm.test/api/v1/operations/inventory/adjust-stock" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 42,
    "warehouse_id": 1,
    "quantity": -3,
    "reason": "Damaged units found during inspection",
    "type": "damage"
  }'

Parameters:

ParameterTypeRequiredDescription
product_idinteger✅ YesProduct to adjust
warehouse_idinteger✅ YesWarehouse location
quantityinteger✅ YesChange amount (+ or -)
reasonstring✅ YesExplanation for adjustment
typestringNoMovement type (damage, theft, expiry, etc.)

Adjustment Types:

  • adjustment - General manual adjustment
  • damage - Damaged goods
  • theft - Theft/shrinkage
  • expiry - Expired/spoiled items
  • found - Found during audit

Response:

json
{
  "message": "Stock adjusted successfully",
  "data": {
    "product_id": 42,
    "warehouse_id": 1,
    "previous_stock": 100,
    "adjustment": -3,
    "new_stock": 97,
    "available_quantity": 87,
    "stock_movement_id": 789
  }
}

Adjustment Approval

Some adjustments require approval (configurable):

Require Approval:

  • Large adjustments (> threshold)
  • Damage/theft/expiry adjustments
  • Negative adjustments

Auto-Approved:

  • Small positive adjustments
  • Recount corrections
  • Physical count updates

Physical Counts

Record Physical Count

Reconcile actual inventory with system records:

bash
curl -X POST "https://api.crm.test/api/v1/operations/inventory/physical-count" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "warehouse_id": 1,
    "counts": [
      {
        "product_id": 42,
        "counted_quantity": 98,
        "location": "A-12-3"
      },
      {
        "product_id": 43,
        "counted_quantity": 145,
        "location": "A-12-4"
      }
    ],
    "counted_by": "John Doe",
    "notes": "Monthly physical count - January 2025"
  }'

Process:

  1. Record counted quantities
  2. Calculate variances (counted - system)
  3. Create adjustment records
  4. Update last_counted_at timestamp
  5. Generate variance report

Response:

json
{
  "message": "Physical count recorded successfully",
  "data": {
    "warehouse_id": 1,
    "total_products_counted": 2,
    "variances": [
      {
        "product_id": 42,
        "product_name": "Laptop - Dell XPS 13",
        "system_quantity": 100,
        "counted_quantity": 98,
        "variance": -2,
        "variance_percentage": -2.0,
        "adjustment_id": 890
      },
      {
        "product_id": 43,
        "product_name": "Mouse - Wireless",
        "system_quantity": 150,
        "counted_quantity": 145,
        "variance": -5,
        "variance_percentage": -3.33,
        "adjustment_id": 891
      }
    ],
    "total_variance_value": -150.00
  }
}

Physical Count Report

View variance analysis:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/physical-count/report?warehouse_id=1&date=2025-01-15" \
  -H "Authorization: Bearer {token}"

Inter-Warehouse Transfers

Transfer Stock Between Warehouses

Move inventory from one location to another:

bash
curl -X POST "https://api.crm.test/api/v1/operations/inventory/transfer" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 42,
    "from_warehouse_id": 1,
    "to_warehouse_id": 2,
    "quantity": 25,
    "reason": "Restocking West Coast warehouse",
    "expected_arrival": "2025-01-20",
    "shipping_method": "Ground"
  }'

Process:

  1. Validate sufficient stock in source warehouse
  2. Decrease stock in source warehouse
  3. Create "in-transit" record
  4. (Later) Receive at destination warehouse
  5. Increase stock in destination warehouse

Response:

json
{
  "message": "Transfer initiated successfully",
  "data": {
    "transfer_id": 123,
    "product_id": 42,
    "from_warehouse": "Main DC",
    "to_warehouse": "West Coast",
    "quantity": 25,
    "status": "in_transit",
    "expected_arrival": "2025-01-20",
    "tracking_number": "TRK-20250115-123",
    "from_inventory": {
      "stock_quantity": 75,
      "available_quantity": 65
    }
  }
}

Transfer Workflow

mermaid
graph LR
    A[Initiate Transfer] --> B[Stock Decreased at Source]
    B --> C[In Transit]
    C --> D[Arrive at Destination]
    D --> E[Stock Increased at Destination]

States:

  • Initiated: Transfer request created
  • In Transit: Stock removed from source, not yet at destination
  • Completed: Stock added to destination
  • Cancelled: Transfer cancelled, stock returned to source

Low Stock Alerts

Reorder Point System

Automatic alerts when stock hits threshold:

Reorder Point: Minimum stock level before reorder Reorder Quantity: Amount to order when replenishing

Example:
Product: Laptop - Dell XPS 13
Reorder Point: 20 units
Reorder Quantity: 50 units

Stock Level: 100 → OK (no alert)
Stock Level: 18 → LOW (alert triggered, order 50 units)
Stock Level: 0 → OUT (critical alert)

Reorder Settings

Configure per product per warehouse:

bash
curl -X PUT "https://api.crm.test/api/v1/operations/inventory/reorder-settings" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 42,
    "warehouse_id": 1,
    "reorder_point": 20,
    "reorder_quantity": 50,
    "auto_generate_po": true
  }'

Parameters:

  • reorder_point: Trigger threshold
  • reorder_quantity: Order amount
  • auto_generate_po: Auto-create purchase orders

Reorder Report

Get products needing reorder:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/reorder-report" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": [
    {
      "product_id": 42,
      "product_name": "Laptop - Dell XPS 13",
      "sku": "DELL-XPS13-001",
      "warehouse_id": 1,
      "current_stock": 15,
      "reorder_point": 20,
      "reorder_quantity": 50,
      "shortage": 5,
      "suggested_order": 50,
      "supplier": {
        "id": 2,
        "name": "Tech Supplies Inc",
        "lead_time_days": 7
      },
      "days_until_stockout": 12,
      "priority": "medium"
    }
  ],
  "meta": {
    "total_items_to_reorder": 23,
    "estimated_order_value": 125000.00,
    "can_auto_generate_pos": true
  }
}

Inventory Reports

Inventory Valuation

Get total inventory value:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/valuation" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": {
    "total_inventory_value": 2450000.00,
    "by_warehouse": [
      {
        "warehouse_id": 1,
        "warehouse_name": "Main DC",
        "total_value": 1850000.00,
        "total_units": 12450
      }
    ],
    "by_category": [
      {
        "category_id": 5,
        "category_name": "Electronics",
        "total_value": 1500000.00,
        "percentage": 61.22
      }
    ],
    "cost_method": "FIFO"
  }
}

Inventory Turnover

Calculate inventory turnover ratio:

bash
curl -X GET "https://api.crm.test/api/v1/operations/inventory/turnover?period=90_days" \
  -H "Authorization: Bearer {token}"

Formula: Cost of Goods Sold / Average Inventory Value

Example:
COGS (90 days): $500,000
Average Inventory: $125,000
Turnover Ratio: 4.0 (inventory turns 4× per quarter)
Days Inventory: 22.5 days

Stock Movement History

View all movements for a product:

bash
curl -X GET "https://api.crm.test/api/v1/operations/stock-movements?product_id=42&warehouse_id=1" \
  -H "Authorization: Bearer {token}"

Response:

json
{
  "data": [
    {
      "id": 789,
      "type": "purchase",
      "quantity": 50,
      "created_at": "2025-01-15 10:00:00",
      "user": "Admin User",
      "reason": "Purchase Order #PO-1234 received",
      "reference": {
        "type": "purchase_order",
        "id": 1234
      },
      "balance_after": 150
    },
    {
      "id": 788,
      "type": "sale",
      "quantity": -5,
      "created_at": "2025-01-14 15:30:00",
      "user": "Sales System",
      "reason": "Sales Order #SO-5678",
      "balance_after": 100
    }
  ]
}

API Endpoints

Inventory Viewing

MethodEndpointDescription
GET/inventoryList inventory with filters
GET/inventory/showShow inventory for product
GET/inventory/summaryInventory statistics

Stock Operations

MethodEndpointDescription
POST/inventory/adjust-stockManual stock adjustment
POST/inventory/reserveReserve stock for orders
POST/inventory/releaseRelease reserved stock
POST/inventory/transferTransfer between warehouses

Physical Counts

MethodEndpointDescription
POST/inventory/physical-countRecord physical count
GET/inventory/physical-count/reportVariance report

Reports

MethodEndpointDescription
GET/inventory/low-stockLow stock report
GET/inventory/out-of-stockOut of stock report
GET/inventory/reorder-reportReorder recommendations
GET/inventory/valuationInventory valuation
GET/inventory/turnoverTurnover analysis

Settings

MethodEndpointDescription
PUT/inventory/reorder-settingsConfigure reorder points

See: API Reference for complete documentation.

Next Steps

  1. Configure Warehouses - Read Warehouse Management Guide
  2. Setup Reorder Points - Configure automatic reordering
  3. Track Movements - Explore Stock Movement Guide
  4. Order Stock - Learn Purchase Order Workflow

Documentation for SynthesQ CRM/ERP Platform