Files
HRM-System/app/Http/Controllers/RoleController.php

256 lines
9.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Http\Requests\RoleRequest;
use App\Models\Permission;
use App\Models\Role;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Inertia\Inertia;
class RoleController extends BaseController
{
public function index()
{
$user = Auth::user();
if ($user->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.'));
}
}
}