entryService = $entryService; $this->auditionService = $auditionService; } /** * returns a collection of doublers for the event in the form of * [studentId => [student=>student, entries=>[entries]] */ public function doublersForEvent(Event $event, string $mode = 'seating') { $cacheKey = 'event'.$event->id.'doublers-'.$mode; return Cache::remember($cacheKey, 60, function () use ($event, $mode) { return $this->findDoublersForEvent($event, $mode); }); } /** * @throws TabulationException */ protected function findDoublersForEvent(Event $event, string $mode = 'seating'): array { // TODO add scoped entry queries to the event model $this->validateEvent($event); $entries = $event->entries()->with('audition')->with('student')->get(); $entries = match ($mode) { 'seating' => $entries->filter(fn ($entry) => $entry->for_seating === 1), 'advancement' => $entries->filter(fn ($entry) => $entry->for_advance === 1), }; $grouped = $entries->groupBy('student_id'); // Filter out student groups with only one entry in the event $grouped = $grouped->filter(fn ($s) => $s->count() > 1); $doubler_array = []; foreach ($grouped as $student_id => $entries) { $doubler_array[$student_id] = [ 'student_id' => $student_id, 'entries' => $entries, ]; } return $doubler_array; } public function simpleDoubleInfo(Entry $primaryEntry) { if (! isset($this->findDoublersForEvent($primaryEntry->audition->event)[$primaryEntry->student_id])) { return false; } return $this->findDoublersForEvent($primaryEntry->audition->event)[$primaryEntry->student_id]['entries']; } public function entryDoublerData(Entry $primaryEntry) { if (! isset($this->doublersForEvent($primaryEntry->audition->event)[$primaryEntry->student_id])) { return false; } $entries = $this->doublersForEvent($primaryEntry->audition->event)[$primaryEntry->student_id]['entries']; $entryData = collect([]); /** @var Collection $entries */ foreach ($entries as $entry) { $status = 'undecided'; if ($entry->hasFlag('declined')) { $status = 'declined'; } if ($entry->hasFlag('no_show')) { $status = 'no_show'; } $lims = $this->auditionService->getSeatingLimits($entry->audition); $limits = []; foreach ($lims as $lim) { $limits[] = [ 'ensemble_name' => $lim['ensemble']->name, 'accepts' => $lim['limit'], 'ensemble' => $lim['ensemble'], ]; } $entryData[$entry->id] = [ 'entry' => $entry, 'audition' => $entry->audition, 'auditionName' => $entry->audition->name, 'status' => $status, 'rank' => $this->entryService->rankOfEntry('seating', $entry), 'unscored_entries' => $entry->audition->unscored_entries_count, 'seating_limits' => $limits, ]; } // find out how many items in the collection $entryData have a status of 'undecided' $undecided_count = $entryData->filter(fn ($entry) => $entry['status'] === 'undecided')->count(); // if $undecided_count is 1 set the item where status is 'undecided' to 'accepted' if ($undecided_count === 1) { $entryData->transform(function ($entry) { if ($entry['status'] === 'undecided') { $entry['status'] = 'accepted'; } return $entry; }); } return $entryData; } /** * @throws TabulationException */ protected function validateEvent(Event $event) { if (! $event->exists) { throw new TabulationException('Invalid event provided'); } } }