calculator = $calculator; $this->auditionService = $auditionService; } 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); } $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 (! $entry->exists()) { 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'); } } }