Allow for bluk declining seats

This commit is contained in:
Matt Young 2025-06-26 18:32:16 -05:00
parent a3e8785767
commit 7670e91f43
4 changed files with 67 additions and 17 deletions

View File

@ -11,6 +11,7 @@ use App\Models\Doubler;
use App\Models\Ensemble; use App\Models\Ensemble;
use App\Models\Entry; use App\Models\Entry;
use App\Models\Seat; use App\Models\Seat;
use Debugbar;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
@ -116,8 +117,44 @@ 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) public function massDecline(Audition $audition)
{ {
$validData = request()->validate([
'decline-below' => ['required', 'integer', 'min:0'],
]);
$ranker = app(RankAuditionEntries::class);
// Get scored entries in order
$scored_entries = $ranker($audition, 'seating');
$scored_entries->load(['student.doublers', 'student.school']);
foreach ($scored_entries as $entry) {
Debugbar::info('Starting entry '.$entry->student->full_name());
if ($entry->hasFlag('declined')) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they have already been declined');
continue;
}
if (! $entry->student->isDoublerInEvent($audition->event_id)) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they are not a doubler');
continue;
}
if ($entry->student->doublers->where('event_id', $audition->event_id)->first()->accepted_entry) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they have already accepted a seat');
continue;
}
$entry->addFlag('declined');
}
Cache::forget('rank_seating_'.$entry->audition_id);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function acceptSeat(
Audition $audition,
Entry $entry
) {
$doublerData = Doubler::findDoubler($entry->student_id, $audition->event_id); $doublerData = Doubler::findDoubler($entry->student_id, $audition->event_id);
foreach ($doublerData->entries() as $doublerEntry) { foreach ($doublerData->entries() as $doublerEntry) {
if (! $doublerEntry->totalScore && ! $doublerEntry->hasFlag('declined') && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim')) { if (! $doublerEntry->totalScore && ! $doublerEntry->hasFlag('declined') && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim')) {
@ -136,8 +173,10 @@ class SeatAuditionFormController extends Controller
$entry->student->full_name().' has accepted '.$audition->name); $entry->student->full_name().' has accepted '.$audition->name);
} }
public function noshow(Audition $audition, Entry $entry) public function noshow(
{ Audition $audition,
Entry $entry
) {
$recorder = app('App\Actions\Tabulation\EnterNoShow'); $recorder = app('App\Actions\Tabulation\EnterNoShow');
try { try {
$msg = $recorder($entry); $msg = $recorder($entry);
@ -148,8 +187,10 @@ class SeatAuditionFormController extends Controller
return redirect()->route('seating.audition', [$audition])->with('success', $msg); return redirect()->route('seating.audition', [$audition])->with('success', $msg);
} }
public function draftSeats(Audition $audition, Request $request) public function draftSeats(
{ Audition $audition,
Request $request
) {
$ranker = app(RankAuditionEntries::class); $ranker = app(RankAuditionEntries::class);
$validated = $request->validate([ $validated = $request->validate([
'ensemble' => ['required', 'array'], 'ensemble' => ['required', 'array'],
@ -192,15 +233,17 @@ class SeatAuditionFormController extends Controller
return redirect()->route('seating.audition', ['audition' => $audition->id]); return redirect()->route('seating.audition', ['audition' => $audition->id]);
} }
public function clearDraft(Audition $audition) public function clearDraft(
{ Audition $audition
) {
session()->forget('proposedSeatingArray-'.$audition->id); session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', ['audition' => $audition->id]); return redirect()->route('seating.audition', ['audition' => $audition->id]);
} }
public function publishSeats(Audition $audition) public function publishSeats(
{ Audition $audition
) {
$publisher = app('App\Actions\Tabulation\PublishSeats'); $publisher = app('App\Actions\Tabulation\PublishSeats');
$seatingProposal = (session('proposedSeatingArray-'.$audition->id)); $seatingProposal = (session('proposedSeatingArray-'.$audition->id));
$proposal = []; $proposal = [];
@ -223,8 +266,9 @@ class SeatAuditionFormController extends Controller
return redirect()->route('seating.audition', [$audition]); return redirect()->route('seating.audition', [$audition]);
} }
public function unpublishSeats(Audition $audition) public function unpublishSeats(
{ Audition $audition
) {
$unpublisher = app('App\Actions\Tabulation\UnpublishSeats'); $unpublisher = app('App\Actions\Tabulation\UnpublishSeats');
$unpublisher($audition); $unpublisher($audition);
session()->forget('proposedSeatingArray-'.$audition->id); session()->forget('proposedSeatingArray-'.$audition->id);
@ -232,8 +276,10 @@ class SeatAuditionFormController extends Controller
return redirect()->route('seating.audition', [$audition]); return redirect()->route('seating.audition', [$audition]);
} }
protected function pickRightPanel(Audition $audition, array $seatable) protected function pickRightPanel(
{ Audition $audition,
array $seatable
) {
if ($audition->hasFlag('seats_published')) { if ($audition->hasFlag('seats_published')) {
$resultsWindow = new GetAuditionSeats; $resultsWindow = new GetAuditionSeats;
$rightPanel['view'] = 'tabulation.auditionSeating-show-published-seats'; $rightPanel['view'] = 'tabulation.auditionSeating-show-published-seats';

View File

@ -99,6 +99,6 @@ class AppServiceProvider extends ServiceProvider
SeatingLimit::observe(SeatingLimitObserver::class); SeatingLimit::observe(SeatingLimitObserver::class);
EntryFlag::observe(EntryFlagObserver::class); EntryFlag::observe(EntryFlagObserver::class);
// Model::preventLazyLoading(! app()->isProduction()); Model::preventLazyLoading(! app()->isProduction());
} }
} }

View File

@ -239,7 +239,6 @@
@endif @endif
@else @else
<div class="ml-4"> <div class="ml-4">
{{-- TODO: Add in bulk decline doubler option --}}
@if($unscored_entries->count() > 0) @if($unscored_entries->count() > 0)
<x-card.card class="p-3 text-red-500 mb-3"> <x-card.card class="p-3 text-red-500 mb-3">
Cannot seat the audition while entries are unscored. Cannot seat the audition while entries are unscored.
@ -247,8 +246,12 @@
@endif @endif
@if($auditionHasUnresolvedDoublers) @if($auditionHasUnresolvedDoublers)
<x-card.card class="p-3 text-red-500"> <x-card.card class="p-3">
Cannot seat the audition while there are unresolved doublers. <p class="text-red-500">Cannot seat the audition while there are unresolved doublers.</p>
<x-form.form method="POST" action="{{ route('seating.audition.mass_decline',[$audition]) }}">
<x-form.field type="number" name="decline-below" label_text="Decline doubler ranked lower than:" />
<x-form.button>Decline</x-form.button>
</x-form.form>
</x-card.card> </x-card.card>
@endif @endif
</div> </div>

View File

@ -45,6 +45,7 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
Route::post('/{audition}/draftSeats', [SeatAuditionFormController::class, 'draftSeats'])->name('seating.audition.draftSeats'); Route::post('/{audition}/draftSeats', [SeatAuditionFormController::class, 'draftSeats'])->name('seating.audition.draftSeats');
Route::post('/{audition}/clearDraft', [SeatAuditionFormController::class, 'clearDraft'])->name('seating.audition.clearDraft'); Route::post('/{audition}/clearDraft', [SeatAuditionFormController::class, 'clearDraft'])->name('seating.audition.clearDraft');
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}/mass_decline', [SeatAuditionFormController::class, 'massDecline'])->name('seating.audition.mass_decline');
Route::post('/{audition}/{entry}/accept', [SeatAuditionFormController::class, 'acceptSeat'])->name('seating.audition.accept'); 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}/{entry}/noshow', [SeatAuditionFormController::class, 'noshow'])->name('seating.audition.noshow');
Route::post('/{audition}/publish', Route::post('/{audition}/publish',