azaharizaman/nexus-inventory

Framework-agnostic inventory and stock management for Nexus ERP

Maintainers

Package info

github.com/azaharizaman/nexus-inventory

pkg:composer/azaharizaman/nexus-inventory

Statistics

Installs: 1

Dependents: 3

Suggesters: 4

Stars: 0

Open Issues: 0

v0.1.0-alpha1 2026-05-05 02:28 UTC

This package is auto-updated.

Last update: 2026-05-05 02:54:36 UTC


README

PHP Version License Status Implementation Test Coverage

Framework-agnostic inventory and stock management package for Nexus ERP. Provides multi-valuation stock tracking (FIFO, Weighted Average, Standard Cost), lot tracking with FEFO enforcement, serial number management, stock reservations with auto-expiry, and inter-warehouse transfers.

Table of Contents

Overview

Nexus\Inventory is a pure PHP 8.3+ package providing comprehensive inventory and stock management capabilities. The package is framework-agnostic and integrates seamlessly with Laravel, Symfony, or vanilla PHP applications.

Key Capabilities:

  • Multi-Valuation Support: FIFO (O(n)), Weighted Average (O(1)), Standard Cost (O(1))
  • Lot Tracking: FEFO (First-Expiry-First-Out) enforcement for regulatory compliance (FDA, HACCP)
  • Serial Number Management: Tenant-scoped uniqueness with history tracking
  • Stock Reservations: Auto-expiry with configurable TTL (24-72 hours)
  • Inter-Warehouse Transfers: FSM-based workflow (pending → in_transit → completed)
  • Event-Driven GL Integration: 8 domain events for Finance package integration

Features

Stock Management

  • Stock Receipt: Record incoming stock from purchase orders, production, transfers
  • Stock Issue: Issue stock for sales orders, production consumption, scrap, adjustments
  • Stock Adjustment: Cycle count, damage, found stock, obsolescence
  • Stock Availability: Real-time calculation (quantity - reserved_quantity)

Lot Tracking (FEFO)

  • Lot Creation: Lot number, quantity, expiry date, manufacture date
  • FEFO Allocation: Automatic allocation from lots with earliest expiry date
  • Expiry Detection: Configurable warning threshold (default: 30 days)
  • Lot History: Track quantity received, quantity remaining, issue history

Serial Number Tracking

  • Serial Registration: Register unique serial numbers per tenant
  • Serial Uniqueness: Enforce tenant-scoped uniqueness (max 100 chars)
  • Serial Issue Tracking: Track serial number issue/return history
  • Serial Availability: Check if serial exists and is available

Stock Reservations

  • Reservation Creation: Reserve stock for sales orders, work orders
  • Configurable TTL: Auto-expire reservations after TTL (default: 48 hours)
  • Auto-Expiry: Background job releases expired reservations
  • Reservation Release: Manual release on fulfillment or cancellation

Inter-Warehouse Transfers

  • Transfer Initiation: Create transfer order (pending state)
  • Shipment Tracking: Record tracking number, shipment date
  • FSM Workflow: pending → in_transit → completed/cancelled
  • Stock Updates: Atomic stock decrement/increment on completion

Installation

composer require azaharizaman/nexus-inventory:"*@dev"

Requirements

  • PHP 8.3 or higher
  • azaharizaman/nexus-uom package (unit of measurement support)
  • PSR-3 logger implementation

Quick Start

Step 1: Implement Required Interfaces

// Implement StockLevelRepositoryInterface, ConfigurationInterface, EventPublisherInterface
// See docs/getting-started.md for complete examples

Step 2: Bind Interfaces in Your Container

// Laravel example
$this->app->singleton(StockManagerInterface::class, StockManager::class);
$this->app->singleton(StockLevelRepositoryInterface::class, DbStockLevelRepository::class);

Step 3: Use in Your Application

use Nexus\Inventory\Contracts\StockManagerInterface;
use Nexus\Inventory\Enums\IssueReason;
use Nexus\Currency\ValueObjects\Money;

