id] = Student::where('grade', '<=', $ensemble->maximum_grade) ->where('grade', '>=', $ensemble->minimum_grade) ->where('school_id', auth()->user()->school_id) ->orderBy('last_name') ->orderBy('first_name') ->get(); $availableInstruments[$ensemble->id] = $ensemble->data['instruments']; $nominatedStudents[$ensemble->id] = $this->collapseNominations(auth()->user()->school, $ensemble, 'nominations'); $nominatedStudentIds = []; // Removed students already nominated from available students foreach ($nominatedStudents[$ensemble->id] as $nominatedStudent) { $nominatedStudentIds[] = $nominatedStudent->student_id; } $availableStudents[$ensemble->id] = $availableStudents[$ensemble->id]->reject(function ($student) use ( $nominatedStudentIds ) { return in_array($student->id, $nominatedStudentIds); }); $nominationsAvailable[$ensemble->id] = $ensemble->data['max_nominations'] > count($nominatedStudents[$ensemble->id]); } return view('nomination_ensembles.scobda.entries.index', compact('ensembles', 'availableStudents', 'availableInstruments', 'nominatedStudents', 'nominationsAvailable')); } public function show(NominationEnsembleEntry $entry) { // TODO: Implement show() method. } public function create() { // TODO: Implement create() method. } public function store() { $validData = request()->validate([ 'ensemble' => [ 'required', 'exists:App\Models\NominationEnsemble,id', ], 'new_student' => [ 'required', 'exists:App\Models\Student,id', ], 'new_instrument' => 'required', ]); if (NominationEnsembleEntry::where('student_id', $validData['new_student']) ->where('nomination_ensemble_id', $validData['ensemble']) ->count() > 0) { return redirect()->route('nomination.entry.index')->with('error', 'Student already nominated for that ensemble'); } $proposedEnsemble = NominationEnsemble::find($validData['ensemble']); if (! in_array($validData['new_instrument'], $proposedEnsemble->data['instruments'])) { return redirect()->route('nomination.entry.index')->with('error', 'Invalid Instrument specified'); } $student = Student::find($validData['new_student']); if (auth()->user()->school_id !== $student->school_id) { return redirect()->route('nomination.entry.index')->with('error', 'You may only nominate students from your school'); } $nextRank = $this->collapseNominations($student->school, $proposedEnsemble, 'next'); if ($nextRank > $proposedEnsemble->data['max_nominations']) { return redirect()->route('nomination.entry.index')->with('error', 'You have already used all of your nominations'); } $entry = new NominationEnsembleEntry(); $entry->student_id = $validData['new_student']; $entry->nomination_ensemble_id = $validData['ensemble']; $data = []; $data['rank'] = $nextRank; $data['instrument'] = $validData['new_instrument']; $entry->data = $data; $entry->save(); return redirect()->route('nomination.entry.index')->with('success', 'Nomination Recorded'); } public function edit(NominationEnsembleEntry $entry) { // TODO: Implement edit() method. } public function update(NominationEnsembleEntry $entry) { // TODO: Implement update() method. } public function destroy(NominationEnsembleEntry $entry) { if ($entry->student->school_id !== auth()->user()->school_id) { return redirect()->route('nomination.entry.index')->with('error', 'You may only delete nominations from your school'); } $entry->delete(); return redirect()->route('nomination.entry.index')->with('success', 'Nomination Deleted'); } /** * Given a school and nomination ensemble, consolidate the rank valuek * * if returnType is next, the next available rank will be returned * if returnType is nominations, a collection of nominations will be returned * * @return int|array * * @var returnType = next|nominations */ private function collapseNominations(School $school, NominationEnsemble $ensemble, $returnType) { $nominations = $school->nominations()->get()->where('nomination_ensemble_id', $ensemble->id)->sortBy('data.rank'); $n = 1; foreach ($nominations as $nomination) { $nomination->update(['data->rank' => $n]); $n++; } if ($returnType == 'next') { return $n; } return $nominations; } }