212 lines
8.2 KiB
PHP
212 lines
8.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Actions\Entries\CreateEntry;
|
|
use App\Actions\Entries\UpdateEntry;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\EntryStoreRequest;
|
|
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 Illuminate\Http\Request;
|
|
|
|
use function auditionSetting;
|
|
use function compact;
|
|
use function to_route;
|
|
|
|
class EntryController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$perPage = 25;
|
|
$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'] ?? false) {
|
|
$entries->where('id', $filters['id']);
|
|
}
|
|
|
|
if ($filters['audition'] ?? false) {
|
|
$entries->where('audition_id', $filters['audition']);
|
|
}
|
|
if ($filters['school'] ?? false) {
|
|
$entries->whereHas('student', function ($query) use ($filters) {
|
|
$query->where('school_id', '=', $filters['school']);
|
|
});
|
|
}
|
|
if ($filters['grade'] ?? false) {
|
|
$entries->whereHas('student', function ($query) use ($filters) {
|
|
$query->where('grade', $filters['grade']);
|
|
});
|
|
}
|
|
|
|
if ($filters['first_name'] ?? false) {
|
|
$entries->whereHas('student', function ($query) use ($filters) {
|
|
$query->where('first_name', 'like', '%'.$filters['first_name'].'%');
|
|
});
|
|
}
|
|
|
|
if ($filters['last_name'] ?? false) {
|
|
$entries->whereHas('student', function ($query) use ($filters) {
|
|
$query->where('last_name', 'like', '%'.$filters['last_name'].'%');
|
|
});
|
|
}
|
|
|
|
if (isset($filters['entry_type']) && $filters['entry_type']) {
|
|
// TODO define actions for each possible type filter from index.blade.php of the admin entry
|
|
match ($filters['entry_type']) {
|
|
'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,
|
|
};
|
|
}
|
|
|
|
if (isset($filters['entries_per_page']) && $filters['entries_per_page']) {
|
|
$perPage = $filters['entries_per_page'];
|
|
}
|
|
|
|
}
|
|
|
|
$entries = $entries->paginate($perPage);
|
|
|
|
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(EntryStoreRequest $request, CreateEntry $creator)
|
|
{
|
|
$validData = $request->validatedWithEnterFor();
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
$entry = $creator(
|
|
student: $validData['student_id'],
|
|
audition: $validData['audition_id'],
|
|
for_seating: $validData['for_seating'],
|
|
for_advancement: $validData['for_advancement'],
|
|
late_fee_waived: $validData['late_fee_waived'],
|
|
);
|
|
|
|
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)
|
|
{
|
|
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();
|
|
// TODO: When updating Laravel, can we use the chaperone method I heard about ot load the entry back into the score
|
|
$scores = $entry->scoreSheets()->with('audition', 'judge', 'entry')->get();
|
|
|
|
$logEntries = AuditLogEntry::whereJsonContains('affected->entries', $entry->id)->orderBy('created_at', 'desc')->get();
|
|
|
|
return view('admin.entries.edit', compact('entry', 'students', 'auditions', 'scores', 'logEntries'));
|
|
}
|
|
|
|
public function update(Request $request, Entry $entry, UpdateEntry $updater)
|
|
{
|
|
// If the entry's current audition is published, we can't change it
|
|
if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advancement_published')) {
|
|
return to_route('admin.entries.index')->with('error',
|
|
'Entries in published auditions cannot be modified');
|
|
}
|
|
|
|
$validData = request()->validate([
|
|
'audition_id' => ['required', 'exists:auditions,id'],
|
|
'late_fee_waived' => ['sometimes'],
|
|
'for_seating' => ['sometimes'],
|
|
'for_advancement' => ['sometimes'],
|
|
]);
|
|
$proposedAudition = Audition::find($validData['audition_id']);
|
|
|
|
// If the entry's new audition is published, we can't change it
|
|
if ($proposedAudition->hasFlag('seats_published') || $proposedAudition->hasFlag('advancement_published')) {
|
|
return to_route('admin.entries.index')->with('error',
|
|
'Entries cannot be moved to published auditions');
|
|
}
|
|
|
|
$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;
|
|
}
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
$updater($entry, $validData);
|
|
|
|
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(Entry $entry)
|
|
{
|
|
if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advancement_published')) {
|
|
return to_route('admin.entries.index')->with('error',
|
|
'Entries in published auditions 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');
|
|
}
|
|
|
|
$entry->delete();
|
|
|
|
return redirect()->route('admin.entries.index')->with('success', 'Entry Deleted');
|
|
}
|
|
}
|