Add ability to change doubler decision from student screen.

Closes #44
This commit is contained in:
Matt Young 2024-10-31 14:46:05 -05:00
parent daedc05646
commit 344ee8e22f
4 changed files with 100 additions and 4 deletions

View File

@ -5,6 +5,8 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Audition; use App\Models\Audition;
use App\Models\AuditLogEntry; use App\Models\AuditLogEntry;
use App\Models\Entry;
use App\Models\Event;
use App\Models\School; use App\Models\School;
use App\Models\Student; use App\Models\Student;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@ -107,9 +109,51 @@ class StudentController extends Controller
$maxGrade = Audition::max('maximum_grade'); $maxGrade = Audition::max('maximum_grade');
$schools = School::orderBy('name')->get(); $schools = School::orderBy('name')->get();
$student->loadCount('entries'); $student->loadCount('entries');
$entries = $student->entries;
$events = Event::all();
$event_entries = [];
foreach ($events as $event) {
$event_entries[$event->id] = $entries->filter(function ($entry) use ($event) {
return $event->id === $entry->audition->event_id;
});
// Check if doubler status can change
foreach ($event_entries[$event->id] as $entry) {
$entry->doubler_decision_frozen = $this->isDoublerStatusFrozen($entry, $event_entries[$event->id]);
}
}
return view('admin.students.edit', return view('admin.students.edit',
['student' => $student, 'schools' => $schools, 'minGrade' => $minGrade, 'maxGrade' => $maxGrade]); compact('student', 'schools', 'minGrade', 'maxGrade', 'events', 'event_entries'));
}
private function isDoublerStatusFrozen(Entry $entry, $entries)
{
// Can't change decision if results are published
if ($entry->audition->hasFlag('seats_published')) {
return true;
}
// Can't change decision if this is the only entry
if ($entries->count() === 1) {
return true;
}
// Can't change decision if this is the only entry with results not published
$unpublished = $entries->reject(function ($entry) {
return $entry->audition->hasFlag('seats_published');
});
if ($unpublished->count() < 2) {
return true;
}
// Can't change decision if we've accepted another audition
foreach ($entries as $checkEntry) {
if ($checkEntry->audition->hasFlag('seats_published') && ! $checkEntry->hasFlag('declined')) {
return true;
}
}
return false;
} }
public function update(Student $student) public function update(Student $student)

View File

@ -104,4 +104,11 @@ class EntryFlagController extends Controller
return to_route('entry-flags.noShowSelect')->with('success', return to_route('entry-flags.noShowSelect')->with('success',
'No Show status has been removed for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').'); 'No Show status has been removed for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').');
} }
public function undoDecline(Entry $entry)
{
$entry->removeFlag('declined');
return redirect()->back()->with('success', 'Decline cleared');
}
} }

View File

@ -4,7 +4,9 @@
Edit Student Edit Student
@if($student->entries_count === 0) @if($student->entries_count === 0)
<x-slot:right_side> <x-slot:right_side>
<x-delete-resource-modal title="Delete Student {{ $student->full_name() }} from {{ $student->school->name }}" :action="route('admin.students.destroy',$student)"> <x-delete-resource-modal
title="Delete Student {{ $student->full_name() }} from {{ $student->school->name }}"
:action="route('admin.students.destroy',$student)">
Please confirm you'd like to delete this student. This action cannot be undone. Please confirm you'd like to delete this student. This action cannot be undone.
</x-delete-resource-modal> </x-delete-resource-modal>
</x-slot:right_side> </x-slot:right_side>
@ -36,4 +38,46 @@
</x-form.footer> </x-form.footer>
</x-form.form> </x-form.form>
</x-card.card> </x-card.card>
@foreach($events as $event)
<x-card.card class="mx-auto max-w-xl mt-3">
<x-card.heading>Entries for {{ $event->name }}</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>ID</x-table.th>
<x-table.th>Audition</x-table.th>
<x-table.th>Draw #</x-table.th>
<x-table.th>Doubler Status</x-table.th>
</tr>
</thead>
<tbody>
@foreach($event_entries[$event->id] as $entry)
<tr>
<x-table.td>{{ $entry->id }} {{ $entry->doubler_decision_frozen ? 'FROZEN':'FLEXIBLE' }}</x-table.td>
<x-table.td>{{ $entry->audition->name }}</x-table.td>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>
@if($entry->doubler_decision_frozen)
<p class="text-red-600">{{ $entry->hasFlag('declined') ? 'DECLINED':'' }}</p>
@else
@if($entry->hasFlag('declined'))
<span class="text-red-600">
{{ $entry->hasFlag('declined') ? 'DECLINED':'' }}
</span>
<form method="POST" action="{{route('entry-flags.undoDecline',$entry)}}">
@csrf
@method('DELETE')
<button>[ Undo ]</button>
</form>
@endif
@endif
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>
@endforeach
</x-layout.app> </x-layout.app>

View File

@ -36,6 +36,7 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
Route::get('/propose-no-show', 'noShowConfirm')->name('entry-flags.confirmNoShow'); Route::get('/propose-no-show', 'noShowConfirm')->name('entry-flags.confirmNoShow');
Route::post('/no-show/{entry}', 'enterNoShow')->name('entry-flags.enterNoShow'); Route::post('/no-show/{entry}', 'enterNoShow')->name('entry-flags.enterNoShow');
Route::delete('/no-show/{entry}', 'undoNoShow')->name('entry-flags.undoNoShow'); Route::delete('/no-show/{entry}', 'undoNoShow')->name('entry-flags.undoNoShow');
Route::delete('/decline/{entry}', 'undoDecline')->name('entry-flags.undoDecline');
}); });
// Seating Routes // Seating Routes