query("SELECT action_value FROM ticket_rule_actions WHERE action_type = 'set_department'")->fetchAll(PDO::FETCH_COLUMN))); $priorities = $pdo->query('SELECT * FROM priorities ORDER BY sort_order')->fetchAll(); $helpTopics = $pdo->query('SELECT * FROM help_topics ORDER BY name')->fetchAll(); $staffList = $pdo->query("SELECT id, name FROM staff WHERE is_active = 1 ORDER BY name")->fetchAll(); $cannedResponses = $pdo->query('SELECT id, title FROM canned_responses ORDER BY title')->fetchAll(); $fieldLabels = [ 'subject' => 'Betreff', 'message' => 'Nachricht', 'requester_email' => 'Absender-E-Mail', 'requester_name' => 'Absender-Name', 'source' => 'Kanal (web/email)', ]; $operatorLabels = [ 'contains' => 'enthält', 'not_contains' => 'enthält nicht', 'equals' => 'ist genau', 'starts_with' => 'beginnt mit', 'ends_with' => 'endet mit', ]; $actionLabels = [ 'set_department' => 'Abteilung setzen', 'set_priority' => 'Priorität setzen', 'set_help_topic' => 'Hilfe-Thema setzen', 'assign_staff' => 'Mitarbeiter zuweisen', 'add_tag' => 'Tag hinzufügen', 'auto_reply' => 'Auto-Antwort senden (Textbaustein)', 'close' => 'Ticket schließen (wird angelegt, aber sofort geschlossen)', 'reject' => 'Ticket verwerfen (z.B. Spam)', ]; $errors = []; if ($_SERVER['REQUEST_METHOD'] === 'POST') { verify_csrf(); $action = $_POST['action'] ?? ''; if ($action === 'create' || $action === 'update') { $name = trim($_POST['name'] ?? ''); $matchType = ($_POST['match_type'] ?? 'all') === 'any' ? 'any' : 'all'; $isActive = ($_POST['status'] ?? 'active') === 'active' ? 1 : 0; $notes = trim($_POST['notes'] ?? ''); $sortOrder = (int) ($_POST['sort_order'] ?? 0); $condFields = $_POST['cond_field'] ?? []; $condOperators = $_POST['cond_operator'] ?? []; $condValues = $_POST['cond_value'] ?? []; $actTypes = $_POST['action_type'] ?? []; $actDept = $_POST['action_value_dept'] ?? []; $actPrio = $_POST['action_value_prio'] ?? []; $actTopic = $_POST['action_value_topic'] ?? []; $actStaff = $_POST['action_value_staff'] ?? []; $actTag = $_POST['action_value_tag'] ?? []; $actCanned = $_POST['action_value_canned'] ?? []; if ($name === '') $errors[] = 'Bitte einen Namen für die Regel angeben.'; $conditions = []; foreach ($condFields as $i => $f) { $val = trim($condValues[$i] ?? ''); if ($val === '') continue; if (!isset($fieldLabels[$f]) || !isset($operatorLabels[$condOperators[$i] ?? ''])) continue; $conditions[] = ['field' => $f, 'operator' => $condOperators[$i], 'value' => $val]; } if (!$conditions) $errors[] = 'Bitte mindestens eine Bedingung mit einem Wert angeben.'; $actionsToSave = []; foreach ($actTypes as $i => $t) { if (!isset($actionLabels[$t])) continue; $value = match ($t) { 'set_department' => $actDept[$i] ?? '', 'set_priority' => $actPrio[$i] ?? '', 'set_help_topic' => $actTopic[$i] ?? '', 'assign_staff' => $actStaff[$i] ?? '', 'add_tag' => trim($actTag[$i] ?? ''), 'auto_reply' => $actCanned[$i] ?? '', 'reject', 'close' => '1', default => '', }; if (!in_array($t, ['reject', 'close'], true) && $value === '') continue; $actionsToSave[] = ['action_type' => $t, 'action_value' => $value]; } if (!$actionsToSave) $errors[] = 'Bitte mindestens eine Aktion festlegen.'; if (!$errors) { if ($action === 'create') { $pdo->prepare('INSERT INTO ticket_rules (name, match_type, is_active, sort_order, notes, created_at, updated_at) VALUES (?,?,?,?,?,?,?)') ->execute([$name, $matchType, $isActive, $sortOrder, $notes ?: null, db_now(), db_now()]); $ruleId = (int) $pdo->lastInsertId(); audit_log($staff['id'], "Ticket-Regel erstellt: {$name}"); flash('success', 'Ticket-Regel erstellt.'); } else { $ruleId = (int) $_POST['id']; $pdo->prepare('UPDATE ticket_rules SET name=?, match_type=?, is_active=?, sort_order=?, notes=?, updated_at=? WHERE id=?') ->execute([$name, $matchType, $isActive, $sortOrder, $notes ?: null, db_now(), $ruleId]); $pdo->prepare('DELETE FROM ticket_rule_conditions WHERE rule_id = ?')->execute([$ruleId]); $pdo->prepare('DELETE FROM ticket_rule_actions WHERE rule_id = ?')->execute([$ruleId]); audit_log($staff['id'], "Ticket-Regel aktualisiert: {$name}"); flash('success', 'Ticket-Regel aktualisiert.'); } $condStmt = $pdo->prepare('INSERT INTO ticket_rule_conditions (rule_id, field, operator, value) VALUES (?,?,?,?)'); foreach ($conditions as $c) { $condStmt->execute([$ruleId, $c['field'], $c['operator'], $c['value']]); } $actStmt = $pdo->prepare('INSERT INTO ticket_rule_actions (rule_id, action_type, action_value) VALUES (?,?,?)'); foreach ($actionsToSave as $a) { $actStmt->execute([$ruleId, $a['action_type'], $a['action_value']]); } redirect('/staff/ticket_rules.php'); } } if ($action === 'toggle_active') { $id = (int) $_POST['id']; $pdo->prepare('UPDATE ticket_rules SET is_active = 1 - is_active WHERE id = ?')->execute([$id]); redirect('/staff/ticket_rules.php'); } if ($action === 'delete') { $id = (int) $_POST['id']; $nameStmt = $pdo->prepare('SELECT name FROM ticket_rules WHERE id = ?'); $nameStmt->execute([$id]); $ruleName = $nameStmt->fetchColumn(); $pdo->prepare('DELETE FROM ticket_rules WHERE id = ?')->execute([$id]); audit_log($staff['id'], "Ticket-Regel gelöscht: {$ruleName}"); flash('success', 'Ticket-Regel gelöscht.'); redirect('/staff/ticket_rules.php'); } if ($action === 'move' && in_array($_POST['dir'] ?? '', ['up', 'down'], true)) { $id = (int) $_POST['id']; $dir = $_POST['dir']; $rules = $pdo->query('SELECT id, sort_order FROM ticket_rules ORDER BY sort_order, id')->fetchAll(); $idx = null; foreach ($rules as $i => $r) { if ((int) $r['id'] === $id) { $idx = $i; break; } } $swapIdx = $dir === 'up' ? $idx - 1 : $idx + 1; if ($idx !== null && isset($rules[$swapIdx])) { $a = $rules[$idx]; $b = $rules[$swapIdx]; $pdo->prepare('UPDATE ticket_rules SET sort_order = ? WHERE id = ?')->execute([$b['sort_order'], $a['id']]); $pdo->prepare('UPDATE ticket_rules SET sort_order = ? WHERE id = ?')->execute([$a['sort_order'], $b['id']]); } redirect('/staff/ticket_rules.php'); } } $rules = $pdo->query('SELECT * FROM ticket_rules ORDER BY sort_order, id')->fetchAll(); foreach ($rules as &$r) { $cs = $pdo->prepare('SELECT * FROM ticket_rule_conditions WHERE rule_id = ?'); $cs->execute([$r['id']]); $r['conditions'] = $cs->fetchAll(); $as = $pdo->prepare('SELECT * FROM ticket_rule_actions WHERE rule_id = ?'); $as->execute([$r['id']]); $r['actions'] = $as->fetchAll(); } unset($r); $editId = $_GET['edit'] ?? null; $showForm = isset($_GET['new']) || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true)); $editRule = null; if ($editId) { foreach ($rules as $r) { if ((int) $r['id'] === (int) $editId) { $editRule = $r; break; } } } $pageTitle = 'Ticket-Regeln'; $activePage = 'ticket_rules'; require __DIR__ . '/_header.php'; /** Rendert die Werte-Auswahl einer Aktionszeile für eine bereits gespeicherte Aktion (Bearbeiten-Modus) */ function render_action_value_selects(array $departments, array $priorities, array $helpTopics, array $staffList, array $cannedResponses, ?array $existing = null): void { $effectiveType = $existing['action_type'] ?? 'set_department'; // Default-Auswahl des Typ-Selects $sel = fn($type) => ($effectiveType === $type) ? '' : 'style="display:none"'; $val = fn($type) => ($existing && $existing['action_type'] === $type) ? $existing['action_value'] : ''; ?> > Noch keine Textbausteine angelegt – jetzt erstellen. Das Ticket wird angelegt und gleich geschlossen. Es gibt keine Benachrichtigung an Mitarbeiter oder Kunden. Keine weitere Einstellung nötig.

Ticket-Regeln (Filter)

Neue Regel hinzufügen

Automatische Aktionen für neue Tickets (Web-Formular und E-Mail-Eingang), ausgewertet in der Reihenfolge unten. Trifft eine Regel mit Aktion „Ticket verwerfen“ zu, werden keine weiteren Regeln mehr geprüft.

$r): ?>
ReihenfolgeNameBedingungenAktionenStatusZuletzt aktualisiert
„“
Bearbeiten ·
Noch keine Ticket-Regeln angelegt.
$_POST[$k] ?? $default; $curActive = $_POST ? (($_POST['status'] ?? 'active') === 'active') : (bool) ($editRule['is_active'] ?? 1); ?>

—

'Regel', 'conds' => 'Bedingungen', 'acts' => 'Aktionen']); ?>

Regelinformationen

Administratornotizen – Interne Notizen, sichtbar für alle Administratoren