public function __construct(
    private readonly StockManagerInterface $stockManager
) {}

// Receive stock from purchase order
public function receiveStock(): void
{
    $this->stockManager->receiveStock(
        tenantId: 'tenant-1',
        productId: 'product-123',
        warehouseId: 'warehouse-main',
        quantity: 100.0,
        unitCost: Money::of(25.50, 'MYR'),
        reference: 'PO-2024-001'
    );
    
    // StockReceivedEvent published → GL posts: DR Inventory Asset / CR GR-IR Clearing
}

// Issue stock for sales order
public function issueStock(): void
{
    $cogs = $this->stockManager->issueStock(
        tenantId: 'tenant-1',
        productId: 'product-123',
        warehouseId: 'warehouse-main',
        quantity: 30.0,
        reason: IssueReason::SALE,
        reference: 'SO-2024-005'
    );
    
    // StockIssuedEvent published → GL posts: DR COGS / CR Inventory Asset
    // $cogs contains calculated Cost of Goods Sold
}

Core Concepts

1. Stock Levels

Stock levels maintained per product per warehouse with three key metrics:

  • Quantity: Total physical stock
  • Reserved Quantity: Stock reserved for sales orders/work orders
  • Available Quantity: quantity - reserved_quantity

2. Valuation Methods

Three valuation engines available (see Valuation Methods below).

3. Lot Tracking (FEFO)

First-Expiry-First-Out (FEFO) enforcement ensures stock is issued from lots with earliest expiry date. Meets FDA and HACCP compliance requirements.

4. Stock Reservations

Temporary stock holds with configurable TTL. Auto-expire via background job if not fulfilled/cancelled within TTL.

5. Stock Transfers

Finite State Machine workflow: pending → in_transit → completed/cancelled

Available Interfaces

Core Service Managers

StockManagerInterface

Primary interface for stock movements (receive, issue, adjust).

Key Methods:

  • receiveStock() - Record incoming stock
  • issueStock() - Issue stock (returns COGS)
  • adjustStock() - Adjust stock levels (cycle count, damage, etc.)
  • getAvailableStock() - Get available stock quantity
  • getTotalStock() - Get total stock quantity

LotManagerInterface

Lot tracking and FEFO enforcement.

Key Methods:

  • createLot() - Create new lot with expiry date
  • allocateFromLots() - FEFO allocation algorithm
  • getAvailableLots() - Get lots ordered by expiry date
  • getExpiringLots() - Get lots expiring within threshold

SerialNumberManagerInterface

Serial number tracking and uniqueness enforcement.

Key Methods:

  • registerSerial() - Register unique serial number
  • issueSerial() - Mark serial as issued
  • isAvailable() - Check serial availability
  • getHistory() - Get serial history

ReservationManagerInterface

Stock reservations with TTL.

Key Methods:

  • reserve() - Create reservation with TTL
  • release() - Release reservation (fulfilled/cancelled)
  • expireReservations() - Expire stale reservations (background job)
  • getActiveReservations() - Query active reservations

TransferManagerInterface

Inter-warehouse transfers with FSM.

Key Methods:

  • initiateTransfer() - Create transfer order (pending)
  • startShipment() - Transition to in_transit
  • completeTransfer() - Complete transfer (update stock levels)
  • cancelTransfer() - Cancel transfer
  • getStatus() - Get current transfer status

Repository Interfaces

  • StockLevelRepositoryInterface - Stock level persistence
  • LotRepositoryInterface - Lot persistence
  • SerialNumberRepositoryInterface - Serial number persistence
  • ReservationRepositoryInterface - Reservation persistence
  • TransferRepositoryInterface - Transfer persistence

Configuration Interface

  • ConfigurationInterface - Product-specific and global configuration

Event Publisher Interface

  • EventPublisherInterface - Domain event publishing

Valuation Methods

FIFO (First-In-First-Out)

Performance: O(n) for stock issues
Best For: Perishables, pharmaceuticals, food & beverage
Accuracy: Matches physical flow of goods

