auditionCacheService = $scoringGuideCacheService; $this->scoreService = $scoreService; $this->entryCacheService = $entryCacheService; } /** * Returns the rank of the entry in its audition * * @return mixed */ public function entryRank(Entry $entry) { return $this->auditionEntries($entry->audition_id)[$entry->id]->rank; } /** * Returns a collection of entries including their calculated final_score_array and ranked * based upon their scores. * * @return \Illuminate\Support\Collection|mixed */ public function auditionEntries(int $auditionId, $mode = 'seating') { static $cache = []; if (isset($cache[$auditionId])) { return $cache[$auditionId]; } $audition = $this->auditionCacheService->getAudition($auditionId); $entries = $this->entryCacheService->getEntriesForAudition($auditionId, $mode); $this->scoreService->calculateScoresForAudition($auditionId); foreach ($entries as $entry) { $entry->final_score_array = $this->scoreService->entryTotalScores($entry); $entry->scoring_complete = ($this->scoreService->entryScoreSheetCounts()[$entry->id] == $audition->judges_count); } // Sort the array $entries by the first element in the final_score_array on each entry, then by the second element in that array continuing through each element in the final_score_array for each entry $entries = $entries->sort(function ($a, $b) { for ($i = 0; $i < count($a->final_score_array); $i++) { if ($a->final_score_array[$i] != $b->final_score_array[$i]) { return $b->final_score_array[$i] > $a->final_score_array[$i] ? 1 : -1; } } return 0; }); //TODO verify this actually sorts by subscores correctly $n = 1; /** @var Entry $entry */ foreach ($entries as $entry) { if (! $entry->hasFlag('declined')) { $entry->rank = $n; $n++; } else { $entry->rank = $n.' - declined'; } } $cache[$auditionId] = $entries->keyBy('id'); return $entries->keyBy('id'); } public function entryScoreSheetsAreValid(Entry $entry): bool { //TODO consider making this move the invalid score to another database for further investigation $validJudges = $this->auditionCacheService->getAudition($entry->audition_id)->judges; foreach ($entry->scoreSheets as $sheet) { if (! $validJudges->contains($sheet->user_id)) { $invalidJudge = User::find($sheet->user_id); Session::flash('error', 'Invalid scores for entry '.$entry->id.' exist from '.$invalidJudge->full_name()); return false; } } return true; } /** * Returns the number of un-scored entries for the audition with the given ID. * * @return mixed */ public function remainingEntriesForAudition($auditionId, $mode = 'seating') { $audition = $this->getAuditionsWithStatus($mode)[$auditionId]; switch ($mode) { case 'seating': return $audition->seating_entries_count - $audition->scored_entries_count; case 'advancement': return $audition->advancement_entries_count - $audition->scored_entries_count; } return $audition->entries_count - $audition->scored_entries_count; } /** * Get the array of all auditions from the cache. For each one, set a property * scored_entries_count that indicates the number of entries for that audition that * have a number of score sheets equal to the number of judges for that audition. * * @return mixed */ public function getAuditionsWithStatus($mode = 'seating') { return Cache::remember('auditionsWithStatus', 30, function () use ($mode) { // Retrieve auditions from the cache and load entry IDs $auditions = $this->auditionCacheService->getAuditions($mode); // Iterate over the auditions and calculate the scored_entries_count foreach ($auditions as $audition) { $scored_entries_count = 0; $entries_to_check = $this->entryCacheService->getEntriesForAudition($audition->id); switch ($mode) { case 'seating': $entries_to_check = $entries_to_check->filter(function ($entry) { return $entry->for_seating; }); $auditions = $auditions->filter(function ($audition) { return $audition->for_seating; }); break; case 'advancement': $entries_to_check = $entries_to_check->filter(function ($entry) { return $entry->for_advancement; }); $auditions = $auditions->filter(function ($audition) { return $audition->for_advancement; }); break; } foreach ($entries_to_check as $entry) { if ($this->scoreService->entryScoreSheetCounts()[$entry->id] - $audition->judges_count == 0) { $scored_entries_count++; } } $audition->scored_entries_count = $scored_entries_count; } return $auditions; }); } }