Files
deskhub/Plugins/plugins/vertretung/pages/vertretung.php
T
2026-11-01 11:18:05 +00:00

94 lines
6.8 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
// Seite des Vertretungs-Plugins. Verfügbar: $staff, $pdo.
$isAdmin = ($staff['role'] ?? '') === 'admin';
$message = null;
$error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'create') {
$staffId = $isAdmin ? (int) ($_POST['staff_id'] ?? 0) : (int) $staff['id'];
$r = vertretung_create($pdo, $staff, $staffId, (int) ($_POST['substitute_id'] ?? 0), (string) ($_POST['start_date'] ?? ''), (string) ($_POST['end_date'] ?? ''), (string) ($_POST['note'] ?? ''));
if ($r['ok']) $message = 'Die Abwesenheit ist eingetragen.'; else $error = $r['error'];
} elseif ($action === 'cancel') {
if (vertretung_cancel($pdo, $staff, (int) ($_POST['id'] ?? 0))) $message = 'Die Abwesenheit wurde beendet, offene Tickets sind wieder bei der ursprünglichen Person.';
else $error = 'Diese Abwesenheit kann nicht beendet werden.';
}
}
$people = $pdo->query('SELECT id, name FROM staff WHERE is_active = 1 ORDER BY name')->fetchAll();
$labels = vertretung_status_labels();
$names = [];
foreach ($people as $p) $names[(int) $p['id']] = $p['name'];
$name = fn($id) => e($names[(int) $id] ?? vertretung_name($pdo, (int) $id));
$current = $pdo->query("SELECT a.*, (SELECT COUNT(*) FROM plugin_vertretung_moves m WHERE m.absence_id = a.id) AS moved, (SELECT COUNT(*) FROM plugin_vertretung_moves m WHERE m.absence_id = a.id AND m.returned_at IS NULL) AS holding FROM plugin_vertretung_absences a WHERE a.status IN ('planned','active') ORDER BY a.start_date, a.id")->fetchAll();
$past = $pdo->query("SELECT a.*, (SELECT COUNT(*) FROM plugin_vertretung_moves m WHERE m.absence_id = a.id) AS moved FROM plugin_vertretung_absences a WHERE a.status NOT IN ('planned','active') ORDER BY a.id DESC LIMIT 20")->fetchAll();
?>
<h1>Abwesenheit und Vertretung</h1>
<?php if ($message): ?><div class="flash success"><?= e($message) ?></div><?php endif; ?>
<?php if ($error): ?><div class="flash error"><?= e($error) ?></div><?php endif; ?>
<form method="post" class="card" style="max-width:900px;margin-bottom:16px">
<?= csrf_field() ?>
<input type="hidden" name="action" value="create">
<h3>Abwesenheit eintragen</h3>
<p class="muted" style="font-size:.85rem">Zum Beginn gehen Ihre offenen Tickets an die Vertretung, neue Tickets ebenfalls (auch bei automatischer Zuweisung). Am Ende bekommen Sie die Tickets zurück, die dann noch bei der Vertretung liegen. Der Urlaubsstatus im Profil wird dafür automatisch gesetzt. Solange die Abwesenheit dauert, sieht und bearbeitet die Vertretung auch die Abteilungen der abwesenden Person, selbst wenn sie dort sonst keinen Zugang hat (Server ab 1.0.55).</p>
<?php if (!function_exists('staff_substitution_department_ids')): ?><div class="flash warning">Dieser Server ist älter als 1.0.55: Die Vertretung bekommt die Tickets, sieht sie aber nur, wenn sie auch Zugang zur Abteilung hat. Bitte den Server aktualisieren.</div><?php endif; ?>
<div style="display:flex;gap:14px;flex-wrap:wrap">
<?php if ($isAdmin): ?>
<div><label>Wer ist abwesend?</label><select name="staff_id"><?php foreach ($people as $p): ?><option value="<?= (int) $p['id'] ?>" <?= (int) $p['id'] === (int) $staff['id'] ? 'selected' : '' ?>><?= e($p['name']) ?></option><?php endforeach; ?></select></div>
<?php endif; ?>
<div><label>Vertretung</label><select name="substitute_id" required><option value="">– wählen –</option><?php foreach ($people as $p): if ((int) $p['id'] === (int) $staff['id'] && !$isAdmin) continue; ?><option value="<?= (int) $p['id'] ?>"><?= e($p['name']) ?></option><?php endforeach; ?></select></div>
<div><label>Von</label><input type="date" name="start_date" value="<?= e(vertretung_today()) ?>" required></div>
<div><label>Bis (einschließlich)</label><input type="date" name="end_date" required></div>
</div>
<label style="margin-top:8px">Notiz (optional)</label><input type="text" name="note" maxlength="250" placeholder="zum Beispiel Sommerurlaub">
<div class="btn-row"><button type="submit" class="btn">Eintragen</button></div>
</form>
<div class="card" style="margin-bottom:16px">
<h3>Laufend und geplant</h3>
<?php if (!$current): ?><p class="muted">Keine Abwesenheiten eingetragen.</p><?php else: ?>
<table style="width:100%">
<thead><tr><th>Wer</th><th>Vertretung</th><th>Zeitraum</th><th>Stand</th><th>Tickets</th><th>Die Vertretung sieht</th><th></th></tr></thead>
<tbody>
<?php foreach ($current as $a):
$dq = $pdo->prepare('SELECT d.name FROM departments d WHERE d.id = (SELECT department_id FROM staff WHERE id = ?) OR d.id IN (SELECT department_id FROM staff_department WHERE staff_id = ?) ORDER BY d.name');
$dq->execute([(int) $a['staff_id'], (int) $a['staff_id']]);
$deptNames = $dq->fetchAll(PDO::FETCH_COLUMN);
$absentAdmin = ($pdo->query('SELECT role FROM staff WHERE id = ' . (int) $a['staff_id'])->fetchColumn() === 'admin');
?>
<tr>
<td><?= $name($a['staff_id']) ?><?php if ($a['note']): ?><div class="muted" style="font-size:.76rem"><?= e((string) $a['note']) ?></div><?php endif; ?></td>
<td><?= $name($a['substitute_id']) ?></td>
<td><?= e(vertretung_date((string) $a['start_date'])) ?> – <?= e(vertretung_date((string) $a['end_date'])) ?></td>
<td><?= e($labels[$a['status']] ?? $a['status']) ?></td>
<td><?= $a['status'] === 'active' ? (int) $a['holding'] . ' bei der Vertretung' : '–' ?></td>
<td style="font-size:.82rem"><?= $absentAdmin ? 'Abteilungen der übernommenen Tickets' : ($deptNames ? e(implode(', ', $deptNames)) : '–') ?></td>
<td>
<?php if (vertretung_can_manage($staff, (int) $a['staff_id'])): ?>
<form method="post" style="display:inline" onsubmit="return confirm('Abwesenheit beenden? Offene Tickets gehen zurück.')"><?= csrf_field() ?><input type="hidden" name="action" value="cancel"><input type="hidden" name="id" value="<?= (int) $a['id'] ?>"><button class="btn secondary" type="submit"><?= $a['status'] === 'active' ? 'Jetzt beenden' : 'Löschen' ?></button></form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php if ($past): ?>
<div class="card">
<h3>Frühere Abwesenheiten</h3>
<table style="width:100%">
<thead><tr><th>Wer</th><th>Vertretung</th><th>Zeitraum</th><th>Ergebnis</th><th>Weitergegeben</th></tr></thead>
<tbody>
<?php foreach ($past as $a): ?>
<tr><td><?= $name($a['staff_id']) ?></td><td><?= $name($a['substitute_id']) ?></td><td><?= e(vertretung_date((string) $a['start_date'])) ?> – <?= e(vertretung_date((string) $a['end_date'])) ?></td><td><?= e($labels[$a['status']] ?? $a['status']) ?></td><td><?= (int) $a['moved'] ?> Tickets</td></tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>