refactor: add methods for retrieving assignable roles and their values in Role enum, and enhance Permission enum with values method for improved role management
This commit is contained in:
parent
da3e3a6895
commit
86956b1c9f
@ -3,6 +3,7 @@
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\ProvidesEnumOptions;
|
||||
use InvalidArgumentException;
|
||||
|
||||
enum CuttingStatus: string
|
||||
{
|
||||
@ -24,4 +25,62 @@ public function label(): string
|
||||
self::REJECTED => 'Ditolak',
|
||||
};
|
||||
}
|
||||
|
||||
public function isEditable(): bool
|
||||
{
|
||||
return in_array($this, [self::IN_PROGRESS, self::REJECTED], true);
|
||||
}
|
||||
|
||||
public function canTransitionTo(self $status): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::IN_PROGRESS => $status === self::COMPLETED,
|
||||
self::COMPLETED => in_array($status, [self::PENDING_VERIFICATION, self::REJECTED, self::IN_PROGRESS], true),
|
||||
self::PENDING_VERIFICATION => in_array($status, [self::VERIFIED, self::REJECTED, self::COMPLETED], true),
|
||||
self::REJECTED => $status === self::IN_PROGRESS,
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
public function transitionPermission(): Permission
|
||||
{
|
||||
return match ($this) {
|
||||
self::COMPLETED => Permission::CUTTINGS_COMPLETE,
|
||||
self::PENDING_VERIFICATION => Permission::CUTTINGS_VERIFY,
|
||||
self::VERIFIED => Permission::CUTTINGS_VERIFY,
|
||||
self::REJECTED => Permission::CUTTINGS_REJECT,
|
||||
self::IN_PROGRESS => Permission::CUTTINGS_UPDATE,
|
||||
default => throw new InvalidArgumentException('Status tidak mendukung transisi.'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{status: string, label: string, destructive: bool, permission: string, icon_only: bool}>
|
||||
*/
|
||||
public function availableActions(): array
|
||||
{
|
||||
return match ($this) {
|
||||
self::IN_PROGRESS => [
|
||||
[
|
||||
'status' => self::COMPLETED->value,
|
||||
'label' => 'Selesai',
|
||||
'destructive' => false,
|
||||
'permission' => Permission::CUTTINGS_COMPLETE->value,
|
||||
'icon_only' => false,
|
||||
],
|
||||
],
|
||||
self::COMPLETED => [],
|
||||
self::PENDING_VERIFICATION => [],
|
||||
self::REJECTED => [
|
||||
[
|
||||
'status' => self::IN_PROGRESS->value,
|
||||
'label' => 'Kembalikan ke Proses',
|
||||
'destructive' => false,
|
||||
'permission' => Permission::CUTTINGS_UPDATE->value,
|
||||
'icon_only' => false,
|
||||
],
|
||||
],
|
||||
default => [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\ProvidesEnumOptions;
|
||||
use InvalidArgumentException;
|
||||
|
||||
enum OrderStatus: string
|
||||
{
|
||||
@ -22,4 +23,70 @@ public function label(): string
|
||||
self::CANCELLED => 'Dibatalkan',
|
||||
};
|
||||
}
|
||||
|
||||
public function isEditable(): bool
|
||||
{
|
||||
return in_array($this, [self::PENDING, self::PROCESSING], true);
|
||||
}
|
||||
|
||||
public function canTransitionTo(self $status): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::PENDING => in_array($status, [self::PROCESSING, self::CANCELLED], true),
|
||||
self::PROCESSING => in_array($status, [self::COMPLETED, self::CANCELLED], true),
|
||||
self::COMPLETED, self::CANCELLED => false,
|
||||
};
|
||||
}
|
||||
|
||||
public function transitionPermission(): Permission
|
||||
{
|
||||
return match ($this) {
|
||||
self::PROCESSING => Permission::ORDERS_SEND,
|
||||
self::COMPLETED => Permission::ORDERS_COMPLETE,
|
||||
self::CANCELLED => Permission::ORDERS_CANCEL,
|
||||
default => throw new InvalidArgumentException('Status tidak mendukung transisi.'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{status: string, label: string, destructive: bool, permission: string, icon_only: bool}>
|
||||
*/
|
||||
public function availableActions(): array
|
||||
{
|
||||
return match ($this) {
|
||||
self::PENDING => [
|
||||
[
|
||||
'status' => self::PROCESSING->value,
|
||||
'label' => 'Kirim',
|
||||
'destructive' => false,
|
||||
'permission' => Permission::ORDERS_SEND->value,
|
||||
'icon_only' => true,
|
||||
],
|
||||
[
|
||||
'status' => self::CANCELLED->value,
|
||||
'label' => 'Batalkan',
|
||||
'destructive' => true,
|
||||
'permission' => Permission::ORDERS_CANCEL->value,
|
||||
'icon_only' => true,
|
||||
],
|
||||
],
|
||||
self::PROCESSING => [
|
||||
[
|
||||
'status' => self::COMPLETED->value,
|
||||
'label' => 'Selesai',
|
||||
'destructive' => false,
|
||||
'permission' => Permission::ORDERS_COMPLETE->value,
|
||||
'icon_only' => true,
|
||||
],
|
||||
[
|
||||
'status' => self::CANCELLED->value,
|
||||
'label' => 'Batalkan',
|
||||
'destructive' => true,
|
||||
'permission' => Permission::ORDERS_CANCEL->value,
|
||||
'icon_only' => true,
|
||||
],
|
||||
],
|
||||
default => [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,4 +267,12 @@ public function group(): string
|
||||
self::ROLES_DELETE => 'Role & Permission',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,4 +285,44 @@ public function permissions(): array
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
public function isAssignable(): bool
|
||||
{
|
||||
return $this !== self::DEVELOPER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{value: string, label: string}>
|
||||
*/
|
||||
public static function assignableSelectOptions(): array
|
||||
{
|
||||
return collect(self::cases())
|
||||
->filter(fn (self $role) => $role->isAssignable())
|
||||
->map(fn (self $role) => [
|
||||
'value' => $role->value,
|
||||
'label' => $role->label(),
|
||||
])
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public static function assignableValues(): array
|
||||
{
|
||||
return collect(self::cases())
|
||||
->filter(fn (self $role) => $role->isAssignable())
|
||||
->map(fn (self $role) => $role->value)
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,16 +27,7 @@ public function __construct(
|
||||
|
||||
private function assignableRoleOptions(): array
|
||||
{
|
||||
$assignable = config('roles.assignable', []);
|
||||
|
||||
return collect(Role::cases())
|
||||
->filter(fn (Role $role) => in_array($role->value, $assignable, true))
|
||||
->map(fn (Role $role) => [
|
||||
'value' => $role->value,
|
||||
'label' => $role->label(),
|
||||
])
|
||||
->values()
|
||||
->all();
|
||||
return Role::assignableSelectOptions();
|
||||
}
|
||||
|
||||
public function index(Request $request): Response
|
||||
|
||||
@ -36,7 +36,7 @@ public function rules(): array
|
||||
'gender' => ['nullable', Rule::enum(Gender::class)],
|
||||
'birth_date' => ['nullable', 'date', 'before:today'],
|
||||
'address' => ['nullable', 'string'],
|
||||
'role' => ['required', Rule::in(config('roles.assignable', []))],
|
||||
'role' => ['required', Rule::in(Role::assignableValues())],
|
||||
];
|
||||
|
||||
if (! $isOwner) {
|
||||
|
||||
@ -26,10 +26,13 @@ public function authorize(): bool
|
||||
|| false;
|
||||
}
|
||||
|
||||
$permissions = config('cutting-status.permissions', $status);
|
||||
$permission = $permissions[$status->value] ?? null;
|
||||
try {
|
||||
$permission = $status->transitionPermission();
|
||||
} catch (\InvalidArgumentException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $permission ? ($this->user()?->can($permission->value) ?? false) : false;
|
||||
return $this->user()?->can($permission->value) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,10 +79,7 @@ public function withValidator(Validator $validator): void
|
||||
return;
|
||||
}
|
||||
|
||||
$transitions = config('cutting-status.transitions', []);
|
||||
$allowedTargets = $transitions[$cutting->status->value] ?? [];
|
||||
|
||||
if (! in_array($status, $allowedTargets, true)) {
|
||||
if (! $cutting->status->canTransitionTo($status)) {
|
||||
$validator->errors()->add('status', 'Status cutting tidak dapat diubah.');
|
||||
}
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ public function withValidator(Validator $validator): void
|
||||
/** @var Order $order */
|
||||
$order = $this->route('order');
|
||||
|
||||
if (! in_array($order->status, config('order-status.editable'), true)) {
|
||||
if (! $order->status->isEditable()) {
|
||||
$validator->errors()->add('status', 'Pesanan tidak dapat diubah.');
|
||||
}
|
||||
});
|
||||
|
||||
@ -18,10 +18,13 @@ public function authorize(): bool
|
||||
return false;
|
||||
}
|
||||
|
||||
$permissions = config('order-status.permissions', []);
|
||||
$permission = $permissions[$status->value] ?? null;
|
||||
try {
|
||||
$permission = $status->transitionPermission();
|
||||
} catch (\InvalidArgumentException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $permission ? ($this->user()?->can($permission->value) ?? false) : false;
|
||||
return $this->user()?->can($permission->value) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,10 +58,7 @@ public function withValidator(Validator $validator): void
|
||||
return;
|
||||
}
|
||||
|
||||
$transitions = config('order-status.transitions', []);
|
||||
$allowedTargets = $transitions[$order->status->value] ?? [];
|
||||
|
||||
if (! in_array($status, $allowedTargets, true)) {
|
||||
if (! $order->status->canTransitionTo($status)) {
|
||||
$validator->errors()->add('status', 'Status pesanan tidak dapat diubah.');
|
||||
}
|
||||
});
|
||||
|
||||
@ -30,22 +30,17 @@ public function __construct(
|
||||
|
||||
public function isEditable(CuttingStatus $status): bool
|
||||
{
|
||||
return in_array($status, config('cutting-status.editable'), true);
|
||||
return $status->isEditable();
|
||||
}
|
||||
|
||||
public function canTransitionTo(CuttingStatus $from, CuttingStatus $to): bool
|
||||
{
|
||||
$transitions = config('cutting-status.transitions', []);
|
||||
|
||||
return in_array($to, $transitions[$from->value] ?? [], true);
|
||||
return $from->canTransitionTo($to);
|
||||
}
|
||||
|
||||
public function transitionPermission(CuttingStatus $status): Permission
|
||||
{
|
||||
$permissions = config('cutting-status.permissions', []);
|
||||
|
||||
return $permissions[$status->value]
|
||||
?? throw new \InvalidArgumentException('Status tidak mendukung transisi.');
|
||||
return $status->transitionPermission();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,7 +48,7 @@ public function transitionPermission(CuttingStatus $status): Permission
|
||||
*/
|
||||
public function availableActions(CuttingStatus $status): array
|
||||
{
|
||||
return config('cutting-status.actions.'.$status->value, []);
|
||||
return $status->availableActions();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -36,22 +36,17 @@ public function __construct(
|
||||
|
||||
public function isEditable(OrderStatus $status): bool
|
||||
{
|
||||
return in_array($status, config('order-status.editable'), true);
|
||||
return $status->isEditable();
|
||||
}
|
||||
|
||||
public function canTransitionTo(OrderStatus $from, OrderStatus $to): bool
|
||||
{
|
||||
$transitions = config('order-status.transitions', []);
|
||||
|
||||
return in_array($to, $transitions[$from->value] ?? [], true);
|
||||
return $from->canTransitionTo($to);
|
||||
}
|
||||
|
||||
public function transitionPermission(OrderStatus $status): Permission
|
||||
{
|
||||
$permissions = config('order-status.permissions', []);
|
||||
|
||||
return $permissions[$status->value]
|
||||
?? throw new \InvalidArgumentException('Status tidak mendukung transisi.');
|
||||
return $status->transitionPermission();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,7 +54,7 @@ public function transitionPermission(OrderStatus $status): Permission
|
||||
*/
|
||||
public function availableActions(OrderStatus $status): array
|
||||
{
|
||||
return config('order-status.actions.'.$status->value, []);
|
||||
return $status->availableActions();
|
||||
}
|
||||
|
||||
public function defaultPriceType(OrderChannel $channel): ?PriceType
|
||||
|
||||
Loading…
Reference in New Issue
Block a user