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
{
$this->scoreService->clearScoringGuideCache();
$this->scoreService->clearAllCachedTotalScores();
}
}

View File

@ -2,6 +2,7 @@
namespace App\Observers;
use App\Events\ScoreSheetChange;
use App\Models\ScoreSheet;
class ScoreSheetObserver
@ -11,7 +12,7 @@ class ScoreSheetObserver
*/
public function created(ScoreSheet $scoreSheet): void
{
//
ScoreSheetChange::dispatch($scoreSheet->entry_id);
}
/**
@ -19,7 +20,7 @@ class ScoreSheetObserver
*/
public function updated(ScoreSheet $scoreSheet): void
{
//
ScoreSheetChange::dispatch($scoreSheet->entry_id);
}
/**
@ -27,7 +28,7 @@ class ScoreSheetObserver
*/
public function deleted(ScoreSheet $scoreSheet): void
{
//
ScoreSheetChange::dispatch($scoreSheet->entry_id);
}
/**
@ -35,7 +36,7 @@ class ScoreSheetObserver
*/
public function restored(ScoreSheet $scoreSheet): void
{
//
ScoreSheetChange::dispatch($scoreSheet->entry_id);
}
/**
@ -43,6 +44,6 @@ class ScoreSheetObserver
*/
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\EntryChange;
use App\Events\ScoreSheetChange;
use App\Events\ScoringGuideChange;
use App\Listeners\RefreshAuditionCache;
use App\Listeners\RefreshEntryCache;
use App\Listeners\RefreshScoreSheetCache;
use App\Listeners\RefreshScoringGuideCache;
use App\Models\Audition;
use App\Models\Entry;
@ -104,5 +106,10 @@ class AppServiceProvider extends ServiceProvider
ScoringGuideChange::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
* of each subscore in tiebreaker order
@ -101,7 +99,7 @@ class ScoreService
$scoringGuideId = $audition->scoring_guide_id;
// $entries = Entry::where('audition_id',$auditionId)->with('scoreSheets')->get();
$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) {
$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
* 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
$subscores = $sg->subscores->sortBy('tiebreak_order');
$ignoredSubscores = []; // This will be subscores not used for seating
// Init final scores array
$finalScoresArray = [];
foreach ($subscores as $subscore) {
if (! $subscore->for_seating) { // Ignore scores that are not for seating
$ignoredSubscores[] = $subscore->id;
continue;
}
$finalScoresArray[$subscore->id] = 0;
}
foreach($scoreSheets as $sheet) {
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'];
}
}
@ -143,6 +172,9 @@ class ScoreService
$totalScore = 0;
$totalWeight = 0;
foreach ($subscores as $subscore) {
if (in_array($subscore->id, $ignoredSubscores)) { // Ignore scores that are not for seating
continue;
}
$totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight);
$totalWeight += $subscore->weight;
}