diff --git a/app/Http/Controllers/Tabulation/AdvancementController.php b/app/Http/Controllers/Tabulation/AdvancementController.php new file mode 100644 index 0000000..9581faa --- /dev/null +++ b/app/Http/Controllers/Tabulation/AdvancementController.php @@ -0,0 +1,60 @@ +tabulationService = $tabulationService; + } + + public function status() + { + $auditions = $this->tabulationService->getAuditionsWithStatus('advancement'); + + return view('tabulation.advancement.status', compact('auditions')); + } + + public function ranking(Request $request, Audition $audition) + { + $entries = $this->tabulationService->auditionEntries($audition->id, 'advancement'); + + $scoringComplete = $entries->every(function ($entry) { + return $entry->scoring_complete; + }); + + return view('tabulation.advancement.ranking', compact('audition', 'entries', 'scoringComplete')); + } + + public function setAuditionPassers(Request $request, Audition $audition) + { + $passingEntries = $request->input('pass'); + $passingEntries = array_keys($passingEntries); + $audition->addFlag('advancement_published'); + $entries = Entry::whereIn('id', $passingEntries)->get(); + foreach ($entries as $entry) { + $entry->addFlag('will_advance'); + } + + return redirect()->route('advancement.ranking', ['audition' => $audition->id])->with('success', 'Passers have been set successfully'); + } + + public function clearAuditionPassers(Request $request, Audition $audition) + { + $audition->removeFlag('advancement_published'); + foreach ($audition->entries as $entry) { + $entry->removeFlag('will_advance'); + } + + return redirect()->route('advancement.ranking', ['audition' => $audition->id])->with('success', 'Passers have been cleared successfully'); + } +} diff --git a/app/Services/DoublerService.php b/app/Services/DoublerService.php index daffd3a..5a1f777 100644 --- a/app/Services/DoublerService.php +++ b/app/Services/DoublerService.php @@ -4,6 +4,7 @@ namespace App\Services; use App\Models\Entry; use App\Models\Student; +use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Support\Facades\Cache; class DoublerService @@ -32,13 +33,19 @@ class DoublerService public function getDoublers(): \Illuminate\Database\Eloquent\Collection { // TODO creating or destroying an entry should refresh the doubler cache - // TODO this currently counts total entries, only need to count seating_entries. Would be an edge case, but needs to be fixed. - return Cache::remember($this->doublersCacheKey, 60, function () { - return Student::withCount('entries') - ->with('entries') + // TODO needs to split by event so that a doubler may enter jazz and concert events for example + $doublers = Cache::remember($this->doublersCacheKey, 60, function () { + return Student::withCount(['entries' => function (Builder $query) { + $query->where('for_seating', true); + }]) + ->with(['entries' => function (Builder $query) { + $query->where('for_seating', true); + }]) ->havingRaw('entries_count > ?', [1]) ->get(); }); + + return $doublers; } public function refreshDoublerCache() diff --git a/app/Services/EntryCacheService.php b/app/Services/EntryCacheService.php index 5ee0e2c..d353d74 100644 --- a/app/Services/EntryCacheService.php +++ b/app/Services/EntryCacheService.php @@ -24,17 +24,30 @@ class EntryCacheService * * @return \Illuminate\Database\Eloquent\Collection */ - public function getEntriesForAudition($auditionId) + public function getEntriesForAudition($auditionId, $mode = 'seating') { // TODO this invokes a lot of lazy loading. Perhaps cache the data for all entries then draw from that for each audition $cacheKey = 'audition'.$auditionId.'entries'; - return Cache::remember($cacheKey, 3600, function () use ($auditionId) { + $entries = Cache::remember($cacheKey, 3600, function () use ($auditionId) { return Entry::where('audition_id', $auditionId) ->with('student.school') ->get() ->keyBy('id'); }); + + switch ($mode) { + case 'seating': + return $entries->filter(function ($entry) { + return $entry->for_seating; + }); + case 'advancement': + return $entries->filter(function ($entry) { + return $entry->for_advancement; + }); + default: + return $entries; + } } /** diff --git a/app/Services/ScoreService.php b/app/Services/ScoreService.php index ad3ec19..128f5f4 100644 --- a/app/Services/ScoreService.php +++ b/app/Services/ScoreService.php @@ -101,7 +101,7 @@ class ScoreService * * @return void */ - public function calculateScoresForAudition($auditionId) + public function calculateScoresForAudition($auditionId, $mode= 'seating') { static $alreadyChecked = []; // if $auditionId is in the array $alreadyChecked return @@ -111,7 +111,7 @@ class ScoreService $alreadyChecked[] = $auditionId; $audition = $this->auditionCache->getAudition($auditionId); $scoringGuideId = $audition->scoring_guide_id; - $entries = $this->entryCache->getEntriesForAudition($auditionId); + $entries = $this->entryCache->getEntriesForAudition($auditionId, $mode); $entries->load('scoreSheets'); // TODO Cache this somehow, it's expensive and repetitive on the seating page foreach ($entries as $entry) { diff --git a/app/Services/TabulationService.php b/app/Services/TabulationService.php index 7c8e3b6..e8899f2 100644 --- a/app/Services/TabulationService.php +++ b/app/Services/TabulationService.php @@ -44,7 +44,7 @@ class TabulationService * * @return \Illuminate\Support\Collection|mixed */ - public function auditionEntries(int $auditionId) + public function auditionEntries(int $auditionId, $mode = 'seating') { static $cache = []; if (isset($cache[$auditionId])) { @@ -52,9 +52,9 @@ class TabulationService } $audition = $this->auditionCacheService->getAudition($auditionId); - $entries = $this->entryCacheService->getEntriesForAudition($auditionId); + $entries = $this->entryCacheService->getEntriesForAudition($auditionId, $mode); $this->scoreService->calculateScoresForAudition($auditionId); - + // TODO will need to pass a mode to the above function to only use subscores for hte appropriate mode foreach ($entries as $entry) { $entry->final_score_array = $this->scoreService->entryTotalScores($entry); $entry->scoring_complete = ($this->scoreService->entryScoreSheetCounts()[$entry->id] == $audition->judges_count); @@ -69,18 +69,20 @@ class TabulationService return 0; }); - //TODO verify this actually sorts by subscores correctly + + // Assign a rank to each entry. In the case of a declined seat by a doubler, indicate as so and do not increment rank $n = 1; /** @var Entry $entry */ foreach ($entries as $entry) { - if (! $entry->hasFlag('declined')) { + if (! $entry->hasFlag('declined') or $mode != 'seating') { $entry->rank = $n; $n++; } else { $entry->rank = $n.' - declined'; } } + $cache[$auditionId] = $entries->keyBy('id'); return $entries->keyBy('id'); @@ -117,6 +119,7 @@ class TabulationService case 'advancement': return $audition->advancement_entries_count - $audition->scored_entries_count; } + return $audition->entries_count - $audition->scored_entries_count; } @@ -132,9 +135,7 @@ class TabulationService return Cache::remember('auditionsWithStatus', 30, function () use ($mode) { // Retrieve auditions from the cache and load entry IDs - $auditions = $this->auditionCacheService->getAuditions(); - - + $auditions = $this->auditionCacheService->getAuditions($mode); // Iterate over the auditions and calculate the scored_entries_count foreach ($auditions as $audition) { $scored_entries_count = 0; @@ -169,6 +170,7 @@ class TabulationService } return $auditions; + }); } } diff --git a/resources/views/components/form/checkbox.blade.php b/resources/views/components/form/checkbox.blade.php index ac46979..ea0af3a 100644 --- a/resources/views/components/form/checkbox.blade.php +++ b/resources/views/components/form/checkbox.blade.php @@ -1,4 +1,4 @@ -@props(['name','label','description' => '', 'checked' => false]) +@props(['name','label' => false,'description' => '', 'checked' => false])
{{ $description }}
+ @if($label) + +{{ $description }}
+ @endif @error($name){{ $message }}
@enderror diff --git a/resources/views/components/layout/navbar/menus/tabulation.blade.php b/resources/views/components/layout/navbar/menus/tabulation.blade.php index 9e1906f..10617d7 100644 --- a/resources/views/components/layout/navbar/menus/tabulation.blade.php +++ b/resources/views/components/layout/navbar/menus/tabulation.blade.php @@ -21,7 +21,8 @@ diff --git a/resources/views/tabulation/advancement/ranking.blade.php b/resources/views/tabulation/advancement/ranking.blade.php new file mode 100644 index 0000000..948a549 --- /dev/null +++ b/resources/views/tabulation/advancement/ranking.blade.php @@ -0,0 +1,48 @@ +