auditionadmin/app/Actions/Tabulation/CalculateScoreSheetTotal.php

65 lines
2.2 KiB
PHP

<?php
/** @noinspection PhpUnhandledExceptionInspection */
namespace App\Actions\Tabulation;
use App\Exceptions\TabulationException;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User;
use App\Services\AuditionService;
use App\Services\EntryService;
use App\Services\UserService;
class CalculateScoreSheetTotal
{
protected AuditionService $auditionService;
protected EntryService $entryService;
protected UserService $userService;
public function __construct(AuditionService $auditionService, EntryService $entryService, UserService $userService)
{
$this->auditionService = $auditionService;
$this->entryService = $entryService;
$this->userService = $userService;
}
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->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 (! $this->entryService->entryExists($entry)) {
throw new TabulationException('Invalid entry provided');
}
if (! $this->userService->userExists($judge)) {
throw new TabulationException('Invalid judge provided');
}
}
}