Get teh right entry data out to seating page

This commit is contained in:
Matt Young 2024-06-14 00:55:05 -05:00
parent 5a629b8cb6
commit edd792cce0
6 changed files with 409 additions and 26 deletions

View File

@ -37,9 +37,11 @@ class TabulationController extends Controller
// $entries = $entries->sortByDesc(function ($entry) {
// return $entry->totalScore();
// });
$entries = $audition->rankedEntries()->load('student.entries.audition','scoreSheets.audition.scoringGuide.subscores');
$judges = $audition->judges();
return view('tabulation.auditionSeating',compact('audition','entries','judges'));
// $entries = $audition->rankedEntries()->load('student.entries.audition','scoreSheets.audition.scoringGuide.subscores');
$entries = $this->tabulationService->auditionEntries($audition->id);
return view('tabulation.auditionSeating',compact('audition','entries'));
}
}

View File

@ -16,7 +16,6 @@ class ScoreSheet extends Model
];
protected $casts = ['subscores' => 'json'];
protected $with = ['entry','judge','audition.scoringGuide'];
public function entry(): BelongsTo
{

View File

@ -18,16 +18,16 @@ class AuditionCacheService
}
public function getAuditions(): \Illuminate\Database\Eloquent\Collection
{
{ //TODO have changes to judging assignments refresh the cache
return Cache::rememberForever($this->cacheKey, function () {
return Audition::with(['scoringGuide.subscores'])
return Audition::with(['scoringGuide.subscores','judges'])
->orderBy('score_order')
->get()
->keyBy('id');
});
}
public function getAudition($id)
public function getAudition($id): Audition
{
return $this->getAuditions()->firstWhere('id',$id);
}

View File

@ -2,12 +2,15 @@
namespace App\Services;
use App\Exceptions\TabulationException;
use App\Models\Audition;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use App\Services\AuditionCacheService;
use Illuminate\Support\Facades\DB;
use function array_unshift;
class TabulationService
@ -30,6 +33,75 @@ class TabulationService
});
}
public function auditionEntries(Int $auditionId)
{
$cache_key = 'audition'.$auditionId.'entries';
$audition = $this->auditionCacheService->getAudition($auditionId);
return Cache::remember($cache_key, 2, function () use ($audition) {
$entries = Entry::where('audition_id',$audition->id)->with(['student.school','scoreSheets'])->get();
foreach ($entries as $entry) {
$entry->final_score_array = $this->entryFinalScores($entry);
}
for ($n=0; $n <= $audition->judges_count; $n++) {
$entries = $entries->sortByDesc(function ($entry) use ($n) {
return $entry['final_score_array'][$n];
});
}
//TODO verify this actually sorts by subscores correcty
return $entries;
});
}
/**
* @throws TabulationException
*/
public function entryFinalScores(Entry $entry) {
$audition = $this->auditionCacheService->getAudition($entry->audition_id);
$this->validateEntryScoreSheets($entry);
$subscores = $audition->scoringGuide->subscores->sortBy('tiebreak_order');
$finalScoresArray = [];
foreach($subscores as $subscore) {
$finalScoresArray[$subscore->id] = 0;
}
foreach ($entry->scoreSheets as $sheet) {
foreach ($sheet->subscores as $ss) {
$finalScoresArray[$ss['subscore_id']] += $ss['score'];
}
}
// calculate weighted final score
$totalScore = 0;
$totalWeight = 0;
foreach ($subscores as $subscore) {
$totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight);
$totalWeight += $subscore->weight;
}
$totalScore = ($totalScore / $totalWeight);
array_unshift($finalScoresArray,$totalScore);
return $finalScoresArray;
}
/**
* @throws TabulationException
*/
public function validateEntryScoreSheets(Entry $entry): bool {
$audition = $this->auditionCacheService->getAudition($entry->audition_id);
foreach ($entry->scoreSheets as $sheet) {
if (! $audition->judges->contains($sheet->user_id)) {
$invalidJudge = User::find($sheet->user_id);
throw new TabulationException('Invalid scores for entry ' . $entry->id . ' exist from ' . $invalidJudge->full_name());
}
}
return true;
}
public function getAuditionsWithStatus()
{
// Create an array with the number of scores for each entry

325
config/debugbar.php Normal file
View File

@ -0,0 +1,325 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Debugbar Settings
|--------------------------------------------------------------------------
|
| Debugbar is enabled by default, when debug is set to true in app.php.
| You can override the value by setting enable to true or false instead of null.
|
| You can provide an array of URI's that must be ignored (eg. 'api/*')
|
*/
'enabled' => env('DEBUGBAR_ENABLED', null),
'except' => [
'telescope*',
'horizon*',
],
/*
|--------------------------------------------------------------------------
| Storage settings
|--------------------------------------------------------------------------
|
| DebugBar stores data for session/ajax requests.
| You can disable this, so the debugbar stores data in headers/session,
| but this can cause problems with large data collectors.
| By default, file storage (in the storage folder) is used. Redis and PDO
| can also be used. For PDO, run the package migrations first.
|
| Warning: Enabling storage.open will allow everyone to access previous
| request, do not enable open storage in publicly available environments!
| Specify a callback if you want to limit based on IP or authentication.
| Leaving it to null will allow localhost only.
*/
'storage' => [
'enabled' => true,
'open' => env('DEBUGBAR_OPEN_STORAGE'), // bool/callback.
'driver' => 'file', // redis, file, pdo, socket, custom
'path' => storage_path('debugbar'), // For file driver
'connection' => null, // Leave null for default connection (Redis/PDO)
'provider' => '', // Instance of StorageInterface for custom driver
'hostname' => '127.0.0.1', // Hostname to use with the "socket" driver
'port' => 2304, // Port to use with the "socket" driver
],
/*
|--------------------------------------------------------------------------
| Editor
|--------------------------------------------------------------------------
|
| Choose your preferred editor to use when clicking file name.
|
| Supported: "phpstorm", "vscode", "vscode-insiders", "vscode-remote",
| "vscode-insiders-remote", "vscodium", "textmate", "emacs",
| "sublime", "atom", "nova", "macvim", "idea", "netbeans",
| "xdebug", "espresso"
|
*/
'editor' => env('DEBUGBAR_EDITOR') ?: env('IGNITION_EDITOR', 'phpstorm'),
/*
|--------------------------------------------------------------------------
| Remote Path Mapping
|--------------------------------------------------------------------------
|
| If you are using a remote dev server, like Laravel Homestead, Docker, or
| even a remote VPS, it will be necessary to specify your path mapping.
|
| Leaving one, or both of these, empty or null will not trigger the remote
| URL changes and Debugbar will treat your editor links as local files.
|
| "remote_sites_path" is an absolute base path for your sites or projects
| in Homestead, Vagrant, Docker, or another remote development server.
|
| Example value: "/home/vagrant/Code"
|
| "local_sites_path" is an absolute base path for your sites or projects
| on your local computer where your IDE or code editor is running on.
|
| Example values: "/Users/<name>/Code", "C:\Users\<name>\Documents\Code"
|
*/
'remote_sites_path' => env('DEBUGBAR_REMOTE_SITES_PATH'),
'local_sites_path' => env('DEBUGBAR_LOCAL_SITES_PATH', env('IGNITION_LOCAL_SITES_PATH')),
/*
|--------------------------------------------------------------------------
| Vendors
|--------------------------------------------------------------------------
|
| Vendor files are included by default, but can be set to false.
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
| and for js: jquery and highlight.js
| So if you want syntax highlighting, set it to true.
| jQuery is set to not conflict with existing jQuery scripts.
|
*/
'include_vendors' => true,
/*
|--------------------------------------------------------------------------
| Capture Ajax Requests
|--------------------------------------------------------------------------
|
| The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
| you can use this option to disable sending the data through the headers.
|
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
|
| Note for your request to be identified as ajax requests they must either send the header
| X-Requested-With with the value XMLHttpRequest (most JS libraries send this), or have application/json as a Accept header.
|
| By default `ajax_handler_auto_show` is set to true allowing ajax requests to be shown automatically in the Debugbar.
| Changing `ajax_handler_auto_show` to false will prevent the Debugbar from reloading.
*/
'capture_ajax' => true,
'add_ajax_timing' => false,
'ajax_handler_auto_show' => true,
'ajax_handler_enable_tab' => true,
/*
|--------------------------------------------------------------------------
| Custom Error Handler for Deprecated warnings
|--------------------------------------------------------------------------
|
| When enabled, the Debugbar shows deprecated warnings for Symfony components
| in the Messages tab.
|
*/
'error_handler' => false,
/*
|--------------------------------------------------------------------------
| Clockwork integration
|--------------------------------------------------------------------------
|
| The Debugbar can emulate the Clockwork headers, so you can use the Chrome
| Extension, without the server-side code. It uses Debugbar collectors instead.
|
*/
'clockwork' => false,
/*
|--------------------------------------------------------------------------
| DataCollectors
|--------------------------------------------------------------------------
|
| Enable/disable DataCollectors
|
*/
'collectors' => [
'phpinfo' => true, // Php version
'messages' => true, // Messages
'time' => true, // Time Datalogger
'memory' => true, // Memory usage
'exceptions' => true, // Exception displayer
'log' => true, // Logs from Monolog (merged in messages if enabled)
'db' => true, // Show database (PDO) queries and bindings
'views' => true, // Views with their data
'route' => true, // Current route information
'auth' => false, // Display Laravel authentication status
'gate' => true, // Display Laravel Gate checks
'session' => true, // Display session data
'symfony_request' => true, // Only one can be enabled..
'mail' => true, // Catch mail messages
'laravel' => false, // Laravel version and environment
'events' => false, // All events fired
'default_request' => false, // Regular or special Symfony request logger
'logs' => false, // Add the latest log messages
'files' => false, // Show the included files
'config' => false, // Display config settings
'cache' => false, // Display cache events
'models' => true, // Display models
'livewire' => true, // Display Livewire (when available)
'jobs' => false, // Display dispatched jobs
],
/*
|--------------------------------------------------------------------------
| Extra options
|--------------------------------------------------------------------------
|
| Configure some DataCollectors
|
*/
'options' => [
'time' => [
'memory_usage' => false, // Calculated by subtracting memory start and end, it may be inaccurate
],
'messages' => [
'trace' => true, // Trace the origin of the debug message
],
'memory' => [
'reset_peak' => false, // run memory_reset_peak_usage before collecting
'with_baseline' => false, // Set boot memory usage as memory peak baseline
'precision' => 0, // Memory rounding precision
],
'auth' => [
'show_name' => true, // Also show the users name/email in the debugbar
'show_guards' => true, // Show the guards that are used
],
'db' => [
'with_params' => true, // Render SQL with the parameters substituted
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
'backtrace_exclude_paths' => [], // Paths to exclude from backtrace. (in addition to defaults)
'timeline' => false, // Add the queries to the timeline
'duration_background' => true, // Show shaded background on each query relative to how long it took to execute.
'explain' => [ // Show EXPLAIN output on queries
'enabled' => false,
'types' => ['SELECT'], // Deprecated setting, is always only SELECT
],
'hints' => false, // Show hints for common mistakes
'show_copy' => false, // Show copy button next to the query,
'slow_threshold' => false, // Only track queries that last longer than this time in ms
'memory_usage' => false, // Show queries memory usage
'soft_limit' => 100, // After the soft limit, no parameters/backtrace are captured
'hard_limit' => 500, // After the hard limit, queries are ignored
],
'mail' => [
'timeline' => false, // Add mails to the timeline
'show_body' => true,
],
'views' => [
'timeline' => false, // Add the views to the timeline (Experimental)
'data' => false, //true for all data, 'keys' for only names, false for no parameters.
'group' => 50, // Group duplicate views. Pass value to auto-group, or true/false to force
'exclude_paths' => [ // Add the paths which you don't want to appear in the views
'vendor/filament' // Exclude Filament components by default
],
],
'route' => [
'label' => true, // show complete route on bar
],
'session' => [
'hiddens' => [], // hides sensitive values using array paths
],
'symfony_request' => [
'hiddens' => [], // hides sensitive values using array paths, example: request_request.password
],
'events' => [
'data' => false, // collect events data, listeners
],
'logs' => [
'file' => null,
],
'cache' => [
'values' => true, // collect cache values
],
],
/*
|--------------------------------------------------------------------------
| Inject Debugbar in Response
|--------------------------------------------------------------------------
|
| Usually, the debugbar is added just before </body>, by listening to the
| Response after the App is done. If you disable this, you have to add them
| in your template yourself. See http://phpdebugbar.com/docs/rendering.html
|
*/
'inject' => true,
/*
|--------------------------------------------------------------------------
| DebugBar route prefix
|--------------------------------------------------------------------------
|
| Sometimes you want to set route prefix to be used by DebugBar to load
| its resources from. Usually the need comes from misconfigured web server or
| from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97
|
*/
'route_prefix' => '_debugbar',
/*
|--------------------------------------------------------------------------
| DebugBar route middleware
|--------------------------------------------------------------------------
|
| Additional middleware to run on the Debugbar routes
*/
'route_middleware' => [],
/*
|--------------------------------------------------------------------------
| DebugBar route domain
|--------------------------------------------------------------------------
|
| By default DebugBar route served from the same domain that request served.
| To override default domain, specify it as a non-empty value.
*/
'route_domain' => null,
/*
|--------------------------------------------------------------------------
| DebugBar theme
|--------------------------------------------------------------------------
|
| Switches between light and dark theme. If set to auto it will respect system preferences
| Possible values: auto, light, dark
*/
'theme' => env('DEBUGBAR_THEME', 'auto'),
/*
|--------------------------------------------------------------------------
| Backtrace stack limit
|--------------------------------------------------------------------------
|
| By default, the DebugBar limits the number of frames returned by the 'debug_backtrace()' function.
| If you need larger stacktraces, you can increase this number. Setting it to 0 will result in no limit.
*/
'debug_backtrace_limit' => 50,
];

View File

@ -21,27 +21,12 @@
<tr>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->student->full_name(true) }}</x-table.td>
<x-table.td>
@if($entry->student->isDoubler())
<x-doubler-block :student="$entry->student" />
@endif
</x-table.td>
{{-- @foreach($judges as $judge)--}}
{{-- <x-table.td>--}}
{{-- @php--}}
{{-- $thisJudgeScore = $entry->scoreFromJudge($judge->id)?->totalScore();--}}
{{-- @endphp--}}
{{-- {{ $thisJudgeScore ? number_format($thisJudgeScore,4) : '' }}--}}
{{-- </x-table.td>--}}
{{-- @endforeach--}}
<x-table.td>{{ number_format($entry->totalScore(), 4) }}</x-table.td>
<x-table.td>
@if($entry->fullyJudged())
<x-icons.checkmark color="green" />
@endif
<span>{{ $entry->student->full_name() }}, </span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
<x-table.td>Doubler Block</x-table.td>
<x-table.td>{{ $entry->final_score_array[0] }}</x-table.td>
</tr>
@endforeach
</x-table.body>