format('Y-m-d'); $ensembles = NominationEnsemble::all(); // populate an array with each ensemble id as a key. Each item will be a collection of students available to be nominated $availableStudents = []; // populate an array with each ensemble id as a key. Each item will be a collection of available instruments $availableInstruments = []; // populate an array with each ensemble id as a key. Each item will be a collection of nominationEntries already made $nominatedStudents = []; // an array of bool values with each ensemble id as a key. It will be true if additional nominations are available $nominationsAvailable = []; foreach ($ensembles as $ensemble) { // Gather a collection of students who may be nominated for this ensemble $availableStudents[$ensemble->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', 'currentDate')); } 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']); $currentDate = Carbon::now('America/Chicago'); $currentDate = $currentDate->format('Y-m-d'); if ($proposedEnsemble->entry_deadline < $currentDate) { return redirect()->route('nomination.entry.index')->with('error', 'The nomination deadline for that ensemble has passed'); } 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'); } $currentDate = Carbon::now('America/Chicago'); $currentDate = $currentDate->format('Y-m-d'); if ($entry->ensemble->entry_deadline < $currentDate) { return redirect()->route('nomination.entry.index')->with('error', 'You cannot delete nominations after the deadline'); } $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 = 'next') { $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; } public function move() { $validData = request()->validate([ 'direction' => 'required|in:up,down', 'nominationId' => 'required|exists:App\Models\NominationEnsembleEntry,id', ]); $direction = $validData['direction']; $nomination = NominationEnsembleEntry::findOrFail($validData['nominationId']); // Verify the entry deadline for the ensemble has not passed $currentDate = Carbon::now('America/Chicago'); $currentDate = $currentDate->format('Y-m-d'); if ($nomination->ensemble->entry_deadline < $currentDate) { return redirect()->route('nomination.entry.index')->with('error', 'The entry deadline for that nomination ensemble has passed'); } // Verify the student being moved is from the users school if (auth()->user()->school_id !== $nomination->student_id) { return redirect()->route('nomination.entry.index')->with('error', 'You cannot modify nominations of another school'); } $data = $nomination->data; if ($validData['direction'] == 'up') { $data['rank'] = $nomination->data['rank'] - 1.5; } if ($validData['direction'] == 'down') { $data['rank'] = $nomination->data['rank'] + 1.5; } $nomination->update(['data' => $data]); $this->collapseNominations($nomination->student->school, $nomination->ensemble, 'next'); return redirect()->route('nomination.entry.index')->with('success', 'Nomination Moved'); } }