diff --git a/app/Http/Controllers/Tabulation/EntryFlagController.php b/app/Http/Controllers/Tabulation/EntryFlagController.php index 14189e2..3a9b1b1 100644 --- a/app/Http/Controllers/Tabulation/EntryFlagController.php +++ b/app/Http/Controllers/Tabulation/EntryFlagController.php @@ -5,6 +5,9 @@ namespace App\Http\Controllers\Tabulation; use App\Http\Controllers\Controller; use App\Models\Entry; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; + +use function to_route; class EntryFlagController extends Controller { @@ -22,6 +25,17 @@ class EntryFlagController extends Controller 'entry_id' => 'required|exists:entries,id', ]); $entry = Entry::with('flags')->withCount('scoreSheets')->find($validData['entry_id']); + + // If any results are published, get gone + if ($entry->audition->hasFlag('seats_published')) { + return to_route('entry-flags.noShowSelect')->with('error', + 'Cannot enter a no-show for an entry in an audition where seats are published'); + } + if ($entry->audition->hasFlag('advance_published')) { + return to_route('entry-flags.noShowSelect')->with('error', + 'Cannot enter a no-show for an entry in an audition where advancement is published'); + } + if ($entry->hasFlag('no_show')) { $formId = 'no-show-cancellation-form'; $buttonName = 'Remove No Show'; @@ -36,10 +50,11 @@ class EntryFlagController extends Controller $method = 'POST'; } $scores = []; - if($entry->score_sheets_count > 0) { + if ($entry->score_sheets_count > 0) { $scores = $entry->scoreSheets; $scores->load('judge'); } + return view('tabulation.no_show_confirm', compact('entry', 'formId', @@ -52,7 +67,21 @@ class EntryFlagController extends Controller public function enterNoShow(Entry $entry) { - // + if ($entry->audition->hasFlag('seats_published')) { + return to_route('entry-flags.noShowSelect')->with('error', + 'Cannot enter a no-show for an entry in an audition where seats are published'); + } + if ($entry->audition->hasFlag('advance_published')) { + return to_route('entry-flags.noShowSelect')->with('error', + 'Cannot enter a no-show for an entry in an audition where advancement is published'); + } + DB::table('score_sheets')->where('entry_id', $entry->id)->delete(); + + $entry->addFlag('no_show'); + + $msg = 'No Show has been entered for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').'; + + return to_route('entry-flags.noShowSelect')->with('success', $msg); } public function undoNoShow(Entry $entry) diff --git a/tests/Feature/Pages/Tabulation/noShowConfirmTest.php b/tests/Feature/Pages/Tabulation/noShowConfirmTest.php index 4e09a6f..011f22f 100644 --- a/tests/Feature/Pages/Tabulation/noShowConfirmTest.php +++ b/tests/Feature/Pages/Tabulation/noShowConfirmTest.php @@ -29,6 +29,19 @@ it('only allows an admin or tab user to confirm a no-show', function () { get(route('entry-flags.confirmNoShow', ['entry_id' => $entry->id])) ->assertOk(); }); +it('will not work with an entry if it is in a published audition', function () { + $entry1 = Entry::factory()->create(); + $entry2 = Entry::factory()->create(); + $entry1->audition->addFlag('seats_published'); + $entry2->audition->addFlag('advance_published'); + actAsTab(); + get(route('entry-flags.confirmNoShow', ['entry_id' => $entry1->id])) + ->assertRedirect(route('entry-flags.noShowSelect')) + ->assertSessionHas('error', 'Cannot enter a no-show for an entry in an audition where seats are published'); + get(route('entry-flags.confirmNoShow', ['entry_id' => $entry2->id])) + ->assertRedirect(route('entry-flags.noShowSelect')) + ->assertSessionHas('error', 'Cannot enter a no-show for an entry in an audition where advancement is published'); +}); it('has information for the requested entry', function () { // Arrange $entry = Entry::factory()->create(); @@ -73,12 +86,12 @@ it('posts to entry-flags.undoNoShow and has a remove button if the entry is alre it('shows a box with scores if the entry is scored', function () { // Arrange $judges = User::factory()->count(3)->create(); - $room = Room::factory()->create(); - $judges->each(fn ($judge) => $room->addJudge($judge->id)); + $room = Room::factory()->create(); + $judges->each(fn($judge) => $room->addJudge($judge->id)); $scoringGuide = ScoringGuide::factory()->create(); SubscoreDefinition::factory()->count(5)->create(['scoring_guide_id' => $scoringGuide->id]); $audition = Audition::factory()->create(['room_id' => $room->id, 'scoring_guide_id' => $scoringGuide->id]); - $entry = Entry::factory()->create(['audition_id' => $audition->id]); + $entry = Entry::factory()->create(['audition_id' => $audition->id]); // Run the ScoreAllAuditions seeder Artisan::call('db:seed', ['--class' => 'ScoreAllAuditions']); // Act & Assert @@ -87,6 +100,6 @@ it('shows a box with scores if the entry is scored', function () { $response->assertOk() ->assertSee('WARNING') ->assertSee('existing scores'); - $judges->each(fn ($judge) => $response->assertSee($judge->full_name())); + $judges->each(fn($judge) => $response->assertSee($judge->full_name())); }); diff --git a/tests/Feature/Pages/Tabulation/noShowEnterAndCancelTest.php b/tests/Feature/Pages/Tabulation/noShowEnterAndCancelTest.php new file mode 100644 index 0000000..51d3bac --- /dev/null +++ b/tests/Feature/Pages/Tabulation/noShowEnterAndCancelTest.php @@ -0,0 +1,60 @@ +create(); + post(route('entry-flags.enterNoShow', $entry)) + ->assertRedirect(route('home')); + actAsAdmin(); + post(route('entry-flags.enterNoShow', $entry)) + ->assertSessionHasNoErrors() + ->assertSessionHas('success', + 'No Show has been entered for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').') + ->assertRedirect(route('entry-flags.noShowSelect')); + actAsTab(); + post(route('entry-flags.enterNoShow', $entry)) + ->assertSessionHasNoErrors() + ->assertSessionHas('success', + 'No Show has been entered for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').') + ->assertRedirect(route('entry-flags.noShowSelect')); +}); +it('will not record an entry in a published audition as a no show', function () { + $entry1 = Entry::factory()->create(); + $entry2 = Entry::factory()->create(); + $entry1->audition->addFlag('seats_published'); + $entry2->audition->addFlag('advance_published'); + actAsAdmin(); + post(route('entry-flags.enterNoShow', $entry1)) + ->assertRedirect(route('entry-flags.noShowSelect')) + ->assertSessionHas('error', 'Cannot enter a no-show for an entry in an audition where seats are published'); + post(route('entry-flags.enterNoShow', $entry2)) + ->assertRedirect(route('entry-flags.noShowSelect')) + ->assertSessionHas('error', + 'Cannot enter a no-show for an entry in an audition where advancement is published'); +}); +it('deletes all scores for an entry when a no-show is entered', function () { + $entry = Entry::factory()->create(); + $judges = User::factory()->count(3)->create(); + $entry->scoreSheets()->create(['user_id' => $judges[0]->id, 'subscores' => 10]); + $entry->scoreSheets()->create(['user_id' => $judges[1]->id, 'subscores' => 10]); + $entry->scoreSheets()->create(['user_id' => $judges[2]->id, 'subscores' => 10]); + expect($entry->scoreSheets()->count())->toBe(3); + actAsAdmin(); + post(route('entry-flags.enterNoShow', $entry)); + expect($entry->scoreSheets()->count())->toBe(0); +}); +it('adds a no_show flag to the entry', function () { + // Arrange + $entry = Entry::factory()->create(); + // Act & Assert + actAsAdmin(); + post(route('entry-flags.enterNoShow', $entry)); + expect(Entry::find($entry->id)->hasFlag('no_show'))->toBeTrue(); +});