This commit is contained in:
Matt Young 2024-06-22 15:45:30 -05:00
parent 98cff5b409
commit 0e5500ca41
4 changed files with 38 additions and 21 deletions

View File

@ -6,20 +6,24 @@ use App\Http\Controllers\Controller;
use App\Models\Entry; use App\Models\Entry;
use App\Models\EntryFlag; use App\Models\EntryFlag;
use App\Services\DoublerService; use App\Services\DoublerService;
use App\Services\EntryCacheService;
class DoublerDecisionController extends Controller class DoublerDecisionController extends Controller
{ {
protected $doublerService; protected $doublerService;
protected $entryService;
public function __construct(DoublerService $doublerService) public function __construct(DoublerService $doublerService, EntryCacheService $entryService)
{ {
$this->doublerService = $doublerService; $this->doublerService = $doublerService;
$this->entryService = $entryService;
} }
public function accept(Entry $entry) public function accept(Entry $entry)
{ {
$doublerInfo = $this->doublerService->getDoublerInfo($entry->student_id); $doublerInfo = $this->doublerService->getDoublerInfo($entry->student_id);
foreach ($doublerInfo as $info) { foreach ($doublerInfo as $info) {
$this->entryService->clearEntryCacheForAudition($info['auditionID']);
if ($info['entryID'] != $entry->id) { if ($info['entryID'] != $entry->id) {
try { try {
EntryFlag::create([ EntryFlag::create([
@ -29,6 +33,7 @@ class DoublerDecisionController extends Controller
} catch (\Exception $e) { } catch (\Exception $e) {
session()->flash('error', 'Entry ID'.$info['entryID'].' has already been declined.'); session()->flash('error', 'Entry ID'.$info['entryID'].' has already been declined.');
} }
} }
} }
$this->doublerService->refreshDoublerCache(); $this->doublerService->refreshDoublerCache();

View File

@ -5,9 +5,7 @@ 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_diff_key;
use function array_key_exists; use function array_key_exists;
use function is_null; use function is_null;
@ -15,7 +13,9 @@ use function is_null;
class ScoringGuide extends Model class ScoringGuide extends Model
{ {
use HasFactory; use HasFactory;
protected $guarded = [];
protected $guarded = [];
protected $with = ['subscores']; protected $with = ['subscores'];
public function auditions(): HasMany public function auditions(): HasMany
@ -30,21 +30,29 @@ class ScoringGuide extends Model
/** /**
* Validate a set of subscores. Expects an array in the form of subscore_id => score * Validate a set of subscores. Expects an array in the form of subscore_id => score
* @param array $prospective_score *
* @return string * @return string
*/ */
public function validateScores(Array $prospective_score) public function validateScores(array $prospective_score)
{ {
// TODO move to either TabulationService or a specific service for scoreValidation // TODO move to either TabulationService or a specific service for scoreValidation
foreach ($this->subscores as $subscore) { foreach ($this->subscores as $subscore) {
if (! array_key_exists($subscore->id,$prospective_score)) return "A score must be provided for " . $subscore->name; if (! array_key_exists($subscore->id, $prospective_score)) {
if (is_null($prospective_score[$subscore->id])) return "A score must be provided for " . $subscore->name; 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; }
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(); $subscore_ids = $this->subscores->pluck('id')->flip()->all();
$diff = array_diff_key($prospective_score, $subscore_ids); $diff = array_diff_key($prospective_score, $subscore_ids);
if (!empty($diff)) return "Invalid scores submitted"; if (! empty($diff)) {
return 'Invalid scores submitted';
}
return 'success'; return 'success';
// TODO this probably needs to be rewritten as a validation rule // TODO this probably needs to be rewritten as a validation rule

View File

@ -9,6 +9,7 @@ use Illuminate\Support\Facades\Cache;
class EntryCacheService class EntryCacheService
{ {
protected $auditionCache; protected $auditionCache;
/** /**
* Create a new class instance. * Create a new class instance.
*/ */
@ -20,14 +21,16 @@ class EntryCacheService
/** /**
* Return a collection of all entries for the provided auditionId along with the * Return a collection of all entries for the provided auditionId along with the
* student.school for each entry. * student.school for each entry.
* @param $auditionId *
* @return \Illuminate\Database\Eloquent\Collection * @return \Illuminate\Database\Eloquent\Collection
*/ */
public function getEntriesForAudition($auditionId) { public function getEntriesForAudition($auditionId)
{
// TODO this invokes a lot of lazy loading. Perhaps cache the data for all entries then draw from that for each audition // TODO this invokes a lot of lazy loading. Perhaps cache the data for all entries then draw from that for each audition
$cacheKey = 'audition' . $auditionId . 'entries'; $cacheKey = 'audition'.$auditionId.'entries';
return Cache::remember($cacheKey, 3600, function () use ($auditionId) {
return Entry::where('audition_id',$auditionId) return Cache::remember($cacheKey, 3600, function () use ($auditionId) {
return Entry::where('audition_id', $auditionId)
->with('student.school') ->with('student.school')
->get() ->get()
->keyBy('id'); ->keyBy('id');
@ -38,7 +41,6 @@ class EntryCacheService
* Returns a collection of collections of entries, one collection for each audition. * Returns a collection of collections of entries, one collection for each audition.
* The outer collection is keyed by the audition ID. The included entries are * The outer collection is keyed by the audition ID. The included entries are
* with their student.school. * with their student.school.
* @return Collection
*/ */
public function getAllEntriesByAudition(): Collection public function getAllEntriesByAudition(): Collection
{ {
@ -47,20 +49,22 @@ class EntryCacheService
foreach ($auditions as $audition) { foreach ($auditions as $audition) {
$allEntries[$audition->id] = $this->getEntriesForAudition($audition->id); $allEntries[$audition->id] = $this->getEntriesForAudition($audition->id);
} }
return collect($allEntries); return collect($allEntries);
} }
public function getAllEntries() public function getAllEntries()
{ {
$cacheKey = 'allEntries'; $cacheKey = 'allEntries';
return Cache::remember($cacheKey, 5, function() {
return Entry::all(); return Cache::remember($cacheKey, 5, function () {
return Entry::all();
}); });
} }
public function clearEntryCacheForAudition($auditionId): void public function clearEntryCacheForAudition($auditionId): void
{ {
$cacheKey = 'audition' . $auditionId . 'entries'; $cacheKey = 'audition'.$auditionId.'entries';
Cache::forget($cacheKey); Cache::forget($cacheKey);
Cache::forget('allEntries'); Cache::forget('allEntries');
} }

View File

@ -18,7 +18,7 @@
From: "opacity-100 translate-y-0" From: "opacity-100 translate-y-0"
To: "opacity-0 translate-y-1" To: "opacity-0 translate-y-1"
--> -->
{{-- TODO conver to named routes --}} {{-- TODO convert to named routes --}}
<div class="absolute left-1/2 z-10 mt-5 flex w-screen max-w-min -translate-x-1/2 px-4" x-show="open" x-cloak> <div class="absolute left-1/2 z-10 mt-5 flex w-screen max-w-min -translate-x-1/2 px-4" x-show="open" x-cloak>
<div class="w-56 shrink rounded-xl bg-white p-4 text-sm font-semibold leading-6 text-gray-900 shadow-lg ring-1 ring-gray-900/5"> <div class="w-56 shrink rounded-xl bg-white p-4 text-sm font-semibold leading-6 text-gray-900 shadow-lg ring-1 ring-gray-900/5">
<x-layout.navbar.menus.menu-item :href="route('admin.events.index')">Events</x-layout.navbar.menus.menu-item> <x-layout.navbar.menus.menu-item :href="route('admin.events.index')">Events</x-layout.navbar.menus.menu-item>