Rewrite tabulation #14

Merged
okorpheus merged 43 commits from rewrite-tabulation into master 2024-07-14 05:36:29 +00:00
6 changed files with 97 additions and 17 deletions
Showing only changes of commit 009c85e044 - Show all commits

View File

@ -22,6 +22,7 @@ class AllJudgesCount implements CalculateEntryScore
public function calculate(string $mode, Entry $entry): array
{
$cacheKey = 'entryScore-'.$entry->id.'-'.$mode;
return Cache::remember($cacheKey, 10, function () use ($mode, $entry) {
$this->basicValidation($mode, $entry);
@ -35,6 +36,7 @@ class AllJudgesCount implements CalculateEntryScore
protected function getJudgeTotals($mode, Entry $entry)
{
$scores = [];
foreach ($this->auditionService->getJudges($entry->audition) as $judge) {
$scores[] = $this->calculator->__invoke($mode, $entry, $judge);
@ -49,7 +51,6 @@ class AllJudgesCount implements CalculateEntryScore
$index++;
}
}
return $sums;
}

View File

@ -4,32 +4,64 @@ namespace App\Http\Controllers\Tabulation;
use App\Actions\Tabulation\CalculateEntryScore;
use App\Actions\Tabulation\RankAuditionEntries;
use App\Exceptions\TabulationException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\Entry;
use App\Services\DoublerService;
use App\Services\EntryService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class SeatAuditionController extends Controller
{
protected CalculateEntryScore $calc;
protected DoublerService $doublerService;
protected RankAuditionEntries $ranker;
public function __construct(CalculateEntryScore $calc, RankAuditionEntries $ranker)
{
protected EntryService $entryService;
public function __construct(
CalculateEntryScore $calc,
RankAuditionEntries $ranker,
DoublerService $doublerService,
EntryService $entryService
) {
$this->calc = $calc;
$this->ranker = $ranker;
$this->doublerService = $doublerService;
$this->entryService = $entryService;
}
public function __invoke(Request $request, Audition $audition)
{
$doublers = $this->doublerService->doublersForEvent($audition->event);
$entryData = [];
#$entries = Entry::forSeating()->with('student.school')->where('audition_id', $audition->id)->get();
$entries = $this->ranker->rank('seating', $audition);
$entries->load('student.school');
foreach ($entries as $entry) {
$totalScoreColumn = $entry->score_totals[0] >= 0 ?
$entry->score_totals[0] : $entry->score_message;
$isDoubler = false;
if (array_key_exists($entry->student->id, $doublers)) {
$isDoubler = true;
$doubleData = [];
$doublerEntries = $doublers[$entry->student->id]['entries'];
foreach ($doublerEntries as $doublerEntry) {
Log::debug('doubler check for entry ' . $doublerEntry->id);
log::debug('Rank: ' . $this->entryService->rankOfEntry('seating', $doublerEntry));
$doubleData[] = [
'name' => $doublerEntry->audition->name,
'entryId' => $doublerEntry->id,
'rank' => $this->entryService->rankOfEntry('seating', $doublerEntry),
];
}
}
$totalScoreColumn = 'No Score';
$fullyScored = false;
if ($entry->score_totals) {
$totalScoreColumn = $entry->score_totals[0] >= 0 ? $entry->score_totals[0] : $entry->score_message;
$fullyScored = $entry->score_totals[0] >= 0;
}
$entryData[] = [
'rank' => $entry->rank,
'id' => $entry->id,
@ -37,11 +69,12 @@ class SeatAuditionController extends Controller
'schoolName' => $entry->student->school->name,
'drawNumber' => $entry->draw_number,
'totalScore' => $totalScoreColumn,
'fullyScored' => $entry->score_totals[0] >= 0,
'fullyScored' => $fullyScored,
'isDoubler' => $isDoubler,
'doubleData' => $doubleData ?? [],
];
}
//dd($entryData);
return view('tabulation.auditionSeating', ['entryData' => $entryData, 'audition' => $audition]);
return view('tabulation.auditionSeating', compact('entryData', 'audition', 'doublers'));
}
}

View File

@ -14,21 +14,25 @@ use Illuminate\Support\Facades\Cache;
*/
class DoublerService
{
public function doublersForEvent(Event $event)
public function doublersForEvent(Event $event, string $mode = 'seating')
{
$cacheKey = 'event'.$event->id.'doublers';
return Cache::remember($cacheKey, 60, function () use ($event) {
return $this->findDoublersForEvent($event);
$cacheKey = 'event'.$event->id.'doublers-'.$mode;
return Cache::remember($cacheKey, 60, function () use ($event, $mode) {
return $this->findDoublersForEvent($event, $mode);
});
}
/**
* @throws TabulationException
*/
protected function findDoublersForEvent(Event $event): array
protected function findDoublersForEvent(Event $event, string $mode): array
{
$this->validateEvent($event);
$entries = $event->entries;
$entries = match ($mode) {
'seating' => $entries->filter(fn ($entry) => $entry->for_seating === 1),
'advancement' => $entries->filter(fn ($entry) => $entry->for_advance === 1),
};
$entries->load('student.school');
$entries->load('audition');
$grouped = $entries->groupBy('student_id');

View File

@ -40,6 +40,6 @@ class EntryService
{
$ranker = App::make(RankAuditionEntries::class);
$rankings = $ranker->rank($mode, $entry->audition);
return $rankings->find($entry->id)->rank;
return $rankings->find($entry->id)->rank ?? 'No Rank';
}
}

View File

@ -26,6 +26,12 @@
<span class="text-xs text-gray-400">{{ $entry['schoolName'] }}</span>
</x-table.td>
<x-table.td class="!py-0">
@if($entry['isDoubler'])
DOUBLER<br>
@foreach($entry['doubleData'] as $double)
ID: {{ $double['entryId'] }} - {{ $double['name'] }} - {{ $double['rank'] }}<br>
@endforeach
@endif
{{-- @if($doublerService->studentIsDoubler($entry->student_id))--}}
{{-- @include('tabulation.auditionSeating-doubler-block')--}}
{{-- @endif--}}

View File

@ -1,6 +1,8 @@
<?php
use App\Models\Audition;
use App\Models\Entry;
use App\Models\Student;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\get;
@ -35,3 +37,37 @@ it('grants access to tabulators', function () {
// Act & Assert
get($this->r)->assertOk();
});
// TODO make tests with varied information
it('returns the audition object and an array of info on each entry', function () {
// Arrange
$entry = Entry::factory()->create(['audition_id' => $this->audition->id]);
actAsAdmin();
// Act
$response = get($this->r);
$response
->assertOk()
->assertViewHas('audition', $this->audition);
$viewData = $response->viewData('entryData');
expect($viewData[0]['rank'])->toBe(1);
expect($viewData[0]['id'])->toBe($entry->id);
expect($viewData[0]['studentName'])->toBe($entry->student->full_name());
expect($viewData[0]['schoolName'])->toBe($entry->student->school->name);
expect($viewData[0]['drawNumber'])->toBe($entry->draw_number);
expect($viewData[0]['totalScore'])->toBe('No Score');
expect($viewData[0]['fullyScored'])->toBeFalse();
});
it('identifies a doubler', function () {
// Arrange
$audition1 = Audition::factory()->create(['event_id' => $this->audition->event_id]);
$audition2 = Audition::factory()->create(['event_id' => $this->audition->event_id]);
$student = Student::factory()->create();
Entry::factory()->create(['audition_id' => $audition1->id, 'student_id' => $student->id]);
Entry::factory()->create(['audition_id' => $audition2->id, 'student_id' => $student->id]);
Entry::factory()->create(['audition_id' => $this->audition->id, 'student_id' => $student->id]);
actAsAdmin();
// Act & Assert
$response = get($this->r);
$response->assertOk();
$viewData = $response->viewData('entryData');
expect($viewData[0]['isDoubler'])->toBeTrue();
});