ScoreService now honors the setting of for_seating on the scoring guides

This commit is contained in:
Matt Young 2024-06-20 23:54:02 -05:00
parent 55b6081fc6
commit 30c2813ecf
6 changed files with 120 additions and 8 deletions

View File

@ -0,0 +1,36 @@
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class ScoreSheetChange
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public int $entryId;
/**
* Create a new event instance.
*/
public function __construct($entryId = null)
{
$this->entryId = $entryId;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new PrivateChannel('channel-name'),
];
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Listeners;
use App\Events\ScoreSheetChange;
use App\Services\ScoreService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class RefreshScoreSheetCache
{
protected $scoreService;
/**
* Create the event listener.
*/
public function __construct(ScoreService $scoreService)
{
$this->scoreService = $scoreService;
}
/**
* Handle the event.
*/
public function handle(ScoreSheetChange $event): void
{
$this->scoreService->clearScoreSheetCountCache();
if ($event->entryId) {
$this->scoreService->clearEntryTotalScoresCache($event->entryId);
}
// If we are in local environment, send a success flash message
if (config('app.env') === 'local') {
session()->flash('success','Cleared cache for entry ID ' . $event->entryId);
}
}
}

View File

@ -24,5 +24,6 @@ class RefreshScoringGuideCache
public function handle(ScoringGuideChange $event): void public function handle(ScoringGuideChange $event): void
{ {
$this->scoreService->clearScoringGuideCache(); $this->scoreService->clearScoringGuideCache();
$this->scoreService->clearAllCachedTotalScores();
} }
} }

View File

@ -2,6 +2,7 @@
namespace App\Observers; namespace App\Observers;
use App\Events\ScoreSheetChange;
use App\Models\ScoreSheet; use App\Models\ScoreSheet;
class ScoreSheetObserver class ScoreSheetObserver
@ -11,7 +12,7 @@ class ScoreSheetObserver
*/ */
public function created(ScoreSheet $scoreSheet): void public function created(ScoreSheet $scoreSheet): void
{ {
// ScoreSheetChange::dispatch($scoreSheet->entry_id);
} }
/** /**
@ -19,7 +20,7 @@ class ScoreSheetObserver
*/ */
public function updated(ScoreSheet $scoreSheet): void public function updated(ScoreSheet $scoreSheet): void
{ {
// ScoreSheetChange::dispatch($scoreSheet->entry_id);
} }
/** /**
@ -27,7 +28,7 @@ class ScoreSheetObserver
*/ */
public function deleted(ScoreSheet $scoreSheet): void public function deleted(ScoreSheet $scoreSheet): void
{ {
// ScoreSheetChange::dispatch($scoreSheet->entry_id);
} }
/** /**
@ -35,7 +36,7 @@ class ScoreSheetObserver
*/ */
public function restored(ScoreSheet $scoreSheet): void public function restored(ScoreSheet $scoreSheet): void
{ {
// ScoreSheetChange::dispatch($scoreSheet->entry_id);
} }
/** /**
@ -43,6 +44,6 @@ class ScoreSheetObserver
*/ */
public function forceDeleted(ScoreSheet $scoreSheet): void public function forceDeleted(ScoreSheet $scoreSheet): void
{ {
// ScoreSheetChange::dispatch($scoreSheet->entry_id);
} }
} }

View File

@ -4,9 +4,11 @@ namespace App\Providers;
use App\Events\AuditionChange; use App\Events\AuditionChange;
use App\Events\EntryChange; use App\Events\EntryChange;
use App\Events\ScoreSheetChange;
use App\Events\ScoringGuideChange; use App\Events\ScoringGuideChange;
use App\Listeners\RefreshAuditionCache; use App\Listeners\RefreshAuditionCache;
use App\Listeners\RefreshEntryCache; use App\Listeners\RefreshEntryCache;
use App\Listeners\RefreshScoreSheetCache;
use App\Listeners\RefreshScoringGuideCache; use App\Listeners\RefreshScoringGuideCache;
use App\Models\Audition; use App\Models\Audition;
use App\Models\Entry; use App\Models\Entry;
@ -104,5 +106,10 @@ class AppServiceProvider extends ServiceProvider
ScoringGuideChange::class, ScoringGuideChange::class,
RefreshScoringGuideCache::class RefreshScoringGuideCache::class
); );
Event::listen(
ScoreSheetChange::class,
RefreshScoreSheetCache::class
);
} }
} }

