auditionadmin/app/Http/Controllers/Admin/EntryController.php

242 lines
9.3 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Actions\Entries\CreateEntry;
use App\Actions\Entries\UpdateEntry;
use App\Actions\Tabulation\CalculateScoreSheetTotal;
use App\Exceptions\ManageEntryException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\AuditLogEntry;
use App\Models\Entry;
use App\Models\School;
use App\Models\Seat;
use App\Models\Student;
use App\Services\ScoreService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use function auditionSetting;
use function compact;
use function to_route;
class EntryController extends Controller
{
public function index()
{
if (! Auth::user()->is_admin) {
abort(403);
}
$filters = session('adminEntryFilters') ?? null;
$minGrade = Audition::min('minimum_grade');
$maxGrade = Audition::max('maximum_grade');
$auditions = Audition::orderBy('score_order')->get();
$schools = School::orderBy('name')->get();
$entries = Entry::with(['student.school', 'audition']);
$entries->orderBy('id', 'DESC');
if ($filters) {
if ($filters['id']) {
$entries->where('id', $filters['id']);
}
if ($filters['audition']) {
$entries->where('audition_id', $filters['audition']);
}
if ($filters['school']) {
$entries->whereHas('student', function ($query) use ($filters) {
$query->where('school_id', '=', $filters['school']);
});
}
if ($filters['grade']) {
$entries->whereHas('student', function ($query) use ($filters) {
$query->where('grade', $filters['grade']);
});
}
if ($filters['first_name']) {
$entries->whereHas('student', function ($query) use ($filters) {
$query->where('first_name', 'like', '%'.$filters['first_name'].'%');
});
}
if ($filters['last_name']) {
$entries->whereHas('student', function ($query) use ($filters) {
$query->where('last_name', 'like', '%'.$filters['last_name'].'%');
});
}
if ($filters['entry_type']) {
// TODO define actions for each possible type filter from index.blade.php of the admin entry
match ($filters['entry_type']) {
'all' => null,
'seats' => $entries->where('for_seating', true),
'advancement' => $entries->where('for_advancement', true),
'seatsOnly' => $entries->where('for_seating', true)->where('for_advancement', false) ,
'advancementOnly' => $entries->where('for_seating', false)->where('for_advancement', true),
default => null,
};
}
}
$entries = $entries->paginate(10000);
return view('admin.entries.index', [
'entries' => $entries,
'auditions' => $auditions,
'schools' => $schools,
'minGrade' => $minGrade,
'maxGrade' => $maxGrade,
'filters' => $filters,
]);
}
public function create()
{
$students = Student::with('school')->orderBy('last_name')->orderBy('first_name')->get();
$auditionsRaw = Audition::with('flags')->orderBy('score_order')->get();
$auditions = $auditionsRaw->reject(function ($audition) {
return $audition->hasFlag('seats_published') || $audition->hasFlag('advancement_published');
});
return view('admin.entries.create', ['students' => $students, 'auditions' => $auditions]);
}
public function store(Request $request, CreateEntry $creator)
{
if (! Auth::user()->is_admin) {
abort(403);
}
$validData = request()->validate([
'student_id' => ['required', 'exists:students,id'],
'audition_id' => ['required', 'exists:auditions,id'],
]);
$validData['for_seating'] = $request->get('for_seating') ? 1 : 0;
$validData['for_advancement'] = $request->get('for_advancement') ? 1 : 0;
$validData['late_fee_waived'] = $request->get('late_fee_waived') ? 1 : 0;
$enter_for = [];
if ($validData['for_seating']) {
$enter_for[] = 'seating';
}
if ($validData['for_advancement']) {
$enter_for[] = 'advancement';
}
try {
$entry = $creator($validData['student_id'], $validData['audition_id'], $enter_for);
} catch (ManageEntryException $ex) {
return redirect()->route('admin.entries.index')->with('error', $ex->getMessage());
}
if ($validData['late_fee_waived']) {
$entry->addFlag('late_fee_waived');
}
return redirect(route('admin.entries.index'))->with('success', 'The entry has been added.');
}
public function edit(Entry $entry, CalculateScoreSheetTotal $calculator, ScoreService $scoreService)
{
if ($entry->audition->hasFlag('seats_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with seats published cannot be modified');
}
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with advancement results published cannot be modified');
}
$students = Student::with('school')->orderBy('last_name')->orderBy('first_name')->get();
$auditions = Audition::orderBy('score_order')->get();
$scores = $entry->scoreSheets()->with('audition', 'judge')->get();
foreach ($scores as $score) {
$score->entry = $entry;
$score->valid = $scoreService->isScoreSheetValid($score);
$score->seating_total_score = $calculator('seating', $entry, $score->judge)[0];
$score->advancement_total_score = $calculator('advancement', $entry, $score->judge)[0];
}
return view('admin.entries.edit', compact('entry', 'students', 'auditions', 'scores'));
}
public function update(Request $request, Entry $entry, UpdateEntry $updater)
{
if ($entry->audition->hasFlag('seats_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with seats published cannot be modified');
}
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with advancement results published cannot be modified');
}
$validData = request()->validate([
'audition_id' => ['required', 'exists:auditions,id'],
]);
$validData['for_seating'] = $request->get('for_seating') ? 1 : 0;
$validData['for_advancement'] = $request->get('for_advancement') ? 1 : 0;
$validData['late_fee_waived'] = $request->get('late_fee_waived') ? 1 : 0;
// If the audition is not set to advance to the next round, then the entry must be for seating
if (! auditionSetting('advanceTo')) {
$validData['for_seating'] = 1;
}
try {
$updater($entry, $validData);
} catch (ManageEntryException $e) {
return redirect()->route('admin.entries.index')->with('error', $e->getMessage());
}
if ($validData['late_fee_waived']) {
$entry->addFlag('late_fee_waived');
} else {
$entry->removeFlag('late_fee_waived');
}
return to_route('admin.entries.index')->with('success', 'Entry updated successfully');
}
public function destroy(Request $request, Entry $entry)
{
if ($entry->audition->hasFlag('seats_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with seats published cannot be deleted');
}
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with advancement results published cannot be deleted');
}
if (Seat::where('entry_id', $entry->id)->exists()) {
return redirect()->route('admin.entries.index')->with('error', 'Cannot delete an entry that is seated');
}
if ($entry->scoreSheets()->count() > 0) {
return redirect()->route('admin.entries.index')->with('error',
'Cannot delete an entry that has been scored');
}
if (auth()->user()) {
$message = 'Deleted entry '.$entry->id;
$affected = [
'entries' => [$entry->id],
'auditions' => [$entry->audition_id],
'schools' => [$entry->student->school_id],
'students' => [$entry->student_id],
];
AuditLogEntry::create([
'user' => auth()->user()->email,
'ip_address' => request()->ip(),
'message' => $message,
'affected' => $affected,
]);
}
$entry->delete();
return redirect()->route('admin.entries.index')->with('success', 'Entry Deleted');
}
}