type === 'company' || $user->can('manage-roles') || $user->can('view-roles') || $user->can('create-roles')) { $query = Role::with(['permissions', 'creator']); if ($user->type !== 'company' && !$user->can('manage-any-roles') && !$user->can('manage-roles')) { if ($user->can('manage-own-roles')) { $query->where('created_by', $user->id); } } $roles = $query->latest()->paginate(10); // Add label and is_editable attribute to each role $roles->getCollection()->transform(function ($role) { if (empty($role->label)) { $role->label = ucwords(str_replace(['-', '_'], ' ', $role->name)); } $role->is_editable = !in_array($role->name, isNotEditableRoles()); return $role; }); $permissions = $this->getFilteredPermissions(); return Inertia::render('roles/index', [ 'roles' => $roles, 'permissions' => $permissions, ]); } else { return redirect()->back()->with('error', __('Permission Denied.')); } } private function getFilteredPermissions($targetRole = null) { $user = Auth::user(); $userType = $user->type ?? 'company'; // Superadmin can see all permissions if ($userType === 'superadmin' || $userType === 'super admin') { $all = Permission::all(); foreach ($all as $p) { if (empty($p->module)) { $p->module = $this->inferModuleFromPermissionName($p->name); $p->save(); } $p->label = ucwords(str_replace(['-', '_'], ' ', $p->name)); } return $all->groupBy('module'); } // Get allowed permissions for current tenant $allowedPermissions = []; if (function_exists('tenant') && tenant()) { try { $enabledModules = \App\Models\TenantModule::where('enabled', 1)->pluck('module_key')->toArray(); $inquiryKeys = []; foreach (\App\Constants\ModuleContract::MODULE_MAP as $inqKey => $cfg) { if (in_array($cfg['module_key'], $enabledModules)) { $inquiryKeys[] = $inqKey; } } $allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys($inquiryKeys); } catch (\Exception $e) { $allowedPermissions = []; } } else { $allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys(\App\Constants\ModuleContract::getAllInquiryKeys()); } foreach ($allowedPermissions as $perm) { Permission::findOrCreate($perm, 'web'); } $permissions = Permission::whereIn('name', $allowedPermissions)->get(); foreach ($permissions as $p) { if (empty($p->module)) { $p->module = $this->inferModuleFromPermissionName($p->name); $p->save(); } $p->label = ucwords(str_replace(['-', '_'], ' ', $p->name)); } return $permissions->groupBy('module'); } private function inferModuleFromPermissionName(string $name): string { foreach (\App\Constants\ModuleContract::MODULE_MAP as $inqKey => $config) { if (in_array($name, $config['permissions'], true)) { return $config['label'] ?? ucfirst($config['module_key']); } } $parts = explode('-', $name); if (count($parts) > 1) { array_shift($parts); return ucfirst(implode(' ', $parts)); } return 'General'; } private function validatePermissions(array $permissions, $role = null) { $user = Auth::user(); if (!$user) { throw new \Exception('User not authenticated'); } $userType = $user->type ?? 'company'; // Superadmin can assign any permission if (in_array($userType, ['superadmin', 'super admin'])) { return array_filter($permissions); } // Get allowed permissions for current tenant $allowedPermissions = []; if (function_exists('tenant') && tenant()) { try { $enabledModules = \App\Models\TenantModule::where('enabled', 1)->pluck('module_key')->toArray(); $inquiryKeys = []; foreach (\App\Constants\ModuleContract::MODULE_MAP as $inqKey => $cfg) { if (in_array($cfg['module_key'], $enabledModules)) { $inquiryKeys[] = $inqKey; } } $allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys($inquiryKeys); } catch (\Exception $e) { $allowedPermissions = []; } } else { $allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys(\App\Constants\ModuleContract::getAllInquiryKeys()); } return array_values(array_intersect(array_filter($permissions), $allowedPermissions)); } public function store(RoleRequest $request) { if (Auth::user()->can('create-roles')) { // Validate permissions against user's allowed modules $validatedPermissions = $this->validatePermissions($request->permissions ?? []); $checkRoleExist = Role::where('name', Str::slug($request->label))->whereIn('created_by', getCompanyAndUsersId())->exists(); if (!$checkRoleExist) { // Use direct model creation to bypass Spatie's duplicate check $role = new Role; $role->label = $request->label; $role->name = Str::slug($request->label); $role->description = $request->description; $role->created_by = Auth::id(); $role->guard_name = 'web'; $role->save(); if ($role) { $role->syncPermissions($validatedPermissions); app(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions(); return redirect()->route('roles.index')->with('success', __('Role created successfully with Permissions!')); } return redirect()->back()->with('error', __('Unable to create Role with permissions. Please try again!')); } else { return redirect()->back()->with('error', __('Role already exists!')); } } else { return redirect()->back()->with('error', __('Permission Denied.')); } } public function update(RoleRequest $request, Role $role) { if (Auth::user()->can('edit-roles')) { if ($role) { // Validate permissions (will keep existing ones from commented modules) $validatedPermissions = $this->validatePermissions($request->permissions ?? [], $role); $newSlug = Str::slug($request->label); // Check if role name already exists (excluding current role) $checkRoleExist = Role::where('name', $newSlug) ->where('id', '!=', $role->id) ->whereIn('created_by', getCompanyAndUsersId()) ->exists(); if ($checkRoleExist) { return redirect()->back()->with('error', __('Role already exists!')); } // Only update name if it's different to avoid duplicate key error if ($role->name !== $newSlug) { $role->name = $newSlug; } $role->label = $request->label; $role->description = $request->description; $role->save(); // Update the permissions $role->syncPermissions($validatedPermissions); app(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions(); return redirect()->route('roles.index')->with('success', __('Role updated successfully with Permissions!')); } return redirect()->back()->with('error', __('Unable to update Role with permissions. Please try again!')); } else { return redirect()->back()->with('error', __('Permission Denied.')); } } public function destroy(Role $role) { if (Auth::user()->can('delete-roles')) { if ($role) { // Prevent deletion of system roles // if ($role->is_system_role) { // return redirect()->back()->with('error', __('System roles cannot be deleted!')); // } if (in_array($role->name, isNotDeletableRoles())) { return redirect()->back()->with('error', __('System roles cannot be deleted!')); } $role->delete(); return redirect()->route('roles.index')->with('success', __('Role deleted successfully!')); } return redirect()->back()->with('error', __('Unable to delete Role. Please try again!')); } else { return redirect()->back()->with('error', __('Permission Denied.')); } } }