This commit is contained in:
Matt Young 2024-06-21 13:31:43 -05:00
parent b21902fc9a
commit 8900503556
3 changed files with 78 additions and 70 deletions

View File

@ -4,20 +4,15 @@ namespace App\Http\Controllers\Tabulation;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Audition; use App\Models\Audition;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Services\DoublerService; use App\Services\DoublerService;
use App\Services\TabulationService; use App\Services\TabulationService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use function compact; use function compact;
use function dd;
use function dump;
use function redirect;
class TabulationController extends Controller class TabulationController extends Controller
{ {
protected $tabulationService; protected $tabulationService;
protected $doublerService; protected $doublerService;
public function __construct(TabulationService $tabulationService, DoublerService $doublerService) public function __construct(TabulationService $tabulationService, DoublerService $doublerService)
@ -26,18 +21,17 @@ class TabulationController extends Controller
$this->doublerService = $doublerService; $this->doublerService = $doublerService;
} }
public function status() public function status()
{ {
$auditions = $this->tabulationService->getAuditionsWithStatus(); $auditions = $this->tabulationService->getAuditionsWithStatus();
return view('tabulation.status',compact('auditions'));
return view('tabulation.status', compact('auditions'));
} }
public function auditionSeating(Audition $audition) public function auditionSeating(Audition $audition)
{ {
$entries = $this->tabulationService->auditionEntries($audition->id); $entries = $this->tabulationService->auditionEntries($audition->id);
return view('tabulation.auditionSeating',compact('audition','entries')); return view('tabulation.auditionSeating', compact('audition', 'entries'));
} }
} }

View File

@ -3,18 +3,18 @@
namespace App\Services; namespace App\Services;
use App\Models\Entry; use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
class TabulationService class TabulationService
{ {
protected AuditionCacheService $auditionCacheService; protected AuditionCacheService $auditionCacheService;
protected EntryCacheService $entryCacheService; protected EntryCacheService $entryCacheService;
protected ScoreService $scoreService; protected ScoreService $scoreService;
/** /**
* Create a new class instance. * Create a new class instance.
*/ */
@ -30,23 +30,24 @@ class TabulationService
/** /**
* Returns the rank of the entry in its audition * Returns the rank of the entry in its audition
* @param Entry $entry *
* @return mixed * @return mixed
*/ */
public function entryRank(Entry $entry) { public function entryRank(Entry $entry)
{
return $this->auditionEntries($entry->audition_id)[$entry->id]->rank; return $this->auditionEntries($entry->audition_id)[$entry->id]->rank;
} }
/** /**
* Returns a collection of entries including their calculated final_score_array and ranked * Returns a collection of entries including their calculated final_score_array and ranked
* based upon their scores. * based upon their scores.
* @param Int $auditionId *
* @return \Illuminate\Support\Collection|mixed * @return \Illuminate\Support\Collection|mixed
*/ */
public function auditionEntries(Int $auditionId) public function auditionEntries(int $auditionId)
{ {
static $cache = []; static $cache = [];
if(isset($cache[$auditionId])) { if (isset($cache[$auditionId])) {
return $cache[$auditionId]; return $cache[$auditionId];
} }
@ -56,7 +57,7 @@ class TabulationService
foreach ($entries as $entry) { foreach ($entries as $entry) {
$entry->final_score_array = $this->scoreService->entryTotalScores($entry); $entry->final_score_array = $this->scoreService->entryTotalScores($entry);
$entry->scoring_complete = $this->scoreService->entryScoreSheetCounts()[$entry->id] ?? 0 == $audition->judges_count; $entry->scoring_complete = $this->scoreService->entryScoreSheetCounts()[$entry->id] ?? $audition->judges_count == 0;
} }
// 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 // 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) { $entries = $entries->sort(function ($a, $b) {
@ -65,41 +66,51 @@ class TabulationService
return $b->final_score_array[$i] > $a->final_score_array[$i] ? 1 : -1; return $b->final_score_array[$i] > $a->final_score_array[$i] ? 1 : -1;
} }
} }
return 0; return 0;
}); });
//TODO verify this actually sorts by subscores correctly //TODO verify this actually sorts by subscores correctly
$n = 1; $n = 1;
/** @var Entry $entry */
foreach ($entries as $entry) { foreach ($entries as $entry) {
if (! $entry->hasFlag('declined')) {
$entry->rank = $n; $entry->rank = $n;
$n++; $n++;
} else {
$entry->rank = 'declined';
}
} }
$cache[$auditionId] = $entries->keyBy('id'); $cache[$auditionId] = $entries->keyBy('id');
return $entries->keyBy('id'); return $entries->keyBy('id');
} }
public function entryScoreSheetsAreValid(Entry $entry): bool
public function entryScoreSheetsAreValid(Entry $entry): bool { {
//TODO consider making this move the invalid score to another database for further investigation //TODO consider making this move the invalid score to another database for further investigation
$validJudges = $this->auditionCacheService->getAudition($entry->audition_id)->judges; $validJudges = $this->auditionCacheService->getAudition($entry->audition_id)->judges;
foreach ($entry->scoreSheets as $sheet) { foreach ($entry->scoreSheets as $sheet) {
if (! $validJudges->contains($sheet->user_id)) { if (! $validJudges->contains($sheet->user_id)) {
$invalidJudge = User::find($sheet->user_id); $invalidJudge = User::find($sheet->user_id);
Session::flash('error','Invalid scores for entry ' . $entry->id . ' exist from ' . $invalidJudge->full_name()); Session::flash('error', 'Invalid scores for entry '.$entry->id.' exist from '.$invalidJudge->full_name());
return false; return false;
} }
} }
return true; return true;
} }
/** /**
* Returns the number of un-scored entries for the audition with the given ID. * Returns the number of un-scored entries for the audition with the given ID.
* @param $auditionId *
* @return mixed * @return mixed
*/ */
public function remainingEntriesForAudition($auditionId) public function remainingEntriesForAudition($auditionId)
{ {
$audition = $this->getAuditionsWithStatus()[$auditionId]; $audition = $this->getAuditionsWithStatus()[$auditionId];
return $audition->entries_count - $audition->scored_entries_count; return $audition->entries_count - $audition->scored_entries_count;
} }
@ -107,26 +118,28 @@ class TabulationService
* Get the array of all auditions from the cache. For each one, set a property * Get the array of all auditions from the cache. For each one, set a property
* scored_entries_count that indicates the number of entries for that audition that * scored_entries_count that indicates the number of entries for that audition that
* have a number of score sheets equal to the number of judges for that audition. * have a number of score sheets equal to the number of judges for that audition.
*
* @return mixed * @return mixed
*/ */
public function getAuditionsWithStatus() public function getAuditionsWithStatus()
{ {
return Cache::remember('auditionsWithStatus',30,function() { return Cache::remember('auditionsWithStatus', 30, function () {
// Retrieve auditions from the cache and load entry IDs // Retrieve auditions from the cache and load entry IDs
$auditions = $this->auditionCacheService->getAuditions(); $auditions = $this->auditionCacheService->getAuditions();
// Iterate over the auditions and calculate the scored_entries_count // Iterate over the auditions and calculate the scored_entries_count
foreach($auditions as $audition) { foreach ($auditions as $audition) {
$scored_entries_count = 0; $scored_entries_count = 0;
foreach ($this->entryCacheService->getEntriesForAudition($audition->id) as $entry) { foreach ($this->entryCacheService->getEntriesForAudition($audition->id) as $entry) {
if ($this->scoreService->entryScoreSheetCounts()[$entry->id] ?? 0 == $audition->judges_count) { if ($this->scoreService->entryScoreSheetCounts()[$entry->id] ?? $audition->judges_count == 0) {
$scored_entries_count++; $scored_entries_count++;
} }
} }
$audition->scored_entries_count = $scored_entries_count; $audition->scored_entries_count = $scored_entries_count;
} }
return $auditions; return $auditions;
}); });
} }