View File

@ -74,8 +74,6 @@ class ScoreService
} }
/** /**
* Get final scores array for the requested entry. The first element is the total score. The following elements are sums * Get final scores array for the requested entry. The first element is the total score. The following elements are sums
* of each subscore in tiebreaker order * of each subscore in tiebreaker order
@ -101,7 +99,7 @@ class ScoreService
$scoringGuideId = $audition->scoring_guide_id; $scoringGuideId = $audition->scoring_guide_id;
// $entries = Entry::where('audition_id',$auditionId)->with('scoreSheets')->get(); // $entries = Entry::where('audition_id',$auditionId)->with('scoreSheets')->get();
$entries = $this->entryCache->getEntriesForAudition($auditionId); $entries = $this->entryCache->getEntriesForAudition($auditionId);
$entries->load('scoreSheets'); $entries->load('scoreSheets'); // TODO Cache this somehow, it's expensive and repetitive on the seating page
foreach ($entries as $entry) { foreach ($entries as $entry) {
$cacheKey = 'entry' . $entry->id . 'totalScores'; $cacheKey = 'entry' . $entry->id . 'totalScores';
@ -111,6 +109,27 @@ class ScoreService
} }
} }
public function clearScoreSheetCountCache()
{
$cacheKey = 'entryScoreSheetCounts';
Cache::forget($cacheKey);
}
public function clearEntryTotalScoresCache($entryId)
{
$cacheKey = 'entry' . $entryId . 'totalScores';
Cache::forget($cacheKey);
}
public function clearAllCachedTotalScores()
{
foreach ($this->entryCache->getAllEntries() as $entry)
{
$cacheKey = 'entry' . $entry->id . 'totalScores';
Cache::forget($cacheKey);
}
}
/** /**
* Calculate final score using the provided scoring guide and score sheets. Returns an array of scores * Calculate final score using the provided scoring guide and score sheets. Returns an array of scores
* The first element is the total score. The following elements are the sum of each subscore * The first element is the total score. The following elements are the sum of each subscore
@ -127,14 +146,24 @@ class ScoreService
// TODO cache the scoring guides with their subscores // TODO cache the scoring guides with their subscores
$subscores = $sg->subscores->sortBy('tiebreak_order'); $subscores = $sg->subscores->sortBy('tiebreak_order');
$ignoredSubscores = []; // This will be subscores not used for seating
// Init final scores array // Init final scores array
$finalScoresArray = []; $finalScoresArray = [];
foreach ($subscores as $subscore) { foreach ($subscores as $subscore) {
if (! $subscore->for_seating) { // Ignore scores that are not for seating
$ignoredSubscores[] = $subscore->id;
continue;
}
$finalScoresArray[$subscore->id] = 0; $finalScoresArray[$subscore->id] = 0;
} }
foreach($scoreSheets as $sheet) { foreach($scoreSheets as $sheet) {
foreach ($sheet->subscores as $ss) { foreach ($sheet->subscores as $ss) {
if (in_array($ss['subscore_id'], $ignoredSubscores)) { // Ignore scores that are not for seating
continue;
}
$finalScoresArray[$ss['subscore_id']] += $ss['score']; $finalScoresArray[$ss['subscore_id']] += $ss['score'];
} }
} }
@ -143,6 +172,9 @@ class ScoreService
$totalScore = 0; $totalScore = 0;
$totalWeight = 0; $totalWeight = 0;
foreach ($subscores as $subscore) { foreach ($subscores as $subscore) {
if (in_array($subscore->id, $ignoredSubscores)) { // Ignore scores that are not for seating
continue;
}
$totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight); $totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight);
$totalWeight += $subscore->weight; $totalWeight += $subscore->weight;
} }