auditionService = $auditionService; $this->tabulationService = $tabulationService; $this->seatingService = $seatingService; } /** * Returns a collection of students that have more than one entry */ public function getDoublers(): \Illuminate\Database\Eloquent\Collection { // TODO creating or destroying an entry should refresh the doubler cache // TODO needs to split by event so that a doubler may enter jazz and concert events for example $doublers = Cache::remember($this->doublersCacheKey, 60, function () { return Student::withCount(['entries' => function (Builder $query) { $query->where('for_seating', true); }]) ->with(['entries' => function (Builder $query) { $query->where('for_seating', true); }]) ->havingRaw('entries_count > ?', [1]) ->get(); }); return $doublers; } public function refreshDoublerCache() { Cache::forget($this->doublersCacheKey); $this->getDoublers(); } /** * Returns an array of information about each entry for a specific doubler. Info for each entry includes * entryID * auditionID * auditionName * rank => This student's rank in the given audition * unscored => How many entries remain to be scored in this audition * limits => acceptance limits for this audition * status => accepted, declined, or undecided * * @param int $studentId The ID of the doubler */ public function getDoublerInfo($studentId): array { $doubler = $this->getDoublers()->firstWhere('id', $studentId); // Split $doubler->entries into two arrays based on the result of hasFlag('declined') $undecidedEntries = $doubler->entries->filter(function ($entry) { return ! $entry->hasFlag('declined'); }); $acceptedEntry = null; if ($undecidedEntries->count() == 1) { $acceptedEntry = $undecidedEntries->first(); } // TODO can I rewrite this? // When getting a doubler we need to know // 1) What their entries are // 2) For each audition they're entered in, what is their rank // 3) For each audition they're entered in, how many entries are unscored // 4) How many are accepted on that instrument // 5) Status - accepted, declined or undecided $info = []; foreach ($doubler->entries as $entry) { if ($entry->hasFlag('declined')) { $status = 'declined'; } elseif ($entry === $acceptedEntry) { $status = 'accepted'; } else { $status = 'undecided'; } $info[$entry->id] = [ 'entryID' => $entry->id, 'auditionID' => $entry->audition_id, 'auditionName' => $this->auditionService->getAudition($entry->audition_id)->name, 'rank' => $this->tabulationService->entryRank($entry), 'unscored' => $this->tabulationService->remainingEntriesForAudition($entry->audition_id), 'limits' => $this->seatingService->getLimitForAudition($entry->audition_id), 'status' => $status, ]; $entry->audition = $this->auditionService->getAudition($entry->audition_id); } return $info; } /** * Checks if a student is a doubler based on the given student ID * * @param int $studentId The ID of the student to check * @return bool Returns true if the student is a doubler, false otherwise */ public function studentIsDoubler($studentId): bool { return $this->getDoublers()->contains('id', $studentId); } }