enum OrderStatus
{
case Pending = 'pending';
case Paid = 'paid';
case Processing = 'processing';
case Shipped = 'shipped';
case Delivered = 'delivered';
case Cancelled = 'cancelled';
//Aquí se definen las transiciones permitidas
public function canTransitionTo(self $newStatus): bool
{
return match ($this) {
self::Pending => in_array($newStatus, [self::Paid, self::Cancelled]),
self::Paid=> in_array($newStatus, [self::Processing, self::Cancelled]),
self::Processing => in_array($newStatus, [self::Shipped, self::Cancelled]),
self::Shipped => $newStatus === self::Delivered,
self::Delivered=> false,// ya no se puede cambiar
self::Cancelled=> false,
};
}
// Bonus: método para aplicar el cambio
public function transitionTo(self $newStatus): void
{
if (!$this->canTransitionTo($newStatus)) {
throw new \InvalidArgumentException(
"Transición inválida: {$this->value} → {$newStatus->value}"
);
}
// aquí actualizarías el modelo
}
}
//USO
$order = Order::find(1);
$current = OrderStatus::from($order->status);
$current->transitionTo(OrderStatus::Paid); // ✅ funciona
// $current->transitionTo(OrderStatus::Delivered); // ❌ lanza excepción