id)); if ($audition->hasFlag('seats_published')) { $publishedSeats = Seat::where('audition_id', $audition->id) ->join('ensembles', 'seats.ensemble_id', '=', 'ensembles.id') ->orderBy('ensembles.rank') ->orderBy('seats.seat') ->select('seats.*') ->with(['ensemble', 'entry.student.school']) ->get(); } else { $publishedSeats = false; } $ranker = app(RankAuditionEntries::class); // Get scored entries in order $scored_entries = $ranker($audition, 'seating'); $scored_entries->load(['student.doublers', 'student.school']); // Get unscored entries sorted by draw number $unscored_entries = $audition->entries() ->whereDoesntHave('totalScore') ->whereDoesntHave('flags', function ($query) { $query->where('flag_name', 'no_show'); }) ->whereDoesntHave('flags', function ($query) { $query->where('flag_name', 'failed_prelim'); }) ->with('student.school') ->orderBy('draw_number', 'asc') ->get(); // Get no show entries sorted by draw number $noshow_entries = $audition->entries() ->whereDoesntHave('totalScore') ->whereHas('flags', function ($query) { $query->where('flag_name', 'no_show'); }) ->with('student.school') ->orderBy('draw_number', 'asc') ->get(); // Get failed prelim entries sorted by draw number $failed_prelim_entries = $audition->entries() ->whereDoesntHave('totalScore') ->whereHas('flags', function ($query) { $query->where('flag_name', 'failed_prelim'); }) ->with('student.school') ->orderBy('draw_number', 'asc') ->get(); // Get Doublers $doublerData = Doubler::where('event_id', $audition->event_id) ->whereIn('student_id', $scored_entries->pluck('student_id')) ->get() ->keyBy('student_id'); $auditionHasUnresolvedDoublers = false; foreach ($doublerData as $doubler) { if (! is_null($doubler->accepted_entry)) { continue; } foreach ($doubler->entries() as $entry) { if ($entry->audition_id === $audition->id && $entry->hasFlag('declined')) { continue 2; } } $auditionHasUnresolvedDoublers = true; } $canSeat = ! $auditionHasUnresolvedDoublers && $unscored_entries->count() === 0; return view('tabulation.auditionSeating', compact('audition', 'scored_entries', 'unscored_entries', 'noshow_entries', 'failed_prelim_entries', 'doublerData', 'auditionHasUnresolvedDoublers', 'canSeat', 'seatingProposal', 'publishedSeats', ) ); } public function declineSeat(Audition $audition, Entry $entry) { $entry->addFlag('declined'); Cache::forget('rank_seating_'.$entry->audition_id); return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success', $entry->student->full_name().' has declined '.$audition->name); } public function massDecline(Audition $audition) { $validData = request()->validate([ 'decline-below' => ['required', 'integer', 'min:0'], ]); $ranker = app(RankAuditionEntries::class); // Get scored entries in order $scored_entries = $ranker($audition, 'seating'); $scored_entries->load(['student.doublers', 'student.school']); foreach ($scored_entries as $entry) { Debugbar::info('Starting entry '.$entry->student->full_name()); if ($entry->hasFlag('declined')) { Debugbar::info('Skipping '.$entry->student->full_name().' because they have already been declined'); continue; } if (! $entry->student->isDoublerInEvent($audition->event_id)) { Debugbar::info('Skipping '.$entry->student->full_name().' because they are not a doubler'); continue; } if ($entry->student->doublers->where('event_id', $audition->event_id)->first()->accepted_entry) { Debugbar::info('Skipping '.$entry->student->full_name().' because they have already accepted a seat'); continue; } $entry->addFlag('declined'); } Cache::forget('rank_seating_'.$entry->audition_id); return redirect()->route('seating.audition', ['audition' => $audition->id]); } public function acceptSeat( Audition $audition, Entry $entry ) { $doublerData = Doubler::findDoubler($entry->student_id, $audition->event_id); foreach ($doublerData->entries() as $doublerEntry) { if (! $doublerEntry->totalScore && ! $doublerEntry->hasFlag('declined') && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim')) { return redirect()->route('seating.audition', ['audition' => $audition->id])->with('error', 'Cannot accept seating for '.$entry->student->full_name().' because student has unscored entries'); } } foreach ($doublerData->entries() as $doublerEntry) { Cache::forget('rank_seating_'.$doublerEntry->audition_id); if ($doublerEntry->id !== $entry->id && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim') && ! $doublerEntry->hasFlag('declined')) { $doublerEntry->addFlag('declined'); } } return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success', $entry->student->full_name().' has accepted '.$audition->name); } public function noshow( Audition $audition, Entry $entry ) { $recorder = app('App\Actions\Tabulation\EnterNoShow'); try { $msg = $recorder($entry); } catch (AuditionAdminException $e) { return redirect()->back()->with('error', $e->getMessage()); } return redirect()->route('seating.audition', [$audition])->with('success', $msg); } public function draftSeats( Audition $audition, Request $request ) { $ranker = app(RankAuditionEntries::class); $validated = $request->validate([ 'ensemble' => ['required', 'array'], 'ensemble.*' => ['required', 'integer', 'min:0'], ]); $proposedSeatingArray = []; $rankedEntries = $ranker($audition, 'seating'); $rankedEntries = $rankedEntries->reject(function ($entry) { return $entry->hasFlag('declined'); }); $rankedEntries->load(['student.school']); $rankedEnembles = Ensemble::orderBy('rank')->where('event_id', $audition->event_id)->get(); $ensembleRankOn = 1; foreach ($rankedEnembles as $ensemble) { if (! Arr::has($validated['ensemble'], $ensemble->id)) { continue; } $proposedSeatingArray[$ensembleRankOn]['ensemble_id'] = $ensemble->id; $proposedSeatingArray[$ensembleRankOn]['ensemble_name'] = $ensemble->name; $proposedSeatingArray[$ensembleRankOn]['accept_count'] = $validated['ensemble'][$ensemble->id]; for ($n = 1; $n <= $validated['ensemble'][$ensemble->id]; $n++) { // Escape the loop if we're out of entries if ($rankedEntries->isEmpty()) { break; } $thisEntry = $rankedEntries->shift(); $proposedSeatingArray[$ensembleRankOn]['seats'][$n]['seat'] = $n; $proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_id'] = $thisEntry->id; $proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_name'] = $thisEntry->student->full_name(); $proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_school'] = $thisEntry->student->school->name; } $ensembleRankOn++; } $sessionKeyName = 'proposedSeatingArray-'.$audition->id; $request->session()->put($sessionKeyName, $proposedSeatingArray, 10); return redirect()->route('seating.audition', ['audition' => $audition->id]); } public function clearDraft( Audition $audition ) { session()->forget('proposedSeatingArray-'.$audition->id); return redirect()->route('seating.audition', ['audition' => $audition->id]); } public function publishSeats( Audition $audition ) { $publisher = app('App\Actions\Tabulation\PublishSeats'); $seatingProposal = (session('proposedSeatingArray-'.$audition->id)); $proposal = []; foreach ($seatingProposal as $ensemble) { $ensembleId = $ensemble['ensemble_id']; if (isset($ensemble['seats'])) { foreach ($ensemble['seats'] as $seat) { $proposal[] = [ 'ensemble_id' => $ensembleId, 'audition_id' => $audition->id, 'seat' => $seat['seat'], 'entry_id' => $seat['entry_id'], ]; } } } $publisher($audition, $proposal); session()->forget('proposedSeatingArray-'.$audition->id); return redirect()->route('seating.audition', [$audition]); } public function unpublishSeats( Audition $audition ) { $unpublisher = app('App\Actions\Tabulation\UnpublishSeats'); $unpublisher($audition); session()->forget('proposedSeatingArray-'.$audition->id); return redirect()->route('seating.audition', [$audition]); } protected function pickRightPanel( Audition $audition, array $seatable ) { if ($audition->hasFlag('seats_published')) { $resultsWindow = new GetAuditionSeats; $rightPanel['view'] = 'tabulation.auditionSeating-show-published-seats'; $rightPanel['data'] = $resultsWindow($audition); return $rightPanel; } if ($seatable['allScored'] == false || $seatable['doublersResolved'] == false) { $rightPanel['view'] = 'tabulation.auditionSeating-unable-to-seat-card'; $rightPanel['data'] = $seatable; return $rightPanel; } $rightPanel['view'] = 'tabulation.auditionSeating-right-complete-not-published'; $rightPanel['data'] = $this->auditionService->getSeatingLimits($audition); return $rightPanel; } }