Seating is working
This commit is contained in:
parent
5e15b85319
commit
6469b063c1
|
|
@ -49,10 +49,8 @@ class DoublerDecisionController extends Controller
|
|||
if ($entry->hasFlag('declined')) {
|
||||
return redirect()->back()->with('caution', 'Entry is already declined');
|
||||
}
|
||||
EntryFlag::create([
|
||||
'entry_id' => $entry->id,
|
||||
'flag_name' => 'declined',
|
||||
]);
|
||||
|
||||
$entry->addFlag('declined');
|
||||
|
||||
$this->doublerService->refreshDoublerCache();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Tabulation;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Audition;
|
||||
use App\Models\Seat;
|
||||
use App\Services\DoublerService;
|
||||
use App\Services\SeatingService;
|
||||
use App\Services\TabulationService;
|
||||
|
|
@ -69,4 +70,32 @@ class TabulationController extends Controller
|
|||
'seatableEntries',
|
||||
'requestedEnsembleAccepts'));
|
||||
}
|
||||
|
||||
public function publishSeats(Request $request, Audition $audition)
|
||||
{
|
||||
// TODO move this to SeatingService
|
||||
$sessionKey = 'audition'.$audition->id.'seatingProposal';
|
||||
$seats = $request->session()->get($sessionKey);
|
||||
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');
|
||||
$request->session()->forget($sessionKey);
|
||||
return redirect()->route('tabulation.audition.seat', ['audition' => $audition->id]);
|
||||
}
|
||||
|
||||
public function unpublishSeats(Request $request, Audition $audition)
|
||||
{
|
||||
// TODO move this to SeatingService
|
||||
$this->seatingService->forgetSeatsForAudition($audition->id);
|
||||
Seat::where('audition_id', $audition->id)->delete();
|
||||
$audition->removeFlag('seats_published');
|
||||
|
||||
return redirect()->route('tabulation.audition.seat', ['audition' => $audition->id]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,4 +158,30 @@ class Audition extends Model
|
|||
|
||||
return $this->attributes['judges_count'];
|
||||
}
|
||||
|
||||
public function flags(): HasMany
|
||||
{
|
||||
return $this->hasMany(AuditionFlag::class);
|
||||
}
|
||||
|
||||
public function hasFlag($flag): bool
|
||||
{
|
||||
// return true if any flag in $this->flags has a flag_name of declined without making another db query if flags are loaded
|
||||
return $this->flags->contains('flag_name', $flag);
|
||||
}
|
||||
|
||||
public function addFlag($flag)
|
||||
{
|
||||
if ($this->hasFlag($flag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->flags()->create(['flag_name' => $flag]);
|
||||
}
|
||||
|
||||
public function removeFlag($flag)
|
||||
{
|
||||
// remove related auditionFlag where flag_name = $flag
|
||||
$this->flags()->where('flag_name', $flag)->delete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class AuditionFlag extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
public function audition(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Audition::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -56,13 +56,28 @@ class Entry extends Model
|
|||
return $this->hasMany(EntryFlag::class);
|
||||
}
|
||||
|
||||
public function hasFlag($flag)
|
||||
public function hasFlag($flag): bool
|
||||
{
|
||||
// return true if any flag in $this->flags has a flag_name of declined without making another db query if flags are loaded
|
||||
return $this->flags->contains('flag_name', $flag);
|
||||
|
||||
}
|
||||
|
||||
public function addFlag($flag)
|
||||
{
|
||||
if ($this->hasFlag($flag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->flags()->create(['flag_name' => $flag]);
|
||||
}
|
||||
|
||||
public function removeFlag($flag)
|
||||
{
|
||||
// remove related auditionFlag where flag_name = $flag
|
||||
$this->flags()->where('flag_name', $flag)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures score_sheets_count property is always available
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -4,8 +4,39 @@ namespace App\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
|
||||
class Seat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public function ensemble(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ensemble::class);
|
||||
}
|
||||
|
||||
public function audition(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Audition::class);
|
||||
}
|
||||
|
||||
public function entry(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Entry::class);
|
||||
}
|
||||
|
||||
public function student(): HasOneThrough
|
||||
{
|
||||
return $this->hasOneThrough(
|
||||
Student::class,
|
||||
Entry::class,
|
||||
'id',
|
||||
'id',
|
||||
'entry_id',
|
||||
'student_id'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Seat;
|
||||
use App\Models\SeatingLimit;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ class SeatingService
|
|||
return $this->getAcceptanceLimits()[$auditionId];
|
||||
}
|
||||
|
||||
public function refershLimits()
|
||||
public function refreshLimits(): void
|
||||
{
|
||||
Cache::forget($this->limitsCacheKey);
|
||||
}
|
||||
|
|
@ -46,8 +47,24 @@ class SeatingService
|
|||
public function getSeatableEntries($auditionId)
|
||||
{
|
||||
$entries = $this->tabulationService->auditionEntries($auditionId);
|
||||
|
||||
return $entries->reject(function ($entry) {
|
||||
return $entry->hasFlag('declined');
|
||||
});
|
||||
}
|
||||
|
||||
public function getSeatsForAudition($auditionId)
|
||||
{
|
||||
$cacheKey = 'audition'.$auditionId.'seats';
|
||||
|
||||
return Cache::remember($cacheKey, now()->addHour(), function () use ($auditionId) {
|
||||
return Seat::with('entry.student')->where('audition_id', $auditionId)->orderBy('seat')->get()->groupBy('ensemble_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function forgetSeatsForAudition($auditionId)
|
||||
{
|
||||
$cacheKey = 'audition'.$auditionId.'seats';
|
||||
Cache::forget($cacheKey);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
\<?php
|
||||
|
||||
use App\Models\Audition;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('audition_flags', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignIdFor(Audition::class)->constrained()->cascadeOnDelete()->cascadeOnUpdate();
|
||||
$table->string('flag_name');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('audition_flags');
|
||||
}
|
||||
};
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
@php
|
||||
$seatingProposal = [];
|
||||
@endphp
|
||||
|
||||
@foreach($ensembleLimits as $ensembleLimit)
|
||||
<x-card.card class="mb-3">
|
||||
<x-card.heading>{{ $ensembleLimit->ensemble->name }} - DRAFT</x-card.heading>
|
||||
|
|
@ -9,6 +13,12 @@
|
|||
@php
|
||||
$entry = $seatableEntries->shift();
|
||||
if (is_null($entry)) continue;
|
||||
$seatingProposal[] = [
|
||||
'ensemble_id' => $ensembleLimit->ensemble->id,
|
||||
'audition_id' => $audition->id,
|
||||
'seat' => $n,
|
||||
'entry_id' => $entry->id,
|
||||
];
|
||||
@endphp
|
||||
|
||||
<x-card.list.row class="!py-2">
|
||||
|
|
@ -18,3 +28,10 @@
|
|||
</x-card.list.body>
|
||||
</x-card.card>
|
||||
@endforeach
|
||||
<form method="POST" action="{{ route('tabulation.seat.publish',['audition' => $audition]) }}">
|
||||
@csrf
|
||||
<x-form.button type="submit">Seat and Publish</x-form.button>
|
||||
</form>
|
||||
@php
|
||||
session(['audition' . $audition->id . 'seatingProposal' => $seatingProposal]);
|
||||
@endphp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
@inject('seatingService','App\Services\SeatingService')
|
||||
|
||||
<x-card.card class="mb-3">
|
||||
<x-card.heading>
|
||||
Seats are Published
|
||||
</x-card.heading>
|
||||
|
||||
<x-form.form method="POST"
|
||||
action="{{ route('tabulation.seat.unpublish',['audition' => $audition->id]) }}"
|
||||
class="mx-5 my-2">
|
||||
<x-form.button type="submit">
|
||||
Unpublish
|
||||
</x-form.button>
|
||||
</x-form.form>
|
||||
|
||||
</x-card.card>
|
||||
|
||||
@foreach($ensembleLimits as $ensembleLimit)
|
||||
@php
|
||||
$ensembleSeats = $seatingService->getSeatsForAudition($audition->id)[$ensembleLimit->ensemble->id];
|
||||
@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
|
||||
|
|
@ -10,7 +10,9 @@
|
|||
@include('tabulation.auditionSeating-results-table')
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
@if(! $auditionComplete)
|
||||
@if($audition->hasFlag('seats_published'))
|
||||
@include('tabulation.auditionSeating-show-published-seats')
|
||||
@elseif(! $auditionComplete)
|
||||
@include('tabulation.auditionSeating-unable-to-seat-card')
|
||||
@else
|
||||
@include('tabulation.auditionSeating-fill-seats-form')
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Test Page</x-slot:page_title>
|
||||
@php
|
||||
dump($seatingService->getLimitForAudition(47));
|
||||
$audition = Audition::find(2);
|
||||
$audition->removeFlag('testFlag');
|
||||
@endphp
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
|
|||
Route::prefix('tabulation/')->controller(\App\Http\Controllers\Tabulation\TabulationController::class)->group(function () {
|
||||
Route::get('/status', '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}/unpublish-seats', 'unpublishSeats')->name('tabulation.seat.unpublish');
|
||||
});
|
||||
|
||||
// Doubler decision routes
|
||||
|
|
|
|||
Loading…
Reference in New Issue