35 lines
1.1 KiB
PHP
35 lines
1.1 KiB
PHP
<?php
|
|||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
require_once __DIR__ . '/ReportDataMapper.php';
|
||
|
|
|
||
|
|
final class HoursPerClientReport
|
||
|
|
{
|
||
|
|
/** @param list<array<string, mixed>> $entries
|
||
|
|
* @return list<array{client_id:int, client_name:string, hours:float}>
|
||
|
|
*/
|
||
|
|
public function aggregate(array $entries): array
|
||
|
|
{
|
||
|
|
$totals = [];
|
||
|
|
foreach ($entries as $entry) {
|
||
|
|
$id = (int)($entry['client_id'] ?? 0);
|
||
|
|
$key = (string)$id;
|
||
|
|
if (!isset($totals[$key])) {
|
||
|
|
$totals[$key] = [
|
||
|
|
'client_id' => $id,
|
||
|
|
'client_name' => (string)($entry['client_name'] ?? ''),
|
||
|
|
'hours' => 0.0,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
$totals[$key]['hours'] += max(0.0, (float)($entry['hours'] ?? 0));
|
||
|
|
}
|
||
|
|
$rows = array_values($totals);
|
||
|
|
foreach ($rows as &$row) {
|
||
|
|
$row['hours'] = round($row['hours'], 2);
|
||
|
|
}
|
||
|
|
unset($row);
|
||
|
|
usort($rows, static fn (array $a, array $b): int => strcmp($a['client_name'], $b['client_name']) ?: $a['client_id'] <=> $b['client_id']);
|
||
|
|
return $rows;
|
||
|
|
}
|
||
|
|
}
|