diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index e8fab6c..20abd9b 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -24,7 +24,7 @@ class DashboardController extends Controller } // If user has a service role - $serviceRoles = ['DSI', 'Batiment', 'ParcAuto']; + $serviceRoles = ['DSI', 'Batiment', 'Parc Auto']; foreach ($serviceRoles as $role) { if ($user->hasRole($role)) { return $this->serviceDashboard($role); @@ -103,6 +103,15 @@ class DashboardController extends Controller }) ->with(['integrationRequest.agent', 'taskItems']) ->get(), + 'processed_integrations' => IntegrationRequest::whereHas('serviceTasks', function ($query) use ($role) { + $query->whereHas('service', function ($q) use ($role) { + $q->where('name', $role); + })->where('status', ServiceTaskStatus::Completed); + }) + ->with(['agent', 'template']) + ->latest('updated_at') + ->take(10) + ->get(), 'completed_tasks' => ServiceTask::where('status', ServiceTaskStatus::Completed) ->whereHas('service', function ($query) use ($role) { $query->where('name', $role); diff --git a/app/Http/Controllers/IntegrationController.php b/app/Http/Controllers/IntegrationController.php index 77520c7..cd89059 100644 --- a/app/Http/Controllers/IntegrationController.php +++ b/app/Http/Controllers/IntegrationController.php @@ -43,10 +43,23 @@ class IntegrationController extends Controller public function show(IntegrationRequest $integration) { + $user = auth()->user(); + + $serviceTaskConstraint = function ($query) use ($user) { + // Admin, RH, and Prescripteur can see all tasks (global progress) + if (!$user->hasRole(['Admin', 'RH', 'Prescripteur'])) { + $query->whereHas('service', function ($q) use ($user) { + $q->whereIn('name', $user->getRoleNames()); + }); + } + }; + $integration->load([ 'agent', 'template', - 'serviceTasks.service', + 'serviceTasks' => $serviceTaskConstraint, + 'serviceTasks.service', + 'serviceTasks.integrationRequest', 'serviceTasks.taskItems', 'serviceTasks.comments.user', 'serviceTasks.attachments', @@ -77,6 +90,10 @@ class IntegrationController extends Controller public function downloadPdf(IntegrationRequest $integration) { + if ($integration->status !== \App\Enums\IntegrationStatus::Completed) { + abort(403, 'Le téléchargement de la fiche agent n\'est possible que lorsque le processus est terminé.'); + } + // Load relationships needed for the PDF $integration->load([ 'agent', diff --git a/app/Http/Controllers/RoleController.php b/app/Http/Controllers/RoleController.php new file mode 100644 index 0000000..9c63482 --- /dev/null +++ b/app/Http/Controllers/RoleController.php @@ -0,0 +1,100 @@ +user()->hasRole('Admin')) { + abort(403); + } + + return Inertia::render('Role/Index', [ + 'roles' => Role::with('permissions')->get(), + ]); + } + + public function create() + { + if (!auth()->user()->hasRole('Admin')) { + abort(403); + } + + return Inertia::render('Role/Create', [ + 'permissions' => Permission::all(), + ]); + } + + public function store(Request $request) + { + if (!auth()->user()->hasRole('Admin')) { + abort(403); + } + + $validated = $request->validate([ + 'name' => 'required|string|unique:roles,name', + 'permissions' => 'array', + ]); + + $role = Role::create(['name' => $validated['name']]); + + if (!empty($validated['permissions'])) { + $role->syncPermissions($validated['permissions']); + } + + return redirect()->route('roles.index')->with('success', 'Rôle créé avec succès.'); + } + + public function edit(Role $role) + { + if (!auth()->user()->hasRole('Admin')) { + abort(403); + } + + return Inertia::render('Role/Edit', [ + 'role' => $role->load('permissions'), + 'permissions' => Permission::all(), + ]); + } + + public function update(Request $request, Role $role) + { + if (!auth()->user()->hasRole('Admin')) { + abort(403); + } + + $validated = $request->validate([ + 'name' => 'required|string|unique:roles,name,' . $role->id, + 'permissions' => 'array', + ]); + + $role->update(['name' => $validated['name']]); + + if (isset($validated['permissions'])) { + $role->syncPermissions($validated['permissions']); + } + + return redirect()->route('roles.index')->with('success', 'Rôle mis à jour avec succès.'); + } + + public function destroy(Role $role) + { + if (!auth()->user()->hasRole('Admin')) { + abort(403); + } + + if ($role->name === 'Admin') { + return back()->with('error', 'Le rôle Admin ne peut pas être supprimé.'); + } + + $role->delete(); + + return redirect()->route('roles.index')->with('success', 'Rôle supprimé avec succès.'); + } +} diff --git a/app/Policies/IntegrationRequestPolicy.php b/app/Policies/IntegrationRequestPolicy.php index 2abd57d..cb4fdd0 100644 --- a/app/Policies/IntegrationRequestPolicy.php +++ b/app/Policies/IntegrationRequestPolicy.php @@ -13,7 +13,7 @@ class IntegrationRequestPolicy */ public function viewAny(User $user): bool { - return $user->hasAnyRole(['Admin', 'RH', 'DSI', 'Batiment', 'ParcAuto']); + return $user->hasAnyRole(['Admin', 'RH', 'DSI', 'Batiment', 'Parc Auto']); } /** @@ -36,7 +36,7 @@ class IntegrationRequestPolicy */ public function create(User $user): bool { - return $user->hasAnyRole(['Admin', 'RH', 'Prescripteur', 'DSI', 'Batiment', 'ParcAuto']); + return $user->hasAnyRole(['Admin', 'RH', 'Prescripteur', 'DSI', 'Batiment', 'Parc Auto']); } /** diff --git a/database/seeders/IntegrationTemplateSeeder.php b/database/seeders/IntegrationTemplateSeeder.php index 9a57904..83caf94 100644 --- a/database/seeders/IntegrationTemplateSeeder.php +++ b/database/seeders/IntegrationTemplateSeeder.php @@ -56,7 +56,7 @@ class IntegrationTemplateSeeder extends Seeder 'label' => 'Attribution Badge', 'is_mandatory' => true, ]); - } elseif ($service->name === 'ParcAuto') { + } elseif ($service->name === 'Parc Auto') { $template->serviceItems()->create([ 'service_id' => $service->id, 'label' => 'Création compte vehicule', @@ -64,5 +64,42 @@ class IntegrationTemplateSeeder extends Seeder ]); } } + /* Offboarding Template */ + $offboardingTemplate = IntegrationTemplate::firstOrCreate([ + 'name' => 'Sortie Standard', + 'is_active' => true, + ]); + + foreach ($services as $service) { + if ($service->name === 'DSI') { + $offboardingTemplate->serviceItems()->create([ + 'service_id' => $service->id, + 'label' => 'Désactivation compte AD', + 'is_mandatory' => true, + ]); + $offboardingTemplate->serviceItems()->create([ + 'service_id' => $service->id, + 'label' => 'Restitution Ordinateur', + 'is_mandatory' => true, + ]); + $offboardingTemplate->serviceItems()->create([ + 'service_id' => $service->id, + 'label' => 'Désactivation email', + 'is_mandatory' => true, + ]); + } elseif ($service->name === 'Batiment') { + $offboardingTemplate->serviceItems()->create([ + 'service_id' => $service->id, + 'label' => 'Restitution Badge', + 'is_mandatory' => true, + ]); + } elseif ($service->name === 'Parc Auto') { + $offboardingTemplate->serviceItems()->create([ + 'service_id' => $service->id, + 'label' => 'Désactivation compte vehicule', + 'is_mandatory' => false, + ]); + } + } } } diff --git a/database/seeders/RolesAndPermissionsSeeder.php b/database/seeders/RolesAndPermissionsSeeder.php index 18e29fb..d366c2d 100644 --- a/database/seeders/RolesAndPermissionsSeeder.php +++ b/database/seeders/RolesAndPermissionsSeeder.php @@ -38,10 +38,10 @@ class RolesAndPermissionsSeeder extends Seeder 'export reports', ]); - $services = ['DSI', 'Batiment', 'ParcAuto']; + $services = ['DSI', 'Batiment', 'Parc Auto']; foreach ($services as $service) { Role::firstOrCreate(['name' => $service])->givePermissionTo([ - 'manage ' . strtolower($service === 'ParcAuto' ? 'parc auto' : $service) . ' tasks', + 'manage ' . strtolower($service) . ' tasks', 'view dashboard', ]); } diff --git a/database/seeders/ServiceSeeder.php b/database/seeders/ServiceSeeder.php index 689c9cf..f7831d7 100644 --- a/database/seeders/ServiceSeeder.php +++ b/database/seeders/ServiceSeeder.php @@ -12,7 +12,7 @@ class ServiceSeeder extends Seeder $services = [ ['name' => 'DSI', 'code' => 'dsi'], ['name' => 'Batiment', 'code' => 'batiment'], - ['name' => 'ParcAuto', 'code' => 'parc_auto'], + ['name' => 'Parc Auto', 'code' => 'parc_auto'], ['name' => 'RH', 'code' => 'rh'], ]; diff --git a/resources/js/Components/App/ActivityTimeline.vue b/resources/js/Components/App/ActivityTimeline.vue index c6f0666..214c1c3 100644 --- a/resources/js/Components/App/ActivityTimeline.vue +++ b/resources/js/Components/App/ActivityTimeline.vue @@ -1,5 +1,6 @@ diff --git a/resources/js/Layouts/AuthenticatedLayout.vue b/resources/js/Layouts/AuthenticatedLayout.vue index 8332447..de9c84d 100644 --- a/resources/js/Layouts/AuthenticatedLayout.vue +++ b/resources/js/Layouts/AuthenticatedLayout.vue @@ -39,6 +39,20 @@ const showingNavigationDropdown = ref(false); > Tableau de Bord + + Utilisateurs + + + Rôles + @@ -146,6 +160,20 @@ const showingNavigationDropdown = ref(false); > Tableau de Bord + + Utilisateurs + + + Rôles + diff --git a/resources/js/Pages/Dashboard/Prescriber.vue b/resources/js/Pages/Dashboard/Prescriber.vue index 08790c4..2d4b2a6 100644 --- a/resources/js/Pages/Dashboard/Prescriber.vue +++ b/resources/js/Pages/Dashboard/Prescriber.vue @@ -55,7 +55,7 @@ const props = defineProps({ Détails | - + diff --git a/resources/js/Pages/Dashboard/RH.vue b/resources/js/Pages/Dashboard/RH.vue index d94231b..861d921 100644 --- a/resources/js/Pages/Dashboard/RH.vue +++ b/resources/js/Pages/Dashboard/RH.vue @@ -132,8 +132,18 @@ const props = defineProps({ {{ req.agent.department }} {{ req.completed_at ? new Date(req.completed_at).toLocaleDateString() : '-' }} - + Consulter + + + + + diff --git a/resources/js/Pages/Dashboard/Service.vue b/resources/js/Pages/Dashboard/Service.vue index ecadc11..268ed42 100644 --- a/resources/js/Pages/Dashboard/Service.vue +++ b/resources/js/Pages/Dashboard/Service.vue @@ -8,6 +8,10 @@ const props = defineProps({ role: String, my_tasks: Array, completed_tasks: Array, + processed_integrations: { + type: Array, + default: () => [] + }, }); const getOverdueCount = () => { @@ -83,6 +87,54 @@ const getOverdueCount = () => { + + +
+
+

Fiches traitées (Récent)

+
+
+ + + + + + + + + + + + + + + + + + + + +
AgentArrivéeTemplateAction
+
{{ integration.agent.first_name }} {{ integration.agent.last_name }}
+
{{ integration.agent.position }}
+
{{ new Date(integration.agent.arrival_date).toLocaleDateString() }}{{ integration.template?.name || 'Standard' }} +
+ Voir + + + + + +
+
Aucune fiche traitée récemment
+
+
diff --git a/resources/js/Pages/Integration/Show.vue b/resources/js/Pages/Integration/Show.vue index 5c98341..c5cdbe3 100644 --- a/resources/js/Pages/Integration/Show.vue +++ b/resources/js/Pages/Integration/Show.vue @@ -31,7 +31,9 @@ const validateRH = () => {