feat: feedback statistics

addresses #869bgtz2d
This commit is contained in:
Björn Fromme
2025-12-23 14:54:27 +01:00
parent 2fb4fd750b
commit cdfd172a1e
16 changed files with 745 additions and 4 deletions
+100
View File
@@ -3,6 +3,7 @@
namespace App\Repository;
use App\Entity\Feedback;
use App\Entity\FeedbackSet;
use App\Entity\Teamer;
use App\Model\FeedbackFilterDto;
use App\Repository\Traits\QueryHelperTrait;
@@ -116,4 +117,103 @@ class FeedbackRepository extends ServiceEntityRepository
->getResult()
;
}
/**
* Returns average ratings per question index grouped by FeedbackSet.
*
* @return array<int, array{
* feedbackSet: FeedbackSet,
* averages: array<int, float>,
* count: int
* }>
*/
public function getAverageRatingsByQuestionAndFeedbackSet(
?\DateTimeImmutable $dateFrom = null,
?\DateTimeImmutable $dateTo = null,
): array {
$qb = $this->createQueryBuilder('f');
$qb
->select('f.ratings', 'IDENTITY(f.feedbackSet) AS feedbackSetId')
->where('f.status = :status')
->andWhere('f.feedbackSet IS NOT NULL')
->setParameter('status', Feedback::STATUS_PUBLISHED)
;
if (null !== $dateFrom) {
$qb
->andWhere($qb->expr()->gte('f.assignmentDateFrom', ':dateFrom'))
->setParameter('dateFrom', $dateFrom)
;
}
if (null !== $dateTo) {
$qb
->andWhere($qb->expr()->lte('f.assignmentDateTo', ':dateTo'))
->setParameter('dateTo', $dateTo)
;
}
$results = $qb->getQuery()->getResult();
// Group by feedbackSet and calculate averages per question index
$grouped = [];
foreach ($results as $row) {
$feedbackSetId = $row['feedbackSetId'];
$ratings = $row['ratings'];
if (false === isset($grouped[$feedbackSetId])) {
$grouped[$feedbackSetId] = [
'sums' => [],
'counts' => [],
'totalCount' => 0,
];
}
foreach ($ratings as $index => $rating) {
if (false === isset($rating['mark'])) {
continue;
}
$mark = (float) $rating['mark'];
if (false === isset($grouped[$feedbackSetId]['sums'][$index])) {
$grouped[$feedbackSetId]['sums'][$index] = 0.0;
$grouped[$feedbackSetId]['counts'][$index] = 0;
}
$grouped[$feedbackSetId]['sums'][$index] += $mark;
++$grouped[$feedbackSetId]['counts'][$index];
}
++$grouped[$feedbackSetId]['totalCount'];
}
// Convert sums to averages and fetch FeedbackSet entities
$feedbackSetRepository = $this->getEntityManager()->getRepository(FeedbackSet::class);
$output = [];
foreach ($grouped as $feedbackSetId => $data) {
$feedbackSet = $feedbackSetRepository->find($feedbackSetId);
if (null === $feedbackSet) {
continue;
}
$averages = [];
foreach ($data['sums'] as $index => $sum) {
$count = $data['counts'][$index];
$averages[$index] = $count > 0 ? round($sum / $count, 2) : 0.0;
}
$output[] = [
'feedbackSet' => $feedbackSet,
'averages' => $averages,
'count' => $data['totalCount'],
];
}
return $output;
}
}