Files
deskhub/DeskHub-Webseite/staff/sla_plans.php
T
2026-10-16 19:12:21 +00:00

138 lines
7.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/../includes/bootstrap.php';
require_once __DIR__ . '/_ui.php';
$staff = require_admin_or_permission('manage_priorities');
$pdo = get_db();
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'create' || $action === 'update') {
$id = $action === 'update' ? (int) ($_POST['id'] ?? 0) : 0;
try {
sla_plan_save($pdo, $id, [
'name' => $_POST['name'] ?? '', 'response_hours' => $_POST['response_hours'] ?? 0, 'resolution_hours' => $_POST['resolution_hours'] ?? 0,
'is_active' => ($_POST['status'] ?? 'active') === 'active', 'notes' => $_POST['notes'] ?? '',
]);
audit_log($staff['id'], ($action === 'create' ? 'SLA-Plan erstellt: ' : 'SLA-Plan aktualisiert: ') . trim($_POST['name'] ?? ''));
flash('success', $action === 'create' ? 'SLA-Plan erstellt.' : 'Änderungen gespeichert. Sie gelten für neue Tickets und bei Prioritätsänderung.');
redirect('/staff/sla_plans.php');
} catch (AdminModelException $e) {
$errors[] = $e->getMessage();
}
}
if ($action === 'delete') {
$deleted = sla_plan_delete($pdo, (int) $_POST['id']);
audit_log($staff['id'], "SLA-Plan gelöscht: {$deleted}");
flash('success', 'SLA-Plan gelöscht. Betroffene Abteilungen und Themen nutzen wieder die Zeiten der Priorität.');
redirect('/staff/sla_plans.php');
}
}
$isNew = isset($_GET['new']);
$editId = (int) ($_GET['edit'] ?? 0);
$showForm = $isNew || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true));
$plans = $pdo->query(
'SELECT p.*,
(SELECT COUNT(*) FROM departments d WHERE d.sla_plan_id = p.id) AS dept_count,
(SELECT COUNT(*) FROM help_topics h WHERE h.sla_plan_id = p.id) AS topic_count
FROM sla_plans p ORDER BY p.name'
)->fetchAll();
$editPlan = null;
if ($editId) {
$stmt = $pdo->prepare('SELECT * FROM sla_plans WHERE id = ?');
$stmt->execute([$editId]);
$editPlan = $stmt->fetch() ?: null;
}
$hours = fn(int $h) => $h >= 24 && $h % 24 === 0 ? ($h / 24) . ' Tag' . ($h / 24 === 1 ? '' : 'e') : $h . ' Std';
$pageTitle = 'SLA-Pläne';
$activePage = 'sla_plans';
require __DIR__ . '/_header.php';
?>
<?php foreach ($errors as $err): ?><div class="flash error"><?= e($err) ?></div><?php endforeach; ?>
<?php if ($showForm): ?>
<?php
$f = fn(string $k, $default = '') => $_POST[$k] ?? $default;
$v = fn(string $k, string $col, $default = '') => $f($k, $editPlan[$col] ?? $default);
$curActive = $_POST ? (($_POST['status'] ?? 'active') === 'active') : (bool) ($editPlan['is_active'] ?? 1);
?>
<h1>
<?= $editPlan ? 'SLA-Plan aktualisieren' : 'Neuer SLA-Plan' ?>
<?php if ($editPlan): ?><span class="muted" style="font-size:1rem;font-weight:400">— <?= e($editPlan['name']) ?></span><?php endif; ?>
</h1>
<form method="post" class="card" style="padding:0">
<?= csrf_field() ?>
<input type="hidden" name="action" value="<?= $editPlan ? 'update' : 'create' ?>">
<?php if ($editPlan): ?><input type="hidden" name="id" value="<?= (int) $editPlan['id'] ?>"><?php endif; ?>
<?php ui_tab_bar(['plan' => 'SLA-Plan']); ?>
<div class="tab-pane" data-pane="plan" style="padding:16px 20px">
<h3 style="margin-top:0">Planinformationen</h3>
<label for="name">Name *</label>
<input type="text" id="name" name="name" value="<?= e($v('name', 'name')) ?>" placeholder="z. B. Premium-Support" required>
<?php ui_status_radios($curActive); ?>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;max-width:520px">
<div><label for="response_hours">Reaktionszeit (Std) *</label>
<input type="number" min="1" id="response_hours" name="response_hours" value="<?= e((string) $v('response_hours', 'response_hours', '4')) ?>" required></div>
<div><label for="resolution_hours">Lösungszeit (Std) *</label>
<input type="number" min="1" id="resolution_hours" name="resolution_hours" value="<?= e((string) $v('resolution_hours', 'resolution_hours', '24')) ?>" required></div>
</div>
<p class="muted" style="font-size:.82rem">Der Plan ersetzt die Zeiten der Priorität für Tickets, deren <strong>Hilfethema</strong> oder <strong>Abteilung</strong> ihn zugeordnet hat (Hilfethema vor Abteilung). Mit aktivierten <a href="/staff/business_hours.php">Geschäftszeiten</a> zählen nur Öffnungszeiten.</p>
<h3>Administratornotizen <span class="muted" style="font-weight:400;font-size:.85rem">– Interne Notizen</span></h3>
<textarea name="notes" rows="5"><?= e($v('notes', 'notes')) ?></textarea>
</div>
<div class="btn-row" style="padding:0 20px 18px">
<button type="submit" class="btn"><?= $editPlan ? 'Änderungen speichern' : 'Erstellen' ?></button>
<a href="/staff/sla_plans.php" class="btn secondary">Abbrechen</a>
</div>
</form>
<?php ui_tab_assets('plan'); ?>
<?php else: ?>
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px">
<h1 style="margin:0">SLA-Pläne</h1>
<a href="/staff/sla_plans.php?new=1" class="btn">Neuen SLA-Plan hinzufügen</a>
</div>
<p class="muted">Benannte Reaktions- und Lösungszeiten, die du Abteilungen und Hilfethemen zuordnest. Ohne Zuordnung gelten die Zeiten der <a href="/staff/priorities.php">Priorität</a>.</p>
<div class="card">
<table>
<thead><tr><th>Name</th><th>Status</th><th>Reaktion</th><th>Lösung</th><th style="text-align:center">Abteilungen</th><th style="text-align:center">Hilfethemen</th><th>Zuletzt aktualisiert</th><th></th></tr></thead>
<tbody>
<?php foreach ($plans as $p): ?>
<tr>
<td><a href="/staff/sla_plans.php?edit=<?= (int) $p['id'] ?>"><?= e($p['name']) ?></a></td>
<td><strong><?= $p['is_active'] ? 'Aktiv' : 'Deaktiviert' ?></strong></td>
<td><?= e($hours((int) $p['response_hours'])) ?></td>
<td><?= e($hours((int) $p['resolution_hours'])) ?></td>
<td style="text-align:center"><?= (int) $p['dept_count'] ?></td>
<td style="text-align:center"><?= (int) $p['topic_count'] ?></td>
<td class="muted" style="font-size:.82rem"><?= e(ui_date($p['updated_at'] ?? null)) ?></td>
<td style="white-space:nowrap">
<a href="/staff/sla_plans.php?edit=<?= (int) $p['id'] ?>">Bearbeiten</a> ·
<form method="post" style="display:inline" onsubmit="return confirm('SLA-Plan wirklich löschen?');">
<?= csrf_field() ?>
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= (int) $p['id'] ?>">
<button type="submit" style="background:none;border:none;color:#dc2626;cursor:pointer;padding:0;font-size:.9rem">Löschen</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php if (!$plans): ?><tr><td colspan="8" class="muted">Noch keine SLA-Pläne angelegt.</td></tr><?php endif; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php require __DIR__ . '/_footer.php'; ?>