Meobda nomination ensemble #107
|
|
@ -0,0 +1,172 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\NominationEnsembles;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\NominationEnsemble;
|
||||||
|
use App\Models\NominationEnsembleEntry;
|
||||||
|
use App\Models\Student;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
|
class MeobdaNominationEnsembleEntryController extends Controller implements NominationEnsembleEntryController
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
// Get current date for checking deadlines
|
||||||
|
$currentDate = Carbon::now('America/Chicago');
|
||||||
|
$currentDate = $currentDate->format('Y-m-d');
|
||||||
|
|
||||||
|
$ensembles = NominationEnsemble::all();
|
||||||
|
$availableInstruments = [];
|
||||||
|
$availableStudents = [];
|
||||||
|
$existingNominations = [];
|
||||||
|
$nominationsAvailable = [];
|
||||||
|
|
||||||
|
foreach ($ensembles as $ensemble) {
|
||||||
|
// Get existing nominations
|
||||||
|
$existingNominations[$ensemble->id] = auth()->user()->school->nominations()
|
||||||
|
->where('nomination_ensemble_id', $ensemble->id)
|
||||||
|
->get()
|
||||||
|
->keyBy('student_id');
|
||||||
|
// Count how many nominations exist on each instrument
|
||||||
|
$nominatedInstrumentCount = [];
|
||||||
|
foreach ($existingNominations[$ensemble->id] as $nom) {
|
||||||
|
$nominatedInstrumentCount[$nom->data['instrument']] =
|
||||||
|
($nominatedInstrumentCount[$nom->data['instrument']] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set available instruments
|
||||||
|
foreach ($ensemble->data['instruments'] as $instrument) {
|
||||||
|
// Skip it if we're at the limit on this instrument
|
||||||
|
if (! is_null($instrument['max']) && $instrument['max'] <= ($nominatedInstrumentCount[$instrument['name']] ?? 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$availableInstruments[$ensemble->id][] = $instrument['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set available students
|
||||||
|
$students = Student::where('school_id', auth()->user()->school_id)
|
||||||
|
->where('grade', '>=', $ensemble->minimum_grade)
|
||||||
|
->where('grade', '<=', $ensemble->maximum_grade)
|
||||||
|
->orderBy('last_name', 'asc')
|
||||||
|
->orderBy('first_name', 'asc')
|
||||||
|
->get();
|
||||||
|
foreach ($existingNominations[$ensemble->id] as $checknom) {
|
||||||
|
$students = $students->reject(function ($student) use ($checknom) {
|
||||||
|
return $checknom->student_id == $student->id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$availableStudents[$ensemble->id] = $students;
|
||||||
|
$nominationsAvailable[$ensemble->id] = $existingNominations[$ensemble->id]->count() < $ensemble->data['max_nominations'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('nomination_ensembles.meobda.entries.index',
|
||||||
|
compact('ensembles', 'currentDate', 'availableInstruments', 'availableStudents', 'existingNominations',
|
||||||
|
'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',
|
||||||
|
]);
|
||||||
|
$ensemble = NominationEnsemble::find($validData['ensemble']);
|
||||||
|
|
||||||
|
// Check that the deadline is not past
|
||||||
|
$currentDate = Carbon::now('America/Chicago');
|
||||||
|
$currentDate = $currentDate->format('Y-m-d');
|
||||||
|
if ($ensemble->entry_deadline < $currentDate) {
|
||||||
|
return redirect()->route('nomination.entry.index')->with('error',
|
||||||
|
'The nomination deadline for that ensemble has passed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if new_instrument is valid
|
||||||
|
foreach ($ensemble->data['instruments'] as $instrument) {
|
||||||
|
$availableInstruments[] = $instrument['name'];
|
||||||
|
}
|
||||||
|
if (! in_array($validData['new_instrument'], $availableInstruments)) {
|
||||||
|
return redirect()->route('nomination.entry.index')->with('error',
|
||||||
|
'Invalid Instrument Specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the student belongs to the current user
|
||||||
|
$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');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the user's school has nominations available
|
||||||
|
$existing_nominations = auth()->user()->school->nominations;
|
||||||
|
if ($existing_nominations->count() >= $ensemble->data['max_nominations']) {
|
||||||
|
return redirect()->route('nomination.entry.index')->with('error',
|
||||||
|
'You have already used all of your nominations for this ensemble');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the user's school isn't over limit for the requested instrument
|
||||||
|
$instrumentLimit = collect($ensemble->data['instruments'])->firstWhere('name',
|
||||||
|
$validData['new_instrument'])['max'];
|
||||||
|
if ($instrumentLimit) {
|
||||||
|
$used = 0;
|
||||||
|
foreach ($existing_nominations as $nom) {
|
||||||
|
if ($nom->data['instrument'] == $validData['new_instrument']) {
|
||||||
|
$used++;
|
||||||
|
}
|
||||||
|
if ($used >= $instrumentLimit) {
|
||||||
|
return redirect()->route('nomination.entry.index')->with('error',
|
||||||
|
'You may not nominate any more students on that instrument');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the student isn't already nominated for this ensemble
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
$newEntry = new NominationEnsembleEntry();
|
||||||
|
$newEntry->student_id = $validData['new_student'];
|
||||||
|
$newEntry->nomination_ensemble_id = $validData['ensemble'];
|
||||||
|
$newEntry->data = ['instrument' => $validData['new_instrument']];
|
||||||
|
$newEntry->save();
|
||||||
|
|
||||||
|
return redirect()->route('nomination.entry.index')->with('success',
|
||||||
|
'Nomination entered');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(NominationEnsembleEntry $entry)
|
||||||
|
{
|
||||||
|
// TODO: Implement edit() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(NominationEnsembleEntry $entry)
|
||||||
|
{
|
||||||
|
// TODO: Implement update() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(NominationEnsembleEntry $entry)
|
||||||
|
{
|
||||||
|
// TODO: Implement destroy() method.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Http\Controllers\NominationEnsembles\MeobdaNominationEnsembleController;
|
use App\Http\Controllers\NominationEnsembles\MeobdaNominationEnsembleController;
|
||||||
|
use App\Http\Controllers\NominationEnsembles\MeobdaNominationEnsembleEntryController;
|
||||||
use App\Http\Controllers\NominationEnsembles\NominationAdminController;
|
use App\Http\Controllers\NominationEnsembles\NominationAdminController;
|
||||||
use App\Http\Controllers\NominationEnsembles\NominationEnsembleController;
|
use App\Http\Controllers\NominationEnsembles\NominationEnsembleController;
|
||||||
use App\Http\Controllers\NominationEnsembles\NominationEnsembleEntryController;
|
use App\Http\Controllers\NominationEnsembles\NominationEnsembleEntryController;
|
||||||
|
|
@ -38,6 +39,7 @@ class NominationEnsembleServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
// meobda implementation
|
// meobda implementation
|
||||||
$this->app->bind(NominationEnsembleController::class, MeobdaNominationEnsembleController::class);
|
$this->app->bind(NominationEnsembleController::class, MeobdaNominationEnsembleController::class);
|
||||||
|
$this->app->bind(NominationEnsembleEntryController::class, MeobdaNominationEnsembleEntryController::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
<x-layout.app>
|
||||||
|
<x-slot:page_title>Nominations</x-slot:page_title>
|
||||||
|
|
||||||
|
<x-layout.page-section-container>
|
||||||
|
@foreach($ensembles as $ensemble)
|
||||||
|
<x-layout.page-section>
|
||||||
|
<x-slot:section_name>{{ $ensemble->name }}</x-slot:section_name>
|
||||||
|
<x-slot:section_description>
|
||||||
|
{{ $ensemble->data['max_nominations'] }} nominations accepted<br>
|
||||||
|
Entry Deadline {{ \Carbon\Carbon::parse($ensemble->entry_deadline)->format('M j, Y') }}
|
||||||
|
</x-slot:section_description>
|
||||||
|
<x-card.card>
|
||||||
|
<x-card.heading>Existing Nominations</x-card.heading>
|
||||||
|
<x-table.table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<x-table.th>Student</x-table.th>
|
||||||
|
<x-table.th>Grade</x-table.th>
|
||||||
|
<x-table.th>Instrument</x-table.th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<x-table.body>
|
||||||
|
@foreach($existingNominations[$ensemble->id] as $nom)
|
||||||
|
<tr>
|
||||||
|
<x-table.td>{{ $nom->student->full_name() }}</x-table.td>
|
||||||
|
<x-table.td>{{ $nom->student->grade }}</x-table.td>
|
||||||
|
<x-table.td>{{ $nom->data['instrument'] }}</x-table.td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</x-table.body>
|
||||||
|
</x-table.table>
|
||||||
|
</x-card.card>
|
||||||
|
|
||||||
|
@if($nominationsAvailable[$ensemble->id])
|
||||||
|
<x-card.card>
|
||||||
|
<x-card.heading>New Entry</x-card.heading>
|
||||||
|
<x-form.form method="POST" action="{{ route('nomination.entry.store') }}">
|
||||||
|
<x-form.body-grid columns="5" class="mb-4 mt-4">
|
||||||
|
<input type="hidden" name="ensemble" value="{{ $ensemble->id }}"/>
|
||||||
|
<x-form.select name="new_student" colspan="2">
|
||||||
|
@foreach($availableStudents[$ensemble->id] as $student)
|
||||||
|
<option value="{{$student->id}}">{{ $student->full_name() }}
|
||||||
|
(Grade {{ $student->grade }})
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</x-form.select>
|
||||||
|
|
||||||
|
<x-form.select name="new_instrument" colspan="2">
|
||||||
|
@foreach($availableInstruments[$ensemble->id] as $instrument)
|
||||||
|
<option value="{{$instrument}}">{{ $instrument }}</option>
|
||||||
|
@endforeach
|
||||||
|
</x-form.select>
|
||||||
|
|
||||||
|
<x-form.button>Add Nomination</x-form.button>
|
||||||
|
|
||||||
|
</x-form.body-grid>
|
||||||
|
</x-form.form>
|
||||||
|
</x-card.card>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</x-layout.page-section>
|
||||||
|
@endforeach
|
||||||
|
</x-layout.page-section-container>
|
||||||
|
</x-layout.app>
|
||||||
Loading…
Reference in New Issue