diff --git a/app/Actions/Tabulation/RankAuditionEntries.php b/app/Actions/Tabulation/RankAuditionEntries.php index 6a3e7d8..5e18fb7 100644 --- a/app/Actions/Tabulation/RankAuditionEntries.php +++ b/app/Actions/Tabulation/RankAuditionEntries.php @@ -6,6 +6,7 @@ namespace App\Actions\Tabulation; use App\Exceptions\AuditionAdminException; use App\Models\Audition; +use App\Models\Entry; use Illuminate\Support\Collection; class RankAuditionEntries @@ -19,7 +20,7 @@ class RankAuditionEntries * The ranked entries are returned as a Collection of Entry objects. * * @param string $rank_type advancement|seating - * @return Collection|void + * @return Collection|void * * @throws AuditionAdminException */ @@ -45,6 +46,7 @@ class RankAuditionEntries ->whereHas('totalScore') ->with('totalScore') ->with('student.school') + ->with('audition') ->join('entry_total_scores', 'entries.id', '=', 'entry_total_scores.entry_id') ->orderBy('entry_total_scores.seating_total', 'desc') ->orderByRaw('COALESCE(JSON_EXTRACT(entry_total_scores.seating_subscore_totals, "$[0]"), -999999) DESC') @@ -67,6 +69,7 @@ class RankAuditionEntries ->whereHas('totalScore') ->with('totalScore') ->with('student.school') + ->with('audition') ->join('entry_total_scores', 'entries.id', '=', 'entry_total_scores.entry_id') ->orderBy('entry_total_scores.advancement_total', 'desc') ->orderByRaw('COALESCE(JSON_EXTRACT(entry_total_scores.advancement_subscore_totals, "$[0]"), -999999) DESC') diff --git a/app/Http/Controllers/Tabulation/SeatAuditionFormController.php b/app/Http/Controllers/Tabulation/SeatAuditionFormController.php index b6f0ccb..e18f8c6 100644 --- a/app/Http/Controllers/Tabulation/SeatAuditionFormController.php +++ b/app/Http/Controllers/Tabulation/SeatAuditionFormController.php @@ -49,12 +49,21 @@ class SeatAuditionFormController extends Controller ->orderBy('draw_number', 'asc') ->get(); + // Get Doubler Data + $doubler_data = []; + foreach ($scored_entries as $e) { + if ($e->student->isDoublerInEvent($audition->event_id)) { + $doubler_data[$e->id] = $e->student->entriesForEvent($e->audition->event_id); + } + } + return view('tabulation.auditionSeating', compact('audition', 'scored_entries', 'unscored_entries', 'noshow_entries', - 'failed_prelim_entries') + 'failed_prelim_entries', + 'doubler_data', ) ); } diff --git a/app/Models/Audition.php b/app/Models/Audition.php index 0531535..d4d6e26 100644 --- a/app/Models/Audition.php +++ b/app/Models/Audition.php @@ -60,6 +60,15 @@ class Audition extends Model return $this->belongsToMany(BonusScoreDefinition::class, 'bonus_score_audition_assignment'); } + public function SeatingLimits(): HasMany + { + return $this->hasMany(SeatingLimit::class) + ->with('ensemble') + ->join('ensembles', 'seating_limits.ensemble_id', '=', 'ensembles.id') + ->orderBy('ensembles.rank') + ->select('seating_limits.*'); + } + public function display_fee(): string { return '$'.number_format($this->entry_fee / 100, 2); diff --git a/app/Models/Entry.php b/app/Models/Entry.php index d4cc57d..4b1cc64 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -2,7 +2,9 @@ namespace App\Models; +use App\Actions\Tabulation\RankAuditionEntries; use App\Enums\EntryFlags; +use App\Exceptions\AuditionAdminException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -24,6 +26,33 @@ class Entry extends Model return $this->hasOne(EntryTotalScore::class); } + /** + * @throws AuditionAdminException + */ + public function rank(string $type) + { + $ranker = app(RankAuditionEntries::class); + + if ($type !== 'seating' && $type !== 'advancement') { + throw new AuditionAdminException('Invalid type specified. Must be either seating or advancement.'); + } + + // Return false if no score. If we have no score, we can't have a rank + if (! $this->totalScore) { + return false; + } + + // Get the ranked entries for this entries audition + $rankedEntries = $ranker($this->audition, $type); + + // Find position of current entry in the ranked entries (1-based index) + $position = $rankedEntries->search(fn ($entry) => $entry->id === $this->id); + + // Return false if entry not found, otherwise return 1-based position + return $position === false ? false : $position + 1; + + } + public function student(): BelongsTo { return $this->belongsTo(Student::class); diff --git a/app/Models/Student.php b/app/Models/Student.php index 004f4bf..3769f74 100644 --- a/app/Models/Student.php +++ b/app/Models/Student.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; +use Illuminate\Support\Collection; class Student extends Model { @@ -103,4 +104,19 @@ class Student extends Model 'student_id' => $this->id, ])->exists(); } + + public function entriesForEvent(Event|int $event): Collection + { + $eventId = $event instanceof Event ? $event->id : $event; + + return Entry::query() + ->where('student_id', $this->id) + ->whereHas('audition', function ($query) use ($event) { + $query->where('event_id', $event); + }) + ->with('audition.SeatingLimits') // Eager load the audition relation if needed + ->with('totalScore') + ->get(); + + } } diff --git a/resources/views/tabulation/auditionSeating.blade.php b/resources/views/tabulation/auditionSeating.blade.php index 765c55f..8b10c6c 100644 --- a/resources/views/tabulation/auditionSeating.blade.php +++ b/resources/views/tabulation/auditionSeating.blade.php @@ -25,18 +25,47 @@ - + @foreach($scored_entries as $entry) - {{ $loop->iteration }} - {{ $entry->id }} - {{ $entry->draw_number }} - - {{ $entry->student->full_name() }} - {{ $entry->student->school->name }} + {{ $loop->iteration }} + {{ $entry->id }} + {{ $entry->draw_number }} + +
{{ $entry->student->full_name() }}
+
{{ $entry->student->school->name }}
- Doubler to Come - {{ $entry->totalScore->seating_total }} + + @if( isset($doubler_data[$entry->id]) ) + {{-- Check if this entry is a doubler --}} + @foreach($doubler_data[$entry->id] as $de) + {{-- If it is, render doubler blocks --}} +
+ {{-- @var \App\Models\Entry $de --}} +
+ {{ $de->audition->name }} #{{$de->draw_number}} ({{ $de->id }}) +
+ @php($unscored = $de->audition->unscoredEntries()->count()) + @if($unscored > 0) +
{{ $unscored }} Unscored Entries
+ @endif + @if(! $de->rank('seating')) +
THIS ENTRY NOT SCORED
+ @else +
Ranked: {{ $de->rank('seating') }}
+
+ Acceptance Limits
+ @foreach ($de->audition->SeatingLimits as $limit) + {{ $limit->ensemble->name }} -> {{ $limit->maximum_accepted }} +
+ @endforeach +
+ @endif +
+ @endforeach + @endif +
+ {{ $entry->totalScore->seating_total }} @endforeach