View File

@ -2,6 +2,7 @@
<x-layout.app> <x-layout.app>
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title> <x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
<x-card.card class="px-3">
<x-table.table> <x-table.table>
<thead> <thead>
<tr> <tr>
@ -10,9 +11,9 @@
<x-table.th>Draw #</x-table.th> <x-table.th>Draw #</x-table.th>
<x-table.th>Student Name</x-table.th> <x-table.th>Student Name</x-table.th>
<x-table.th>Doubler</x-table.th> <x-table.th>Doubler</x-table.th>
{{-- @foreach($judges as $judge)--}} {{-- @foreach($judges as $judge)--}}
{{-- <x-table.th>{{ $judge->short_name() }}</x-table.th>--}} {{-- <x-table.th>{{ $judge->short_name() }}</x-table.th>--}}
{{-- @endforeach--}} {{-- @endforeach--}}
<x-table.th>Total Score</x-table.th> <x-table.th>Total Score</x-table.th>
<x-table.th>All Scores?</x-table.th> <x-table.th>All Scores?</x-table.th>
</tr> </tr>
@ -33,9 +34,9 @@
<x-doubler-block :doublerEntryInfo="$doublerService->getDoublerInfo($entry->student_id)" /> <x-doubler-block :doublerEntryInfo="$doublerService->getDoublerInfo($entry->student_id)" />
@endif @endif
{{-- @if($entry->is_doubler)--}} {{-- @if($entry->is_doubler)--}}
{{-- <x-doubler-block :studentID="$entry->student->id" />--}} {{-- <x-doubler-block :studentID="$entry->student->id" />--}}
{{-- @endif--}} {{-- @endif--}}
</x-table.td> </x-table.td>
<x-table.td>{{ number_format($entry->final_score_array[0] ?? 0,4) }}</x-table.td> <x-table.td>{{ number_format($entry->final_score_array[0] ?? 0,4) }}</x-table.td>
<x-table.td>@if($entry->scoring_complete) <x-icons.checkmark color="green" /> @endif</x-table.td> <x-table.td>@if($entry->scoring_complete) <x-icons.checkmark color="green" /> @endif</x-table.td>
@ -43,7 +44,7 @@
@endforeach @endforeach
</x-table.body> </x-table.body>
</x-table.table> </x-table.table>
</x-card.card>
</x-layout.app> </x-layout.app>