191 lines
7.2 KiB
PHP
191 lines
7.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\NominationEnsembles;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\NominationEnsemble;
|
|
use App\Models\NominationEnsembleEntry;
|
|
use App\Models\School;
|
|
use App\Models\Student;
|
|
|
|
class ScobdaNominationEnsembleEntryController extends Controller implements NominationEnsembleEntryController
|
|
{
|
|
public function index()
|
|
{
|
|
$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'));
|
|
}
|
|
|
|
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 = '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()
|
|
{
|
|
|
|
// TODO: Verify the student being moved is from the users school
|
|
$validData = request()->validate([
|
|
'direction' => 'required|in:up,down',
|
|
'nominationId' => 'required|exists:App\Models\NominationEnsembleEntry,id',
|
|
]);
|
|
$direction = $validData['direction'];
|
|
$nomination = NominationEnsembleEntry::findOrFail($validData['nominationId']);
|
|
$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');
|
|
|
|
}
|
|
}
|