104 lines
3.7 KiB
PHP
104 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\NominationEnsembles;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\NominationEnsemble;
|
|
use App\Models\NominationEnsembleEntry;
|
|
|
|
use function redirect;
|
|
|
|
class ScobdaNominationSeatingController extends Controller implements NominationSeatingController
|
|
{
|
|
public function index()
|
|
{
|
|
$ensembles = NominationEnsemble::all();
|
|
$ensemble = null;
|
|
|
|
return view('nomination_ensembles.scobda.admin.seating.index', compact('ensembles', 'ensemble'));
|
|
}
|
|
|
|
public function show(NominationEnsemble $ensemble)
|
|
{
|
|
$ensembles = NominationEnsemble::all();
|
|
$acceptedNominations = NominationEnsembleEntry::where('nomination_ensemble_id', $ensemble->id)
|
|
->where('data->accepted', true)
|
|
->orderByRaw('CAST(data->"$.rank" AS UNSIGNED)')
|
|
->get();
|
|
$acceptedNominations = $acceptedNominations->groupBy(function ($item) {
|
|
return $item->data['instrument'];
|
|
});
|
|
|
|
return view('nomination_ensembles.scobda.admin.seating.index',
|
|
compact('ensembles', 'ensemble', 'acceptedNominations'));
|
|
|
|
}
|
|
|
|
public function seat(NominationEnsemble $ensemble)
|
|
{
|
|
$nominations = NominationEnsembleEntry::where('nomination_ensemble_id',
|
|
$ensemble->id)->orderByRaw('CAST(data->"$.rank" AS UNSIGNED)')->inRandomOrder()->get();
|
|
$rankGroupedNominations = $nominations->groupBy(function ($entry) {
|
|
return $entry->data['rank'];
|
|
});
|
|
|
|
$validData = request()->validate([
|
|
'action' => ['required', 'in:seat,clear'],
|
|
]);
|
|
$action = $validData['action'];
|
|
|
|
if ($action == 'clear') {
|
|
foreach ($nominations as $nomination) {
|
|
$data = $nomination->data;
|
|
unset($data['accepted']);
|
|
$nomination->update(['data' => $data]);
|
|
}
|
|
|
|
$data = $ensemble->data;
|
|
$data['seated'] = false;
|
|
$ensemble->data = $data;
|
|
$ensemble->update();
|
|
|
|
return redirect()->route('nomination.admin.seating.show',
|
|
['ensemble' => $ensemble])->with('Seating Cleared');
|
|
}
|
|
|
|
$acceptedNominations = collect();
|
|
$rankOn = 1;
|
|
// Collect students to add to the ensemble
|
|
while ($rankOn <= $ensemble->data['max_nominations'] && $rankGroupedNominations->has($rankOn)) {
|
|
// If were at or over the target size of the ensemble, stop adding people
|
|
if ($acceptedNominations->count() >= $ensemble->data['target_size']) {
|
|
break;
|
|
}
|
|
// Add people of the current rank to the ensemble
|
|
foreach ($rankGroupedNominations[$rankOn] as $nomination) {
|
|
$acceptedNominations->push($nomination);
|
|
}
|
|
$rankOn++;
|
|
|
|
// If we want to round down the ensemble size, quit adding people if hte next rank will exceed the target
|
|
if (
|
|
$rankGroupedNominations->has($rankOn) &&
|
|
$acceptedNominations->count() + $rankGroupedNominations[$rankOn]->count() >= $ensemble->data['target_size'] &&
|
|
$ensemble->data['rounding_direction'] === 'down'
|
|
) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach ($acceptedNominations as $nomination) {
|
|
$data = $nomination->data;
|
|
$data['accepted'] = true;
|
|
$nomination->update(['data' => $data]);
|
|
}
|
|
|
|
$data = $ensemble->data;
|
|
$data['seated'] = true;
|
|
$ensemble->data = $data;
|
|
$ensemble->update();
|
|
|
|
return redirect()->route('nomination.admin.seating.show', ['ensemble' => $ensemble])->with('Seating Complete');
|
|
}
|
|
}
|