Skip to main content
ShelfWise uses PHP 8.1+ enums extensively to define type-safe constants, status values, and state machines. All enums include helper methods for labels, colors, and validation.

Enum Conventions

  • Location: app/Enums/
  • Type: All enums are backed by string values
  • Methods: Each enum provides label(), description(), and color() methods
  • Database: Never use database-level enums; always use PHP enums

OrderStatus

Defines the lifecycle states of an order with status transition validation. Location: app/Enums/OrderStatus.php

Values

PENDING
string
Order created, awaiting confirmation
CONFIRMED
string
Order confirmed, inventory reserved, awaiting processing
PROCESSING
string
Order is being prepared for shipment
PACKED
string
Order has been packed and ready for shipment
SHIPPED
string
Order has been shipped to customer
DELIVERED
string
Order has been delivered to customer (final success state)
CANCELLED
string
Order has been cancelled (final failure state)
REFUNDED
string
Order has been refunded (final state)

Methods

label()
string
Human-readable label
description()
string
Detailed description of the status
color()
string
UI color identifier (warning, success, error, etc.)
canTransitionTo(status)
bool
Check if transition to another status is allowed
isFinal()
bool
Check if this is a terminal status
canEdit()
bool
Check if order can be edited in this status
canCancel()
bool
Check if order can be cancelled from this status

Status Transitions

use App\Enums\OrderStatus;

// Valid transitions
OrderStatus::PENDING->canTransitionTo(OrderStatus::CONFIRMED); // true
OrderStatus::CONFIRMED->canTransitionTo(OrderStatus::PROCESSING); // true
OrderStatus::PROCESSING->canTransitionTo(OrderStatus::PACKED); // true
OrderStatus::PACKED->canTransitionTo(OrderStatus::SHIPPED); // true
OrderStatus::SHIPPED->canTransitionTo(OrderStatus::DELIVERED); // true

// Invalid transitions
OrderStatus::PENDING->canTransitionTo(OrderStatus::SHIPPED); // false
OrderStatus::DELIVERED->canTransitionTo(OrderStatus::PROCESSING); // false

// Cancellation allowed before delivery
OrderStatus::CONFIRMED->canTransitionTo(OrderStatus::CANCELLED); // true
OrderStatus::DELIVERED->canTransitionTo(OrderStatus::CANCELLED); // false

Example Usage

use App\Enums\OrderStatus;

$order->status = OrderStatus::PENDING;

echo $order->status->label(); // "Pending"
echo $order->status->description(); // "Order created, awaiting confirmation"
echo $order->status->color(); // "warning"

if ($order->status->canEdit()) {
    // Allow editing
}

if ($order->status->canTransitionTo(OrderStatus::CONFIRMED)) {
    $order->status = OrderStatus::CONFIRMED;
    $order->save();
}

// Get active statuses (not final)
$activeStatuses = OrderStatus::activeStatuses();
// [PENDING, CONFIRMED, PROCESSING, PACKED, SHIPPED]

// For dropdown select
$options = OrderStatus::forSelect();
// ['pending' => 'Pending', 'confirmed' => 'Confirmed', ...]

PaymentStatus

Defines payment states for orders with transition rules. Location: app/Enums/PaymentStatus.php

Values

UNPAID
string
No payment received
PARTIAL
string
Partial payment received
PAID
string
Payment completed in full
REFUNDED
string
Payment refunded to customer
FAILED
string
Payment attempt failed

Methods

label()
string
Human-readable label
description()
string
Status description
color()
string
UI color (error, warning, success, gray)
canTransitionTo(status)
bool
Validate status transition
isComplete()
bool
Check if payment is complete

Example Usage

use App\Enums\PaymentStatus;

$order->payment_status = PaymentStatus::UNPAID;

if ($order->payment_status->canTransitionTo(PaymentStatus::PARTIAL)) {
    $order->payment_status = PaymentStatus::PARTIAL;
    $order->save();
}

