80 lines
3.2 KiB
PHP
80 lines
3.2 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
require_once __DIR__ . '/common.php';
|
||
|
||
/**
|
||
* api/staff/v1/availability.php
|
||
*
|
||
* Mobile-Pendant zu staff/availability.php (nur der Status-Teil, kein Schichtplan-
|
||
* Editor – der bleibt eine Web-Admin-Aufgabe). Gleiche staff_availability-Tabelle
|
||
* und dieselbe "keine Zeile = Offline"-Konvention wie im Web (siehe dort und
|
||
* live_chat_locked_by_other()/chat_any_staff_available() in includes/functions.php
|
||
* bzw. live_chat.php für die Stellen, die sich darauf verlassen).
|
||
*/
|
||
|
||
api_require_method('GET', 'POST');
|
||
$staff = api_require_staff();
|
||
$pdo = get_db();
|
||
|
||
const AVAILABILITY_STATUSES = ['available', 'busy', 'break', 'offline'];
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||
staff_run_auto_offline($pdo);
|
||
$agents = $pdo->query(
|
||
'SELECT s.id, s.name, s.is_on_vacation, s.last_active_at, sa.auto_offline, sa.status, sa.note, sa.updated_at
|
||
FROM staff s
|
||
LEFT JOIN staff_availability sa ON sa.staff_id = s.id
|
||
WHERE s.is_active = 1
|
||
ORDER BY s.name'
|
||
)->fetchAll();
|
||
|
||
$me = null;
|
||
$team = [];
|
||
foreach ($agents as $a) {
|
||
$entry = [
|
||
'id' => (int) $a['id'],
|
||
'name' => $a['name'],
|
||
'status' => $a['is_on_vacation'] ? 'offline' : ($a['status'] ?: 'offline'),
|
||
'note' => $a['is_on_vacation'] ? 'Urlaub' : ($a['note'] ?? ''),
|
||
'isOnVacation' => (bool) $a['is_on_vacation'],
|
||
'updatedAt' => $a['updated_at'],
|
||
'lastActiveAt' => $a['last_active_at'] ?? null,
|
||
'autoOffline' => !empty($a['auto_offline']),
|
||
];
|
||
$team[] = $entry;
|
||
if ((int) $a['id'] === (int) $staff['id']) {
|
||
// "Mein Status" fällt (wie im Web) auf "available" zurück, solange nie gesetzt –
|
||
// reine Anzeige-Vorauswahl, ändert nichts an der "Offline"-Team-Konvention oben.
|
||
$me = ['status' => $a['status'] ?: 'available', 'note' => $a['note'] ?? ''];
|
||
}
|
||
}
|
||
|
||
api_json(['myStatus' => $me['status'] ?? 'available', 'myNote' => $me['note'] ?? '', 'team' => $team]);
|
||
}
|
||
|
||
$body = api_request_body();
|
||
$newStatus = (string) ($body['status'] ?? '');
|
||
$note = trim((string) ($body['note'] ?? ''));
|
||
|
||
if (!in_array($newStatus, AVAILABILITY_STATUSES, true)) {
|
||
api_error(422, 'INVALID_STATUS', 'Ungültiger Status.');
|
||
}
|
||
|
||
// Ein Admin darf den Status eines anderen Mitarbeiters setzen (staffId), alle anderen nur den eigenen
|
||
$targetId = (int) $staff['id'];
|
||
if (isset($body['staffId']) && (int) $body['staffId'] !== $targetId) {
|
||
if (($staff['role'] ?? '') !== 'admin') {
|
||
api_error(403, 'FORBIDDEN', 'Nur Administratoren dürfen den Status anderer Mitarbeiter ändern.');
|
||
}
|
||
$targetId = (int) $body['staffId'];
|
||
$exists = $pdo->prepare('SELECT COUNT(*) FROM staff WHERE id = ? AND is_active = 1');
|
||
$exists->execute([$targetId]);
|
||
if ((int) $exists->fetchColumn() === 0) {
|
||
api_error(404, 'STAFF_NOT_FOUND', 'Mitarbeiter nicht gefunden.');
|
||
}
|
||
audit_log((int) $staff['id'], "Status von Mitarbeiter #$targetId auf $newStatus gesetzt");
|
||
}
|
||
staff_set_status($pdo, $targetId, $newStatus, $note);
|
||
staff_touch_activity($pdo, (int) $staff['id']);
|
||
api_json(['ok' => true, 'status' => $newStatus, 'staffId' => $targetId]);
|