Everything ready for seating the audition.

This commit is contained in:
Matt Young 2025-06-25 22:51:27 -05:00
parent 0468cb5d11
commit 14b6bb61c7
10 changed files with 56 additions and 14 deletions

View File

@ -9,6 +9,7 @@ namespace App\Actions\Tabulation;
use App\Exceptions\ScoreEntryException;
use App\Models\AuditLogEntry;
use App\Models\Entry;
use App\Models\EntryTotalScore;
use App\Models\ScoreSheet;
use App\Models\User;
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
{
// TODO: Remove the CalculatedScore model and table when rewrite is complete, they'll be obsolete
// CalculatedScore::where('entry_id', $entry->id)->delete();
EntryTotalScore::where('entry_id', $entry->id)->delete();
$scores = collect($scores);
// Basic Validity Checks

View File

@ -42,7 +42,7 @@ class RankAuditionEntries
private function get_seating_ranks(Audition $audition): Collection
{
return $audition->entries()
$sortedEntries = $audition->entries()
->whereHas('totalScore')
->with('totalScore')
->with('student.school')
@ -61,6 +61,18 @@ class RankAuditionEntries
->orderByRaw('COALESCE(JSON_EXTRACT(entry_total_scores.seating_subscore_totals, "$[9]"), -999999) DESC')
->select('entries.*')
->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

View File

@ -5,8 +5,8 @@ namespace App\Http\Controllers\Tabulation;
use App\Actions\Tabulation\EnterScore;
use App\Exceptions\ScoreEntryException;
use App\Http\Controllers\Controller;
use App\Models\CalculatedScore;
use App\Models\Entry;
use App\Models\EntryTotalScore;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Http\Request;
@ -25,7 +25,7 @@ class ScoreController extends Controller
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')) {
return redirect()->back()->with('error', 'Cannot delete scores for an entry where seats are published');
}

View File

@ -10,6 +10,9 @@ use App\Models\Audition;
use App\Models\Doubler;
use App\Models\Entry;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use function PHPUnit\Framework\isNull;
class SeatAuditionFormController extends Controller
{
@ -58,19 +61,38 @@ class SeatAuditionFormController extends Controller
->get()
->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',
compact('audition',
'scored_entries',
'unscored_entries',
'noshow_entries',
'failed_prelim_entries',
'doublerData')
'doublerData',
'auditionHasUnresolvedDoublers',
'canSeat',
)
);
}
public function declineSeat(Audition $audition, Entry $entry)
{
$entry->addFlag('declined');
Cache::forget('rank_seating_'.$entry->audition_id);
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
$entry->student->full_name().' has declined '.$audition->name);
@ -86,6 +108,7 @@ class SeatAuditionFormController extends Controller
}
}
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')) {
$doublerEntry->addFlag('declined');
}

View File

@ -45,6 +45,11 @@ class Entry extends Model
// Get the ranked entries for this entries audition
$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)
$position = $rankedEntries->search(fn ($entry) => $entry->id === $this->id);

View File

@ -13,6 +13,7 @@ class EntryFlagObserver
public function created(EntryFlag $entryFlag): void
{
Doubler::syncDoublers();
}
/**

View File

@ -2,7 +2,7 @@
namespace App\Observers;
use App\Events\ScoreSheetChange;
use App\Actions\Tabulation\TotalEntryScores;
use App\Models\ScoreSheet;
class ScoreSheetObserver
@ -12,7 +12,8 @@ class ScoreSheetObserver
*/
public function created(ScoreSheet $scoreSheet): void
{
//
$calculator = app(TotalEntryScores::class);
$calculator($scoreSheet->entry, true);
}
/**

View File

@ -55,7 +55,7 @@
@foreach($event_entries[$event->id] as $entry)
<tr>
<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>
@if($entry->doubler_decision_frozen)

View File

@ -1,6 +1,6 @@
<div class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block for doubler entry --}}
<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 }})
</div>
@if($de->hasFlag('no_show'))

View File

@ -27,8 +27,8 @@
</thead>
<tbody class="divide-y divide-gray-200">
@foreach($scored_entries as $entry)
<tr>
<x-table.td class="align-top">{{ $loop->iteration }}</x-table.td>
<tr id="entry-{{ $entry->id }}">
<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->draw_number }}</x-table.td>
<x-table.td class="align-top">
@ -165,8 +165,8 @@
Cannot seat the audition while entries are unscored.
</x-card.card>
@endif
<hr>
@if($doublerData->contains('accepted_entry', null))
@if($auditionHasUnresolvedDoublers)
<x-card.card class="p-3 text-red-500">
Cannot seat the audition while there are unresolved doublers.
</x-card.card>