add ability to mark no-shows and accept/decline doublers from the seating page.

This commit is contained in:
Matt Young 2025-06-25 21:20:33 -05:00
parent 5e687bcbc6
commit 0468cb5d11
5 changed files with 64 additions and 31 deletions

View File

@ -4,12 +4,8 @@ namespace App\Http\Controllers\Tabulation;
use App\Exceptions\AuditionAdminException; use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\BonusScore;
use App\Models\Entry; use App\Models\Entry;
use App\Models\EntryTotalScore;
use App\Models\ScoreSheet;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use function to_route; use function to_route;
@ -82,27 +78,6 @@ class EntryFlagController extends Controller
return to_route('entry-flags.noShowSelect')->with('error', $e->getMessage()); return to_route('entry-flags.noShowSelect')->with('error', $e->getMessage());
} }
// if ($entry->audition->hasFlag('seats_published')) {
// return to_route('entry-flags.noShowSelect')->with('error',
// 'Cannot enter a no-show for an entry in an audition where seats are published');
// }
// if ($entry->audition->hasFlag('advancement_published')) {
// return to_route('entry-flags.noShowSelect')->with('error',
// 'Cannot enter a no-show for an entry in an audition where advancement is published');
// }
// DB::table('score_sheets')->where('entry_id', $entry->id)->delete();
//
// ScoreSheet::where('entry_id', $entry->id)->delete();
// BonusScore::where('entry_id', $entry->id)->delete();
// EntryTotalScore::where('entry_id', $entry->id)->delete();
// if (request()->input('noshow-type') == 'failprelim') {
// $msg = 'Failed prelim has been entered for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').';
// $entry->addFlag('failed_prelim');
// } else {
// $entry->addFlag('no_show');
// $msg = 'No Show has been entered for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').';
// }
return to_route('entry-flags.noShowSelect')->with('success', $msg); return to_route('entry-flags.noShowSelect')->with('success', $msg);
} }

View File

