auditionadmin/app/Actions/Tabulation/CalculateScoreSheetTotal.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');
}
}