kimai-plugin-heatmap/Service/HeatmapService.php

69 lines
2.2 KiB
PHP

<?php
namespace KimaiPlugin\KimaiHeatmapBundle\Service;
use App\Entity\User;
use App\Repository\TimesheetRepository;
class HeatmapService
{
public function __construct(private readonly TimesheetRepository $repository)
{
}
/**
* @return array<int, array{date: string, hours: float, count: int}>
*/
public function getDailyAggregation(User $user, \DateTimeInterface $begin, \DateTimeInterface $end, ?int $projectId = null): array
{
$qb = $this->repository->createQueryBuilder('t');
$qb
->select('COALESCE(SUM(t.duration), 0) as duration')
->addSelect('COUNT(t.id) as count')
->addSelect('DATE(t.date) as day')
->andWhere($qb->expr()->between('t.date', ':begin', ':end'))
->andWhere($qb->expr()->eq('t.user', ':user'))
->andWhere($qb->expr()->isNotNull('t.end'))
->setParameter('begin', $begin->format('Y-m-d'))
->setParameter('end', $end->format('Y-m-d'))
->setParameter('user', $user)
->groupBy('day')
->orderBy('day', 'ASC')
;
if ($projectId !== null) {
$qb->andWhere($qb->expr()->eq('t.project', ':project'))
->setParameter('project', $projectId);
}
$results = $qb->getQuery()->getResult();
return array_map(function (array $row) {
return [
'date' => $row['day'],
'hours' => round((int) $row['duration'] / 3600, 2),
'count' => (int) $row['count'],
];
}, $results);
}
/**
* @return array<int, array{id: int, name: string}>
*/
public function getUserProjects(User $user): array
{
$qb = $this->repository->createQueryBuilder('t');
$qb->select('DISTINCT IDENTITY(t.project) as projectId, p.name')
->join('t.project', 'p')
->andWhere($qb->expr()->eq('t.user', ':user'))
->andWhere($qb->expr()->isNotNull('t.end'))
->setParameter('user', $user)
->orderBy('p.name', 'ASC');
return array_map(fn(array $row) => [
'id' => (int) $row['projectId'],
'name' => $row['name'],
], $qb->getQuery()->getResult());
}
}