diff --git a/app/Actions/Tabulation/AllowForOlympicScoring.php b/app/Actions/Tabulation/AllowForOlympicScoring.php
new file mode 100644
index 0000000..a5346cf
--- /dev/null
+++ b/app/Actions/Tabulation/AllowForOlympicScoring.php
@@ -0,0 +1,99 @@
+calculator = $calculator;
+ $this->auditionService = $auditionService;
+ $this->entryService = $entryService;
+ }
+
+ public function calculate(string $mode, Entry $entry): array
+ {
+
+ $cacheKey = 'entryScore-'.$entry->id.'-'.$mode;
+ return Cache::remember($cacheKey, 10, function () use ($mode, $entry) {
+ $this->basicValidation($mode, $entry);
+ $this->areAllJudgesIn($entry);
+ $this->areAllJudgesValid($entry);
+
+ return $this->getJudgeTotals($mode, $entry);
+ });
+
+ }
+
+ protected function getJudgeTotals($mode, Entry $entry)
+ {
+
+ $scores = [];
+ foreach ($this->auditionService->getJudges($entry->audition) as $judge) {
+ $scores[] = $this->calculator->__invoke($mode, $entry, $judge);
+ }
+ // sort the scores array by the total score
+ usort($scores, function ($a, $b) {
+ return $a[0] <=> $b[0];
+ });
+
+ // we can only really do olympic scoring if there are at least 3 scores
+ if (count($scores) >= 3 && auditionSetting('olympic_scoring')) {
+ // remove the highest and lowest scores
+ array_pop($scores);
+ array_shift($scores);
+ }
+ $sums = [];
+ // Sum each subscore from the judges
+ foreach ($scores as $score) {
+ $index = 0;
+ foreach ($score as $value) {
+ $sums[$index] = $sums[$index] ?? 0;
+ $sums[$index] += $value;
+ $index++;
+ }
+ }
+ return $sums;
+ }
+
+ protected function basicValidation($mode, $entry): void
+ {
+ if ($mode !== 'seating' && $mode !== 'advancement') {
+ throw new TabulationException('Mode must be seating or advancement');
+ }
+
+ if (! $this->entryService->entryExists($entry)) {
+ throw new TabulationException('Invalid entry specified');
+ }
+ }
+
+ protected function areAllJudgesIn(Entry $entry): void
+ {
+ $assignedJudgeCount = $this->auditionService->getJudges($entry->audition)->count();
+ if ($entry->scoreSheets->count() !== $assignedJudgeCount) {
+ throw new TabulationException('Not all score sheets are in');
+ }
+ }
+
+ protected function areAllJudgesValid(Entry $entry): void
+ {
+ $validJudgeIds = $this->auditionService->getJudges($entry->audition)->sort()->pluck('id')->toArray();
+ $existingJudgeIds = $entry->scoreSheets->sort()->pluck('user_id')->toArray();
+ if ($validJudgeIds !== $existingJudgeIds) {
+ throw new TabulationException('Score exists from a judge not assigned to this audition');
+ }
+ }
+}
diff --git a/app/Http/Controllers/Admin/EntryController.php b/app/Http/Controllers/Admin/EntryController.php
index 79e016a..a04da74 100644
--- a/app/Http/Controllers/Admin/EntryController.php
+++ b/app/Http/Controllers/Admin/EntryController.php
@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Admin;
+use App\Actions\Tabulation\CalculateEntryScore;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\Entry;
@@ -109,7 +110,7 @@ class EntryController extends Controller
return redirect('/admin/entries');
}
- public function edit(Entry $entry)
+ public function edit(Entry $entry, CalculateEntryScore $calculator)
{
if ($entry->audition->hasFlag('seats_published')) {
return to_route('admin.entries.index')->with('error',
@@ -123,8 +124,8 @@ class EntryController extends Controller
$students = Student::with('school')->orderBy('last_name')->orderBy('first_name')->get();
$auditions = Audition::orderBy('score_order')->get();
- $scores = $entry->scoreSheets()->get();
-
+ $scores = $entry->scoreSheets()->with('audition', 'judge')->get();
+ $scores->each(fn ($score) => $score->entry = $entry);
// return view('admin.entries.edit', ['entry' => $entry, 'students' => $students, 'auditions' => $auditions]);
return view('admin.entries.edit', compact('entry', 'students', 'auditions', 'scores'));
}
diff --git a/app/Models/ScoreSheet.php b/app/Models/ScoreSheet.php
index cf93064..1d41ccc 100644
--- a/app/Models/ScoreSheet.php
+++ b/app/Models/ScoreSheet.php
@@ -2,9 +2,11 @@
namespace App\Models;
+use App\Actions\Tabulation\CalculateScoreSheetTotal;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
+use Illuminate\Support\Facades\App;
class ScoreSheet extends Model
{
@@ -50,4 +52,11 @@ class ScoreSheet extends Model
return $judges->contains('id', $this->judge->id);
}
+
+ public function totalScore($mode)
+ {
+ $calculator = App::make(CalculateScoreSheetTotal::class);
+
+ return $calculator($mode, $this->entry, $this->judge);
+ }
}
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 845e62b..6b048c4 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -2,7 +2,7 @@
namespace App\Providers;
-use App\Actions\Tabulation\AllJudgesCount;
+use App\Actions\Tabulation\AllowForOlympicScoring;
use App\Actions\Tabulation\CalculateEntryScore;
use App\Actions\Tabulation\CalculateScoreSheetTotal;
use App\Models\Audition;
@@ -45,7 +45,7 @@ class AppServiceProvider extends ServiceProvider
public function register(): void
{
$this->app->singleton(CalculateScoreSheetTotal::class, CalculateScoreSheetTotal::class);
- $this->app->singleton(CalculateEntryScore::class, AllJudgesCount::class);
+ $this->app->singleton(CalculateEntryScore::class, AllowForOlympicScoring::class);
$this->app->singleton(DrawService::class, DrawService::class);
$this->app->singleton(AuditionService::class, AuditionService::class);
$this->app->singleton(EntryService::class, EntryService::class);
diff --git a/app/Providers/CalculateEntryScoreProvider.php b/app/Providers/CalculateEntryScoreProvider.php
deleted file mode 100644
index 8d0a2d1..0000000
--- a/app/Providers/CalculateEntryScoreProvider.php
+++ /dev/null
@@ -1,28 +0,0 @@
-app->singleton(CalculateScoreSheetTotal::class, CalculateScoreSheetTotal::class);
- $this->app->singleton(CalculateEntryScore::class, AllJudgesCount::class);
- }
-
- /**
- * Bootstrap services.
- */
- public function boot(): void
- {
- //
- }
-}
diff --git a/bootstrap/providers.php b/bootstrap/providers.php
index fd4c1d5..9edefb0 100644
--- a/bootstrap/providers.php
+++ b/bootstrap/providers.php
@@ -2,7 +2,6 @@
return [
App\Providers\AppServiceProvider::class,
- App\Providers\CalculateEntryScoreProvider::class,
App\Providers\FortifyServiceProvider::class,
App\Providers\InvoiceDataServiceProvider::class,
];
diff --git a/resources/views/admin/audition-settings.blade.php b/resources/views/admin/audition-settings.blade.php
index 17cbcf9..87a1d34 100644
--- a/resources/views/admin/audition-settings.blade.php
+++ b/resources/views/admin/audition-settings.blade.php
@@ -29,7 +29,10 @@
+ {{ auditionSetting('auditionAbbreviation') }} Total + {{ $score->totalScore('seating')[0] }} +
+ + @if( auditionSetting('advanceTo')) ++ {{ auditionSetting('advanceTo') }} Total + {{ $score->totalScore('advancement')[0] }} +
+ @endif @if(! $score->isValid())