feat: feedback statistics
addresses #869bgtz2d
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user