diff --git a/app/Services/ScoreService.php b/app/Services/ScoreService.php index 42dc109..dc7d5e9 100644 --- a/app/Services/ScoreService.php +++ b/app/Services/ScoreService.php @@ -8,12 +8,15 @@ use App\Models\ScoringGuide; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; + use function array_unshift; class ScoreService { protected $auditionCache; + protected $entryCache; + /** * Create a new class instance. */ @@ -25,64 +28,69 @@ class ScoreService /** * Cache all scoring guides - * @return \Illuminate\Database\Eloquent\Collection */ public function getScoringGuides(): \Illuminate\Database\Eloquent\Collection { $cacheKey = 'scoringGuides'; - return Cache::remember($cacheKey, 3600, fn() => ScoringGuide::with('subscores')->withCount('subscores')->get()); + + return Cache::remember($cacheKey, 3600, fn () => ScoringGuide::with('subscores')->withCount('subscores')->get()); } /** * Retrieve a single scoring guide from the cache - * @param $id - * @return ScoringGuide */ public function getScoringGuide($id): ScoringGuide { - return $this->getScoringGuides()->find($id); + return $this->getScoringGuides()->find($id); } /** * Clear the scoring guide cache - * @return void */ public function clearScoringGuideCache(): void { Cache::forget('scoringGuides'); } - /** * Returns an array where each key is an entry id and the value is the number * of score sheets assigned to that entry. + * * @return Collection */ public function entryScoreSheetCounts() { $cacheKey = 'entryScoreSheetCounts'; - return Cache::remember($cacheKey, 10, function() { + + return Cache::remember($cacheKey, 10, function () { // For each Entry get the number of ScoreSheets associated with it - $entryScoreSheetCounts = ScoreSheet::select('entry_id', DB::raw('count(*) as count')) + $scoreSheetCountsByEntry = ScoreSheet::select('entry_id', DB::raw('count(*) as count')) ->groupBy('entry_id') ->get() - ->pluck('count','entry_id'); + ->pluck('count', 'entry_id'); + + $entryScoreSheetCounts = []; + $entries = $this->entryCache->getAllEntries(); + foreach ($entries as $entry) { + $entryScoreSheetCounts[$entry->id] = $scoreSheetCountsByEntry[$entry->id] ?? 0; + } + return $entryScoreSheetCounts; }); - } /** * Get final scores array for the requested entry. The first element is the total score. The following elements are sums * of each subscore in tiebreaker order - * @param Entry $entry + * * @return array */ public function entryTotalScores(Entry $entry) { - $cacheKey = 'entry' . $entry->id . 'totalScores'; + $cacheKey = 'entry'.$entry->id.'totalScores'; + return Cache::remember($cacheKey, 3600, function () use ($entry) { return $this->calculateFinalScoreArray($entry->audition->scoring_guide_id, $entry->scoreSheets); }); @@ -90,22 +98,24 @@ class ScoreService /** * Calculate and cache scores for all entries for the provided audition ID - * @param $auditionId + * * @return void */ public function calculateScoresForAudition($auditionId) { $audition = $this->auditionCache->getAudition($auditionId); $scoringGuideId = $audition->scoring_guide_id; -// $entries = Entry::where('audition_id',$auditionId)->with('scoreSheets')->get(); + // $entries = Entry::where('audition_id',$auditionId)->with('scoreSheets')->get(); $entries = $this->entryCache->getEntriesForAudition($auditionId); $entries->load('scoreSheets'); // TODO Cache this somehow, it's expensive and repetitive on the seating page foreach ($entries as $entry) { - $cacheKey = 'entry' . $entry->id . 'totalScores'; - if (Cache::has($cacheKey)) continue; + $cacheKey = 'entry'.$entry->id.'totalScores'; + if (Cache::has($cacheKey)) { + continue; + } $thisTotalScore = $this->calculateFinalScoreArray($scoringGuideId, $entry->scoreSheets); - Cache::put($cacheKey,$thisTotalScore,3600); + Cache::put($cacheKey, $thisTotalScore, 3600); } } @@ -117,15 +127,14 @@ class ScoreService public function clearEntryTotalScoresCache($entryId) { - $cacheKey = 'entry' . $entryId . 'totalScores'; + $cacheKey = 'entry'.$entryId.'totalScores'; Cache::forget($cacheKey); } public function clearAllCachedTotalScores() { - foreach ($this->entryCache->getAllEntries() as $entry) - { - $cacheKey = 'entry' . $entry->id . 'totalScores'; + foreach ($this->entryCache->getAllEntries() as $entry) { + $cacheKey = 'entry'.$entry->id.'totalScores'; Cache::forget($cacheKey); } } @@ -134,9 +143,6 @@ class ScoreService * Calculate final score using the provided scoring guide and score sheets. Returns an array of scores * The first element is the total score. The following elements are the sum of each subscore * in tiebreaker order. - * @param $scoringGuideId - * @param array|Collection $scoreSheets - * @return array */ public function calculateFinalScoreArray($scoringGuideId, array|Collection $scoreSheets): array { @@ -148,18 +154,18 @@ class ScoreService $ignoredSubscores = []; // This will be subscores not used for seating - // Init final scores array $finalScoresArray = []; foreach ($subscores as $subscore) { if (! $subscore->for_seating) { // Ignore scores that are not for seating $ignoredSubscores[] = $subscore->id; + continue; } $finalScoresArray[$subscore->id] = 0; } - foreach($scoreSheets as $sheet) { + foreach ($scoreSheets as $sheet) { foreach ($sheet->subscores as $ss) { if (in_array($ss['subscore_id'], $ignoredSubscores)) { // Ignore scores that are not for seating continue; @@ -179,14 +185,15 @@ class ScoreService $totalWeight += $subscore->weight; } $totalScore = ($totalScore / $totalWeight); - array_unshift($finalScoresArray,$totalScore); + array_unshift($finalScoresArray, $totalScore); + return $finalScoresArray; } /** * Validate that the judge on the score sheet is actually assigned to judge * then entry - * @param ScoreSheet $sheet + * * @return bool */ public function validateScoreSheet(ScoreSheet $sheet) @@ -196,14 +203,12 @@ class ScoreService $audition = $this->auditionCache->getAudition($entry->audition_id); $validJudges = $audition->judges; // send a laravel flash message with an error if the $sheet->user_id is not in the collection $validJudges - if (!$validJudges->contains('id', $sheet->user_id)) { - session()->flash('error', 'Entry ID ' . $sheet->entry_id . ' has an invalid score entered by ' . $sheet->judge->full_name()); + if (! $validJudges->contains('id', $sheet->user_id)) { + session()->flash('error', 'Entry ID '.$sheet->entry_id.' has an invalid score entered by '.$sheet->judge->full_name()); } // check if $sheet->user_id is in the collection $validJudges, return false if not, true if it is return $validJudges->contains('id', $sheet->user_id); - } - } diff --git a/app/Services/TabulationService.php b/app/Services/TabulationService.php index a9edc6d..924e465 100644 --- a/app/Services/TabulationService.php +++ b/app/Services/TabulationService.php @@ -57,7 +57,7 @@ class TabulationService foreach ($entries as $entry) { $entry->final_score_array = $this->scoreService->entryTotalScores($entry); - $entry->scoring_complete = $this->scoreService->entryScoreSheetCounts()[$entry->id] ?? $audition->judges_count == 0; + $entry->scoring_complete = ($this->scoreService->entryScoreSheetCounts()[$entry->id] == $audition->judges_count); } // Sort the array $entries by the first element in the final_score_array on each entry, then by the second element in that array continuing through each element in the final_score_array for each entry $entries = $entries->sort(function ($a, $b) { diff --git a/resources/views/tabulation/audition-results-table.blade.php b/resources/views/tabulation/audition-results-table.blade.php new file mode 100644 index 0000000..7b571f0 --- /dev/null +++ b/resources/views/tabulation/audition-results-table.blade.php @@ -0,0 +1,44 @@ + + + + + Rank + ID + Draw # + Student Name + Doubler + {{-- @foreach($judges as $judge)--}} + {{-- {{ $judge->short_name() }}--}} + {{-- @endforeach--}} + Total Score + All Scores? + + + + + @foreach($entries as $entry) + + {{ $entry->rank }} + {{ $entry->id }} + {{ $entry->draw_number }} + + {{ $entry->student->full_name() }}, + {{ $entry->student->school->name }} + + + @if($doublerService->studentIsDoubler($entry->student_id)) + @include('tabulation.doubler-block') + @endif + + {{ number_format($entry->final_score_array[0] ?? 0,4) }} + + @if($entry->scoring_complete) + + @endif + + + @endforeach + + + + diff --git a/resources/views/tabulation/auditionSeating.blade.php b/resources/views/tabulation/auditionSeating.blade.php index df5ec2b..8eb733a 100644 --- a/resources/views/tabulation/auditionSeating.blade.php +++ b/resources/views/tabulation/auditionSeating.blade.php @@ -1,50 +1,28 @@ @inject('doublerService','App\Services\DoublerService') +@php($blockSeating = []) Audition Seating - {{ $audition->name }} +
+
+
+ @include('tabulation.audition-results-table') +
+
+ + + Seating Form + +
- - - - - Rank - ID - Draw # - Student Name - Doubler - {{-- @foreach($judges as $judge)--}} - {{-- {{ $judge->short_name() }}--}} - {{-- @endforeach--}} - Total Score - All Scores? - - + @foreach($entries as $entry) + {{ dump($entry) }} + @endforeach +
+
+
+
- - @foreach($entries as $entry) - - {{ $entry->rank }} - {{ $entry->id }} - {{ $entry->draw_number }} - - {{ $entry->student->full_name() }}, - {{ $entry->student->school->name }} - - - @if($doublerService->studentIsDoubler($entry->student_id)) - - @endif - {{-- @if($entry->is_doubler)--}} - {{-- --}} - {{-- @endif--}} - - {{ number_format($entry->final_score_array[0] ?? 0,4) }} - @if($entry->scoring_complete) @endif - - @endforeach - - -
diff --git a/resources/views/components/doubler-block.blade.php b/resources/views/tabulation/doubler-block.blade.php similarity index 87% rename from resources/views/components/doubler-block.blade.php rename to resources/views/tabulation/doubler-block.blade.php index b8db0b1..747b12a 100644 --- a/resources/views/components/doubler-block.blade.php +++ b/resources/views/tabulation/doubler-block.blade.php @@ -1,10 +1,10 @@ -@props(['doublerEntryInfo']) -@php($doublerButtonClasses = 'hidden rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:block') +@php($doublerEntryInfo = $doublerService->getDoublerInfo($entry->student_id)) +@php($doublerButtonClasses = 'hidden rounded-md bg-white px-2.5 py-1.5 text-xs text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:block')