Example:

use Nexus\Inventory\Core\Engine\FifoEngine;

$valuationEngine = new FifoEngine($stockLevelRepo);

Weighted Average

Performance: O(1) for both receipts and issues
Best For: Commodities, bulk materials, chemicals
Calculation: new_avg = ((old_qty × old_avg) + (new_qty × new_cost)) / (old_qty + new_qty)

Example:

use Nexus\Inventory\Core\Engine\WeightedAverageEngine;

$valuationEngine = new WeightedAverageEngine($stockLevelRepo);

Standard Cost

Performance: O(1) for both receipts and issues
Best For: Manufacturing, electronics, variance analysis
Behavior: Uses fixed standard cost, ignores actual receipt costs

Example:

use Nexus\Inventory\Core\Engine\StandardCostEngine;

$valuationEngine = new StandardCostEngine($stockLevelRepo, $config);

Event-Driven Architecture

The package publishes 8 domain events for integration with other packages:

Event Triggered When GL Impact
StockReceivedEvent Stock received DR Inventory Asset / CR GR-IR Clearing
StockIssuedEvent Stock issued DR COGS / CR Inventory Asset
StockAdjustedEvent Stock adjusted DR/CR Inventory Asset (variance)
LotCreatedEvent Lot created -
LotAllocatedEvent FEFO allocation -
SerialRegisteredEvent Serial registered -
ReservationCreatedEvent Reservation created -
ReservationExpiredEvent Reservation expired -

Example Event Listener (Laravel):

// Listen to StockIssuedEvent for GL integration
public function handleStockIssued(StockIssuedEvent $event): void
{
    $this->glManager->postJournalEntry(
        tenantId: $event->tenantId,
        entries: [
            ['account' => '5000', 'debit' => $event->cogs], // COGS
            ['account' => '1200', 'credit' => $event->cogs'], // Inventory Asset
        ]
    );
}

Progressive Disclosure

This package has optional dependencies for advanced features:

Event Sourcing (Recommended for Large Enterprises)

composer require azaharizaman/nexus-event-stream:"*@dev"

Benefits:

  • Full stock movement replay capability
  • Temporal queries ("What was stock level on 2024-10-15?")
  • Audit trail with complete history

Machine Learning Forecasting

composer require azaharizaman/nexus-machine-learning:"*@dev"

Benefits:

  • Demand forecasting
  • Stock optimization recommendations
  • Reorder point suggestions

Requirements: Minimum 90 days of historical stock movement data

Core inventory features work without these dependencies.

Documentation

Getting Started

Code Examples

Implementation Documentation

Testing

Current Status: 🚨 0% coverage (CRITICAL PRIORITY)

Planned Tests: 85 tests (70 unit + 15 integration)

Test Breakdown:

  • StockManager: 12 tests
  • FIFO Engine: 8 tests
  • Weighted Average Engine: 6 tests
  • Standard Cost Engine: 7 tests
  • LotManager: 10 tests
  • SerialNumberManager: 8 tests
  • ReservationManager: 10 tests
  • TransferManager: 9 tests
  • Integration Tests: 15 tests

Target Coverage: 90%+

See: TEST_SUITE_SUMMARY.md for complete test plan.

Run Tests (after implementation):

composer test
composer test:coverage

Contributing

This package is part of the Nexus ERP monorepo. Contributions welcome following architectural guidelines:

  1. Framework Agnosticism: No framework-specific dependencies in src/
  2. Interface-Driven: All external dependencies via interfaces
  3. Strict Types: declare(strict_types=1); in all files
  4. PHP 8.3+: Use modern PHP features (enums, readonly, constructor promotion)
  5. Test Coverage: Maintain 90%+ coverage

License

MIT License. See LICENSE file for details.

Package Maintainer: Nexus Architecture Team
Last Updated: November 25, 2024
Package Version: 1.0.0
Status: Production Ready (100% implementation, 0% test coverage - tests pending)