Seating Publication Working
This commit is contained in:
parent
14b6bb61c7
commit
98378c6182
|
|
@ -8,16 +8,33 @@ 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;
|
||||||
|
use App\Models\Ensemble;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
use App\Models\Seat;
|
||||||
|
use Debugbar;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
use function PHPUnit\Framework\isNull;
|
use function redirect;
|
||||||
|
|
||||||
class SeatAuditionFormController extends Controller
|
class SeatAuditionFormController extends Controller
|
||||||
{
|
{
|
||||||
public function showForm(Request $request, Audition $audition)
|
public function showForm(Request $request, Audition $audition)
|
||||||
{
|
{
|
||||||
|
$seatingProposal = (session('proposedSeatingArray-'.$audition->id));
|
||||||
|
if ($audition->hasFlag('seats_published')) {
|
||||||
|
$publishedSeats = Seat::where('audition_id', $audition->id)
|
||||||
|
->join('ensembles', 'seats.ensemble_id', '=', 'ensembles.id')
|
||||||
|
->orderBy('ensembles.rank')
|
||||||
|
->orderBy('seats.seat')
|
||||||
|
->select('seats.*')
|
||||||
|
->with(['ensemble', 'entry.student.school'])
|
||||||
|
->get();
|
||||||
|
} else {
|
||||||
|
$publishedSeats = false;
|
||||||
|
}
|
||||||
|
|
||||||
$ranker = app(RankAuditionEntries::class);
|
$ranker = app(RankAuditionEntries::class);
|
||||||
// Get scored entries in order
|
// Get scored entries in order
|
||||||
$scored_entries = $ranker($audition, 'seating');
|
$scored_entries = $ranker($audition, 'seating');
|
||||||
|
|
@ -63,7 +80,7 @@ class SeatAuditionFormController extends Controller
|
||||||
|
|
||||||
$auditionHasUnresolvedDoublers = false;
|
$auditionHasUnresolvedDoublers = false;
|
||||||
foreach ($doublerData as $doubler) {
|
foreach ($doublerData as $doubler) {
|
||||||
if (! isNull($doubler->accepted_entry)) {
|
if (! is_null($doubler->accepted_entry)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ($doubler->entries() as $entry) {
|
foreach ($doubler->entries() as $entry) {
|
||||||
|
|
@ -75,6 +92,7 @@ class SeatAuditionFormController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$canSeat = ! $auditionHasUnresolvedDoublers && $unscored_entries->count() === 0;
|
$canSeat = ! $auditionHasUnresolvedDoublers && $unscored_entries->count() === 0;
|
||||||
|
Debugbar::info($seatingProposal);
|
||||||
|
|
||||||
return view('tabulation.auditionSeating',
|
return view('tabulation.auditionSeating',
|
||||||
compact('audition',
|
compact('audition',
|
||||||
|
|
@ -85,6 +103,8 @@ class SeatAuditionFormController extends Controller
|
||||||
'doublerData',
|
'doublerData',
|
||||||
'auditionHasUnresolvedDoublers',
|
'auditionHasUnresolvedDoublers',
|
||||||
'canSeat',
|
'canSeat',
|
||||||
|
'seatingProposal',
|
||||||
|
'publishedSeats',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -130,6 +150,90 @@ 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)
|
||||||
|
{
|
||||||
|
$ranker = app(RankAuditionEntries::class);
|
||||||
|
$validated = $request->validate([
|
||||||
|
'ensemble' => ['required', 'array'],
|
||||||
|
'ensemble.*' => ['required', 'integer', 'min:0'],
|
||||||
|
]);
|
||||||
|
$proposedSeatingArray = [];
|
||||||
|
$rankedEntries = $ranker($audition, 'seating');
|
||||||
|
$rankedEntries = $rankedEntries->reject(function ($entry) {
|
||||||
|
return $entry->hasFlag('declined');
|
||||||
|
});
|
||||||
|
|
||||||
|
$rankedEntries->load(['student.school']);
|
||||||
|
$rankedEnembles = Ensemble::orderBy('rank')->where('event_id', $audition->event_id)->get();
|
||||||
|
$ensembleRankOn = 1;
|
||||||
|
foreach ($rankedEnembles as $ensemble) {
|
||||||
|
if (! Arr::has($validated['ensemble'], $ensemble->id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['ensemble_id'] = $ensemble->id;
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['ensemble_name'] = $ensemble->name;
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['accept_count'] = $validated['ensemble'][$ensemble->id];
|
||||||
|
for ($n = 1; $n <= $validated['ensemble'][$ensemble->id]; $n++) {
|
||||||
|
// Escape the loop if we're out of entries
|
||||||
|
if ($rankedEntries->isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$thisEntry = $rankedEntries->shift();
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['seat'] = $n;
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_id'] = $thisEntry->id;
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_name'] = $thisEntry->student->full_name();
|
||||||
|
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_school'] = $thisEntry->student->school->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ensembleRankOn++;
|
||||||
|
}
|
||||||
|
$sessionKeyName = 'proposedSeatingArray-'.$audition->id;
|
||||||
|
$request->session()->put($sessionKeyName, $proposedSeatingArray, 10);
|
||||||
|
|
||||||
|
return redirect()->route('seating.audition', ['audition' => $audition->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearDraft(Audition $audition)
|
||||||
|
{
|
||||||
|
session()->forget('proposedSeatingArray-'.$audition->id);
|
||||||
|
|
||||||
|
return redirect()->route('seating.audition', ['audition' => $audition->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function publishSeats(Audition $audition)
|
||||||
|
{
|
||||||
|
$publisher = app('App\Actions\Tabulation\PublishSeats');
|
||||||
|
$seatingProposal = (session('proposedSeatingArray-'.$audition->id));
|
||||||
|
$proposal = [];
|
||||||
|
foreach ($seatingProposal as $ensemble) {
|
||||||
|
$ensembleId = $ensemble['ensemble_id'];
|
||||||
|
if (isset($ensemble['seats'])) {
|
||||||
|
foreach ($ensemble['seats'] as $seat) {
|
||||||
|
$proposal[] = [
|
||||||
|
'ensemble_id' => $ensembleId,
|
||||||
|
'audition_id' => $audition->id,
|
||||||
|
'seat' => $seat['seat'],
|
||||||
|
'entry_id' => $seat['entry_id'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$publisher($audition, $proposal);
|
||||||
|
session()->forget('proposedSeatingArray-'.$audition->id);
|
||||||
|
|
||||||
|
return redirect()->route('seating.audition', [$audition]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unpublishSeats(Audition $audition)
|
||||||
|
{
|
||||||
|
$unpublisher = app('App\Actions\Tabulation\UnpublishSeats');
|
||||||
|
$unpublisher($audition);
|
||||||
|
session()->forget('proposedSeatingArray-'.$audition->id);
|
||||||
|
|
||||||
|
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')) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
|
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
|
||||||
<div class="grid grid-cols-4"></div>
|
<div class="grid grid-cols-4 gap-4">
|
||||||
<div class="grid grid-cols-4">
|
|
||||||
|
|
||||||
<div class="col-span-3"> {{-- Entry Ranking Table --}}
|
<div class="col-span-3"> {{-- Entry Ranking Table --}}
|
||||||
<x-card.card class="px-3"> {{-- Scored Entries --}}
|
<x-card.card class="px-3"> {{-- Scored Entries --}}
|
||||||
|
|
@ -94,7 +93,8 @@
|
||||||
<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-table.td>
|
||||||
<x-form.form method="POST" action="{{ route('seating.audition.noshow',[$audition, $entry]) }}">
|
<x-form.form method="POST"
|
||||||
|
action="{{ route('seating.audition.noshow',[$audition, $entry]) }}">
|
||||||
<x-form.button>Record No Show</x-form.button>
|
<x-form.button>Record No Show</x-form.button>
|
||||||
</x-form.form>
|
</x-form.form>
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
|
|
@ -157,9 +157,80 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div> {{-- Right Column Wrapper --}}
|
||||||
|
@if($audition->hasFlag('seats_published'))
|
||||||
|
<x-card.card>
|
||||||
|
<x-card.heading>Published Results</x-card.heading>
|
||||||
|
<x-card.list.body>
|
||||||
|
@php($previousEnsemble = '')
|
||||||
|
@foreach($publishedSeats as $seat)
|
||||||
|
@if($previousEnsemble !== $seat->ensemble->name)
|
||||||
|
@php($previousEnsemble = $seat->ensemble->name)
|
||||||
|
<x-card.list.row class="font-semibold">{{ $seat->ensemble->name }}</x-card.list.row>
|
||||||
|
@endif
|
||||||
|
<x-card.list.row>
|
||||||
|
<div>
|
||||||
|
<p>{{ $seat->seat }}. {{ $seat->student->full_name() }}</p>
|
||||||
|
<p class="ml-5 text-xs">{{ $seat->student->school->name }}</p>
|
||||||
|
</div>
|
||||||
|
</x-card.list.row>
|
||||||
|
@endforeach
|
||||||
|
</x-card.list.body>
|
||||||
|
</x-card.card>
|
||||||
|
|
||||||
|
<x-form.form method="POST" action="{{ route('seating.audition.unpublishSeats',[$audition]) }}">
|
||||||
|
<x-form.button class="mt-3">Unpublish Results</x-form.button>
|
||||||
|
</x-form.form>
|
||||||
|
@else
|
||||||
|
@if($canSeat)
|
||||||
|
@if($seatingProposal)
|
||||||
|
<x-card.card>
|
||||||
|
<x-card.heading>
|
||||||
|
Seating Proposal
|
||||||
|
<x-slot:subheading>Results are not yet published</x-slot:subheading>
|
||||||
|
</x-card.heading>
|
||||||
|
@foreach($seatingProposal as $proposedEnsemble)
|
||||||
|
<h3 class="m-3 font-semibold">{{ $proposedEnsemble['ensemble_name'] }}</h3>
|
||||||
|
<x-card.list.body>
|
||||||
|
@if(isset($proposedEnsemble['seats']))
|
||||||
|
@foreach($proposedEnsemble['seats'] as $seat)
|
||||||
|
<x-card.list.row>{{ $seat['seat'] }}
|
||||||
|
. {{ $seat['entry_name'] }}</x-card.list.row>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</x-card.list.body>
|
||||||
|
@endforeach
|
||||||
|
<x-form.form method="POST" action="{{ route('seating.audition.clearDraft',[$audition]) }}">
|
||||||
|
<x-form.button class="mb-3">Clear Draft</x-form.button>
|
||||||
|
</x-form.form>
|
||||||
|
<x-form.form method="POST"
|
||||||
|
action="{{ route('seating.audition.publishSeats',[$audition]) }}">
|
||||||
|
<x-form.button class="mb-3">Publish</x-form.button>
|
||||||
|
</x-form.form>
|
||||||
|
</x-card.card>
|
||||||
|
@else
|
||||||
|
<x-card.card class="p-3">
|
||||||
|
<x-form.form metohd="POST" action="{{ route('seating.audition.draftSeats',[$audition]) }}">
|
||||||
|
<x-card.heading class="-ml-5">Seat Audition
|
||||||
|
<x-slot:subheading>Choose how many entries to seat in each ensemble
|
||||||
|
</x-slot:subheading>
|
||||||
|
</x-card.heading>
|
||||||
|
@foreach($audition->SeatingLimits()->where('maximum_accepted','>',0)->get() as $limit)
|
||||||
|
<x-form.select name="ensemble[{{ $limit->ensemble_id }}]">
|
||||||
|
<x-slot:label>{{$limit->ensemble->name}}</x-slot:label>
|
||||||
|
@for($n = 0; $n< $limit->maximum_accepted; $n++)
|
||||||
|
<option value="{{$n}}">{{$n}}</option>
|
||||||
|
@endfor
|
||||||
|
<option value="{{$n}}" SELECTED>{{$n}}</option>
|
||||||
|
</x-form.select>
|
||||||
|
@endforeach
|
||||||
|
<x-form.button class="mt-3">Draft Seats</x-form.button>
|
||||||
|
</x-form.form>
|
||||||
|
</x-card.card>
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
{{-- TODO: Add in bulk delince doubler option --}}
|
{{-- 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.
|
||||||
|
|
@ -172,6 +243,11 @@
|
||||||
</x-card.card>
|
</x-card.card>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use App\Http\Controllers\Tabulation\DoublerDecisionController;
|
||||||
use App\Http\Controllers\Tabulation\EntryFlagController;
|
use App\Http\Controllers\Tabulation\EntryFlagController;
|
||||||
use App\Http\Controllers\Tabulation\ScoreController;
|
use App\Http\Controllers\Tabulation\ScoreController;
|
||||||
use App\Http\Controllers\Tabulation\SeatAuditionFormController;
|
use App\Http\Controllers\Tabulation\SeatAuditionFormController;
|
||||||
use App\Http\Controllers\Tabulation\SeatingPublicationController;
|
|
||||||
use App\Http\Controllers\Tabulation\SeatingStatusController;
|
use App\Http\Controllers\Tabulation\SeatingStatusController;
|
||||||
use App\Http\Middleware\CheckIfCanTab;
|
use App\Http\Middleware\CheckIfCanTab;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
@ -43,13 +42,15 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
|
||||||
Route::prefix('seating/')->group(function () {
|
Route::prefix('seating/')->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}/draftSeats', [SeatAuditionFormController::class, 'draftSeats'])->name('seating.audition.draftSeats');
|
||||||
|
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}/{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',
|
||||||
[SeatingPublicationController::class, 'publishSeats'])->name('seating.audition.publish');
|
[SeatAuditionFormController::class, 'publishSeats'])->name('seating.audition.publishSeats');
|
||||||
Route::post('/{audition}/unpublish',
|
Route::post('/{audition}/unpublish',
|
||||||
[SeatingPublicationController::class, 'unpublishSeats'])->name('seating.audition.unpublish');
|
[SeatAuditionFormController::class, 'unpublishSeats'])->name('seating.audition.unpublishSeats');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Advancement Routes
|
// Advancement Routes
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue