129 lines
5.0 KiB
PHP
129 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Tabulation;
|
|
|
|
use App\Exceptions\AuditionAdminException;
|
|
use App\Models\Entry;
|
|
use App\Models\PrelimDefinition;
|
|
use App\Models\PrelimScoreSheet;
|
|
use App\Models\User;
|
|
use DB;
|
|
|
|
use function auditionLog;
|
|
|
|
class EnterPrelimScore
|
|
{
|
|
public function __invoke(
|
|
User $user,
|
|
Entry $entry,
|
|
array $scores,
|
|
PrelimScoreSheet|false $prelimScoreSheet = false
|
|
): PrelimScoreSheet {
|
|
$scores = collect($scores);
|
|
|
|
// Basic Validity Checks
|
|
if (! User::where('id', $user->id)->exists()) {
|
|
throw new AuditionAdminException('User does not exist');
|
|
}
|
|
if (! Entry::where('id', $entry->id)->exists()) {
|
|
throw new AuditionAdminException('Entry does not exist');
|
|
}
|
|
if ($entry->audition->hasFlag('seats_published')) {
|
|
throw new AuditionAdminException('Cannot score an entry in an audition where seats are published');
|
|
}
|
|
|
|
// Check if the entries audition has a prelim definition
|
|
if (! PrelimDefinition::where('audition_id', $entry->audition->id)->exists()) {
|
|
throw new AuditionAdminException('The entries audition does not have a prelim');
|
|
}
|
|
$prelimDefinition = PrelimDefinition::where('audition_id', $entry->audition->id)->first();
|
|
|
|
// Check that the specified user is assigned to judge this entry in prelims
|
|
$check = DB::table('room_user')
|
|
->where('user_id', $user->id)
|
|
->where('room_id', $prelimDefinition->room_id)->exists();
|
|
if (! $check) {
|
|
throw new AuditionAdminException('This judge is not assigned to judge this entry in prelims');
|
|
}
|
|
|
|
// Check if a score already exists
|
|
if (! $prelimScoreSheet) {
|
|
if (PrelimScoreSheet::where('user_id', $user->id)->where('entry_id', $entry->id)->exists()) {
|
|
throw new AuditionAdminException('That judge has already entered a prelim score for that entry');
|
|
}
|
|
} else {
|
|
if ($prelimScoreSheet->user_id != $user->id) {
|
|
throw new AuditionAdminException('Existing score sheet is from a different judge');
|
|
}
|
|
if ($prelimScoreSheet->entry_id != $entry->id) {
|
|
throw new AuditionAdminException('Existing score sheet is for a different entry');
|
|
}
|
|
}
|
|
|
|
// Check the validity of submitted subscores, format array for storage, and sum score
|
|
$subscoresRequired = $prelimDefinition->scoringGuide->subscores;
|
|
$subscoresStorageArray = [];
|
|
$totalScore = 0;
|
|
$maxPossibleTotal = 0;
|
|
if ($scores->count() !== $subscoresRequired->count()) {
|
|
throw new AuditionAdminException('Invalid number of scores');
|
|
}
|
|
|
|
foreach ($subscoresRequired as $subscore) {
|
|
// check that there is an element in the $scores collection with the key = $subscore->id
|
|
if (! $scores->keys()->contains($subscore->id)) {
|
|
throw new AuditionAdminException('Invalid Score Submission');
|
|
}
|
|
|
|
if ($scores[$subscore->id] > $subscore->max_score) {
|
|
throw new AuditionAdminException('Supplied subscore exceeds maximum allowed');
|
|
}
|
|
|
|
// Add subscore to the storage array
|
|
$subscoresStorageArray[$subscore->id] = [
|
|
'score' => $scores[$subscore->id],
|
|
'subscore_id' => $subscore->id,
|
|
'subscore_name' => $subscore->name,
|
|
];
|
|
|
|
// Multiply subscore by weight then add to total
|
|
$totalScore += ($subscore->weight * $scores[$subscore->id]);
|
|
$maxPossibleTotal += ($subscore->weight * $subscore->max_score);
|
|
}
|
|
$finalTotalScore = ($maxPossibleTotal === 0) ? 0 : (($totalScore / $maxPossibleTotal) * 100);
|
|
|
|
$entry->removeFlag('no_show');
|
|
if ($prelimScoreSheet instanceof PrelimScoreSheet) {
|
|
$prelimScoreSheet->update([
|
|
'user_id' => $user->id,
|
|
'entry_id' => $entry->id,
|
|
'subscores' => $subscoresStorageArray,
|
|
'total' => $finalTotalScore,
|
|
]);
|
|
} else {
|
|
$prelimScoreSheet = PrelimScoreSheet::create([
|
|
'user_id' => $user->id,
|
|
'entry_id' => $entry->id,
|
|
'subscores' => $subscoresStorageArray,
|
|
'total' => $finalTotalScore,
|
|
]);
|
|
}
|
|
|
|
// Log the prelim score entry
|
|
$log_message = 'Entered prelim score for entry id '.$entry->id.'.<br />';
|
|
$log_message .= 'Judge: '.$user->full_name().'<br />';
|
|
foreach ($prelimScoreSheet->subscores as $subscore) {
|
|
$log_message .= $subscore['subscore_name'].': '.$subscore['score'].'<br />';
|
|
}
|
|
$log_message .= 'Total :'.$prelimScoreSheet->total.'<br />';
|
|
auditionLog($log_message, [
|
|
'entries' => [$entry->id],
|
|
'users' => [$user->id],
|
|
'auditions' => [$entry->audition_id],
|
|
'students' => [$entry->student_id],
|
|
]);
|
|
|
|
return $prelimScoreSheet;
|
|
}
|
|
}
|