<?php declare(strict_types=1); namespace App\Services\Private; use App\Dto\Builder\Role as RoleBuilderDto; use App\Dto\QuerySettingsDto; use App\Dto\Request\Private\Role\StoreUpdate; use App\Models\Role; use App\Models\User; use App\Repositories\RoleRepository; use App\ServiceResults\ServiceResultArray; use App\ServiceResults\ServiceResultError; use App\ServiceResults\ServiceResultSuccess; use App\ServiceResults\StoreUpdateResult; use App\Services\Role\RoleCommandHandler; use App\Services\Role\RoleSyncPermissionsCommandHandler; use App\Services\Service; use Illuminate\Support\Facades\DB; final class RoleService extends Service { public function __construct( private readonly RoleRepository $roleRepository, private readonly RoleCommandHandler $roleCommandHandler, private readonly RoleSyncPermissionsCommandHandler $roleSyncPermissionsCommandHandler ) { } public function index(RoleBuilderDto $roleBuilderDto, QuerySettingsDto $querySettingsDto, User $user): ServiceResultError | ServiceResultArray { if ($user->cannot('viewAny', Role::class)) { return $this->errFobidden(__('Access is denied')); } $roles = $this->roleRepository->getRoles( $roleBuilderDto, $querySettingsDto->getQueryWith() )->pagination( $querySettingsDto->getLimit(), $querySettingsDto->getPage() ); return $this->result([ 'roles' => $roles ]); } public function create(User $user): ServiceResultError | ServiceResultArray { if ($user->cannot('create', Role::class)) { return $this->errFobidden(__('Access is denied')); } return $this->result([ 'role' => new Role(), ]); } public function edit(int $id, User $user): ServiceResultError | ServiceResultArray { $role = $this->roleRepository->getRoleById($id); if (is_null($role)) { return $this->errNotFound(__('Not Found')); } if ($user->cannot('view', $role)) { return $this->errFobidden(__('Access is denied')); } return $this->result([ 'role' => $role, ]); } public function store(StoreUpdate $data, User $user): ServiceResultError | StoreUpdateResult { if ($user->cannot('create', Role::class)) { return $this->errFobidden(__('Access is denied')); } if ($this->roleRepository->isExistsCode($data->getCode())) { return $this->errValidate( __('validation.unique', ['attribute' => __('validation.attributes.code')]), ['code' => __('validation.unique', ['attribute' => __('validation.attributes.code')])] ); } try { $role = DB::transaction(function () use ($data) { $dataRole = $this->getDataRole($data); $dataRole['code'] = $data->getCode(); $role = $this->roleCommandHandler->handleStore($dataRole); $role = $this->roleSyncPermissionsCommandHandler->handle($role, $data->getPermissions()); return $role; }); } catch (\Throwable $e) { report($e); return $this->errService(__('Server Error')); } return $this->resultStoreUpdateModel($role, __('The group was successfully created')); } public function update(int $id, StoreUpdate $data, User $user): ServiceResultError | StoreUpdateResult { $role = $this->roleRepository->getRoleById($id); if (is_null($role)) { return $this->errNotFound(__('Not Found')); } if ($user->cannot('update', $role)) { return $this->errFobidden(__('Access is denied')); } try { $role = DB::transaction(function () use ($data, $role) { $dataRole = $this->getDataRole($data); $role = $this->roleCommandHandler->handleUpdate($role, $dataRole); $role = $this->roleSyncPermissionsCommandHandler->handle($role, $data->getPermissions()); return $role; }); } catch (\Throwable $e) { report($e); return $this->errService(__('Server Error')); } return $this->resultStoreUpdateModel($role, __('The group was successfully updated')); } public function destroy(int $id, User $user): ServiceResultError|ServiceResultSuccess { $role = $this->roleRepository->getRoleById($id); if (is_null($role)) { return $this->errNotFound(__('Not Found')); } if ($user->cannot('delete', $role)) { return $this->errFobidden(__('Access is denied')); } try { DB::transaction(function () use ($role) { $this->roleCommandHandler->handleDestroy($role); }); } catch (\Throwable $e) { report($e); return $this->errService(__('Server Error')); } return $this->ok(__('The group has been deleted')); } private function getDataRole(StoreUpdate $data): array { return [ 'name' => $data->getName(), ]; } }