*/ 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 */ 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()); } }