113 lines
4.0 KiB
PHP
113 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Entries;
|
|
|
|
use App\Exceptions\AuditionAdminException;
|
|
use App\Exceptions\ManageEntryException;
|
|
use App\Models\Audition;
|
|
use App\Models\AuditLogEntry;
|
|
use App\Models\Entry;
|
|
use App\Models\Student;
|
|
|
|
use function auth;
|
|
|
|
class CreateEntry
|
|
{
|
|
public function __construct()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* @throws ManageEntryException
|
|
*/
|
|
public function __invoke(Student|int $student, Audition|int $audition, string|array|null $entry_for = null)
|
|
{
|
|
return $this->createEntry($student, $audition, $entry_for);
|
|
}
|
|
|
|
/**
|
|
* @throws ManageEntryException
|
|
*/
|
|
public function createEntry(Student|int $student, Audition|int $audition, string|array|null $entry_for = null)
|
|
{
|
|
if (is_int($student)) {
|
|
$student = Student::find($student);
|
|
}
|
|
if (is_int($audition)) {
|
|
$audition = Audition::find($audition);
|
|
}
|
|
|
|
if (! $entry_for) {
|
|
$entry_for = ['seating', 'advancement'];
|
|
}
|
|
$entry_for = collect($entry_for);
|
|
$this->verifySubmission($student, $audition);
|
|
$entry = Entry::make([
|
|
'student_id' => $student->id,
|
|
'audition_id' => $audition->id,
|
|
'draw_number' => $this->checkDraw($audition),
|
|
'for_seating' => $entry_for->contains('seating'),
|
|
'for_advancement' => $entry_for->contains('advancement'),
|
|
]);
|
|
$entry->save();
|
|
if (auth()->user()) {
|
|
$message = 'Entered '.$entry->student->full_name().' from '.$entry->student->school->name.' in '.$entry->audition->name.'.';
|
|
AuditLogEntry::create([
|
|
'user' => auth()->user()->email,
|
|
'ip_address' => request()->ip(),
|
|
'message' => $message,
|
|
'affected' => [
|
|
'entries' => [$entry->id],
|
|
'students' => [$entry->student_id],
|
|
'auditions' => [$entry->audition_id],
|
|
'schools' => [$entry->student->school_id],
|
|
],
|
|
]);
|
|
}
|
|
|
|
return $entry;
|
|
}
|
|
|
|
private function checkDraw(Audition $audition)
|
|
{
|
|
if (! $audition->hasFlag('drawn')) {
|
|
return null;
|
|
}
|
|
// get the maximum value of draw_number from $audition->entries()
|
|
$draw_number = $audition->entries()->max('draw_number');
|
|
|
|
return $draw_number + 1;
|
|
}
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
private function verifySubmission(?Student $student, ?Audition $audition): void
|
|
{
|
|
// Make sure it's a valid student
|
|
if (! $student || ! $student->exists()) {
|
|
throw new AuditionAdminException('Invalid student provided');
|
|
}
|
|
// Make sure the audition is valid
|
|
if (! $audition || ! $audition->exists()) {
|
|
throw new AuditionAdminException('Invalid audition provided');
|
|
}
|
|
// A student can't enter the same audition twice
|
|
if (Entry::where('student_id', $student->id)->where('audition_id', $audition->id)->exists()) {
|
|
throw new AuditionAdminException('That student is already entered in that audition');
|
|
}
|
|
// Can't enter a published audition
|
|
if ($audition->hasFlag('seats_published')) {
|
|
throw new AuditionAdminException('Cannot add an entry to an audition where seats are published');
|
|
}
|
|
if ($audition->hasFlag('advancement_published')) {
|
|
throw new AuditionAdminException('Cannot add an entry to an audition where advancement is published');
|
|
}
|
|
// Verify the grade of the student is in range for the audition
|
|
if ($student->grade > $audition->maximum_grade) {
|
|
throw new AuditionAdminException('The grade of the student exceeds the maximum for that audition');
|
|
}
|
|
if ($student->grade < $audition->minimum_grade) {
|
|
throw new AuditionAdminException('The grade of the student does not meet the minimum for that audition');
|
|
}
|
|
}
|
|
}
|