136 lines
5.2 KiB
PHP
136 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Tabulation;
|
|
|
|
use App\Actions\Tabulation\CalculateAuditionScores;
|
|
use App\Actions\Tabulation\RankAuditionEntries;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Audition;
|
|
use App\Models\EntryFlag;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
use function is_null;
|
|
|
|
class AdvancementController extends Controller
|
|
{
|
|
public function status()
|
|
{
|
|
// Total auditions scores if we haven't done it lately
|
|
if (! Cache::has('advancement_status_audition_totaler_throttle')) {
|
|
$lock = Cache::lock('advancement_status_audition_totaler_lock');
|
|
|
|
if ($lock->get()) {
|
|
try {
|
|
$totaler = app(CalculateAuditionScores::class);
|
|
foreach (Audition::forAdvancement()->with('judges')->get() as $audition) {
|
|
$totaler($audition);
|
|
}
|
|
|
|
// set throttle
|
|
Cache::put('advancement_status_audition_totaler_throttle', true, 15);
|
|
} finally {
|
|
$lock->release();
|
|
}
|
|
}
|
|
}
|
|
|
|
$auditions = Audition::forAdvancement()
|
|
->with('flags')
|
|
->withCount([
|
|
'entries' => function ($query) {
|
|
$query->where('for_advancement', true);
|
|
},
|
|
])
|
|
->withCount([
|
|
'unscoredEntries' => function ($query) {
|
|
$query->where('for_advancement', true);
|
|
},
|
|
])
|
|
->orderBy('score_order')
|
|
->get();
|
|
|
|
$auditionData = [];
|
|
$auditions->each(function (Audition $audition) use (&$auditionData) {
|
|
$auditionData[] = [
|
|
'id' => $audition->id,
|
|
'name' => $audition->name,
|
|
'entries_count' => $audition->entries_count,
|
|
'unscored_entries_count' => $audition->unscored_entries_count,
|
|
'scored_entries_count' => $audition->entries_count - $audition->unscored_entries_count,
|
|
'scored_percentage' => $audition->entries_count > 0 ? ((($audition->entries_count - $audition->unscored_entries_count) / $audition->entries_count) * 100) : 0,
|
|
'scoring_complete' => $audition->unscored_entries_count === 0,
|
|
'published' => $audition->hasFlag('advancement_published'),
|
|
];
|
|
});
|
|
|
|
return view('tabulation.advancement.status', compact('auditionData'));
|
|
}
|
|
|
|
public function ranking(Request $request, Audition $audition)
|
|
{
|
|
$ranker = app(RankAuditionEntries::class);
|
|
$entries = $ranker($audition, 'advancement');
|
|
$entries->load(['advancementVotes', 'totalScore', 'student.school']);
|
|
|
|
$unscoredEntries = $audition->entries()->orderBy('draw_number')->get()->filter(function ($entry) {
|
|
return ! $entry->totalScore && ! $entry->hasFlag('no_show');
|
|
});
|
|
|
|
$noShowEntries = $audition->entries()->orderBy('draw_number')->get()->filter(function ($entry) {
|
|
return $entry->hasFlag('no_show');
|
|
});
|
|
|
|
$scoringComplete = $audition->entries->every(function ($entry) {
|
|
return $entry->totalScore || $entry->hasFlag('no_show');
|
|
});
|
|
|
|
return view('tabulation.advancement.ranking', compact('audition', 'entries', 'scoringComplete', 'unscoredEntries', 'noShowEntries'));
|
|
}
|
|
|
|
public function setAuditionPassers(Request $request, Audition $audition)
|
|
{
|
|
|
|
$passingEntries = $request->input('pass');
|
|
if (is_null($passingEntries) || count($passingEntries) < 1) {
|
|
return redirect()->route('advancement.ranking', ['audition' => $audition->id])->with('error',
|
|
'Cannot publish advancement if no entries advance');
|
|
}
|
|
|
|
$audition->addFlag('advancement_published');
|
|
if (! is_null($passingEntries)) {
|
|
$passEntries = collect(array_keys($passingEntries));
|
|
EntryFlag::insert(
|
|
$passEntries
|
|
->map(fn ($entryId) => [
|
|
'entry_id' => $entryId,
|
|
'flag_name' => 'will_advance',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
])->toArray()
|
|
);
|
|
|
|
}
|
|
Cache::forget('audition'.$audition->id.'advancement');
|
|
Cache::forget('publicResultsPage');
|
|
Cache::forget('rank_advancement_'.$audition->id);
|
|
|
|
return redirect()->route('advancement.ranking', ['audition' => $audition->id])->with('success',
|
|
'Passers have been set successfully');
|
|
}
|
|
|
|
public function clearAuditionPassers(Request $request, Audition $audition)
|
|
{
|
|
$audition->removeFlag('advancement_published');
|
|
$audition->entries
|
|
->filter(fn ($entry) => $entry->hasFlag('will_advance'))
|
|
->each(fn ($entry) => $entry->removeFlag('will_advance'));
|
|
|
|
Cache::forget('audition'.$audition->id.'advancement');
|
|
Cache::forget('publicResultsPage');
|
|
|
|
return redirect()->route('advancement.ranking', ['audition' => $audition->id])->with('success',
|
|
'Passers have been cleared successfully');
|
|
}
|
|
}
|