auditionadmin/app/Services/TabulationService.php

115 lines
4.2 KiB
PHP

<?php
namespace App\Services;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class TabulationService
{
protected AuditionCacheService $auditionCacheService;
protected EntryCacheService $entryCacheService;
protected ScoreService $scoreService;
/**
* Create a new class instance.
*/
public function __construct(
AuditionCacheService $scoringGuideCacheService,
ScoreService $scoreService,
EntryCacheService $entryCacheService)
{
$this->auditionCacheService = $scoringGuideCacheService;
$this->scoreService = $scoreService;
$this->entryCacheService = $entryCacheService;
}
public function entryRank(Entry $entry) {
return $this->auditionEntries($entry->audition_id)[$entry->id]->rank;
}
public function auditionEntries(Int $auditionId)
{
$cache_key = 'audition'.$auditionId.'entries';
$audition = $this->auditionCacheService->getAudition($auditionId);
return Cache::remember($cache_key, 5, function () use ($audition) {
$entries = Entry::where('audition_id',$audition->id)->with(['student.school','scoreSheets'])->withCount('scoreSheets')->get();
foreach ($entries as $entry) {
// $entry->final_score_array = $this->entryFinalScores($entry);
$entry->final_score_array = $this->scoreService->entryTotalScores($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++) {
$entries = $entries->sortByDesc(function ($entry) use ($n) {
return $entry['final_score_array'][$n];
});
}
//TODO verify this actually sorts by subscores correctly
$n = 1;
foreach ($entries as $entry) {
$entry->rank = $n;
$n++;
}
return $entries->keyBy('id');
});
}
public function entryScoreSheetsAreValid(Entry $entry): bool {
//TODO consider making this move the invalid score to another database for further investigation
$validJudges = $this->auditionCacheService->getAudition($entry->audition_id)->judges;
foreach ($entry->scoreSheets as $sheet) {
if (! $validJudges->contains($sheet->user_id)) {
$invalidJudge = User::find($sheet->user_id);
Session::flash('error','Invalid scores for entry ' . $entry->id . ' exist from ' . $invalidJudge->full_name());
return false;
}
}
return true;
}
public function remainingEntriesForAudition($auditionId)
{
$audition = $this->getAuditionsWithStatus()[$auditionId];
return $audition->entries_count - $audition->scored_entries_count;
}
/**
* Get the array of all auditions from the cache. For each one, set a property
* scored_entries_count that indicates the number of entries for that audition that
* have a number of score sheets equal to the number of judges for that audition.
* @return mixed
*/
public function getAuditionsWithStatus()
{
return Cache::remember('auditionsWithStatus',30,function() {
// Retrieve auditions from the cache and load entry IDs
$auditions = $this->auditionCacheService->getAuditions();
// Iterate over the auditions and calculate the scored_entries_count
foreach($auditions as $audition) {
$scored_entries_count = 0;
foreach ($this->entryCacheService->getEntriesForAudition($audition->id) as $entry) {
if ($this->scoreService->entryScoreSheetCounts()[$entry->id] ?? 0 == $audition->judges_count) {
$scored_entries_count++;
}
}
$audition->scored_entries_count = $scored_entries_count;
}
return $auditions;
});
}
}