152 lines
6.6 KiB
PHP
152 lines
6.6 KiB
PHP
<?php
|
||
require_once __DIR__ . '/../includes/bootstrap.php';
|
||
$staff = require_admin_or_permission('merge_split_ticket');
|
||
$pdo = get_db();
|
||
|
||
$ticketId = (int)($_GET['id'] ?? 0);
|
||
if (!$ticketId) redirect('/staff/tickets.php');
|
||
|
||
$stmt = $pdo->prepare(
|
||
'SELECT t.*, d.name AS department_name, p.name AS priority_name
|
||
FROM tickets t
|
||
JOIN departments d ON d.id = t.department_id
|
||
JOIN priorities p ON p.id = t.priority_id
|
||
WHERE t.id = ?'
|
||
);
|
||
$stmt->execute([$ticketId]);
|
||
$ticket = $stmt->fetch();
|
||
if (!$ticket) { http_response_code(404); die('Ticket nicht gefunden.'); }
|
||
if (!staff_can_access_department($staff, (int) $ticket['department_id'])) { http_response_code(403); die('Sie haben keinen Zugriff auf Tickets dieser Abteilung.'); }
|
||
|
||
// Nachrichten laden
|
||
$threads = $pdo->prepare(
|
||
'SELECT tt.*, s.name AS staff_name
|
||
FROM ticket_threads tt
|
||
LEFT JOIN staff s ON s.id = tt.staff_id
|
||
WHERE tt.ticket_id = ? AND tt.is_internal_note = 0
|
||
ORDER BY tt.created_at ASC'
|
||
);
|
||
$threads->execute([$ticketId]);
|
||
$messages = $threads->fetchAll();
|
||
|
||
$errors = [];
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
verify_csrf();
|
||
|
||
$selectedMsgIds = array_map('intval', $_POST['message_ids'] ?? []);
|
||
$newSubject = trim($_POST['new_subject'] ?? '');
|
||
|
||
if (empty($selectedMsgIds)) {
|
||
$errors[] = 'Bitte mindestens eine Nachricht auswählen.';
|
||
} elseif (!$newSubject) {
|
||
$errors[] = 'Bitte einen Betreff für das neue Ticket angeben.';
|
||
} else {
|
||
// Neues Ticket erstellen
|
||
$newNumber = generate_ticket_number();
|
||
$pdo->prepare(
|
||
'INSERT INTO tickets (ticket_number, subject, status, priority_id, department_id,
|
||
user_id, requester_name, requester_email, source, created_at, updated_at)
|
||
VALUES (?,?,?,?,?,?,?,?,?,?,?)'
|
||
)->execute([
|
||
$newNumber, $newSubject, 'open',
|
||
$ticket['priority_id'], $ticket['department_id'],
|
||
$ticket['user_id'], $ticket['requester_name'], $ticket['requester_email'],
|
||
'staff', db_now(), db_now()
|
||
]);
|
||
$newId = $pdo->lastInsertId();
|
||
|
||
// Ausgewählte Nachrichten verschieben
|
||
$moved = 0;
|
||
foreach ($selectedMsgIds as $msgId) {
|
||
$rows = $pdo->prepare('UPDATE ticket_threads SET ticket_id=? WHERE id=? AND ticket_id=?');
|
||
$rows->execute([$newId, $msgId, $ticketId]);
|
||
$moved += $rows->rowCount();
|
||
}
|
||
|
||
// Anhänge der verschobenen Nachrichten mitnehmen
|
||
if ($moved > 0) {
|
||
$placeholders = implode(',', array_fill(0, count($selectedMsgIds), '?'));
|
||
$pdo->prepare("UPDATE ticket_attachments SET ticket_id=? WHERE thread_id IN ($placeholders)")
|
||
->execute(array_merge([$newId], $selectedMsgIds));
|
||
}
|
||
|
||
// Log-Einträge
|
||
log_activity($pdo, $ticketId, $staff['id'], "Ticket aufgeteilt → #{$newNumber} ({$moved} Nachrichten)");
|
||
log_activity($pdo, $newId, $staff['id'], "Erstellt durch Aufteilen von #{$ticket['ticket_number']}");
|
||
audit_log($staff['id'], "Ticket #{$ticket['ticket_number']} aufgeteilt → #{$newNumber}");
|
||
|
||
flash('success', "Ticket aufgeteilt. Neues Ticket: #{$newNumber}");
|
||
redirect('/staff/ticket_view.php?n=' . urlencode($newNumber));
|
||
}
|
||
}
|
||
|
||
$pageTitle = 'Ticket aufteilen';
|
||
$activePage = 'tickets';
|
||
require __DIR__ . '/_header.php';
|
||
?>
|
||
|
||
<div class="topbar">
|
||
<div>
|
||
<h1>Ticket aufteilen</h1>
|
||
<span class="ticket-no">#<?= e($ticket['ticket_number']) ?></span>
|
||
</div>
|
||
<a href="/staff/ticket_view.php?n=<?= urlencode($ticket['ticket_number']) ?>" class="btn secondary">← Zurück</a>
|
||
</div>
|
||
|
||
<?php foreach ($errors as $err): ?><div class="flash error"><?= e($err) ?></div><?php endforeach; ?>
|
||
|
||
<div style="display:grid; grid-template-columns:2fr 1fr; gap:20px; align-items:start">
|
||
<div class="card">
|
||
<h3>Nachrichten auswählen</h3>
|
||
<p class="muted" style="font-size:.85rem; margin-bottom:16px">
|
||
Wähle die Nachrichten aus die in das neue Ticket verschoben werden sollen. Die gewählten Nachrichten werden aus diesem Ticket entfernt.
|
||
</p>
|
||
<form method="post" id="split-form">
|
||
<?= csrf_field() ?>
|
||
<div style="display:flex; flex-direction:column; gap:10px; margin-bottom:20px">
|
||
<?php foreach ($messages as $msg): ?>
|
||
<label style="display:flex; gap:12px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer; transition:background .12s"
|
||
onmouseover="this.style.background='var(--bg-soft)'" onmouseout="this.style.background=''">
|
||
<input type="checkbox" name="message_ids[]" value="<?= $msg['id'] ?>"
|
||
style="width:auto; margin-top:3px; flex-shrink:0">
|
||
<div style="min-width:0; flex:1">
|
||
<div style="display:flex; justify-content:space-between; margin-bottom:4px">
|
||
<strong style="font-size:.83rem"><?= e($msg['staff_name'] ?? $ticket['requester_name']) ?></strong>
|
||
<span class="muted" style="font-size:.75rem"><?= format_dt($msg['created_at']) ?></span>
|
||
</div>
|
||
<div style="font-size:.85rem; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis">
|
||
<?= e(mb_substr(strip_tags($msg['message']), 0, 120)) ?>
|
||
</div>
|
||
</div>
|
||
</label>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<label>Betreff des neuen Tickets</label>
|
||
<input type="text" name="new_subject" value="<?= e('Re: '.$ticket['subject']) ?>" required>
|
||
<div class="btn-row" style="margin-top:16px">
|
||
<button type="submit" class="btn" onclick="return confirm('Ausgewählte Nachrichten in neues Ticket verschieben?')">
|
||
✂️ Ticket aufteilen
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>Hinweise</h3>
|
||
<ul style="padding-left:20px; line-height:2; font-size:.85rem; color:var(--muted)">
|
||
<li>Ausgewählte Nachrichten werden in ein <strong style="color:var(--ink)">neues Ticket</strong> verschoben</li>
|
||
<li>Anhänge der Nachrichten werden mitgenommen</li>
|
||
<li>Das ursprüngliche Ticket bleibt mit den verbleibenden Nachrichten erhalten</li>
|
||
<li>Beide Tickets erhalten einen Log-Eintrag</li>
|
||
</ul>
|
||
<div style="background:var(--bg-soft); border-radius:8px; padding:14px; margin-top:16px; font-size:.83rem">
|
||
<div class="muted" style="margin-bottom:6px">Ursprüngliches Ticket</div>
|
||
<strong>#<?= e($ticket['ticket_number']) ?></strong> – <?= e($ticket['subject']) ?>
|
||
<div class="muted" style="margin-top:4px"><?= count($messages) ?> Nachrichten gesamt</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php require __DIR__ . '/_footer.php'; ?>
|