Seats Publish and Unpublish Working

This commit is contained in:
Matt Young 2024-07-13 15:16:12 -05:00
parent fab34992df
commit 79bc3bb46d
10 changed files with 178 additions and 84 deletions

View File

@ -0,0 +1,40 @@
<?php
namespace App\Actions\Tabulation;
use App\Models\Audition;
use App\Models\Ensemble;
use App\Models\Seat;
use function dd;
class GetAuditionSeats
{
public function __construct()
{
}
public function __invoke(Audition $audition): array
{
return $this->getSeats($audition);
}
protected function getSeats(Audition $audition)
{
$ensembles = Ensemble::where('event_id', $audition->event_id)->orderBy('rank')->get();
$seats = Seat::with('student.school')->where('audition_id', $audition->id)->orderBy('seat')->get();
$return = [];
foreach ($ensembles as $ensemble) {
$ensembleSeats = $seats->filter(fn ($seat) => $seat->ensemble_id === $ensemble->id);
foreach ($ensembleSeats as $seat) {
$return[] = [
'ensemble' => $ensemble->name,
'seat' => $seat->seat,
'student_name' => $seat->student->full_name(),
'school_name' => $seat->student->school->name,
];
}
}
return $return;
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Actions\Tabulation;
use App\Models\Audition;
use App\Models\Seat;
use Illuminate\Support\Facades\Cache;
class PublishSeats
{
public function __construct()
{
//
}
public function __invoke(Audition $audition, array $seats): void
{
// Delete from the seats table where audition_id = $audition->id
Seat::where('audition_id', $audition->id)->delete();
foreach ($seats as $seat) {
Seat::create([
'ensemble_id' => $seat['ensemble_id'],
'audition_id' => $seat['audition_id'],
'seat' => $seat['seat'],
'entry_id' => $seat['entry_id'],
]);
}
$audition->addFlag('seats_published');
Cache::forget('resultsSeatList');
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Actions\Tabulation;
use App\Models\Audition;
use App\Models\Seat;
use Illuminate\Support\Facades\Cache;
class UnpublishSeats
{
public function __construct()
{
}
public function __invoke(Audition $audition): void
{
$audition->removeFlag('seats_published');
Cache::forget('resultsSeatList');
Seat::where('audition_id', $audition->id)->delete();
}
}

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Tabulation; namespace App\Http\Controllers\Tabulation;
use App\Actions\Tabulation\CalculateEntryScore; use App\Actions\Tabulation\CalculateEntryScore;
use App\Actions\Tabulation\GetAuditionSeats;
use App\Actions\Tabulation\RankAuditionEntries; use App\Actions\Tabulation\RankAuditionEntries;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Audition; use App\Models\Audition;
@ -11,7 +12,7 @@ use App\Services\DoublerService;
use App\Services\EntryService; use App\Services\EntryService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class SeatAuditionController extends Controller class SeatAuditionFormController extends Controller
{ {
protected CalculateEntryScore $calc; protected CalculateEntryScore $calc;
@ -39,6 +40,13 @@ class SeatAuditionController extends Controller
public function __invoke(Request $request, Audition $audition) public function __invoke(Request $request, Audition $audition)
{ {
// If a seating proposal was posted, deal wth it
if ($request->method() == 'POST') {
$requestedEnsembleAccepts = $request->input('ensembleAccept');
} else {
$requestedEnsembleAccepts = false;
}
$entryData = []; $entryData = [];
$entries = $this->ranker->rank('seating', $audition); $entries = $this->ranker->rank('seating', $audition);
$entries->load('student.school'); $entries->load('student.school');
@ -89,15 +97,15 @@ class SeatAuditionController extends Controller
}); });
} }
return view('tabulation.auditionSeating', compact('entryData', 'audition', 'rightPanel', 'seatableEntries')); return view('tabulation.auditionSeating', compact('entryData', 'audition', 'rightPanel', 'seatableEntries', 'requestedEnsembleAccepts'));
} }
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;
$rightPanel['view'] = 'tabulation.auditionSeating-show-published-seats'; $rightPanel['view'] = 'tabulation.auditionSeating-show-published-seats';
$rightPanel['data'] = ''; $rightPanel['data'] = $resultsWindow($audition);
return $rightPanel; return $rightPanel;
} }
if ($seatable['allScored'] == false || $seatable['doublersResolved'] == false) { if ($seatable['allScored'] == false || $seatable['doublersResolved'] == false) {

View File

@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers\Tabulation;
use App\Actions\Tabulation\PublishSeats;
use App\Actions\Tabulation\UnpublishSeats;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use Illuminate\Http\Request;
class SeatingPublicationController extends Controller
{
public function publishSeats(Request $request, Audition $audition)
{
$publisher = new PublishSeats;
$sessionKey = 'audition'.$audition->id.'seatingProposal';
$seats = $request->session()->get($sessionKey);
$publisher($audition, $seats);
$request->session()->forget($sessionKey);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function unpublishSeats(Request $request, Audition $audition)
{
$publisher = new UnpublishSeats;
$publisher($audition);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
}

View File

@ -35,57 +35,6 @@ class TabulationController extends Controller
$this->auditionService = $auditionService; $this->auditionService = $auditionService;
} }
public function status()
{
// Needs to provide a collection of auditions
$auditions = $this->tabulationService->getAuditionsWithStatus('seating');
return view('tabulation.status', compact('auditions'));
}
public function auditionSeating(Request $request, Audition $audition)
{
if ($request->method() == 'POST') {
$requestedEnsembleAccepts = $request->input('ensembleAccept');
} else {
$requestedEnsembleAccepts = false;
}
$entries = $this->tabulationService->auditionEntries($audition->id);
$entries = $entries->filter(function ($entry) {
return $entry->for_seating;
});
$doublerComplete = true;
foreach ($entries as $entry) {
if ($this->doublerService->studentIsDoubler($entry->student_id)) { // If this entry is a doubler
if ($this->doublerService->getDoublerInfo($entry->student_id)[$entry->id]['status'] === 'undecided') { // If there is no decision for this entry
$doublerComplete = false;
}
}
}
$scoringComplete = $entries->every(function ($entry) {
return $entry->scoring_complete;
});
$ensembleLimits = $this->seatingService->getLimitForAudition($audition->id);
$auditionComplete = $scoringComplete && $doublerComplete;
$seatableEntries = $this->seatingService->getSeatableEntries($audition->id);
$seatableEntries = $seatableEntries->filter(function ($entry) {
return $entry->for_seating;
});
return view('tabulation.auditionSeating', compact('audition',
'entries',
'scoringComplete',
'doublerComplete',
'auditionComplete',
'ensembleLimits',
'seatableEntries',
'requestedEnsembleAccepts'));
}
public function publishSeats(Request $request, Audition $audition) public function publishSeats(Request $request, Audition $audition)
{ {

View File

@ -3,12 +3,12 @@
@endphp @endphp
<x-card.heading>Seating</x-card.heading> <x-card.heading>Seating</x-card.heading>
<div class="py-3 px-1"> <div class="py-3 px-1">
<x-form.form method="POST" action="{{ route('tabulation.audition.seat',['audition' => $audition]) }}"> <x-form.form method="POST" action="{{ route('seating.audition',['audition' => $audition]) }}">
@csrf @csrf
@foreach($rightPanel['data'] as $ensembleLimit) @foreach($rightPanel['data'] as $ensembleLimit)
@php @php
//$value = $requestedEnsembleAccepts[$ensembleLimit->ensemble->id] ?? $ensembleLimit['limit']; $value = $requestedEnsembleAccepts[$ensembleLimit['ensemble']->id] ?? $ensembleLimit['limit'];
$value = $ensembleLimit['limit']; // $value = $ensembleLimit['limit'];
@endphp @endphp
<x-form.field name="ensembleAccept[{{ $ensembleLimit['ensemble']->id }}]" <x-form.field name="ensembleAccept[{{ $ensembleLimit['ensemble']->id }}]"

View File

@ -7,8 +7,8 @@
<x-card.heading>{{ $ensembleLimit['ensemble']->name }} - DRAFT</x-card.heading> <x-card.heading>{{ $ensembleLimit['ensemble']->name }} - DRAFT</x-card.heading>
<x-card.list.body> <x-card.list.body>
@php @php
// $maxAccepted = $requestedEnsembleAccepts[$ensembleLimit->ensemble->id] ?? $ensembleLimit->maximum_accepted; $maxAccepted = $requestedEnsembleAccepts[$ensembleLimit['ensemble']->id] ?? $ensembleLimit['limit'];
$maxAccepted = $ensembleLimit['limit']; // $maxAccepted = $ensembleLimit['limit'];
@endphp @endphp
@for($n=1; $n <= $maxAccepted; $n++) @for($n=1; $n <= $maxAccepted; $n++)
@php @php
@ -29,7 +29,7 @@
</x-card.list.body> </x-card.list.body>
</x-card.card> </x-card.card>
@endforeach @endforeach
<form method="POST" action="{{ route('tabulation.seat.publish',['audition' => $audition]) }}"> <form method="POST" action="{{ route('seating.audition.publish',['audition' => $audition]) }}">
@csrf @csrf
<x-form.button type="submit">Seat and Publish</x-form.button> <x-form.button type="submit">Seat and Publish</x-form.button>
</form> </form>

View File

@ -1,12 +1,10 @@
@inject('seatingService','App\Services\SeatingService')
<x-card.card class="mb-3"> <x-card.card class="mb-3">
<x-card.heading> <x-card.heading>
Seats are Published Seats are Published
</x-card.heading> </x-card.heading>
<x-form.form method="POST" <x-form.form method="POST"
action="{{ route('tabulation.seat.unpublish',['audition' => $audition->id]) }}" action="{{ route('seating.audition.unpublish',['audition' => $audition->id]) }}"
class="mx-5 my-2"> class="mx-5 my-2">
<x-form.button type="submit"> <x-form.button type="submit">
Unpublish Unpublish
@ -15,17 +13,34 @@
</x-card.card> </x-card.card>
@foreach($ensembleLimits as $ensembleLimit) <x-card.card class="mb-3">
@php @php
$ensembleSeats = $seatingService->getSeatsForAudition($audition->id)[$ensembleLimit->ensemble->id] ?? array(); $previousEnsemble = null;
@endphp @endphp
<x-card.card class="mb-3"> @foreach($rightPanel['data'] as $seat)
<x-card.heading>{{ $ensembleLimit->ensemble->name }}</x-card.heading> @if($seat['ensemble'] !== $previousEnsemble)
@foreach($ensembleSeats as $seat) <x-card.heading>{{$seat['ensemble']}}</x-card.heading>
@endif
<x-card.list.row class="!py-2"> <x-card.list.row class="!py-2">
{{ $seat->seat }} - {{ $seat->student->full_name() }} {{ $seat['seat'] }} - {{ $seat['student_name'] }}
</x-card.list.row> </x-card.list.row>
@endforeach @php
</x-card.card> $previousEnsemble = $seat['ensemble'];
@endforeach @endphp
@endforeach
</x-card.card>
{{--@foreach($ensembleLimits as $ensembleLimit)--}}
{{-- @php--}}
{{-- $ensembleSeats = $seatingService->getSeatsForAudition($audition->id)[$ensembleLimit->ensemble->id] ?? array();--}}
{{-- @endphp--}}
{{-- <x-card.card class="mb-3">--}}
{{-- <x-card.heading>{{ $ensembleLimit->ensemble->name }}</x-card.heading>--}}
{{-- @foreach($ensembleSeats as $seat)--}}
{{-- <x-card.list.row class="!py-2">--}}
{{-- {{ $seat->seat }} - {{ $seat->student->full_name() }}--}}
{{-- </x-card.list.row>--}}
{{-- @endforeach--}}
{{-- </x-card.card>--}}
{{--@endforeach--}}

View File

@ -5,11 +5,11 @@ use App\Http\Controllers\Tabulation\AdvancementController;
use App\Http\Controllers\Tabulation\DoublerDecisionController; 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\SeatAuditionController; 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\Controllers\Tabulation\TabulationController; use App\Http\Controllers\Tabulation\TabulationController;
use App\Http\Middleware\CheckIfCanTab; use App\Http\Middleware\CheckIfCanTab;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function () { Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function () {
@ -24,8 +24,7 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
}); });
// Entry Flagging // Entry Flagging
Route::prefix('entry-flags/')->controller(EntryFlagController::class)->group(function ( Route::prefix('entry-flags/')->controller(EntryFlagController::class)->group(function () {
) {
Route::get('/choose_no_show', 'noShowSelect')->name('entry-flags.noShowSelect'); Route::get('/choose_no_show', 'noShowSelect')->name('entry-flags.noShowSelect');
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');
@ -35,21 +34,19 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
// Seating Routes // Seating Routes
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}', SeatAuditionController::class)->name('seating.audition'); Route::match(['get', 'post'], '/{audition}', SeatAuditionFormController::class)->name('seating.audition');
Route::post('/{audition}/publish', [SeatingPublicationController::class, 'publishSeats'])->name('seating.audition.publish');
Route::post('/{audition}/unpublish', [SeatingPublicationController::class, 'unpublishSeats'])->name('seating.audition.unpublish');
}); });
// Generic Tabulation Routes (TO BE REPLACED) // Generic Tabulation Routes (TO BE REPLACED)
Route::prefix('tabulation/')->controller(TabulationController::class)->group(function ( Route::prefix('tabulation/')->controller(TabulationController::class)->group(function () {
) {
Route::get('/status', 'status')->name('tabulation.status');
Route::match(['get', 'post'], '/auditions/{audition}', 'auditionSeating')->name('tabulation.audition.seat');
Route::post('/auditions/{audition}/publish-seats', 'publishSeats')->name('tabulation.seat.publish'); Route::post('/auditions/{audition}/publish-seats', 'publishSeats')->name('tabulation.seat.publish');
Route::post('/auditions/{audition}/unpublish-seats', 'unpublishSeats')->name('tabulation.seat.unpublish'); Route::post('/auditions/{audition}/unpublish-seats', 'unpublishSeats')->name('tabulation.seat.unpublish');
}); });
// Advancement Routes // Advancement Routes
Route::prefix('advancement/')->controller(AdvancementController::class)->group(function ( Route::prefix('advancement/')->controller(AdvancementController::class)->group(function () {
) {
Route::get('/status', 'status')->name('advancement.status'); Route::get('/status', 'status')->name('advancement.status');
Route::get('/{audition}', 'ranking')->name('advancement.ranking'); Route::get('/{audition}', 'ranking')->name('advancement.ranking');
Route::post('/{audition}', 'setAuditionPassers')->name('advancement.setAuditionPassers'); Route::post('/{audition}', 'setAuditionPassers')->name('advancement.setAuditionPassers');