in_array($layer, $requested, true); $events = []; // ---- Maintenances -------------------------------------------------- if ($wants('maintenances') && mnt_user_can('maintenance.calendar.view')) { $stmt = $pdo->prepare(" SELECT m.id, m.title, m.code, m.next_due_date, m.alert_days, m.is_critical, e.id AS equipment_id, e.name AS equipment_name FROM maint_maintenances m INNER JOIN inv_equipment e ON e.id = m.equipment_id WHERE m.is_active = 1 AND e.status = 'active' AND m.next_due_date BETWEEN ? AND ? "); $stmt->execute([$start, $end]); foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $state = mnt_due_state($row['next_due_date'], (int)$row['alert_days']); $color = $state === 'overdue' ? '#dc3545' : '#2f7d8f'; $events[] = [ 'id' => 'maint-' . $row['id'], 'title' => '🔧 ' . $row['equipment_name'] . ': ' . $row['title'], 'start' => $row['next_due_date'], 'allDay' => true, 'backgroundColor' => $color, 'borderColor' => $color, 'extendedProps' => [ 'layer' => 'maintenances', 'url' => 'manutenzioni/equipment.php?id=' . (int)$row['equipment_id'], 'state' => $state, ], ]; } } // ---- Deadlines (scadenzario) -------------------------------------- if ($wants('deadlines') && mnt_user_can('deadlines.view')) { $stmt = $pdo->prepare(" SELECT d.id, d.topic, d.due_date, d.status, d.notification_days, s.name AS subject_name FROM scad_deadlines d LEFT JOIN scad_subjects s ON s.id = d.subject_id WHERE d.due_date BETWEEN ? AND ? "); $stmt->execute([$start, $end]); foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $isCompleted = $row['status'] === 'completed'; $state = $isCompleted ? 'ok' : mnt_due_state($row['due_date'], (int)$row['notification_days']); $color = $isCompleted ? '#6c757d' : ($state === 'overdue' ? '#b02a37' : '#6f42c1'); $events[] = [ 'id' => 'scad-' . $row['id'], 'title' => '📅 ' . $row['topic'], 'start' => $row['due_date'], 'allDay' => true, 'backgroundColor' => $color, 'borderColor' => $color, 'extendedProps' => [ 'layer' => 'deadlines', 'url' => 'scadenzario/detail.php?id=' . (int)$row['id'], 'state' => $state, ], ]; } } // ---- Trainings (formazione) --------------------------------------- if ($wants('trainings') && mnt_user_can('hr.trainings.view')) { $stmt = $pdo->prepare(" SELECT t.id, t.next_due_date, t.reminder_days, tt.name AS topic_name, CONCAT(e.first_name, ' ', e.last_name) AS employee_name FROM employee_trainings t INNER JOIN training_topics tt ON tt.id = t.training_topic_id INNER JOIN employees e ON e.id = t.employee_id WHERE t.next_due_date IS NOT NULL AND t.next_due_date BETWEEN ? AND ? "); $stmt->execute([$start, $end]); foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $state = mnt_due_state($row['next_due_date'], (int)($row['reminder_days'] ?? 0)); $color = $state === 'overdue' ? '#a94442' : '#198754'; $events[] = [ 'id' => 'train-' . $row['id'], 'title' => '🎓 ' . $row['topic_name'] . ' — ' . $row['employee_name'], 'start' => $row['next_due_date'], 'allDay' => true, 'backgroundColor' => $color, 'borderColor' => $color, 'extendedProps' => [ 'layer' => 'trainings', 'url' => 'trainings.php', 'state' => $state, ], ]; } } echo json_encode($events); } catch (Throwable $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()]); }