get('shirtReportType') ?? 'none'; $ensembles = NominationEnsemble::all(); $ensemble = null; $shirtCounts = ($shirtReportType == 'full') ? $this->totalShirtCount() : null; $schoolShirtCounts = ($shirtReportType == 'by_school') ? $this->schoolShirtCount() : null; $shirtSizes = Student::$shirtSizes; $schools = School::all(); return view('nomination_ensembles.scobda.admin.seating.index', compact('ensembles', 'ensemble', 'shirtReportType', 'shirtCounts', 'schoolShirtCounts', 'shirtSizes', 'schools')); } protected function totalShirtCount() { $acceptedNominationEntries = NominationEnsembleEntry::where('data->accepted', true)->with('student')->get(); $possibleSizes = Student::$shirtSizes; $shirtCounts = ['none' => 0]; foreach ($possibleSizes as $shortSize => $size) { $shirtCounts[$shortSize] = 0; } foreach ($acceptedNominationEntries as $entry) { $shirtSize = $entry->student->optional_data['shirt_size'] ?? 'none'; $shirtCounts[$shirtSize] += 1; } return $shirtCounts; } /** * @return array an array of school ids, each containing and array where the key is a shirt size and the value is the count */ protected function schoolShirtCount(): array { $acceptedNominationEntries = NominationEnsembleEntry::where('data->accepted', true) ->with('student.school') ->get(); $schoolShirtCounts = []; foreach ($acceptedNominationEntries as $entry) { $shirtSize = $entry->student->optional_data['shirt_size'] ?? 'none'; $schoolId = $entry->student->school->id; if (! isset($schoolShirtCounts[$schoolId])) { $schoolShirtCounts[$schoolId] = []; } $schoolShirtCounts[$schoolId][$shirtSize] = ($schoolShirtCounts[$schoolId][$shirtSize] ?? 0) + 1; } return $schoolShirtCounts; } public function show(NominationEnsemble $ensemble) { $shirtReportType = request()->get('shirtReportType') ?? 'none'; $ensembles = NominationEnsemble::all(); $acceptedNominations = NominationEnsembleEntry::where('nomination_ensemble_id', $ensemble->id) ->where('data->accepted', true) ->orderByRaw('CAST(data->"$.rank" AS UNSIGNED)') ->get(); $acceptedNominations = $acceptedNominations->groupBy(function ($item) { return $item->data['instrument']; }); return view('nomination_ensembles.scobda.admin.seating.index', compact('ensembles', 'ensemble', 'acceptedNominations', 'shirtReportType')); } public function seat(NominationEnsemble $ensemble) { $nominations = NominationEnsembleEntry::where('nomination_ensemble_id', $ensemble->id)->orderByRaw('CAST(data->"$.rank" AS UNSIGNED)')->inRandomOrder()->get(); $rankGroupedNominations = $nominations->groupBy(function ($entry) { return $entry->data['rank']; }); $validData = request()->validate([ 'action' => ['required', 'in:seat,clear'], ]); $action = $validData['action']; if ($action == 'clear') { foreach ($nominations as $nomination) { $data = $nomination->data; unset($data['accepted']); $nomination->update(['data' => $data]); } $data = $ensemble->data; $data['seated'] = false; $ensemble->data = $data; $ensemble->update(); return redirect()->route('nomination.admin.seating.show', ['ensemble' => $ensemble])->with('Seating Cleared'); } $acceptedNominations = collect(); $rankOn = 1; // Collect students to add to the ensemble while ($rankOn <= $ensemble->data['max_nominations'] && $rankGroupedNominations->has($rankOn)) { // If were at or over the target size of the ensemble, stop adding people if ($acceptedNominations->count() >= $ensemble->data['target_size']) { break; } // Add people of the current rank to the ensemble foreach ($rankGroupedNominations[$rankOn] as $nomination) { $acceptedNominations->push($nomination); } $rankOn++; // If we want to round down the ensemble size, quit adding people if hte next rank will exceed the target if ( $rankGroupedNominations->has($rankOn) && $acceptedNominations->count() + $rankGroupedNominations[$rankOn]->count() >= $ensemble->data['target_size'] && $ensemble->data['rounding_direction'] === 'down' ) { break; } } foreach ($acceptedNominations as $nomination) { $data = $nomination->data; $data['accepted'] = true; $nomination->update(['data' => $data]); } $data = $ensemble->data; $data['seated'] = true; $ensemble->data = $data; $ensemble->update(); return redirect()->route('nomination.admin.seating.show', ['ensemble' => $ensemble])->with('Seating Complete'); } }