Refactor done I think
This commit is contained in:
parent
f7ff0bd734
commit
c4ea5be570
|
|
@ -6,42 +6,40 @@ use App\Http\Controllers\Controller;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use App\Models\ScoreSheet;
|
use App\Models\ScoreSheet;
|
||||||
|
use App\Services\DoublerService;
|
||||||
use App\Services\TabulationService;
|
use App\Services\TabulationService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use function compact;
|
use function compact;
|
||||||
|
use function dd;
|
||||||
use function dump;
|
use function dump;
|
||||||
use function redirect;
|
use function redirect;
|
||||||
|
|
||||||
class TabulationController extends Controller
|
class TabulationController extends Controller
|
||||||
{
|
{
|
||||||
protected $tabulationService;
|
protected $tabulationService;
|
||||||
|
protected $doublerService;
|
||||||
|
|
||||||
public function __construct(TabulationService $tabulationService)
|
public function __construct(TabulationService $tabulationService, DoublerService $doublerService)
|
||||||
{
|
{
|
||||||
$this->tabulationService = $tabulationService;
|
$this->tabulationService = $tabulationService;
|
||||||
|
$this->doublerService = $doublerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function status()
|
public function status()
|
||||||
{
|
{
|
||||||
// $auditions = Audition::with(['entries' => function($query) {
|
|
||||||
// $query->withCount('scoreSheets');
|
|
||||||
// },'room.judges'])->orderBy('score_order')->get();
|
|
||||||
$auditions = $this->tabulationService->getAuditionsWithStatus();
|
$auditions = $this->tabulationService->getAuditionsWithStatus();
|
||||||
return view('tabulation.status',compact('auditions'));
|
return view('tabulation.status',compact('auditions'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function auditionSeating(Audition $audition)
|
public function auditionSeating(Audition $audition)
|
||||||
{
|
{
|
||||||
// $entries = $audition->entries()->with(['student','scoreSheets.audition.scoringGuide','audition.room.judges'])->get();
|
|
||||||
// $entries = $entries->sortByDesc(function ($entry) {
|
|
||||||
// return $entry->totalScore();
|
|
||||||
// });
|
|
||||||
// $entries = $audition->rankedEntries()->load('student.entries.audition','scoreSheets.audition.scoringGuide.subscores');
|
|
||||||
$entries = $this->tabulationService->auditionEntries($audition->id);
|
$entries = $this->tabulationService->auditionEntries($audition->id);
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$entry->is_doubler = $this->doublerService->entryIsDoubler($entry);
|
||||||
return view('tabulation.auditionSeating',compact('audition','entries'));
|
}
|
||||||
|
return view('tabulation.auditionSeating',compact('audition','entries'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ class Audition extends Model
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
protected $rankedEntries = null;
|
protected $rankedEntries = null;
|
||||||
protected static $completeAuditions = null;
|
protected static $completeAuditions = null;
|
||||||
|
protected $fully_scored; // Set by TabulationService
|
||||||
|
|
||||||
public static function getCompleteAuditions()
|
public static function getCompleteAuditions()
|
||||||
{
|
{
|
||||||
|
|
@ -137,6 +138,7 @@ class Audition extends Model
|
||||||
$entry->save();
|
$entry->save();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
// TODO move all draw functions to a DrawService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -154,6 +156,17 @@ class Audition extends Model
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensures judges_count property is always available
|
||||||
|
*/
|
||||||
|
public function getJudgesCountAttribute()
|
||||||
|
{
|
||||||
|
if (!isset($this->attributes['judges_count'])) {
|
||||||
|
$this->attributes['judges_count'] = $this->judges()->count();
|
||||||
|
}
|
||||||
|
return $this->attributes['judges_count'];
|
||||||
|
}
|
||||||
|
|
||||||
public function scoredEntries()
|
public function scoredEntries()
|
||||||
{
|
{
|
||||||
return $this->entries->filter(function($entry) {
|
return $this->entries->filter(function($entry) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ class Entry extends Model
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
protected $hasCheckedScoreSheets = false;
|
protected $hasCheckedScoreSheets = false;
|
||||||
|
public $final_scores_array; // Set by TabulationService
|
||||||
|
public $scoring_complete; // Set by TabulationService
|
||||||
|
public $is_doubler; // Set by DoublerService
|
||||||
|
|
||||||
public function student(): BelongsTo
|
public function student(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|
@ -43,80 +46,14 @@ class Entry extends Model
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensures score_sheets_count property is always available
|
||||||
|
*/
|
||||||
public function getScoreSheetsCountAttribute()
|
public function getScoreSheetsCountAttribute()
|
||||||
{
|
{
|
||||||
if (!isset($this->attributes['score_sheets_count'])) {
|
if (!isset($this->attributes['score_sheets_count'])) {
|
||||||
$this->attributes['score_sheets_count'] = $this->scoreSheets()->count();
|
$this->attributes['score_sheets_count'] = $this->scoreSheets()->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->attributes['score_sheets_count'];
|
return $this->attributes['score_sheets_count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public 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 fullyJudged(){
|
|
||||||
return $this->scoreSheets->count() >= $this->audition->room->judges->count();
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,8 @@ class ScoreSheet extends Model
|
||||||
return $this->subscores[$id]['score'] ?? false;
|
return $this->subscores[$id]['score'] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function totalScore() {
|
|
||||||
$totalScore = 0;
|
|
||||||
$totalWeights = 0;
|
|
||||||
foreach ( $this->audition->scoringGuide->subscores as $subscore) {
|
|
||||||
$totalScore += $this->getSubscore($subscore->id) * $subscore->weight;
|
|
||||||
$totalWeights += $subscore->weight;
|
|
||||||
}
|
|
||||||
return $totalScore / $totalWeights;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isValid() {
|
public function isValid() {
|
||||||
|
// TODO move to either TabulationService or a specific service for scoreValidation
|
||||||
$judges = $this->audition->judges();
|
$judges = $this->audition->judges();
|
||||||
return $judges->contains('id', $this->judge->id);
|
return $judges->contains('id', $this->judge->id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class ScoringGuide extends Model
|
||||||
*/
|
*/
|
||||||
public function validateScores(Array $prospective_score)
|
public function validateScores(Array $prospective_score)
|
||||||
{
|
{
|
||||||
|
// TODO move to either TabulationService or a specific service for scoreValidation
|
||||||
foreach ($this->subscores as $subscore) {
|
foreach ($this->subscores as $subscore) {
|
||||||
if (! array_key_exists($subscore->id,$prospective_score)) return "A score must be provided for " . $subscore->name;
|
if (! array_key_exists($subscore->id,$prospective_score)) return "A score must be provided for " . $subscore->name;
|
||||||
if (is_null($prospective_score[$subscore->id])) return "A score must be provided for " . $subscore->name;
|
if (is_null($prospective_score[$subscore->id])) return "A score must be provided for " . $subscore->name;
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,4 @@ class Student extends Model
|
||||||
if ($last_name_first) return $this->last_name . ', ' . $this->first_name;
|
if ($last_name_first) return $this->last_name . ', ' . $this->first_name;
|
||||||
return $this->first_name . ' ' . $this->last_name;
|
return $this->first_name . ' ' . $this->last_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isDoubler()
|
|
||||||
{
|
|
||||||
return $this->entries->count() > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,13 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
|
|
||||||
public function scoresForEntry($entry)
|
public function scoresForEntry($entry)
|
||||||
{
|
{
|
||||||
|
// TODO Again, why is this here? Needs to go somewhere else. Maybe a Judging service
|
||||||
return $this->scoreSheets->where('entry_id','=',$entry)->first()?->subscores;
|
return $this->scoreSheets->where('entry_id','=',$entry)->first()?->subscores;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function timeForEntryScores($entry)
|
public function timeForEntryScores($entry)
|
||||||
{
|
{
|
||||||
|
// TODO Why is this in the User mode? Move it somewhere else
|
||||||
return $this->scoreSheets->where('entry_id','=',$entry)->first()?->created_at;
|
return $this->scoreSheets->where('entry_id','=',$entry)->first()?->created_at;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace App\Providers;
|
||||||
use App\Events\AuditionChange;
|
use App\Events\AuditionChange;
|
||||||
use App\Listeners\RefreshAuditionCache;
|
use App\Listeners\RefreshAuditionCache;
|
||||||
use App\Services\AuditionCacheService;
|
use App\Services\AuditionCacheService;
|
||||||
|
use App\Services\DoublerService;
|
||||||
use App\Services\TabulationService;
|
use App\Services\TabulationService;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
@ -16,13 +17,17 @@ class AppServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->app->singleton(AuditionCacheService::class, function ($app) {
|
$this->app->singleton(AuditionCacheService::class, function () {
|
||||||
return new AuditionCacheService();
|
return new AuditionCacheService();
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->app->singleton(TabulationService::class, function($app) {
|
$this->app->singleton(TabulationService::class, function($app) {
|
||||||
return new TabulationService($app->make(AuditionCacheService::class));
|
return new TabulationService($app->make(AuditionCacheService::class));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->app->singleton(DoublerService::class, function($app) {
|
||||||
|
return new DoublerService($app->make(AuditionCacheService::class),$app->make(TabulationService::class));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ class AuditionCacheService
|
||||||
{ //TODO have changes to judging assignments refresh the cache
|
{ //TODO have changes to judging assignments refresh the cache
|
||||||
return Cache::rememberForever($this->cacheKey, function () {
|
return Cache::rememberForever($this->cacheKey, function () {
|
||||||
return Audition::with(['scoringGuide.subscores','judges'])
|
return Audition::with(['scoringGuide.subscores','judges'])
|
||||||
|
->withCount('judges')
|
||||||
|
->withCount('entries')
|
||||||
->orderBy('score_order')
|
->orderBy('score_order')
|
||||||
->get()
|
->get()
|
||||||
->keyBy('id');
|
->keyBy('id');
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,62 @@
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\Entry;
|
||||||
|
use App\Models\Student;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class DoublerService
|
class DoublerService
|
||||||
{
|
{
|
||||||
|
protected $doublersCacheKey = 'doublers';
|
||||||
|
protected $auditionCacheService;
|
||||||
|
protected $tabulationService;
|
||||||
/**
|
/**
|
||||||
* Create a new class instance.
|
* Create a new class instance.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(AuditionCacheService $auditionCacheService, TabulationService $tabulationService)
|
||||||
{
|
{
|
||||||
//
|
$this->auditionCacheService = $auditionCacheService;
|
||||||
|
$this->tabulationService = $tabulationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDoublers(): \Illuminate\Database\Eloquent\Collection
|
||||||
|
{
|
||||||
|
return Cache::remember($this->doublersCacheKey, 10, function () {
|
||||||
|
$students = Student::withCount('entries')
|
||||||
|
->with('entries')
|
||||||
|
->havingRaw('entries_count > ?', [1])
|
||||||
|
->get();
|
||||||
|
return $students;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDoublerInfo($id): Array
|
||||||
|
{
|
||||||
|
// When getting a doubler we need to know
|
||||||
|
// 1) What their entrires are
|
||||||
|
// 2) For each audition they're entered in, what is their rank
|
||||||
|
// 3) For each audition they'er entered in, how many entries are unscored
|
||||||
|
// 4) How many are accepted on that instrument
|
||||||
|
$doubler = $this->getDoublers()->firstWhere('id',$id);
|
||||||
|
$info = [];
|
||||||
|
|
||||||
|
foreach ($doubler->entries as $entry) {
|
||||||
|
$info[] = [
|
||||||
|
'auditionID' => $entry->audition_id,
|
||||||
|
'auditionName' => $this->auditionCacheService->getAudition($entry->audition_id)->name,
|
||||||
|
'rank' => $this->tabulationService->entryRank($entry),
|
||||||
|
'unscored' => $this->tabulationService->remainingEntriesForAudition($entry->audition_id)
|
||||||
|
];
|
||||||
|
$entry->audition = $this->auditionCacheService->getAudition($entry->audition_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function entryIsDoubler(Entry $entry): bool
|
||||||
|
{
|
||||||
|
// Return true if $entry->student_id is associated with a student in the collection from $this->getDoublers()
|
||||||
|
return $this->getDoublers()->contains('id', $entry->student_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use App\Services\AuditionCacheService;
|
use App\Services\AuditionCacheService;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use function array_unshift;
|
|
||||||
|
|
||||||
|
|
||||||
class TabulationService
|
class TabulationService
|
||||||
|
|
@ -25,12 +24,8 @@ class TabulationService
|
||||||
$this->auditionCacheService = $scoringGuideCacheService;
|
$this->auditionCacheService = $scoringGuideCacheService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getScoredEntries()
|
public function entryRank(Entry $entry) {
|
||||||
{
|
return $this->auditionEntries($entry->audition_id)[$entry->id]->rank;
|
||||||
return Cache::remember($this->cacheKey, 10, function () {
|
|
||||||
$entries = Entry::with(['scoreSheets'])->get();
|
|
||||||
return $entries->keyBy('id');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function auditionEntries(Int $auditionId)
|
public function auditionEntries(Int $auditionId)
|
||||||
|
|
@ -38,21 +33,28 @@ class TabulationService
|
||||||
$cache_key = 'audition'.$auditionId.'entries';
|
$cache_key = 'audition'.$auditionId.'entries';
|
||||||
$audition = $this->auditionCacheService->getAudition($auditionId);
|
$audition = $this->auditionCacheService->getAudition($auditionId);
|
||||||
|
|
||||||
return Cache::remember($cache_key, 2, function () use ($audition) {
|
return Cache::remember($cache_key, 5, function () use ($audition) {
|
||||||
$entries = Entry::where('audition_id',$audition->id)->with(['student.school','scoreSheets'])->get();
|
$entries = Entry::where('audition_id',$audition->id)->with(['student.school','scoreSheets'])->withCount('scoreSheets')->get();
|
||||||
|
|
||||||
|
|
||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
$entry->final_score_array = $this->entryFinalScores($entry);
|
$entry->final_score_array = $this->entryFinalScores($entry);
|
||||||
|
$entry->scoring_complete = ($entry->score_sheets_count == $audition->judges_count) ? true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort based on final_score_array
|
||||||
for ($n=0; $n <= $audition->judges_count; $n++) {
|
for ($n=0; $n <= $audition->judges_count; $n++) {
|
||||||
$entries = $entries->sortByDesc(function ($entry) use ($n) {
|
$entries = $entries->sortByDesc(function ($entry) use ($n) {
|
||||||
return $entry['final_score_array'][$n];
|
return $entry['final_score_array'][$n];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//TODO verify this actually sorts by subscores correcty
|
//TODO verify this actually sorts by subscores correcty
|
||||||
|
$n = 1;
|
||||||
return $entries;
|
foreach ($entries as $entry) {
|
||||||
|
$entry->rank = $n;
|
||||||
|
$n++;
|
||||||
|
}
|
||||||
|
return $entries->keyBy('id');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,28 +104,44 @@ class TabulationService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function remainingEntriesForAudition($auditionId)
|
||||||
|
{
|
||||||
|
$audition = $this->getAuditionsWithStatus()[$auditionId];
|
||||||
|
return $audition->entries_count - $audition->scored_entries_count;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAuditionsWithStatus()
|
public function getAuditionsWithStatus()
|
||||||
{
|
{
|
||||||
// Create an array with the number of scores for each entry
|
return Cache::remember('auditionsWithStatus',30,function() {
|
||||||
$scoreCountByEntry = ScoreSheet::select('entry_id', DB::raw('count(*) as count'))
|
// Create an array with the number of scores for each entry
|
||||||
->groupBy('entry_id')
|
$scoreCountByEntry = ScoreSheet::select('entry_id', DB::raw('count(*) as count'))
|
||||||
->get()
|
->groupBy('entry_id')
|
||||||
->pluck('count','entry_id');
|
->get()
|
||||||
|
->pluck('count','entry_id');
|
||||||
|
|
||||||
// Retrieve auditions from the cache and load entry IDs
|
// Retrieve auditions from the cache and load entry IDs
|
||||||
$auditions = $this->auditionCacheService->getAuditions();
|
$auditions = $this->auditionCacheService->getAuditions();
|
||||||
$auditions->load('entries');
|
$auditions->load('entries');
|
||||||
|
|
||||||
// Eager load the count of related models
|
// Eager load the count of related models
|
||||||
$auditions->loadCount(['judges', 'entries']);
|
$auditions->loadCount(['judges', 'entries']);
|
||||||
|
|
||||||
// Iterate over the auditions and calculate the scored_entries_count
|
// Iterate over the auditions and calculate the scored_entries_count
|
||||||
return $auditions->map(function ($audition) use ($scoreCountByEntry) {
|
return $auditions->map(function ($audition) use ($scoreCountByEntry) {
|
||||||
$audition->scored_entries_count = $audition->entries->reduce(function ($carry, $entry) use ($audition, $scoreCountByEntry) {
|
$audition->scored_entries_count = $audition->entries->reduce(function ($carry, $entry) use ($audition, $scoreCountByEntry) {
|
||||||
$entry->fully_scored = $audition->judges_count == $scoreCountByEntry[$entry->id];
|
$entry->fully_scored = $audition->judges_count == $scoreCountByEntry[$entry->id];
|
||||||
return $carry + ($entry->fully_scored ? 1 : 0);
|
return $carry + ($entry->fully_scored ? 1 : 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
return $audition;
|
return $audition;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function allResults() {
|
||||||
|
$auditions = $this->getAuditionsWithStatus();
|
||||||
|
foreach ($auditions as $audition) {
|
||||||
|
$audition->entries = $this->auditionEntries($audition->id);
|
||||||
|
}
|
||||||
|
return $auditions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,46 @@
|
||||||
@php use App\Models\Audition; @endphp
|
@inject('doublers','\App\Services\DoublerService')
|
||||||
@props(['student'])
|
@inject('tabulation','\App\Services\TabulationService')
|
||||||
{{--complete badge--}}
|
@props(['studentID'])
|
||||||
{{--<p class="mt-0.5 whitespace-nowrap rounded-md bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">Complete</p>--}}
|
@php
|
||||||
{{--in progress badge--}}
|
$doublerEntryInfo = $doublers->getDoublerInfo($studentID);
|
||||||
{{--<p class="mt-0.5 whitespace-nowrap rounded-md bg-gray-50 px-1.5 py-0.5 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10">In progress</p>--}}
|
@endphp
|
||||||
|
|
||||||
<ul role="list" class="divide-y divide-gray-100">
|
<ul role="list" class="divide-y divide-gray-100">
|
||||||
@foreach($student->entries as $entry)
|
|
||||||
<li class="flex items-center justify-between gap-x-1 py-5">
|
|
||||||
|
|
||||||
|
@foreach($doublerEntryInfo as $info)
|
||||||
|
<li class="flex items-center justify-between gap-x-6 py-5">
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
|
|
||||||
<div class="flex items-start gap-x-3">
|
<div class="flex items-start gap-x-3">
|
||||||
<p class="text-sm font-semibold leading-6 text-gray-900">
|
<p class="text-sm font-semibold leading-6 text-gray-900">
|
||||||
<a href="/tabulation/auditions/{{ $entry->audition->id }}">
|
<a href="/tabulation/auditions/{{ $info['auditionID'] }}">
|
||||||
{{ $entry->audition->name }}
|
{{ $info['auditionName'] }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@if(Audition::getCompleteAuditions()->contains('id', $entry->audition->id))
|
|
||||||
<p class="mt-0.5 whitespace-nowrap rounded-md bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">Complete</p>
|
|
||||||
@else
|
|
||||||
<p class="mt-0.5 whitespace-nowrap rounded-md bg-gray-50 px-1.5 py-0.5 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10">In progress</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-1 flex items-center gap-x-2 text-xs leading-5 text-gray-500">
|
|
||||||
@if(Audition::getCompleteAuditions()->contains('id', $entry->audition->id))
|
|
||||||
@php
|
|
||||||
$entryPlace = $entry->audition->rankedEntries()->search(function ($rankedEntry) use ($entry) {
|
|
||||||
return $rankedEntry->id == $entry->id;
|
|
||||||
});
|
|
||||||
@endphp
|
|
||||||
@if($entryPlace !== false)
|
|
||||||
Rank: {{ $entryPlace +1 }}{{-- The place of $entry->id in the array is $entryPlace --}}
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-1 flex items-center gap-x-2 text-xs leading-5 text-gray-500">
|
||||||
|
<p class="whitespace-nowrap">Ranked {{ $info['rank'] }}</p>
|
||||||
|
<svg viewBox="0 0 2 2" class="h-0.5 w-0.5 fill-current">
|
||||||
|
<circle cx="1" cy="1" r="1" />
|
||||||
|
</svg>
|
||||||
|
<p class="truncate">{{ $info['unscored'] }} Unscored</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-1 flex items-center gap-x-2 text-xs leading-5 text-gray-500">
|
||||||
|
Acceptance Limits
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex items-center gap-x-4">
|
||||||
|
<a href="#" class="hidden rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:block">Accept</a>
|
||||||
|
<a href="#" class="hidden rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:block">Decline</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
{{--Complete Badge--}}
|
||||||
|
{{--<p class="mt-0.5 whitespace-nowrap rounded-md bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">Complete</p>--}}
|
||||||
|
|
||||||
|
{{--In Progres Badge--}}
|
||||||
|
{{--<p class="mt-0.5 whitespace-nowrap rounded-md bg-yellow-50 px-1.5 py-0.5 text-xs font-medium text-yellow-800 ring-1 ring-inset ring-yellow-600/20">In Progress</p>--}}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
|
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
|
||||||
|
|
||||||
|
|
@ -25,8 +26,13 @@
|
||||||
<span>{{ $entry->student->full_name() }}, </span>
|
<span>{{ $entry->student->full_name() }}, </span>
|
||||||
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
|
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
<x-table.td>Doubler Block</x-table.td>
|
<x-table.td>
|
||||||
<x-table.td>{{ $entry->final_score_array[0] }}</x-table.td>
|
@if($entry->is_doubler)
|
||||||
|
<x-doubler-block :studentID="$entry->student->id" />
|
||||||
|
@endif
|
||||||
|
</x-table.td>
|
||||||
|
<x-table.td>{{ number_format($entry->final_score_array[0],4) }}</x-table.td>
|
||||||
|
<x-table.td>@if($entry->scoring_complete) <x-icons.checkmark color="green" /> @endif</x-table.td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-table.body>
|
</x-table.body>
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,9 @@
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
<x-slot:page_title>Test Page</x-slot:page_title>
|
<x-slot:page_title>Test Page</x-slot:page_title>
|
||||||
|
|
||||||
@php
|
@php(dd($auditions))
|
||||||
dump($auditions);
|
|
||||||
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
@foreach($auditions as $audition)
|
@foreach($auditions as $audition)
|
||||||
@php
|
|
||||||
@endphp
|
|
||||||
{{ $audition->name }} has {{ $audition->entries_count }} entries. {{ $audition->scored_entries_count }} are fully scored.<br>
|
{{ $audition->name }} has {{ $audition->entries_count }} entries. {{ $audition->scored_entries_count }} are fully scored.<br>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue