75 lines
2.5 KiB
PHP
75 lines
2.5 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 CalculateScoreSheetTotalDivideByWeightedPossible implements 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;
|
|
$weightedMaxPossible = 0;
|
|
$scoreArray = [];
|
|
foreach ($subscores as $subscore) {
|
|
$weight = $subscore['weight'];
|
|
$score = $scoreSheet->subscores[$subscore->id]['score'];
|
|
$maxPossible = $subscore['max_score'];
|
|
$scoreArray[] = $score;
|
|
$scoreTotal += ($score * $weight);
|
|
$weightsTotal += $weight;
|
|
$weightedMaxPossible += $maxPossible;
|
|
}
|
|
if ($weightedMaxPossible > 0) {
|
|
$finalScore = ($scoreTotal / $weightedMaxPossible) * 100;
|
|
} else {
|
|
$finalScore = 0;
|
|
}
|
|
// 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');
|
|
}
|
|
}
|
|
}
|