@ -4,6 +4,7 @@ namespace App\Http\Controllers\Tabulation;
use App\Actions\Tabulation\GetAuditionSeats; use App\Actions\Tabulation\GetAuditionSeats;
use App\Actions\Tabulation\RankAuditionEntries; use App\Actions\Tabulation\RankAuditionEntries;
use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Audition; use App\Models\Audition;
use App\Models\Doubler; use App\Models\Doubler;
@ -75,6 +76,37 @@ class SeatAuditionFormController extends Controller
$entry->student->full_name().' has declined '.$audition->name); $entry->student->full_name().' has declined '.$audition->name);
} }
public function acceptSeat(Audition $audition, Entry $entry)
{
$doublerData = Doubler::findDoubler($entry->student_id, $audition->event_id);
foreach ($doublerData->entries() as $doublerEntry) {
if (! $doublerEntry->totalScore && ! $doublerEntry->hasFlag('declined') && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim')) {
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('error',
'Cannot accept seating for '.$entry->student->full_name().' because student has unscored entries');
}
}
foreach ($doublerData->entries() as $doublerEntry) {
if ($doublerEntry->id !== $entry->id && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim') && ! $doublerEntry->hasFlag('declined')) {
$doublerEntry->addFlag('declined');
}
}
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
$entry->student->full_name().' has accepted '.$audition->name);
}
public function noshow(Audition $audition, Entry $entry)
{
$recorder = app('App\Actions\Tabulation\EnterNoShow');
try {
$msg = $recorder($entry);
} catch (AuditionAdminException $e) {
return redirect()->back()->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', [$audition])->with('success', $msg);
}
protected function pickRightPanel(Audition $audition, array $seatable) protected function pickRightPanel(Audition $audition, array $seatable)
{ {
if ($audition->hasFlag('seats_published')) { if ($audition->hasFlag('seats_published')) {

View File

@ -27,6 +27,10 @@
@endforeach @endforeach
</div> </div>
<div class="mt-3"> <div class="mt-3">
{{-- TODO: Don't show the option to accept if it cannot be done --}}
<x-form.form method="POST" action="{{ route('seating.audition.accept',[$audition, $de]) }}" class="mb-3">
<x-form.button>Accept {{ $de->audition->name }}</x-form.button>
</x-form.form>
<x-form.form method="POST" action="{{ route('seating.audition.decline',[$audition,$de]) }}"> <x-form.form method="POST" action="{{ route('seating.audition.decline',[$audition,$de]) }}">
<x-form.button>Decline {{ $de->audition->name }}</x-form.button> <x-form.button>Decline {{ $de->audition->name }}</x-form.button>
</x-form.form> </x-form.form>

View File

@ -32,7 +32,9 @@
<x-table.td class="align-top">{{ $entry->id }}</x-table.td> <x-table.td class="align-top">{{ $entry->id }}</x-table.td>
<x-table.td class="align-top">{{ $entry->draw_number }}</x-table.td> <x-table.td class="align-top">{{ $entry->draw_number }}</x-table.td>
<x-table.td class="align-top"> <x-table.td class="align-top">
<div><a href="{{ route('admin.students.edit',[$entry->student_id]) }}">{{ $entry->student->full_name() }}</a></div> <div>
<a href="{{ route('admin.students.edit',[$entry->student_id]) }}">{{ $entry->student->full_name() }}</a>
</div>
<div class="text-xs text-gray-400">{{ $entry->student->school->name }}</div> <div class="text-xs text-gray-400">{{ $entry->student->school->name }}</div>
</x-table.td> </x-table.td>
<x-table.td class="align-top"> <x-table.td class="align-top">
@ -44,7 +46,8 @@
DECLINED DECLINED
@else @else
@if($request = $entry->student->doublerRequests()->where('event_id',$entry->audition->event_id)->first()) @if($request = $entry->student->doublerRequests()->where('event_id',$entry->audition->event_id)->first())
<div class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block seating request --}} <div
class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block seating request --}}
<div class="font-semibold mb-2"> <div class="font-semibold mb-2">
Request Request
</div> </div>
@ -78,6 +81,7 @@
<x-table.th>Draw #</x-table.th> <x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th> <x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th> <x-table.th>Student</x-table.th>
<x-table.th></x-table.th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -89,6 +93,11 @@
<span>{{ $entry->student->full_name() }}</span> <span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span> <span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td> </x-table.td>
<x-table.td>
<x-form.form method="POST" action="{{ route('seating.audition.noshow',[$audition, $entry]) }}">
<x-form.button>Record No Show</x-form.button>
</x-form.form>
</x-table.td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>
@ -150,7 +159,18 @@
<div class="ml-4"> <div class="ml-4">
Controls {{-- TODO: Add in bulk delince doubler option --}}
@if($unscored_entries->count() > 0)
<x-card.card class="p-3 text-red-500 mb-3">
Cannot seat the audition while entries are unscored.
</x-card.card>
@endif
<hr>
@if($doublerData->contains('accepted_entry', null))
<x-card.card class="p-3 text-red-500">
Cannot seat the audition while there are unresolved doublers.
</x-card.card>
@endif
</div> </div>
</div> </div>

View File

@ -44,6 +44,8 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
Route::get('/', SeatingStatusController::class)->name('seating.status'); Route::get('/', SeatingStatusController::class)->name('seating.status');
Route::get('/{audition}', [SeatAuditionFormController::class, 'showForm'])->name('seating.audition'); Route::get('/{audition}', [SeatAuditionFormController::class, 'showForm'])->name('seating.audition');
Route::post('/{audition}/{entry}/decline', [SeatAuditionFormController::class, 'declineSeat'])->name('seating.audition.decline'); Route::post('/{audition}/{entry}/decline', [SeatAuditionFormController::class, 'declineSeat'])->name('seating.audition.decline');
Route::post('/{audition}/{entry}/accept', [SeatAuditionFormController::class, 'acceptSeat'])->name('seating.audition.accept');
Route::post('/{audition}/{entry}/noshow', [SeatAuditionFormController::class, 'noshow'])->name('seating.audition.noshow');
Route::post('/{audition}/publish', Route::post('/{audition}/publish',
[SeatingPublicationController::class, 'publishSeats'])->name('seating.audition.publish'); [SeatingPublicationController::class, 'publishSeats'])->name('seating.audition.publish');
Route::post('/{audition}/unpublish', Route::post('/{audition}/unpublish',