query('SELECT * FROM priorities ORDER BY sort_order')->fetchAll(); $staffList = $pdo->query("SELECT id, name FROM staff WHERE is_active = 1 ORDER BY name")->fetchAll(); $depts = $pdo->query('SELECT id, name FROM departments ORDER BY name')->fetchAll(); $triggerTypes = [ 'no_reply' => 'Keine Mitarbeiter-Antwort seit X Stunden', 'no_update' => 'Kein Update seit X Stunden', 'overdue' => 'Ticket ist überfällig (SLA überschritten)', 'open_too_long' => 'Ticket offen seit X Stunden', ]; $errors = []; if ($_SERVER['REQUEST_METHOD'] === 'POST') { verify_csrf(); $action = $_POST['action'] ?? ''; if ($action === 'save') { $id = (int)($_POST['id'] ?? 0); $name = trim($_POST['name'] ?? ''); $isActive = !empty($_POST['is_active']) ? 1 : 0; $triggerType = $_POST['trigger_type'] ?? 'no_reply'; $triggerHours = max(1, (int)($_POST['trigger_hours'] ?? 24)); $condStatus = trim($_POST['condition_status'] ?? ''); $condPrioId = ($_POST['condition_priority_id'] ?? '') !== '' ? (int)$_POST['condition_priority_id'] : null; $condDeptId = ($_POST['condition_dept_id'] ?? '') !== '' ? (int)$_POST['condition_dept_id'] : null; $actPrioId = ($_POST['action_set_priority_id'] ?? '') !== '' ? (int)$_POST['action_set_priority_id'] : null; $actStaffId = ($_POST['action_assign_staff_id'] ?? '') !== '' ? (int)$_POST['action_assign_staff_id'] : null; $actStatus = $_POST['action_set_status'] ?? ''; $actNotAdmin = !empty($_POST['action_notify_admin']) ? 1 : 0; $actNotStaff = !empty($_POST['action_notify_staff']) ? 1 : 0; $sortOrder = (int)($_POST['sort_order'] ?? 0); if ($name === '') $errors[] = 'Bitte einen Namen angeben.'; if (!array_key_exists($triggerType, $triggerTypes)) $errors[] = 'Ungültiger Trigger.'; if (!$errors) { $data = [$name, $isActive, $triggerType, $triggerHours, $condStatus ?: null, $condPrioId, $condDeptId, $actPrioId, $actStaffId, $actStatus ?: null, $actNotAdmin, $actNotStaff, $sortOrder]; if ($id) { $pdo->prepare( 'UPDATE escalation_rules SET name=?,is_active=?,trigger_type=?,trigger_hours=?, condition_status=?,condition_priority_id=?,condition_dept_id=?, action_set_priority_id=?,action_assign_staff_id=?,action_set_status=?, action_notify_admin=?,action_notify_staff=?,sort_order=? WHERE id=?' )->execute(array_merge($data, [$id])); audit_log($staff['id'], "Eskalationsregel geändert: $name"); } else { $pdo->prepare( 'INSERT INTO escalation_rules (name,is_active,trigger_type,trigger_hours, condition_status,condition_priority_id,condition_dept_id, action_set_priority_id,action_assign_staff_id,action_set_status, action_notify_admin,action_notify_staff,sort_order,created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)' )->execute(array_merge($data, [db_now()])); audit_log($staff['id'], "Eskalationsregel erstellt: $name"); } flash('success', 'Eskalationsregel gespeichert.'); redirect('/staff/escalation_rules.php'); } } if ($action === 'delete') { $id = (int)($_POST['id'] ?? 0); $pdo->prepare('DELETE FROM escalation_rules WHERE id = ?')->execute([$id]); $pdo->prepare('DELETE FROM escalation_log WHERE rule_id = ?')->execute([$id]); audit_log($staff['id'], "Eskalationsregel gelöscht: #$id"); flash('success', 'Regel gelöscht.'); redirect('/staff/escalation_rules.php'); } if ($action === 'toggle') { $id = (int)($_POST['id'] ?? 0); $pdo->prepare('UPDATE escalation_rules SET is_active = 1 - is_active WHERE id = ?')->execute([$id]); redirect('/staff/escalation_rules.php'); } } try { $rules = $pdo->query( 'SELECT er.*, p.name AS prio_name, s.name AS staff_name, d.name AS dept_name, cp.name AS cond_prio_name, (SELECT COUNT(*) FROM escalation_log el WHERE el.rule_id = er.id) AS applied_count FROM escalation_rules er LEFT JOIN priorities p ON p.id = er.action_set_priority_id LEFT JOIN staff s ON s.id = er.action_assign_staff_id LEFT JOIN departments d ON d.id = er.condition_dept_id LEFT JOIN priorities cp ON cp.id = er.condition_priority_id ORDER BY er.sort_order, er.id' )->fetchAll(); } catch (Throwable $e) { $rules = []; } $editId = (int)($_GET['edit'] ?? 0); $editRule = null; if ($editId) { foreach ($rules as $r) { if ($r['id'] === $editId) { $editRule = $r; break; } } } $pageTitle = 'Eskalationsregeln'; $activePage = 'ticket_rules'; require __DIR__ . '/_header.php'; ?>
Eskalationsregeln werden stündlich per Cron geprüft (cron/check_escalations.php).
Jede Regel wird pro Ticket nur einmal angewendet.
| Name | Auslöser | Aktionen | Angewendet | Status | |
|---|---|---|---|---|---|
| = e($r['name']) ?> |
= e($triggerTypes[$r['trigger_type']] ?? $r['trigger_type']) ?>
(= (int)$r['trigger_hours'] ?> Std)
= $r['cond_prio_name'] ? '· Priorität: '.e($r['cond_prio_name']) : '' ?>
= $r['dept_name'] ? '· Abteilung: '.e($r['dept_name']) : '' ?>
|
= implode(', ', $acts) ?: 'Nur benachrichtigen' ?> | = (int)$r['applied_count'] ?>× | = $r['is_active'] ? 'Aktiv' : 'Inaktiv' ?> | Bearbeiten · · |
0 * * * * php /pfad/zu/deskhub/cron/check_escalations.php
Stündliche Prüfung. Letzte Ausführung: = e(get_setting('cron_check_escalations_last_run', 'noch nie')) ?>