110 lines
3.3 KiB
PHP
110 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Exceptions\TabulationException;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
|
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
|
|
|
class Entry extends Model
|
|
{
|
|
use HasFactory;
|
|
protected $guarded = [];
|
|
protected $hasCheckedScoreSheets = false;
|
|
|
|
public function student(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Student::class);
|
|
}
|
|
|
|
public function audition(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Audition::class);
|
|
}
|
|
|
|
public function school(): HasOneThrough
|
|
{
|
|
return $this->hasOneThrough(
|
|
School::class,
|
|
Student::class,
|
|
'id',
|
|
'id',
|
|
'student_id',
|
|
'school_id');
|
|
}
|
|
|
|
public function scoreSheets(): HasMany
|
|
{
|
|
return $this->hasMany(ScoreSheet::class);
|
|
|
|
}
|
|
|
|
function verifyScoreSheets()
|
|
{
|
|
if ($this->hasCheckedScoreSheets) return true;
|
|
$judges = $this->audition->room->judges;
|
|
foreach ($this->scoreSheets as $sheet) {
|
|
if (! $judges->contains($sheet->user_id)) {
|
|
$invalidJudge = User::find($sheet->user_id);
|
|
// redirect ('/tabulation')->with('warning','Invalid scores for entry ' . $this->id . ' exist from ' . $invalidJudge->full_name());
|
|
// Abort execution, and redirect to /tabulation with a warning message
|
|
throw new TabulationException('Invalid scores for entry ' . $this->id . ' exist from ' . $invalidJudge->full_name());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public function scoreFromJudge($user): ScoreSheet|null
|
|
{
|
|
// return $this->scoreSheets()->where('user_id','=',$user)->first() ?? null;
|
|
return $this->scoreSheets->firstWhere('user_id', $user) ?? null;
|
|
|
|
}
|
|
|
|
public function totalScore()
|
|
{
|
|
$this->verifyScoreSheets();
|
|
$totalScore = 0;
|
|
foreach ($this->scoreSheets as $sheet)
|
|
{
|
|
$totalScore += $sheet->totalScore();
|
|
}
|
|
return $totalScore;
|
|
}
|
|
|
|
/**
|
|
* @throws TabulationException
|
|
*/
|
|
public function finalScoresArray()
|
|
{
|
|
$this->verifyScoreSheets();
|
|
$finalScoresArray = [];
|
|
$subscoresTiebreakOrder = $this->audition->scoringGuide->subscores->sortBy('tiebreak_order');
|
|
// initialize the return array
|
|
foreach ($subscoresTiebreakOrder as $subscore) {
|
|
$finalScoresArray[$subscore->id] = 0;
|
|
}
|
|
// add the subscores from each score sheet
|
|
foreach($this->scoreSheets as $sheet) {
|
|
foreach($sheet->subscores as $ss) {
|
|
$finalScoresArray[$ss['subscore_id']] += $ss['score'];
|
|
}
|
|
}
|
|
// calculate weighted final score
|
|
$totalScore = 0;
|
|
$totalWeight = 0;
|
|
foreach ($subscoresTiebreakOrder as $subscore) {
|
|
$totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight);
|
|
$totalWeight += $subscore->weight;
|
|
}
|
|
$totalScore = ($totalScore / $totalWeight);
|
|
array_unshift($finalScoresArray,$totalScore);
|
|
return $finalScoresArray;
|
|
}
|
|
}
|