$data['agent_id'], 'template_id' => $templateId, 'status' => IntegrationStatus::PendingRHValidation, 'type' => $data['type'], 'global_deadline' => isset($data['departure_date']) ? $data['departure_date'] : now()->addDays(15), ]); // Tasks are NOT generated here anymore. They will be generated upon RH validation. return $request; }); } public function createOnboarding(array $agentData, ?int $templateId = null): IntegrationRequest { return DB::transaction(function () use ($agentData, $templateId) { $agent = Agent::create([ ...$agentData, 'integration_status' => IntegrationStatus::PendingRHValidation, 'created_by' => auth()->id() ?? 1, ]); $request = $this->createProcess([ 'agent_id' => $agent->id, 'template_id' => $templateId, 'type' => 'onboarding', ]); // Notify RH users about the new request $rhUsers = \App\Models\User::role('RH')->get(); \Illuminate\Support\Facades\Notification::send($rhUsers, new \App\Notifications\NewIntegrationRequestNotification($request)); return $request; }); } public function generateTasksFromTemplate(IntegrationRequest $request, int $templateId): void { $template = IntegrationTemplate::with('serviceItems')->findOrFail($templateId); foreach ($template->serviceItems->groupBy('service_id') as $serviceId => $items) { $serviceTask = ServiceTask::create([ 'integration_request_id' => $request->id, 'service_id' => $serviceId, 'status' => ServiceTaskStatus::Pending, 'sla_deadline' => now()->addDays(3), // Default SLA ]); foreach ($items as $item) { TaskItem::create([ 'service_task_id' => $serviceTask->id, 'label' => $item->label, 'is_mandatory' => $item->is_mandatory, 'fields_definition' => $item->fields, 'data' => [], ]); } // Notify service users $serviceRole = $serviceTask->service->name; // Assumption: role name matches service name $users = \App\Models\User::role($serviceRole)->get(); \Illuminate\Support\Facades\Notification::send($users, new \App\Notifications\TaskAssignedNotification($serviceTask)); } } public function validateRH(IntegrationRequest $request): void { // Transition to InProgress $request->update(['status' => IntegrationStatus::InProgress]); $request->agent->update(['validated_by_rh_at' => now(), 'integration_status' => IntegrationStatus::InProgress]); // Generate tasks if template exists if ($request->template_id) { $this->generateTasksFromTemplate($request, $request->template_id); } } public function checkCompletion(IntegrationRequest $request): bool { $allCompleted = $request->serviceTasks() ->where('status', '!=', ServiceTaskStatus::Completed) ->count() === 0; if ($allCompleted) { $request->update([ 'status' => IntegrationStatus::Completed, 'completed_at' => now() ]); $request->agent->update(['integration_status' => IntegrationStatus::Completed]); // Notify RH (Standard notification) $rhUsers = \App\Models\User::role('RH')->get(); \Illuminate\Support\Facades\Notification::send($rhUsers, new \App\Notifications\ProcessCompletedNotification($request)); // Generate PDF for Prescriber and DSI $request->load([ 'agent', 'template', 'serviceTasks.service', 'serviceTasks.taskItems.completedBy' ]); $pdfContent = null; try { $pdf = \Barryvdh\DomPDF\Facade\Pdf::loadView('pdf.integration', [ 'integration' => $request, 'agent' => $request->agent, 'date' => now()->format('d/m/Y'), ]); $pdf->setPaper('a4', 'portrait'); $pdfContent = $pdf->output(); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("Failed to generate PDF for integration {$request->id}: " . $e->getMessage()); } if ($pdfContent) { $base64Pdf = base64_encode($pdfContent); // Notify Prescriber with PDF if ($prescriber = $request->agent->creator) { $prescriber->notify(new \App\Notifications\IntegrationCompletedWithAttachment($request, $base64Pdf)); } // Notify DSI with PDF $dsiUsers = \App\Models\User::role('DSI')->get(); if ($dsiUsers->count() > 0) { \Illuminate\Support\Facades\Notification::send($dsiUsers, new \App\Notifications\IntegrationCompletedWithAttachment($request, $base64Pdf)); } } } return $allCompleted; } }