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
Order created, awaiting confirmation
Order confirmed, inventory reserved, awaiting processing
Order is being prepared for shipment
Order has been packed and ready for shipment
Order has been shipped to customer
Order has been delivered to customer (final success state)
Order has been cancelled (final failure state)
Order has been refunded (final state)
Methods
Detailed description of the status
UI color identifier (warning, success, error, etc.)
Check if transition to another status is allowed
Check if this is a terminal status
Check if order can be edited in this status
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
Payment completed in full
Payment refunded to customer
Methods
UI color (error, warning, success, gray)
Validate status transition
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
Platform administrator (level 999)
Manages multiple stores (level 80)
Manages single store (level 60)
Supports store manager (level 50)
Processes sales (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
Role responsibilities description
Hierarchy level (higher = more authority)
Array of permission strings
hasPermission(permission)
Check if role has specific permission
canAccessMultipleStores()
Check if role can access multiple stores
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
StockMovementType
PaymentMethod
OrderType
PayrollStatus
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"
Location : app/Enums/PaymentMethod.phpPayment methods accepted in the system. Values
CASH - Cash payment
CARD - Card payment (debit/credit)
MOBILE_MONEY - Mobile money transfer
BANK_TRANSFER - Bank transfer
CREDIT - Customer credit account
PAYSTACK - Paystack gateway
FLUTTERWAVE - Flutterwave gateway
OPAY - OPay gateway
use App\Enums\ PaymentMethod ;
$payment -> method = PaymentMethod :: CASH ;
echo $payment -> method -> label (); // "Cash"
Location : app/Enums/OrderType.phpTypes of orders in the system. Values
POS - Point of sale transaction
CUSTOMER - Customer online order
INTERNAL - Internal transfer/requisition
Methods
salesTypes() - Get types that count as sales (POS, CUSTOMER)
use App\Enums\ OrderType ;
$order -> order_type = OrderType :: POS ;
echo $order -> order_type -> label (); // "POS Sale"
if ( in_array ( $order -> order_type , OrderType :: salesTypes ())) {
// Count as revenue
}
Location : app/Enums/PayrollStatus.phpStatus of payroll processing runs. Values
DRAFT - Pay run in draft state
PENDING_APPROVAL - Awaiting manager approval
APPROVED - Approved, ready for payment
PROCESSING - Payment in progress
PAID - All payments completed
PARTIALLY_PAID - Some payments completed
CANCELLED - Pay run cancelled
use App\Enums\ PayrollStatus ;
$payRun -> status = PayrollStatus :: DRAFT ;
if ( $payRun -> status -> canTransitionTo ( PayrollStatus :: APPROVED )) {
$payRun -> status = PayrollStatus :: APPROVED ;
}
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 ();