From f9e936fd075101f961108b6096884ea15cbc05ed Mon Sep 17 00:00:00 2001 From: Matt Young Date: Fri, 21 Jun 2024 10:44:38 -0500 Subject: [PATCH] Flags for entries to store declined. Seating page will correctly display doubler status --- app/Models/Entry.php | 26 +++++++++++-- app/Models/EntryFlag.php | 16 ++++++++ app/Services/DoublerService.php | 38 ++++++++++++++++--- ..._06_21_144809_create_entry_flags_table.php | 31 +++++++++++++++ .../views/components/doubler-block.blade.php | 2 +- 5 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 app/Models/EntryFlag.php create mode 100644 database/migrations/2024_06_21_144809_create_entry_flags_table.php diff --git a/app/Models/Entry.php b/app/Models/Entry.php index fbaa02f..1a21fc3 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -2,23 +2,28 @@ namespace App\Models; -use App\Exceptions\TabulationException; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; -use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasOneThrough; class Entry extends Model { use HasFactory; + protected $guarded = []; + protected $hasCheckedScoreSheets = false; + public $final_scores_array; // Set by TabulationService + public $scoring_complete; // Set by TabulationService + public $is_doubler; // Set by DoublerService + protected $with = ['flags']; + public function student(): BelongsTo { return $this->belongsTo(Student::class); @@ -46,14 +51,27 @@ class Entry extends Model } - /* + public function flags(): HasMany + { + return $this->hasMany(EntryFlag::class); + } + + public function hasFlag($flag) + { + // return true if any flag in $this->flags has a flag_name of declined without making another db query if flags are loaded + return $this->flags->contains('flag_name', $flag); + + } + + /** * Ensures score_sheets_count property is always available */ public function getScoreSheetsCountAttribute() { - if (!isset($this->attributes['score_sheets_count'])) { + if (! isset($this->attributes['score_sheets_count'])) { $this->attributes['score_sheets_count'] = $this->scoreSheets()->count(); } + return $this->attributes['score_sheets_count']; } } diff --git a/app/Models/EntryFlag.php b/app/Models/EntryFlag.php new file mode 100644 index 0000000..cf44243 --- /dev/null +++ b/app/Models/EntryFlag.php @@ -0,0 +1,16 @@ +belongsTo(Entry::class); + } +} diff --git a/app/Services/DoublerService.php b/app/Services/DoublerService.php index 382ef24..225c163 100644 --- a/app/Services/DoublerService.php +++ b/app/Services/DoublerService.php @@ -9,9 +9,13 @@ use Illuminate\Support\Facades\Cache; class DoublerService { protected $doublersCacheKey = 'doublers'; + protected $auditionCacheService; + protected $tabulationService; + protected $seatingService; + /** * Create a new class instance. */ @@ -24,12 +28,11 @@ class DoublerService /** * Returns a collection of students that have more than one entry - * @return \Illuminate\Database\Eloquent\Collection */ public function getDoublers(): \Illuminate\Database\Eloquent\Collection { // TODO creating or destroying an entry should refresh the doubler cache - return Cache::remember($this->doublersCacheKey, 3600, function () { + return Cache::remember($this->doublersCacheKey, 60, function () { return Student::withCount('entries') ->with('entries') ->havingRaw('entries_count > ?', [1]) @@ -37,6 +40,12 @@ class DoublerService }); } + public function refreshDoublerCache() + { + Cache::forget($this->doublersCacheKey); + $this->getDoublers(); + } + /** * Returns an array of information about each entry for a specific doubler. Info for each entry includes * auditionID @@ -45,25 +54,45 @@ class DoublerService * unscored => How many entries remain to be scored in this audition * * @param int $studentId The ID of the doubler - * @return array */ public function getDoublerInfo($studentId): array { + $doubler = $this->getDoublers()->firstWhere('id', $studentId); + + // Split $doubler->entries into two arrays based on the result of hasFlag('declined') + $undecidedEntries = $doubler->entries->filter(function ($entry) { + return ! $entry->hasFlag('declined'); + }); + $acceptedEntry = null; + if ($undecidedEntries->count() == 1) { + $acceptedEntry = $undecidedEntries->first(); + } + // TODO can I rewrite this? + // When getting a doubler we need to know // 1) What their entries are // 2) For each audition they're entered in, what is their rank // 3) For each audition they're entered in, how many entries are unscored // 4) How many are accepted on that instrument - $doubler = $this->getDoublers()->firstWhere('id',$studentId); + // 5) Status - accepted, declined or undecided + $info = []; foreach ($doubler->entries as $entry) { + if ($entry->hasFlag('declined')) { + $status = 'declined'; + } elseif ($entry === $acceptedEntry) { + $status = 'accepted'; + } else { + $status = 'undecided'; + } $info[$entry->id] = [ 'auditionID' => $entry->audition_id, 'auditionName' => $this->auditionCacheService->getAudition($entry->audition_id)->name, 'rank' => $this->tabulationService->entryRank($entry), 'unscored' => $this->tabulationService->remainingEntriesForAudition($entry->audition_id), 'limits' => $this->seatingService->getLimitForAudition($entry->audition_id), + 'status' => $status, ]; $entry->audition = $this->auditionCacheService->getAudition($entry->audition_id); } @@ -71,7 +100,6 @@ class DoublerService return $info; } - /** * Checks if a student is a doubler based on the given student ID * diff --git a/database/migrations/2024_06_21_144809_create_entry_flags_table.php b/database/migrations/2024_06_21_144809_create_entry_flags_table.php new file mode 100644 index 0000000..1c77359 --- /dev/null +++ b/database/migrations/2024_06_21_144809_create_entry_flags_table.php @@ -0,0 +1,31 @@ +id(); + $table->foreignIdFor(Entry::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete(); + $table->string('flag_name'); + $table->unique(['entry_id', 'flag_name']); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('entry_flags'); + } +}; diff --git a/resources/views/components/doubler-block.blade.php b/resources/views/components/doubler-block.blade.php index 46260ba..db93986 100644 --- a/resources/views/components/doubler-block.blade.php +++ b/resources/views/components/doubler-block.blade.php @@ -8,7 +8,7 @@

- {{ $info['auditionName'] }} + {{ $info['auditionName'] }} - {{ $info['status'] }}