86 lines
2.9 KiB
PHP
86 lines
2.9 KiB
PHP
<?php
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
|
|
namespace App\Actions\Tabulation;
|
|
|
|
use App\Exceptions\TabulationException;
|
|
use App\Models\Audition;
|
|
use App\Models\Entry;
|
|
use App\Models\ScoreSheet;
|
|
use App\Models\User;
|
|
use App\Services\AuditionService;
|
|
|
|
class CalculateScoreSheetTotal
|
|
{
|
|
protected AuditionService $auditionService;
|
|
public function __construct(AuditionService $auditionService)
|
|
{
|
|
$this->auditionService = $auditionService;
|
|
}
|
|
|
|
public function __invoke(string $mode, Entry $entry, User $judge): array
|
|
{
|
|
$this->basicValidations($mode, $entry, $judge);
|
|
$scoreSheet = ScoreSheet::where('entry_id', $entry->id)->where('user_id', $judge->id)->first();
|
|
if (! $scoreSheet) {
|
|
throw new TabulationException('No score sheet by that judge for that entry');
|
|
}
|
|
#$subscores = $this->getSubscores($mode, $entry->audition);
|
|
$subscores = $this->auditionService->getSubscores($entry->audition, $mode);
|
|
$scoreTotal = 0;
|
|
$weightsTotal = 0;
|
|
$scoreArray = [];
|
|
foreach ($subscores as $subscore) {
|
|
$weight = $subscore['weight'];
|
|
$score = $scoreSheet->subscores[$subscore->id]['score'];
|
|
$scoreArray[] = $score;
|
|
$scoreTotal += ($score * $weight);
|
|
$weightsTotal += $weight;
|
|
}
|
|
$finalScore = $scoreTotal / $weightsTotal;
|
|
// put $final score at the beginning of the $ScoreArray
|
|
array_unshift($scoreArray, $finalScore);
|
|
|
|
return $scoreArray;
|
|
}
|
|
|
|
protected function basicValidations($mode, $entry, $judge): void
|
|
{
|
|
if ($mode !== 'seating' and $mode !== 'advancement') {
|
|
throw new TabulationException('Invalid mode requested. Mode must be seating or advancement');
|
|
}
|
|
if (! $entry->exists()) {
|
|
throw new TabulationException('Invalid entry provided');
|
|
}
|
|
if (! $judge->exists()) {
|
|
throw new TabulationException('Invalid judge provided');
|
|
}
|
|
}
|
|
|
|
protected function getSubscores($mode, Audition $audition)
|
|
{
|
|
static $seatingSubscores = [];
|
|
static $advancementSubscores = [];
|
|
|
|
if ($mode === 'seating') {
|
|
if (! isset($seatingSubscores[$audition->id])) {
|
|
$seatingSubscores[$audition->id] = $audition->scoringGuide->subscores->where('for_seating',
|
|
true)->sortBy('tiebreak_order');
|
|
}
|
|
|
|
return $seatingSubscores[$audition->id];
|
|
}
|
|
if ($mode === 'advancement') {
|
|
if (! isset($advancementSubscores[$audition->id])) {
|
|
$advancementSubscores[$audition->id] = $audition->scoringGuide->subscores->where('for_advance',
|
|
true)->sortBy('tiebreak_order');
|
|
}
|
|
|
|
return $advancementSubscores[$audition->id];
|
|
}
|
|
|
|
throw new TabulationException('Invalid mode requested. Mode must be seating or advancement');
|
|
}
|
|
}
|