56 lines
1.9 KiB
PHP
56 lines
1.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/common.php';
|
|
|
|
api_require_method('GET');
|
|
$staff = api_require_staff();
|
|
api_require_admin_or_permission($staff, 'view_time_entries');
|
|
$pdo = get_db();
|
|
|
|
$filterStaffId = trim((string) ($_GET['staffId'] ?? ''));
|
|
$filterFrom = trim((string) ($_GET['from'] ?? '')) ?: date('Y-m-01');
|
|
$filterTo = trim((string) ($_GET['to'] ?? '')) ?: date('Y-m-d');
|
|
|
|
$allStaff = $pdo->query('SELECT id, name FROM staff WHERE is_active=1 ORDER BY name')->fetchAll();
|
|
|
|
$where = ['te.logged_at BETWEEN ? AND ?'];
|
|
$params = [$filterFrom . ' 00:00:00', $filterTo . ' 23:59:59'];
|
|
|
|
if ($filterStaffId !== '') {
|
|
$where[] = 'te.staff_id = ?';
|
|
$params[] = (int) $filterStaffId;
|
|
}
|
|
|
|
$stmt = $pdo->prepare(
|
|
"SELECT te.*, s.name AS staff_name, t.ticket_number, t.subject
|
|
FROM ticket_time_entries te
|
|
JOIN staff s ON s.id = te.staff_id
|
|
JOIN tickets t ON t.id = te.ticket_id
|
|
WHERE " . implode(' AND ', $where) . "
|
|
ORDER BY te.logged_at DESC
|
|
LIMIT 500"
|
|
);
|
|
$stmt->execute($params);
|
|
$entries = $stmt->fetchAll();
|
|
|
|
$byStaff = [];
|
|
foreach ($entries as $e) {
|
|
$byStaff[$e['staff_name']] = ($byStaff[$e['staff_name']] ?? 0) + (int) $e['minutes'];
|
|
}
|
|
$totalMinutes = array_sum(array_column($entries, 'minutes'));
|
|
|
|
api_json([
|
|
'staffOptions' => array_map(fn(array $s) => ['id' => (int) $s['id'], 'name' => $s['name']], $allStaff),
|
|
'entries' => array_map(fn(array $e) => [
|
|
'id' => (int) $e['id'],
|
|
'staffName' => $e['staff_name'],
|
|
'ticketNumber' => $e['ticket_number'],
|
|
'subject' => $e['subject'],
|
|
'minutes' => (int) $e['minutes'],
|
|
'note' => $e['note'],
|
|
'loggedAt' => $e['logged_at'],
|
|
], $entries),
|
|
'totalsByStaff' => array_map(fn($name, $mins) => ['staffName' => $name, 'minutes' => $mins], array_keys($byStaff), array_values($byStaff)),
|
|
'totalMinutes' => $totalMinutes,
|
|
]);
|