Validate score array and refill form on error
This commit is contained in:
parent
9e577824a3
commit
cf51c46d2e
|
|
@ -5,7 +5,10 @@ namespace App\Http\Controllers\Tabulation;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
use App\Rules\ValidScoreArray;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use function dump;
|
||||||
|
use function redirect;
|
||||||
|
|
||||||
class TabulationController extends Controller
|
class TabulationController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -26,5 +29,17 @@ class TabulationController extends Controller
|
||||||
return view('tabulation.entry_score_sheet', compact('entry','judges','scoring_guide','subscores'));
|
return view('tabulation.entry_score_sheet', compact('entry','judges','scoring_guide','subscores'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function saveEntryScoreSheet(Request $request, Entry $entry)
|
||||||
|
{
|
||||||
|
$judges = $entry->audition->room->judges;
|
||||||
|
$subscores = $entry->audition->scoringGuide->subscores->sortBy('tiebreak_order');
|
||||||
|
$scoringGuide = $entry->audition->scoringGuide;
|
||||||
|
foreach ($judges as $judge) {
|
||||||
|
$scoreValidation = $scoringGuide->validateScores($request->input('judge'.$judge->id));
|
||||||
|
if ($scoreValidation != 'success') {
|
||||||
|
return redirect(url()->previous())->with('error', $judge->full_name() . ': ' . $scoreValidation)->with('oldScores',$request->all());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@ namespace App\Models;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use phpDocumentor\Reflection\Types\Boolean;
|
||||||
|
use PhpParser\Node\Expr\Cast\Bool_;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
use function array_diff_key;
|
||||||
|
use function array_key_exists;
|
||||||
|
use function is_null;
|
||||||
|
|
||||||
class ScoringGuide extends Model
|
class ScoringGuide extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -20,4 +26,20 @@ class ScoringGuide extends Model
|
||||||
{
|
{
|
||||||
return $this->hasMany(SubscoreDefinition::class);
|
return $this->hasMany(SubscoreDefinition::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateScores(Array $prospective_score)
|
||||||
|
{
|
||||||
|
foreach ($this->subscores as $subscore) {
|
||||||
|
if (! array_key_exists($subscore->id,$prospective_score)) return "A score must be provided for " . $subscore->name;
|
||||||
|
if (is_null($prospective_score[$subscore->id])) return "A score must be provided for " . $subscore->name;
|
||||||
|
if ($prospective_score[$subscore->id] > $subscore->max_score) return "The " . $subscore->name . " score must be less than or equal to " . $subscore->max_score;
|
||||||
|
}
|
||||||
|
|
||||||
|
$subscore_ids = $this->subscores->pluck('id')->flip()->all();
|
||||||
|
$diff = array_diff_key($prospective_score, $subscore_ids);
|
||||||
|
if (!empty($diff)) return "Invalid scores submitted";
|
||||||
|
|
||||||
|
return 'success';
|
||||||
|
// TODO this probably needs to be rewritten as a validation rule
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('score_sheets', function (Blueprint $table) {
|
||||||
|
$table->unique('user_id','entry_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('score_sheets', function (Blueprint $table) {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
</x-layout.page-header>
|
</x-layout.page-header>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
{{-- @php(dump(session()->get('oldScores')))--}}
|
||||||
|
|
||||||
<main {{ $attributes }}>
|
<main {{ $attributes }}>
|
||||||
<div class="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
|
<div class="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
|
@php($oldScores = session()->get('oldScores')) {{-- TODO Need to handle if null --}}
|
||||||
<x-slot:page_title>Entry Score Sheet</x-slot:page_title>
|
<x-slot:page_title>Entry Score Sheet</x-slot:page_title>
|
||||||
<x-card.card class="mx-auto max-w-7xl">
|
<x-card.card class="mx-auto max-w-7xl">
|
||||||
<x-card.heading>
|
<x-card.heading>
|
||||||
|
|
@ -10,29 +11,31 @@
|
||||||
</x-slot:right_side>
|
</x-slot:right_side>
|
||||||
</x-card.heading>
|
</x-card.heading>
|
||||||
|
|
||||||
<x-form.form>
|
<x-form.form method="POST" action="/tabulation/entries/{{ $entry->id }}">
|
||||||
<x-table.table>
|
<x-table.table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<x-table.th>Judges</x-table.th>
|
<x-table.th>Judges</x-table.th>
|
||||||
@foreach($subscores as $subscore)
|
@foreach($subscores as $subscore)
|
||||||
<x-table.th>{{ $subscore->name }}</x-table.th>
|
<x-table.th>
|
||||||
|
<p>{{ $subscore->name }}<span class="text-xs text-gray-500 pl-2">Max: {{ $subscore->max_score }}</span></p>
|
||||||
|
</x-table.th>
|
||||||
@endforeach
|
@endforeach
|
||||||
<x-table.th>Total (unweighted)</x-table.th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<x-table.body :sortable="false">
|
<x-table.body :sortable="false">
|
||||||
@foreach($judges as $judge)
|
@foreach($judges as $judge)
|
||||||
<tr x-data="{ scores: [], total: 0, calculateTotal: function() { this.total = this.scores.reduce((a, b) => parseFloat(a) + parseFloat(b), 0); } }">
|
<tr >
|
||||||
<x-table.td>{{ $judge->full_name() }}</x-table.td>
|
<x-table.td>{{ $judge->full_name() }}</x-table.td>
|
||||||
@foreach($subscores as $subscore)
|
@foreach($subscores as $subscore)
|
||||||
<x-table.td>
|
<x-table.td>
|
||||||
<input type="number"
|
<input type="number"
|
||||||
|
{{-- max="{{ $subscore->max_score }}"--}}
|
||||||
id="j{{ $judge->id }}ss{{ $subscore->id }}"
|
id="j{{ $judge->id }}ss{{ $subscore->id }}"
|
||||||
name="judge{{ $judge->id }}[subscore{{ $subscore->id }}]"
|
name="judge{{ $judge->id }}[{{ $subscore->id }}]"
|
||||||
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 judge{{$judge->id}}score"
|
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 judge{{$judge->id}}score"
|
||||||
x-model="scores[{{ $loop->index }}]"
|
@if($oldScores) value="{{ $oldScores['judge'.$judge->id][$subscore->id] }}" @endif
|
||||||
x-on:input="calculateTotal" >
|
>
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
@endforeach
|
@endforeach
|
||||||
<x-table.td id="judge{{ $judge->id }}total" x-text="total">
|
<x-table.td id="judge{{ $judge->id }}total" x-text="total">
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ Route::middleware(['auth','verified',CheckIfCanTab::class])->prefix('tabulation/
|
||||||
Route::get('/enter_scores','chooseEntry')->name('tabulation.chooseEntry');
|
Route::get('/enter_scores','chooseEntry')->name('tabulation.chooseEntry');
|
||||||
Route::get('/record_noshow','chooseEntry');
|
Route::get('/record_noshow','chooseEntry');
|
||||||
Route::get('/entries','entryScoreSheet');
|
Route::get('/entries','entryScoreSheet');
|
||||||
|
Route::post('/entries/{entry}','saveEntryScoreSheet');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue