auditionCacheService = $scoringGuideCacheService; } public function getScoredEntries() { return Cache::remember($this->cacheKey, 10, function () { $entries = Entry::with(['scoreSheets'])->get(); return $entries->keyBy('id'); }); } public function auditionEntries(Int $auditionId) { $cache_key = 'audition'.$auditionId.'entries'; $audition = $this->auditionCacheService->getAudition($auditionId); return Cache::remember($cache_key, 2, function () use ($audition) { $entries = Entry::where('audition_id',$audition->id)->with(['student.school','scoreSheets'])->get(); foreach ($entries as $entry) { $entry->final_score_array = $this->entryFinalScores($entry); } for ($n=0; $n <= $audition->judges_count; $n++) { $entries = $entries->sortByDesc(function ($entry) use ($n) { return $entry['final_score_array'][$n]; }); } //TODO verify this actually sorts by subscores correcty return $entries; }); } /** * @throws TabulationException */ public function entryFinalScores(Entry $entry) { $audition = $this->auditionCacheService->getAudition($entry->audition_id); $this->validateEntryScoreSheets($entry); $subscores = $audition->scoringGuide->subscores->sortBy('tiebreak_order'); $finalScoresArray = []; foreach($subscores as $subscore) { $finalScoresArray[$subscore->id] = 0; } foreach ($entry->scoreSheets as $sheet) { foreach ($sheet->subscores as $ss) { $finalScoresArray[$ss['subscore_id']] += $ss['score']; } } // calculate weighted final score $totalScore = 0; $totalWeight = 0; foreach ($subscores as $subscore) { $totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight); $totalWeight += $subscore->weight; } $totalScore = ($totalScore / $totalWeight); array_unshift($finalScoresArray,$totalScore); return $finalScoresArray; } /** * @throws TabulationException */ public function validateEntryScoreSheets(Entry $entry): bool { $audition = $this->auditionCacheService->getAudition($entry->audition_id); foreach ($entry->scoreSheets as $sheet) { if (! $audition->judges->contains($sheet->user_id)) { $invalidJudge = User::find($sheet->user_id); throw new TabulationException('Invalid scores for entry ' . $entry->id . ' exist from ' . $invalidJudge->full_name()); } } return true; } public function getAuditionsWithStatus() { // Create an array with the number of scores for each entry $scoreCountByEntry = ScoreSheet::select('entry_id', DB::raw('count(*) as count')) ->groupBy('entry_id') ->get() ->pluck('count','entry_id'); // Retrieve auditions from the cache and load entry IDs $auditions = $this->auditionCacheService->getAuditions(); $auditions->load('entries'); // Eager load the count of related models $auditions->loadCount(['judges', 'entries']); // Iterate over the auditions and calculate the scored_entries_count return $auditions->map(function ($audition) use ($scoreCountByEntry) { $audition->scored_entries_count = $audition->entries->reduce(function ($carry, $entry) use ($audition, $scoreCountByEntry) { $entry->fully_scored = $audition->judges_count == $scoreCountByEntry[$entry->id]; return $carry + ($entry->fully_scored ? 1 : 0); }, 0); return $audition; }); } }