auditionadmin/app/Actions/CalculateScoreSheetTotal.php

58 lines
1.9 KiB
PHP

<?php
/** @noinspection PhpUnhandledExceptionInspection */
namespace App\Actions;
use App\Exceptions\TabulationException;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User;
class CalculateScoreSheetTotal
{
public function __construct()
{
}
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 = match ($mode) {
'seating' => $entry->audition->scoringGuide->subscores->where('for_seating', true)->sortBy('tiebreak_order'),
'advancement' => $entry->audition->scoringGuide->subscores->where('for_advance', true)->sortBy('tiebreak_order'),
};
$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');
}
}
}