Bonus Score Entry
#20 Implement bonus scores Judges entry list screen correctly show scored entries.
This commit is contained in:
parent
475ac181c6
commit
7e908024d7
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Judging;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Audition;
|
||||
use App\Models\BonusScore;
|
||||
use App\Models\BonusScoreDefinition;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class BonusScoreEntryListController extends Controller
|
||||
{
|
||||
public function __invoke(Audition $audition)
|
||||
{
|
||||
/** @var BonusScoreDefinition $bonusScore */
|
||||
$bonusScore = $audition->bonusScore()->first();
|
||||
if (! $bonusScore->judges->contains(auth()->id())) {
|
||||
return redirect()->route('dashboard')->with('error', 'You are not assigned to judge this bonus score');
|
||||
}
|
||||
$entries = $audition->entries()->orderBy('draw_number')->get();
|
||||
$entries = $entries->reject(fn ($entry) => $entry->hasFlag('no_show'));
|
||||
$entries->each(fn ($entry) => $entry->audition = $audition);
|
||||
|
||||
$scores = BonusScore::where('user_id', Auth::user()->id)
|
||||
->with('entry.audition')
|
||||
->with('originallyScoredEntry.audition')
|
||||
->get()
|
||||
->keyBy('entry_id');
|
||||
|
||||
return view('judging.bonus_score_entry_list', compact('audition', 'entries', 'scores'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Judging;
|
||||
|
||||
use App\Actions\Tabulation\EnterScore;
|
||||
use App\Exceptions\AuditionServiceException;
|
||||
use App\Exceptions\ScoreEntryException;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Audition;
|
||||
use App\Models\Entry;
|
||||
use App\Models\JudgeAdvancementVote;
|
||||
|
|
@ -3,8 +3,24 @@
|
|||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class BonusScore extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
public function entry(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Entry::class);
|
||||
}
|
||||
|
||||
public function judge(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function originallyScoredEntry(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Entry::class, 'originally_scored_entry');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
@php use Carbon\Carbon; @endphp
|
||||
<x-layout.app>
|
||||
<x-slot:page_title>Judging Dashboard - Bonus Scores</x-slot:page_title>
|
||||
<x-table.table>
|
||||
<x-slot:title>{{ $audition->name }} - Bonus Score</x-slot:title>
|
||||
<x-table.body>
|
||||
<thead>
|
||||
<tr>
|
||||
<x-table.th>Entry</x-table.th>
|
||||
<x-table.th>Score</x-table.th>
|
||||
<x-table.th>Scored On</x-table.th>
|
||||
<x-table.th>Score Timestamp</x-table.th>
|
||||
</tr>
|
||||
</thead>
|
||||
<x-table.body>
|
||||
@foreach($entries as $entry)
|
||||
<tr>
|
||||
<x-table.td>{{ $audition->name }} {{ $entry->draw_number }}</x-table.td>
|
||||
@if($scores->has($entry->id))
|
||||
<x-table.td>{{ $scores[$entry->id]->score }}</x-table.td>
|
||||
<x-table.td>{{ $scores[$entry->id]->originallyScoredEntry->audition->name }}</x-table.td>
|
||||
<x-table.td>{{ Carbon::create($scores[$entry->id]->created_at)->setTimezone('America/Chicago')->format('m/d/y H:i') }}</x-table.td>
|
||||
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</x-table.body>
|
||||
</x-table.body>
|
||||
</x-table.table>
|
||||
</x-layout.app>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
<x-card.heading>{{ $bonusScore->name }}</x-card.heading>
|
||||
<x-card.list.body>
|
||||
@foreach($bonusScore->auditions as $audition)
|
||||
<a href="#">
|
||||
<a href="{{ route('judging.bonusScore.EntryList', $audition) }}">
|
||||
<x-card.list.row class="!py-3 ml-3">
|
||||
{{ $audition->name }}
|
||||
</x-card.list.row>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
// Judging Routes
|
||||
use App\Http\Controllers\JudgingController;
|
||||
use App\Http\Controllers\Judging\BonusScoreEntryListController;
|
||||
use App\Http\Controllers\Judging\JudgingController;
|
||||
use App\Http\Middleware\CheckIfCanJudge;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
|
@ -11,3 +13,8 @@ Route::middleware(['auth', 'verified', CheckIfCanJudge::class])->prefix('judging
|
|||
Route::post('/entry/{entry}', 'saveScoreSheet')->name('judging.saveScoreSheet');
|
||||
Route::patch('/entry/{entry}', 'updateScoreSheet')->name('judging.updateScoreSheet');
|
||||
});
|
||||
|
||||
// Bonus score judging routes
|
||||
Route::middleware(['auth', 'verified', CheckIfCanJudge::class])->prefix('judging/bonus_scores')->group(function () {
|
||||
Route::get('/{audition}', BonusScoreEntryListController::class)->name('judging.bonusScore.EntryList');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,19 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\DashboardController;
|
||||
use App\Http\Controllers\EntryController;
|
||||
use App\Http\Controllers\FilterController;
|
||||
use App\Http\Controllers\JudgingController;
|
||||
use App\Http\Controllers\PdfInvoiceController;
|
||||
use App\Http\Controllers\SchoolController;
|
||||
use App\Http\Controllers\StudentController;
|
||||
use App\Http\Controllers\Tabulation\DoublerDecisionController;
|
||||
use App\Http\Controllers\TestController;
|
||||
use App\Http\Controllers\UserController;
|
||||
use App\Http\Middleware\CheckIfAdmin;
|
||||
use App\Http\Middleware\CheckIfCanJudge;
|
||||
use App\Http\Middleware\CheckIfCanTab;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
require __DIR__.'/admin.php';
|
||||
|
|
@ -23,7 +11,6 @@ require __DIR__.'/user.php';
|
|||
|
||||
Route::get('/test', [TestController::class, 'flashTest'])->middleware('auth', 'verified');
|
||||
|
||||
|
||||
Route::view('/', 'welcome')->middleware('guest')->name('home');
|
||||
Route::get('/results', [App\Http\Controllers\ResultsPage::class, '__invoke'])->name('results');
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Audition;
|
||||
use App\Models\BonusScore;
|
||||
use App\Models\BonusScoreDefinition;
|
||||
use App\Models\Entry;
|
||||
use App\Models\Room;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
use function Pest\Laravel\actingAs;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('denies access go a guest', function () {
|
||||
$response = $this->get(route('judging.bonusScore.EntryList', 1));
|
||||
$response->assertRedirect(route('home'));
|
||||
});
|
||||
it('denies access to a user not assigned to judge this bonus score', function () {
|
||||
$bonusScore = BonusScoreDefinition::factory()->create();
|
||||
$audition = Audition::factory()->create();
|
||||
$audition->bonusScore()->attach($bonusScore->id);
|
||||
$room = Room::factory()->create();
|
||||
$user = User::factory()->create();
|
||||
$room->addJudge($user->id);
|
||||
actingAs($user);
|
||||
$this->get(route('judging.bonusScore.EntryList', $audition->id))
|
||||
->assertRedirect(route('dashboard'))
|
||||
->assertSessionHas('error', 'You are not assigned to judge this bonus score');
|
||||
});
|
||||
it('shows all entries to an authorized judge', function () {
|
||||
// Arrange
|
||||
$bonusScore = BonusScoreDefinition::factory()->create();
|
||||
$audition = Audition::factory()->create();
|
||||
$audition->bonusScore()->attach($bonusScore->id);
|
||||
$entries[1] = Entry::factory()->create(['audition_id' => $audition->id, 'draw_number' => 1]);
|
||||
$entries[2] = Entry::factory()->create(['audition_id' => $audition->id, 'draw_number' => 2]);
|
||||
$entries[3] = Entry::factory()->create(['audition_id' => $audition->id, 'draw_number' => 3]);
|
||||
$entries[4] = Entry::factory()->create(['audition_id' => $audition->id, 'draw_number' => 4]);
|
||||
$entries = collect($entries);
|
||||
$judge = User::factory()->create();
|
||||
$bonusScore->judges()->attach($judge->id);
|
||||
actingAs($judge);
|
||||
// Act & Assert
|
||||
$response = $this->get(route('judging.bonusScore.EntryList', $audition->id));
|
||||
$response->assertOk();
|
||||
$entries->each(fn ($entry) => $response->assertSee($entry->audition->name.' '.$entry->draw_number));
|
||||
});
|
||||
it('shows existing scores for an entry', function () {
|
||||
$bonusScore = BonusScoreDefinition::factory()->create(['max_score' => 100]);
|
||||
$audition = Audition::factory()->create();
|
||||
$audition->bonusScore()->attach($bonusScore->id);
|
||||
$entry = Entry::factory()->create(['audition_id' => $audition->id, 'draw_number' => 1]);
|
||||
$judge = User::factory()->create();
|
||||
$bonusScore->judges()->attach($judge->id);
|
||||
BonusScore::create([
|
||||
'entry_id' => $entry->id,
|
||||
'user_id' => $judge->id,
|
||||
'originally_scored_entry' => $entry->id,
|
||||
'score' => 42,
|
||||
]);
|
||||
actingAs($judge);
|
||||
// Act
|
||||
$response = $this->get(route('judging.bonusScore.EntryList', $audition));
|
||||
$response->assertOk()
|
||||
->assertSeeInOrder(['<tr>', e($audition->name), $entry->draw_number, 42, '</tr>'], false);
|
||||
});
|
||||
Loading…
Reference in New Issue