if ($order->payment_status->isComplete()) {
    // Process fulfillment
}

echo $order->payment_status->label(); // "Unpaid"
echo $order->payment_status->color(); // "error"

UserRole

Defines the 8-level role hierarchy with permissions and authorization levels. Location: app/Enums/UserRole.php

Values

SUPER_ADMIN
string
Platform administrator (level 999)
OWNER
string
Tenant owner (level 100)
GENERAL_MANAGER
string
Manages multiple stores (level 80)
STORE_MANAGER
string
Manages single store (level 60)
ASSISTANT_MANAGER
string
Supports store manager (level 50)
SALES_REP
string
Sales focused (level 40)
CASHIER
string
Processes sales (level 30)
INVENTORY_CLERK
string
Manages stock (level 30)

Role Hierarchy

Super Admin (999)
  └─ Owner (100)
      └─ General Manager (80)
          └─ Store Manager (60)
              └─ Assistant Manager (50)
                  └─ Sales Rep (40)
                      └─ Cashier (30)
                      └─ Inventory Clerk (30)

Methods

label()
string
Role display name
description()
string
Role responsibilities description
level()
int
Hierarchy level (higher = more authority)
permissions()
array
Array of permission strings
hasPermission(permission)
bool
Check if role has specific permission
canAccessMultipleStores()
bool
Check if role can access multiple stores
isSuperAdmin()
bool
Check if role is super admin

Example Usage

use App\Enums\UserRole;

$user->role = UserRole::STORE_MANAGER;

echo $user->role->label(); // "Store Manager"
echo $user->role->level(); // 60

if ($user->role->hasPermission('manage_inventory')) {
    // Allow inventory management
}

if ($user->role->canAccessMultipleStores()) {
    // Show all stores
} else {
    // Show only assigned store
}

// Compare role levels
if ($requester->role->level() >= UserRole::GENERAL_MANAGER->level()) {
    // Allow cross-store operations
}

// Get permissions
$permissions = $user->role->permissions();
// ['manage_store_users', 'view_store_reports', ...]

// For dropdown (excludes super admin)
$roles = UserRole::forSelect();

Additional Enums

Location: app/Enums/StockMovementType.phpTypes of inventory movements for audit trail.

Values

  • SALE - Stock sold to customer
  • PURCHASE - Stock received from supplier
  • RETURN - Customer return
  • ADJUSTMENT - Manual stock adjustment
  • TRANSFER_IN - Transfer from another location
  • TRANSFER_OUT - Transfer to another location
  • DAMAGED - Damaged/expired stock writeoff
  • LOST - Lost/stolen stock
use App\Enums\StockMovementType;

$movement->type = StockMovementType::SALE;
echo $movement->type->label(); // "Sale"

Enum Best Practices

Store enum values as strings in database:
// Migration
$table->string('status')->default('pending');
$table->string('payment_method')->nullable();

// Model cast
protected $casts = [
    'status' => OrderStatus::class,
    'payment_method' => PaymentMethod::class,
];
Use enum validation rules:
use Illuminate\Validation\Rules\Enum;

'status' => ['required', new Enum(OrderStatus::class)],
'payment_method' => ['nullable', new Enum(PaymentMethod::class)],
Include enum metadata in API responses:
return [
    'status' => $order->status->value,
    'status_label' => $order->status->label(),
    'status_color' => $order->status->color(),
];
Use forSelect() method for dropdowns:
$statuses = OrderStatus::forSelect();
// ['pending' => 'Pending', 'confirmed' => 'Confirmed', ...]

// In Inertia props
return Inertia::render('Orders/Create', [
    'statuses' => OrderStatus::forSelect(),
]);
Always validate transitions:
if (!$order->status->canTransitionTo($newStatus)) {
    throw new \Exception(
        "Cannot transition from {$order->status->value} to {$newStatus->value}"
    );
}

$order->status = $newStatus;
$order->save();

Build docs developers (and LLMs) love