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, ]);