auditionadmin/app/Models/Entry.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;
}
}