> /pfad/zu/deskhub/cron/check_sla.log 2>&1 * * Kann außerdem manuell aus dem Backend (Einstellungen → Cron-Jobs) ausgeführt werden. */ require_once __DIR__ . '/../includes/bootstrap.php'; /** * Führt die SLA-Prüfung aus. Kann vom Cron und manuell aus settings.php aufgerufen werden. * * @return array{overdueTotal: int, newlyOverdue: int, log: string[]} */ function run_check_sla(PDO $pdo, bool $verbose = false): array { $now = db_now(); $stmt = $pdo->prepare( "SELECT t.*, d.email AS department_email, d.name AS department_name FROM tickets t JOIN departments d ON d.id = t.department_id WHERE t.status NOT IN ('resolved','closed') AND t.sla_paused_at IS NULL AND t.resolution_due_at IS NOT NULL AND t.resolution_due_at < ?" ); $stmt->execute([$now]); $overdue = $stmt->fetchAll(); $newlyOverdue = 0; $log = []; foreach ($overdue as $t) { if (!$t['is_overdue']) { $pdo->prepare('UPDATE tickets SET is_overdue = 1, updated_at = updated_at WHERE id = ?')->execute([$t['id']]); ticket_sla_log_overdue($pdo, (int) $t['id'], 'resolution', (string) $t['resolution_due_at']); log_activity($pdo, $t['id'], null, 'SLA überschritten – Ticket als überfällig markiert'); // Nur die Betroffenen bekommen eine Mail (Bearbeiter bzw. Abteilung), nicht die Postfach-Adresse der Abteilung und nicht alle Admins notify_overdue_ticket_staff($t); fcm_notify_overdue($t); // Push auf die Android-App $newlyOverdue++; if ($verbose) { $log[] = "[ok] Ticket #{$t['ticket_number']} als überfällig markiert"; } } } $responseStmt = $pdo->prepare("SELECT id, first_response_due_at FROM tickets WHERE first_responded_at IS NULL AND first_response_due_at IS NOT NULL AND first_response_due_at < ? AND sla_paused_at IS NULL AND status NOT IN ('resolved','closed')"); $responseStmt->execute([$now]); foreach ($responseStmt->fetchAll() as $ticket) ticket_sla_log_overdue($pdo, (int) $ticket['id'], 'first_response', (string) $ticket['first_response_due_at']); // Tickets, die nicht mehr überfällig sind (z.B. weil sie gelöst wurden), zurücksetzen $pdo->exec("UPDATE tickets SET is_overdue = 0, updated_at = updated_at WHERE status IN ('resolved','closed') AND is_overdue = 1"); // Erinnerung an Bearbeiter: Ticket wartet seit mehreren Arbeitsstunden auf Antwort, bevor die Frist reißt $waitReminders = wait_reminders_run($pdo, $now); foreach ($waitReminders['log'] as $line) $log[] = $line; set_setting('cron_check_sla_last_run', $now); $log[] = "[" . date('Y-m-d H:i:s') . "] SLA-Prüfung abgeschlossen. " . count($overdue) . " überfällige Tickets insgesamt, davon {$newlyOverdue} neu erkannt."; return ['overdueTotal' => count($overdue), 'newlyOverdue' => $newlyOverdue, 'waitReminders' => $waitReminders['sent'], 'log' => $log]; } if (php_sapi_name() === 'cli') { $result = run_check_sla(get_db(), true); foreach ($result['log'] as $line) { echo $line . "\n"; } }