Everything ready for seating the audition.
This commit is contained in:
parent
0468cb5d11
commit
14b6bb61c7
|
|
@ -9,6 +9,7 @@ namespace App\Actions\Tabulation;
|
||||||
use App\Exceptions\ScoreEntryException;
|
use App\Exceptions\ScoreEntryException;
|
||||||
use App\Models\AuditLogEntry;
|
use App\Models\AuditLogEntry;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
use App\Models\EntryTotalScore;
|
||||||
use App\Models\ScoreSheet;
|
use App\Models\ScoreSheet;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
@ -28,8 +29,7 @@ class EnterScore
|
||||||
*/
|
*/
|
||||||
public function __invoke(User $user, Entry $entry, array $scores, ScoreSheet|false $scoreSheet = false): ScoreSheet
|
public function __invoke(User $user, Entry $entry, array $scores, ScoreSheet|false $scoreSheet = false): ScoreSheet
|
||||||
{
|
{
|
||||||
// TODO: Remove the CalculatedScore model and table when rewrite is complete, they'll be obsolete
|
EntryTotalScore::where('entry_id', $entry->id)->delete();
|
||||||
// CalculatedScore::where('entry_id', $entry->id)->delete();
|
|
||||||
$scores = collect($scores);
|
$scores = collect($scores);
|
||||||
|
|
||||||
// Basic Validity Checks
|
// Basic Validity Checks
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class RankAuditionEntries
|
||||||
|
|
||||||
private function get_seating_ranks(Audition $audition): Collection
|
private function get_seating_ranks(Audition $audition): Collection
|
||||||
{
|
{
|
||||||
return $audition->entries()
|
$sortedEntries = $audition->entries()
|
||||||
->whereHas('totalScore')
|
->whereHas('totalScore')
|
||||||
->with('totalScore')
|
->with('totalScore')
|
||||||
->with('student.school')
|
->with('student.school')
|
||||||
|
|
@ -61,6 +61,18 @@ class RankAuditionEntries
|
||||||
->orderByRaw('COALESCE(JSON_EXTRACT(entry_total_scores.seating_subscore_totals, "$[9]"), -999999) DESC')
|
->orderByRaw('COALESCE(JSON_EXTRACT(entry_total_scores.seating_subscore_totals, "$[9]"), -999999) DESC')
|
||||||
->select('entries.*')
|
->select('entries.*')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
$rankOn = 1;
|
||||||
|
foreach ($sortedEntries as $entry) {
|
||||||
|
if ($entry->hasFlag('declined')) {
|
||||||
|
$entry->seatingRank = 'declined';
|
||||||
|
} else {
|
||||||
|
$entry->seatingRank = $rankOn;
|
||||||
|
$rankOn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sortedEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function get_advancement_ranks(Audition $audition): Collection
|
private function get_advancement_ranks(Audition $audition): Collection
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ namespace App\Http\Controllers\Tabulation;
|
||||||
use App\Actions\Tabulation\EnterScore;
|
use App\Actions\Tabulation\EnterScore;
|
||||||
use App\Exceptions\ScoreEntryException;
|
use App\Exceptions\ScoreEntryException;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\CalculatedScore;
|
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
use App\Models\EntryTotalScore;
|
||||||
use App\Models\ScoreSheet;
|
use App\Models\ScoreSheet;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -25,7 +25,7 @@ class ScoreController extends Controller
|
||||||
|
|
||||||
public function destroyScore(ScoreSheet $score)
|
public function destroyScore(ScoreSheet $score)
|
||||||
{
|
{
|
||||||
CalculatedScore::where('entry_id', $score->entry_id)->delete();
|
EntryTotalScore::where('entry_id', $score->entry_id)->delete();
|
||||||
if ($score->entry->audition->hasFlag('seats_published')) {
|
if ($score->entry->audition->hasFlag('seats_published')) {
|
||||||
return redirect()->back()->with('error', 'Cannot delete scores for an entry where seats are published');
|
return redirect()->back()->with('error', 'Cannot delete scores for an entry where seats are published');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ use App\Models\Audition;
|
||||||
use App\Models\Doubler;
|
use App\Models\Doubler;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
use function PHPUnit\Framework\isNull;
|
||||||
|
|
||||||
class SeatAuditionFormController extends Controller
|
class SeatAuditionFormController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -58,19 +61,38 @@ class SeatAuditionFormController extends Controller
|
||||||
->get()
|
->get()
|
||||||
->keyBy('student_id');
|
->keyBy('student_id');
|
||||||
|
|
||||||
|
$auditionHasUnresolvedDoublers = false;
|
||||||
|
foreach ($doublerData as $doubler) {
|
||||||
|
if (! isNull($doubler->accepted_entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach ($doubler->entries() as $entry) {
|
||||||
|
if ($entry->audition_id === $audition->id && $entry->hasFlag('declined')) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$auditionHasUnresolvedDoublers = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$canSeat = ! $auditionHasUnresolvedDoublers && $unscored_entries->count() === 0;
|
||||||
|
|
||||||
return view('tabulation.auditionSeating',
|
return view('tabulation.auditionSeating',
|
||||||
compact('audition',
|
compact('audition',
|
||||||
'scored_entries',
|
'scored_entries',
|
||||||
'unscored_entries',
|
'unscored_entries',
|
||||||
'noshow_entries',
|
'noshow_entries',
|
||||||
'failed_prelim_entries',
|
'failed_prelim_entries',
|
||||||
'doublerData')
|
'doublerData',
|
||||||
|
'auditionHasUnresolvedDoublers',
|
||||||
|
'canSeat',
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function declineSeat(Audition $audition, Entry $entry)
|
public function declineSeat(Audition $audition, Entry $entry)
|
||||||
{
|
{
|
||||||
$entry->addFlag('declined');
|
$entry->addFlag('declined');
|
||||||
|
Cache::forget('rank_seating_'.$entry->audition_id);
|
||||||
|
|
||||||
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
|
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
|
||||||
$entry->student->full_name().' has declined '.$audition->name);
|
$entry->student->full_name().' has declined '.$audition->name);
|
||||||
|
|
@ -86,6 +108,7 @@ class SeatAuditionFormController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($doublerData->entries() as $doublerEntry) {
|
foreach ($doublerData->entries() as $doublerEntry) {
|
||||||
|
Cache::forget('rank_seating_'.$doublerEntry->audition_id);
|
||||||
if ($doublerEntry->id !== $entry->id && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim') && ! $doublerEntry->hasFlag('declined')) {
|
if ($doublerEntry->id !== $entry->id && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim') && ! $doublerEntry->hasFlag('declined')) {
|
||||||
$doublerEntry->addFlag('declined');
|
$doublerEntry->addFlag('declined');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,11 @@ class Entry extends Model
|
||||||
// Get the ranked entries for this entries audition
|
// Get the ranked entries for this entries audition
|
||||||
$rankedEntries = $ranker($this->audition, $type);
|
$rankedEntries = $ranker($this->audition, $type);
|
||||||
|
|
||||||
|
// If we're looking for seating rank, return the rank from the list of ranked entries
|
||||||
|
if ($type === 'seating') {
|
||||||
|
return $rankedEntries->where('id', $this->id)->first()->seatingRank;
|
||||||
|
}
|
||||||
|
|
||||||
// Find position of current entry in the ranked entries (1-based index)
|
// Find position of current entry in the ranked entries (1-based index)
|
||||||
$position = $rankedEntries->search(fn ($entry) => $entry->id === $this->id);
|
$position = $rankedEntries->search(fn ($entry) => $entry->id === $this->id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class EntryFlagObserver
|
||||||
public function created(EntryFlag $entryFlag): void
|
public function created(EntryFlag $entryFlag): void
|
||||||
{
|
{
|
||||||
Doubler::syncDoublers();
|
Doubler::syncDoublers();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Observers;
|
namespace App\Observers;
|
||||||
|
|
||||||
use App\Events\ScoreSheetChange;
|
use App\Actions\Tabulation\TotalEntryScores;
|
||||||
use App\Models\ScoreSheet;
|
use App\Models\ScoreSheet;
|
||||||
|
|
||||||
class ScoreSheetObserver
|
class ScoreSheetObserver
|
||||||
|
|
@ -12,7 +12,8 @@ class ScoreSheetObserver
|
||||||
*/
|
*/
|
||||||
public function created(ScoreSheet $scoreSheet): void
|
public function created(ScoreSheet $scoreSheet): void
|
||||||
{
|
{
|
||||||
//
|
$calculator = app(TotalEntryScores::class);
|
||||||
|
$calculator($scoreSheet->entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
@foreach($event_entries[$event->id] as $entry)
|
@foreach($event_entries[$event->id] as $entry)
|
||||||
<tr>
|
<tr>
|
||||||
<x-table.td>{{ $entry->id }}</x-table.td>
|
<x-table.td>{{ $entry->id }}</x-table.td>
|
||||||
<x-table.td>{{ $entry->audition->name }}</x-table.td>
|
<x-table.td><a href="{{ route ('seating.audition',[$entry->audition_id]) }}#entry-{{ $entry->id }}">{{ $entry->audition->name }}</a></x-table.td>
|
||||||
<x-table.td>{{ $entry->draw_number }}</x-table.td>
|
<x-table.td>{{ $entry->draw_number }}</x-table.td>
|
||||||
<x-table.td>
|
<x-table.td>
|
||||||
@if($entry->doubler_decision_frozen)
|
@if($entry->doubler_decision_frozen)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block for doubler entry --}}
|
<div class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block for doubler entry --}}
|
||||||
<div class="font-semibold mb-2">
|
<div class="font-semibold mb-2">
|
||||||
<a href="{{route('seating.audition',[$de->audition])}}">{{ $de->audition->name }}</a> #{{$de->draw_number}}
|
<a href="{{route('seating.audition',[$de->audition])}}#entry-{{ $de->id }}">{{ $de->audition->name }}</a> #{{$de->draw_number}}
|
||||||
({{ $de->id }})
|
({{ $de->id }})
|
||||||
</div>
|
</div>
|
||||||
@if($de->hasFlag('no_show'))
|
@if($de->hasFlag('no_show'))
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200">
|
<tbody class="divide-y divide-gray-200">
|
||||||
@foreach($scored_entries as $entry)
|
@foreach($scored_entries as $entry)
|
||||||
<tr>
|
<tr id="entry-{{ $entry->id }}">
|
||||||
<x-table.td class="align-top">{{ $loop->iteration }}</x-table.td>
|
<x-table.td class="align-top">{{ $entry->seatingRank }}</x-table.td>
|
||||||
<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">
|
||||||
|
|
@ -165,8 +165,8 @@
|
||||||
Cannot seat the audition while entries are unscored.
|
Cannot seat the audition while entries are unscored.
|
||||||
</x-card.card>
|
</x-card.card>
|
||||||
@endif
|
@endif
|
||||||
<hr>
|
|
||||||
@if($doublerData->contains('accepted_entry', null))
|
@if($auditionHasUnresolvedDoublers)
|
||||||
<x-card.card class="p-3 text-red-500">
|
<x-card.card class="p-3 text-red-500">
|
||||||
Cannot seat the audition while there are unresolved doublers.
|
Cannot seat the audition while there are unresolved doublers.
|
||||||
</x-card.card>
|
</x-card.card>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue