feat: Initialize core application structure including authentication, role-based dashboards, service task management, and integration workflows.

This commit is contained in:
jeremy bayse
2026-02-16 09:30:23 +01:00
commit af060a8847
208 changed files with 26822 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
<?php
namespace App\Services;
use App\Models\Agent;
use App\Models\IntegrationRequest;
use App\Models\IntegrationTemplate;
use App\Models\ServiceTask;
use App\Models\TaskItem;
use App\Enums\IntegrationStatus;
use App\Enums\ServiceTaskStatus;
use Illuminate\Support\Facades\DB;
class IntegrationService
{
public function createProcess(array $data): IntegrationRequest
{
return DB::transaction(function () use ($data) {
$templateId = $data['template_id'] ?? null;
$request = IntegrationRequest::create([
'agent_id' => $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;
}
}