96 lines
3.5 KiB
PHP
96 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Entries;
|
|
|
|
use App\Exceptions\AuditionAdminException;
|
|
use App\Models\Doubler;
|
|
use App\Models\Entry;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class DoublerDecision
|
|
{
|
|
/**
|
|
* @throws AuditionAdminException
|
|
*/
|
|
public function __invoke(Entry $entry, string $decision): void
|
|
{
|
|
$this->doublerDecision($entry, $decision);
|
|
}
|
|
|
|
/**
|
|
* @throws AuditionAdminException
|
|
*/
|
|
public function doublerDecision(Entry $entry, string $decision): void
|
|
{
|
|
match ($decision) {
|
|
'accept' => $this->accept($entry),
|
|
'decline' => $this->decline($entry),
|
|
default => throw new AuditionAdminException('Invalid decision specified')
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Accepts an entry for the given audition.
|
|
*
|
|
* This method ensures the entry is not already declined, and that the
|
|
* audition is not in a state where seats or advancement are published.
|
|
* If the entry is already declined, this method does nothing.
|
|
* If the audition is in a state where seats or advancement are published,
|
|
* this method throws an exception.
|
|
*
|
|
* This method also declines all other entries in the same audition,
|
|
* clearing the rank cache for the audition.
|
|
*
|
|
* @throws AuditionAdminException
|
|
*/
|
|
public function accept(Entry $entry): void
|
|
{
|
|
if ($entry->hasFlag('declined')) {
|
|
throw new AuditionAdminException('Entry '.$entry->id.' is already declined');
|
|
}
|
|
if ($entry->audition->hasFlag('seats_published')) {
|
|
throw new AuditionAdminException('Cannot accept an entry in an audition where seats are published');
|
|
}
|
|
Cache::forget('rank_seating_'.$entry->audition_id);
|
|
|
|
// Process student entries
|
|
$doublerData = Doubler::findDoubler($entry->student_id, $entry->audition->event_id);
|
|
// Check each entry and see if it is unscored. We can't accept this entry if that is the case.
|
|
foreach ($doublerData->entries() as $doublerEntry) {
|
|
if (! $doublerEntry->totalScore && ! $doublerEntry->hasFlag('declined') && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim')) {
|
|
throw new AuditionAdminException('Cannot accept seating for '.$entry->student->full_name().' because student has unscored entries');
|
|
}
|
|
}
|
|
// Decline all other entries
|
|
foreach ($doublerData->entries() as $doublerEntry) {
|
|
Cache::forget('rank_seating_'.$doublerEntry->audition_id);
|
|
if ($doublerEntry->id !== $entry->id && ! $doublerEntry->hasFlag('no_show') && ! $doublerEntry->hasFlag('failed_prelim') && ! $doublerEntry->hasFlag('declined')) {
|
|
$this->decline($doublerEntry);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws AuditionAdminException
|
|
*/
|
|
public function decline($entry): void
|
|
{
|
|
// Entry cannot decline a seat twice
|
|
if ($entry->hasFlag('declined')) {
|
|
throw new AuditionAdminException('Entry '.$entry->id.' is already declined');
|
|
}
|
|
if (! $entry->totalScore) {
|
|
throw new AuditionAdminException('Cannot decline an unscored entry');
|
|
}
|
|
if ($entry->audition->hasFlag('seats_published')) {
|
|
throw new AuditionAdminException('Cannot decline an entry in an audition where seats are published');
|
|
}
|
|
|
|
// Flag this entry
|
|
$entry->addFlag('declined');
|
|
|
|
// Clear rank cache
|
|
Cache::forget('rank_seating_'.$entry->audition_id);
|
|
}
|
|
}
|