feat: average marks per destination
addresses #869bgtynb
This commit is contained in:
@@ -118,6 +118,96 @@ class FeedbackRepository extends ServiceEntityRepository
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns overall average ratings grouped by normalized destination code and FeedbackSet.
|
||||
*
|
||||
* @return array{
|
||||
* destinations: array<string, array<int, array{average: float, count: int}>>,
|
||||
* feedbackSets: array<int, FeedbackSet>
|
||||
* }
|
||||
*/
|
||||
public function getAverageRatingsByDestinationAndFeedbackSet(
|
||||
?\DateTimeImmutable $dateFrom = null,
|
||||
?\DateTimeImmutable $dateTo = null,
|
||||
): array {
|
||||
$conn = $this->getEntityManager()->getConnection();
|
||||
|
||||
$sql = '
|
||||
SELECT
|
||||
CASE
|
||||
WHEN f.hotel_code LIKE \'SER%\' THEN SUBSTRING(f.hotel_code, 4, 3)
|
||||
ELSE SUBSTRING(f.hotel_code, 1, 3)
|
||||
END AS normalized_code,
|
||||
f.feedback_set_id,
|
||||
AVG(f.average_rating) AS avg_rating,
|
||||
COUNT(*) AS feedback_count
|
||||
FROM feedback f
|
||||
WHERE f.status = :status
|
||||
AND f.feedback_set_id IS NOT NULL
|
||||
AND f.hotel_code IS NOT NULL
|
||||
';
|
||||
|
||||
$params = ['status' => Feedback::STATUS_PUBLISHED];
|
||||
|
||||
if (null !== $dateFrom) {
|
||||
$sql .= ' AND f.assignment_date_from >= :dateFrom';
|
||||
$params['dateFrom'] = $dateFrom->format('Y-m-d');
|
||||
}
|
||||
|
||||
if (null !== $dateTo) {
|
||||
$sql .= ' AND f.assignment_date_to <= :dateTo';
|
||||
$params['dateTo'] = $dateTo->format('Y-m-d');
|
||||
}
|
||||
|
||||
$sql .= '
|
||||
GROUP BY normalized_code, f.feedback_set_id
|
||||
ORDER BY normalized_code, f.feedback_set_id
|
||||
';
|
||||
|
||||
$results = $conn->executeQuery($sql, $params)->fetchAllAssociative();
|
||||
|
||||
// Collect all feedback set IDs and fetch entities
|
||||
$feedbackSetIds = array_unique(array_column($results, 'feedback_set_id'));
|
||||
$feedbackSetRepository = $this->getEntityManager()->getRepository(FeedbackSet::class);
|
||||
$feedbackSets = [];
|
||||
|
||||
foreach ($feedbackSetIds as $id) {
|
||||
$feedbackSet = $feedbackSetRepository->find($id);
|
||||
if (null !== $feedbackSet) {
|
||||
$feedbackSets[$id] = $feedbackSet;
|
||||
}
|
||||
}
|
||||
|
||||
// Build pivot structure: destinations[code][feedbackSetId] = {average, count}
|
||||
$destinations = [];
|
||||
|
||||
foreach ($results as $row) {
|
||||
$code = $row['normalized_code'];
|
||||
$feedbackSetId = (int) $row['feedback_set_id'];
|
||||
|
||||
if (false === isset($feedbackSets[$feedbackSetId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false === isset($destinations[$code])) {
|
||||
$destinations[$code] = [];
|
||||
}
|
||||
|
||||
// Convert from percentage (stored as integer * 100) to 1-5 scale
|
||||
$destinations[$code][$feedbackSetId] = [
|
||||
'average' => round((float) $row['avg_rating'] / 100, 2),
|
||||
'count' => (int) $row['feedback_count'],
|
||||
];
|
||||
}
|
||||
|
||||
ksort($destinations);
|
||||
|
||||
return [
|
||||
'destinations' => $destinations,
|
||||
'feedbackSets' => $feedbackSets,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns average ratings per question index grouped by FeedbackSet.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user