Cleanup doubler info
This commit is contained in:
parent
b2bb3654ff
commit
a1f5191a19
|
|
@ -36,7 +36,6 @@ class DoublerDecisionController extends Controller
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->doublerService->refreshDoublerCache();
|
|
||||||
|
|
||||||
$returnMessage = $entry->student->full_name().' accepted seating in '.$entry->audition->name;
|
$returnMessage = $entry->student->full_name().' accepted seating in '.$entry->audition->name;
|
||||||
|
|
||||||
|
|
@ -52,8 +51,6 @@ class DoublerDecisionController extends Controller
|
||||||
|
|
||||||
$entry->addFlag('declined');
|
$entry->addFlag('declined');
|
||||||
|
|
||||||
$this->doublerService->refreshDoublerCache();
|
|
||||||
|
|
||||||
$returnMessage = $entry->student->full_name().' declined seating in '.$entry->audition->name;
|
$returnMessage = $entry->student->full_name().' declined seating in '.$entry->audition->name;
|
||||||
|
|
||||||
return redirect()->back()->with('success', $returnMessage);
|
return redirect()->back()->with('success', $returnMessage);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ use App\Services\AuditionService;
|
||||||
use App\Services\DoublerService;
|
use App\Services\DoublerService;
|
||||||
use App\Services\EntryService;
|
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
|
||||||
{
|
{
|
||||||
|
|
@ -46,28 +45,6 @@ class SeatAuditionController extends Controller
|
||||||
$entries->load('student.school');
|
$entries->load('student.school');
|
||||||
|
|
||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
$isDoubler = false;
|
|
||||||
if (array_key_exists($entry->student->id, $doublers)) {
|
|
||||||
$isDoubler = true;
|
|
||||||
$doubleData = [];
|
|
||||||
$doublerEntries = $doublers[$entry->student->id]['entries'];
|
|
||||||
|
|
||||||
foreach ($doublerEntries as $doublerEntry) {
|
|
||||||
$limits = $this->auditionService->getSeatingLimits($doublerEntry->audition);
|
|
||||||
$limits = $limits->reject(function ($lim) {
|
|
||||||
return $lim['limit'] === 0;
|
|
||||||
});
|
|
||||||
$doubleData[] = [
|
|
||||||
'audition' => $doublerEntry->audition,
|
|
||||||
'name' => $doublerEntry->audition->name,
|
|
||||||
'entryId' => $doublerEntry->id,
|
|
||||||
'rank' => $this->entryService->rankOfEntry('seating', $doublerEntry),
|
|
||||||
'limits' => $limits,
|
|
||||||
'status' => 'undecided', // Will be undecided, accepted, or declined
|
|
||||||
'unscored_in_audition' => $doublerEntry->audition->unscoredEntries()->count(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$totalScoreColumn = 'No Score';
|
$totalScoreColumn = 'No Score';
|
||||||
$fullyScored = false;
|
$fullyScored = false;
|
||||||
if ($entry->score_totals) {
|
if ($entry->score_totals) {
|
||||||
|
|
@ -82,8 +59,7 @@ class SeatAuditionController extends Controller
|
||||||
'drawNumber' => $entry->draw_number,
|
'drawNumber' => $entry->draw_number,
|
||||||
'totalScore' => $totalScoreColumn,
|
'totalScore' => $totalScoreColumn,
|
||||||
'fullyScored' => $fullyScored,
|
'fullyScored' => $fullyScored,
|
||||||
'isDoubler' => $isDoubler,
|
'doubleData' => $this->doublerService->entryDoublerData($entry),
|
||||||
'doubleData' => $doubleData ?? [],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,15 +98,15 @@ class AuditionService
|
||||||
$limits = SeatingLimit::all();
|
$limits = SeatingLimit::all();
|
||||||
|
|
||||||
foreach ($limits as $limit) {
|
foreach ($limits as $limit) {
|
||||||
$lims[$limit->audition_id][$limit->ensemble_id] = collect([
|
$lims[$limit->audition_id][$limit->ensemble_id] = [
|
||||||
'ensemble' => $ensembles->find($limit->ensemble_id),
|
'ensemble' => $ensembles->find($limit->ensemble_id),
|
||||||
'limit' =>$limit->maximum_accepted,
|
'limit' =>$limit->maximum_accepted,
|
||||||
]);
|
];
|
||||||
}
|
}
|
||||||
return collect($lims);
|
return $lims;
|
||||||
});
|
});
|
||||||
|
|
||||||
return collect($allLimits[$audition->id]) ?? [];
|
return $allLimits[$audition->id] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function validateAudition($audition)
|
protected function validateAudition($audition)
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,29 @@ use App\Exceptions\TabulationException;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use App\Models\Event;
|
use App\Models\Event;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class DoublerService
|
||||||
|
{
|
||||||
|
protected EntryService $entryService;
|
||||||
|
|
||||||
|
protected AuditionService $auditionService;
|
||||||
|
|
||||||
|
public function __construct(EntryService $entryService, AuditionService $auditionService)
|
||||||
|
{
|
||||||
|
$this->entryService = $entryService;
|
||||||
|
$this->auditionService = $auditionService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a collection of doublers for the event in the form of
|
* returns a collection of doublers for the event in the form of
|
||||||
* [studentId => [student=>student, entries=>[entries]]
|
* [studentId => [student=>student, entries=>[entries]]
|
||||||
*/
|
*/
|
||||||
class DoublerService
|
|
||||||
{
|
|
||||||
public function doublersForEvent(Event $event, string $mode = 'seating')
|
public function doublersForEvent(Event $event, string $mode = 'seating')
|
||||||
{
|
{
|
||||||
$cacheKey = 'event'.$event->id.'doublers-'.$mode;
|
$cacheKey = 'event'.$event->id.'doublers-'.$mode;
|
||||||
|
|
||||||
return Cache::remember($cacheKey, 60, function () use ($event, $mode) {
|
return Cache::remember($cacheKey, 60, function () use ($event, $mode) {
|
||||||
return $this->findDoublersForEvent($event, $mode);
|
return $this->findDoublersForEvent($event, $mode);
|
||||||
});
|
});
|
||||||
|
|
@ -25,7 +37,7 @@ class DoublerService
|
||||||
/**
|
/**
|
||||||
* @throws TabulationException
|
* @throws TabulationException
|
||||||
*/
|
*/
|
||||||
protected function findDoublersForEvent(Event $event, string $mode): array
|
protected function findDoublersForEvent(Event $event, string $mode = 'seating'): array
|
||||||
{
|
{
|
||||||
$this->validateEvent($event);
|
$this->validateEvent($event);
|
||||||
$entries = $event->entries;
|
$entries = $event->entries;
|
||||||
|
|
@ -49,6 +61,59 @@ class DoublerService
|
||||||
return $doubler_array;
|
return $doubler_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function entryDoublerData(Entry $primaryEntry)
|
||||||
|
{
|
||||||
|
if (! isset($this->findDoublersForEvent($primaryEntry->audition->event)[$primaryEntry->student_id])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$entries = $this->findDoublersForEvent($primaryEntry->audition->event)[$primaryEntry->student_id]['entries'];
|
||||||
|
$entryData = collect([]);
|
||||||
|
/** @var Collection $entries */
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$status = 'undecided';
|
||||||
|
if ($entry->hasFlag('declined')) {
|
||||||
|
$status = 'declined';
|
||||||
|
}
|
||||||
|
if ($entry->hasFlag('no_show')) {
|
||||||
|
$status = 'no_show';
|
||||||
|
}
|
||||||
|
|
||||||
|
$lims = $this->auditionService->getSeatingLimits($entry->audition);
|
||||||
|
$limits = [];
|
||||||
|
foreach ($lims as $lim) {
|
||||||
|
$limits[] = [
|
||||||
|
'ensemble_name' => $lim['ensemble']->name,
|
||||||
|
'accepts' => $lim['limit'],
|
||||||
|
'ensemble' => $lim['ensemble'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$entryData[$entry->id] = [
|
||||||
|
'entry' => $entry,
|
||||||
|
'audition' => $entry->audition,
|
||||||
|
'auditionName' => $entry->audition->name,
|
||||||
|
'status' => $status,
|
||||||
|
'rank' => $this->entryService->rankOfEntry('seating', $entry),
|
||||||
|
'unscored_entries' => $entry->audition->unscoredEntries()->count(),
|
||||||
|
'seating_limits' => $limits,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// find out how many items in the collection $entryData have a status of 'undecided'
|
||||||
|
$undecided_count = $entryData->filter(fn ($entry) => $entry['status'] === 'undecided')->count();
|
||||||
|
// if $undecided_count is 1 set the item where status is 'undecided' to 'accepted'
|
||||||
|
if ($undecided_count === 1) {
|
||||||
|
$entryData->transform(function ($entry) {
|
||||||
|
if ($entry['status'] === 'undecided') {
|
||||||
|
$entry['status'] = 'accepted';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $entry;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $entryData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws TabulationException
|
* @throws TabulationException
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ class EntryService
|
||||||
{
|
{
|
||||||
$ranker = App::make(RankAuditionEntries::class);
|
$ranker = App::make(RankAuditionEntries::class);
|
||||||
$rankings = $ranker->rank($mode, $entry->audition);
|
$rankings = $ranker->rank($mode, $entry->audition);
|
||||||
|
$rankedEntry = $rankings->find($entry->id);
|
||||||
|
if (isset($rankedEntry->score_message)) {
|
||||||
|
return $rankedEntry->score_message;
|
||||||
|
}
|
||||||
return $rankings->find($entry->id)->rank ?? 'No Rank';
|
return $rankings->find($entry->id)->rank ?? 'No Rank';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,8 @@
|
||||||
<li class="pb-2 pt-0 px-0 my-2 rounded-xl border border-gray-200 max-w-xs" x-data="{ open: {{ $isopen ? 'true':'false' }} }">
|
<li class="pb-2 pt-0 px-0 my-2 rounded-xl border border-gray-200 max-w-xs" x-data="{ open: {{ $isopen ? 'true':'false' }} }">
|
||||||
<div class="flex items-start gap-x-3 bg-gray-100 px-3 py-2 rounded-t-xl" >
|
<div class="flex items-start gap-x-3 bg-gray-100 px-3 py-2 rounded-t-xl" >
|
||||||
<p class="text-sm font-semibold leading-6 text-gray-900">
|
<p class="text-sm font-semibold leading-6 text-gray-900">
|
||||||
{{-- TODO put in link --}}
|
|
||||||
<a href="{{ route('seating.audition', $double['audition']) }}">
|
<a href="{{ route('seating.audition', $double['audition']) }}">
|
||||||
{{ $double['name'] }} - {{ $double['status'] }}
|
{{ $double['auditionName'] }} - {{ $double['status'] }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<div class="w-full flex justify-end" >
|
<div class="w-full flex justify-end" >
|
||||||
|
|
@ -21,26 +20,23 @@
|
||||||
<div class="grid grid-cols-4" x-show="open">
|
<div class="grid grid-cols-4" x-show="open">
|
||||||
<div class="mt-1 px-3 text-xs leading-5 text-gray-500 col-span-3">
|
<div class="mt-1 px-3 text-xs leading-5 text-gray-500 col-span-3">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="flex items-center gap-x-2">
|
<li class="">
|
||||||
<p class="whitespace-nowrap">Ranked {{ $double['rank'] }}</p>
|
<p class="whitespace-nowrap">Ranked {{ $double['rank'] }}</p>
|
||||||
<svg viewBox="0 0 2 2" class="h-0.5 w-0.5 fill-current">
|
<p class="truncate">{{ $double['unscored_entries'] }} Unscored</p>
|
||||||
<circle cx="1" cy="1" r="1" />
|
|
||||||
</svg>
|
|
||||||
<p class="truncate">{{ $double['unscored_in_audition'] }} Unscored</p>
|
|
||||||
</li>
|
</li>
|
||||||
@foreach($double['limits'] as $limit)
|
@foreach($double['seating_limits'] as $limit)
|
||||||
<li>{{$limit['ensemble']->name}} accepts {{ $limit['limit'] }}</li>
|
<li>{{$limit['ensemble_name']}} accepts {{ $limit['accepts'] }}</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col justify-end gap-y-1 pt-1">
|
<div class="flex flex-col justify-end gap-y-1 pt-1">
|
||||||
@if ($double['status'] == 'undecided')
|
@if ($double['status'] == 'undecided')
|
||||||
<form method="POST" action="{{ route('doubler.accept',['entry'=>$double['entryId']]) }}">
|
<form method="POST" action="{{ route('doubler.accept',['entry'=>$double['entry']]) }}">
|
||||||
@csrf
|
@csrf
|
||||||
<button class="{{ $doublerButtonClasses }}">Accept</button>
|
<button class="{{ $doublerButtonClasses }}">Accept</button>
|
||||||
</form>
|
</form>
|
||||||
<form method="POST" action="{{ route('doubler.decline',['entry'=>$double['entryId']]) }}">
|
<form method="POST" action="{{ route('doubler.decline',['entry'=>$double['entry']]) }}">
|
||||||
@csrf
|
@csrf
|
||||||
<button class="{{ $doublerButtonClasses }}">Decline</button>
|
<button class="{{ $doublerButtonClasses }}">Decline</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
<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'])
|
@if($entry['doubleData'])
|
||||||
@include('tabulation.auditionSeating-doubler-block')
|
@include('tabulation.auditionSeating-doubler-block')
|
||||||
{{-- DOUBLER<br>--}}
|
{{-- DOUBLER<br>--}}
|
||||||
{{-- @foreach($entry['doubleData'] as $double)--}}
|
{{-- @foreach($entry['doubleData'] as $double)--}}
|
||||||
|
|
|
||||||
|
|
@ -23,38 +23,37 @@ it('throws an error if an invalid event is provided', function () {
|
||||||
it('returns doublers for an event', function () {
|
it('returns doublers for an event', function () {
|
||||||
$concertEvent = Event::factory()->create(['name' => 'Concert Band', 'id' => 1000]);
|
$concertEvent = Event::factory()->create(['name' => 'Concert Band', 'id' => 1000]);
|
||||||
$jazzEvent = Event::factory()->create(['name' => 'Jazz Band', 'id' => 1001]);
|
$jazzEvent = Event::factory()->create(['name' => 'Jazz Band', 'id' => 1001]);
|
||||||
|
Audition::factory()->create([
|
||||||
$auditionAS = Audition::factory()->create([
|
|
||||||
'event_id' => 1000, 'name' => 'Alto Sax', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1000,
|
'event_id' => 1000, 'name' => 'Alto Sax', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1000,
|
||||||
]);
|
]);
|
||||||
$auditionTS = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1000, 'name' => 'Tenor Sax', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1001,
|
'event_id' => 1000, 'name' => 'Tenor Sax', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1001,
|
||||||
]);
|
]);
|
||||||
$auditionBS = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1000, 'name' => 'Baritone Sax', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1002,
|
'event_id' => 1000, 'name' => 'Baritone Sax', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1002,
|
||||||
]);
|
]);
|
||||||
$auditionCL = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1000, 'name' => 'Clarinet', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1003,
|
'event_id' => 1000, 'name' => 'Clarinet', 'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1003,
|
||||||
]);
|
]);
|
||||||
$auditionBCL = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1000, 'name' => 'Bass Clarinet',
|
'event_id' => 1000, 'name' => 'Bass Clarinet',
|
||||||
'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1004,
|
'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1004,
|
||||||
]);
|
]);
|
||||||
$auditionJAS = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1001, 'name' => 'Jazz Alto', 'minimum_grade' => 7,
|
'event_id' => 1001, 'name' => 'Jazz Alto', 'minimum_grade' => 7,
|
||||||
'maximum_grade' => 12, 'id' => 1005,
|
'maximum_grade' => 12, 'id' => 1005,
|
||||||
]);
|
]);
|
||||||
$auditionJTS = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1001, 'name' => 'Jazz Tenor', 'minimum_grade' => 7,
|
'event_id' => 1001, 'name' => 'Jazz Tenor', 'minimum_grade' => 7,
|
||||||
'maximum_grade' => 12, 'id' => 1006,
|
'maximum_grade' => 12, 'id' => 1006,
|
||||||
]);
|
]);
|
||||||
$auditionJBS = Audition::factory()->create([
|
Audition::factory()->create([
|
||||||
'event_id' => 1001, 'name' => 'Jazz Baritone',
|
'event_id' => 1001, 'name' => 'Jazz Baritone',
|
||||||
'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1007,
|
'minimum_grade' => 7, 'maximum_grade' => 12, 'id' => 1007,
|
||||||
]);
|
]);
|
||||||
$allSaxDude = Student::factory()->create(['grade' => 11, 'id' => 1000]);
|
$allSaxDude = Student::factory()->create(['grade' => 11, 'id' => 1000]);
|
||||||
$clarinetGal = Student::factory()->create(['grade' => 9, 'id' => 1001]);
|
Student::factory()->create(['grade' => 9, 'id' => 1001]);
|
||||||
$justAlto = Student::factory()->create(['grade' => 9, 'id' => 1002]);
|
Student::factory()->create(['grade' => 9, 'id' => 1002]);
|
||||||
Entry::create(['student_id' => 1000, 'audition_id' => 1000]);
|
Entry::create(['student_id' => 1000, 'audition_id' => 1000]);
|
||||||
Entry::create(['student_id' => 1000, 'audition_id' => 1001]);
|
Entry::create(['student_id' => 1000, 'audition_id' => 1001]);
|
||||||
Entry::create(['student_id' => 1000, 'audition_id' => 1002]);
|
Entry::create(['student_id' => 1000, 'audition_id' => 1002]);
|
||||||
|
|
@ -67,13 +66,13 @@ it('returns doublers for an event', function () {
|
||||||
Entry::create(['student_id' => 1002, 'audition_id' => 1005]);
|
Entry::create(['student_id' => 1002, 'audition_id' => 1005]);
|
||||||
|
|
||||||
$return = $this->doublerService->doublersForEvent($concertEvent);
|
$return = $this->doublerService->doublersForEvent($concertEvent);
|
||||||
expect(count($return))->toBe(2);
|
expect(count($return))->toBe(2)
|
||||||
expect($return[1000]['student']->id)->toBe($allSaxDude->id);
|
->and($return[1000]['student']->id)->toBe($allSaxDude->id)
|
||||||
expect($return[1000]['entries']->count())->toBe(3);
|
->and($return[1000]['entries']->count())->toBe(3)
|
||||||
expect($return[1001]['entries']->count())->toBe(2);
|
->and($return[1001]['entries']->count())->toBe(2);
|
||||||
assertArrayNotHasKey(1002, $return);
|
assertArrayNotHasKey(1002, $return);
|
||||||
$return = $this->doublerService->doublersForEvent($jazzEvent);
|
$return = $this->doublerService->doublersForEvent($jazzEvent);
|
||||||
expect(count($return))->toBe(1);
|
expect(count($return))->toBe(1)
|
||||||
expect($return[1000]['student']->id)->toBe($allSaxDude->id);
|
->and($return[1000]['student']->id)->toBe($allSaxDude->id)
|
||||||
expect($return[1000]['entries']->count())->toBe(3);
|
->and($return[1000]['entries']->count())->toBe(3);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue