Rewrite tabulation #14
|
|
@ -22,6 +22,7 @@ class AllJudgesCount implements CalculateEntryScore
|
||||||
|
|
||||||
public function calculate(string $mode, Entry $entry): array
|
public function calculate(string $mode, Entry $entry): array
|
||||||
{
|
{
|
||||||
|
|
||||||
$cacheKey = 'entryScore-'.$entry->id.'-'.$mode;
|
$cacheKey = 'entryScore-'.$entry->id.'-'.$mode;
|
||||||
return Cache::remember($cacheKey, 10, function () use ($mode, $entry) {
|
return Cache::remember($cacheKey, 10, function () use ($mode, $entry) {
|
||||||
$this->basicValidation($mode, $entry);
|
$this->basicValidation($mode, $entry);
|
||||||
|
|
@ -35,6 +36,7 @@ class AllJudgesCount implements CalculateEntryScore
|
||||||
|
|
||||||
protected function getJudgeTotals($mode, Entry $entry)
|
protected function getJudgeTotals($mode, Entry $entry)
|
||||||
{
|
{
|
||||||
|
|
||||||
$scores = [];
|
$scores = [];
|
||||||
foreach ($this->auditionService->getJudges($entry->audition) as $judge) {
|
foreach ($this->auditionService->getJudges($entry->audition) as $judge) {
|
||||||
$scores[] = $this->calculator->__invoke($mode, $entry, $judge);
|
$scores[] = $this->calculator->__invoke($mode, $entry, $judge);
|
||||||
|
|
@ -49,7 +51,6 @@ class AllJudgesCount implements CalculateEntryScore
|
||||||
$index++;
|
$index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sums;
|
return $sums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,32 +4,64 @@ namespace App\Http\Controllers\Tabulation;
|
||||||
|
|
||||||
use App\Actions\Tabulation\CalculateEntryScore;
|
use App\Actions\Tabulation\CalculateEntryScore;
|
||||||
use App\Actions\Tabulation\RankAuditionEntries;
|
use App\Actions\Tabulation\RankAuditionEntries;
|
||||||
use App\Exceptions\TabulationException;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
use App\Models\Entry;
|
use App\Services\DoublerService;
|
||||||
|
use App\Services\EntryService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class SeatAuditionController extends Controller
|
class SeatAuditionController extends Controller
|
||||||
{
|
{
|
||||||
protected CalculateEntryScore $calc;
|
protected CalculateEntryScore $calc;
|
||||||
|
|
||||||
|
protected DoublerService $doublerService;
|
||||||
|
|
||||||
protected RankAuditionEntries $ranker;
|
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->calc = $calc;
|
||||||
$this->ranker = $ranker;
|
$this->ranker = $ranker;
|
||||||
|
$this->doublerService = $doublerService;
|
||||||
|
$this->entryService = $entryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(Request $request, Audition $audition)
|
public function __invoke(Request $request, Audition $audition)
|
||||||
{
|
{
|
||||||
|
$doublers = $this->doublerService->doublersForEvent($audition->event);
|
||||||
$entryData = [];
|
$entryData = [];
|
||||||
#$entries = Entry::forSeating()->with('student.school')->where('audition_id', $audition->id)->get();
|
|
||||||
$entries = $this->ranker->rank('seating', $audition);
|
$entries = $this->ranker->rank('seating', $audition);
|
||||||
$entries->load('student.school');
|
$entries->load('student.school');
|
||||||
|
|
||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
$totalScoreColumn = $entry->score_totals[0] >= 0 ?
|
$isDoubler = false;
|
||||||
$entry->score_totals[0] : $entry->score_message;
|
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[] = [
|
$entryData[] = [
|
||||||
'rank' => $entry->rank,
|
'rank' => $entry->rank,
|
||||||
'id' => $entry->id,
|
'id' => $entry->id,
|
||||||
|
|
@ -37,11 +69,12 @@ class SeatAuditionController extends Controller
|
||||||
'schoolName' => $entry->student->school->name,
|
'schoolName' => $entry->student->school->name,
|
||||||
'drawNumber' => $entry->draw_number,
|
'drawNumber' => $entry->draw_number,
|
||||||
'totalScore' => $totalScoreColumn,
|
'totalScore' => $totalScoreColumn,
|
||||||
'fullyScored' => $entry->score_totals[0] >= 0,
|
'fullyScored' => $fullyScored,
|
||||||
|
'isDoubler' => $isDoubler,
|
||||||
|
'doubleData' => $doubleData ?? [],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
//dd($entryData);
|
return view('tabulation.auditionSeating', compact('entryData', 'audition', 'doublers'));
|
||||||
return view('tabulation.auditionSeating', ['entryData' => $entryData, 'audition' => $audition]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,21 +14,25 @@ use Illuminate\Support\Facades\Cache;
|
||||||
*/
|
*/
|
||||||
class DoublerService
|
class DoublerService
|
||||||
{
|
{
|
||||||
public function doublersForEvent(Event $event)
|
public function doublersForEvent(Event $event, string $mode = 'seating')
|
||||||
{
|
{
|
||||||
$cacheKey = 'event'.$event->id.'doublers';
|
$cacheKey = 'event'.$event->id.'doublers-'.$mode;
|
||||||
return Cache::remember($cacheKey, 60, function () use ($event) {
|
return Cache::remember($cacheKey, 60, function () use ($event, $mode) {
|
||||||
return $this->findDoublersForEvent($event);
|
return $this->findDoublersForEvent($event, $mode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws TabulationException
|
* @throws TabulationException
|
||||||
*/
|
*/
|
||||||
protected function findDoublersForEvent(Event $event): array
|
protected function findDoublersForEvent(Event $event, string $mode): array
|
||||||
{
|
{
|
||||||
$this->validateEvent($event);
|
$this->validateEvent($event);
|
||||||
$entries = $event->entries;
|
$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('student.school');
|
||||||
$entries->load('audition');
|
$entries->load('audition');
|
||||||
$grouped = $entries->groupBy('student_id');
|
$grouped = $entries->groupBy('student_id');
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,6 @@ class EntryService
|
||||||
{
|
{
|
||||||
$ranker = App::make(RankAuditionEntries::class);
|
$ranker = App::make(RankAuditionEntries::class);
|
||||||
$rankings = $ranker->rank($mode, $entry->audition);
|
$rankings = $ranker->rank($mode, $entry->audition);
|
||||||
return $rankings->find($entry->id)->rank;
|
return $rankings->find($entry->id)->rank ?? 'No Rank';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@
|
||||||
<span class="text-xs text-gray-400">{{ $entry['schoolName'] }}</span>
|
<span class="text-xs text-gray-400">{{ $entry['schoolName'] }}</span>
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
<x-table.td class="!py-0">
|
<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))--}}
|
{{-- @if($doublerService->studentIsDoubler($entry->student_id))--}}
|
||||||
{{-- @include('tabulation.auditionSeating-doubler-block')--}}
|
{{-- @include('tabulation.auditionSeating-doubler-block')--}}
|
||||||
{{-- @endif--}}
|
{{-- @endif--}}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
|
use App\Models\Entry;
|
||||||
|
use App\Models\Student;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
use function Pest\Laravel\get;
|
use function Pest\Laravel\get;
|
||||||
|
|
@ -35,3 +37,37 @@ it('grants access to tabulators', function () {
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
get($this->r)->assertOk();
|
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();
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue