auditionadmin/app/Actions/Entries/CreateEntry.php

110 lines
3.6 KiB
PHP

<?php
namespace App\Actions\Entries;
use App\Exceptions\AuditionAdminException;
use App\Exceptions\ManageEntryException;
use App\Models\Audition;
use App\Models\Entry;
use App\Models\Student;
class CreateEntry
{
public function __construct()
{
}
/**
* @throws ManageEntryException
*/
public function __invoke(
Student|int $student,
Audition|int $audition,
$for_seating = false,
$for_advancement = false,
$late_fee_waived = false
) {
return $this->createEntry($student, $audition, $for_seating, $for_advancement, $late_fee_waived);
}
/**
* @throws ManageEntryException
*/
public function createEntry(
Student|int $student,
Audition|int $audition,
$for_seating = false,
$for_advancement = false,
$late_fee_waived = false
): Entry {
if (is_int($student)) {
$student = Student::find($student);
}
if (is_int($audition)) {
$audition = Audition::find($audition);
}
$this->verifySubmission($student, $audition);
if (! $for_advancement && ! $for_seating) {
$for_seating = true;
$for_advancement = true;
}
$entry = Entry::make([
'student_id' => $student->id,
'audition_id' => $audition->id,
'draw_number' => $this->checkDraw($audition),
'for_seating' => $for_seating,
'for_advancement' => $for_advancement,
]);
$entry->save();
if ($late_fee_waived) {
$entry->addFlag('late_fee_waived');
$entry->refresh();
}
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');
}
}
}