From 90ea8d81d26d4b87f3dd4580f20e81acd3278971 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 20 Aug 2026 16:21:14 +1000 Subject: [PATCH] Allow "Log 1st Flight" achievement to be awarded even if flight is upcoming --- .../Commands/RecalculateAchievements.php | 24 +++++++++++++++---- .../Achievements/AchievementService.php | 11 ++++++--- .../Achievements/Checkers/BaseChecker.php | 5 ++++ .../Checkers/GeneralFlyingChecker.php | 3 ++- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/app/Console/Commands/RecalculateAchievements.php b/app/Console/Commands/RecalculateAchievements.php index 19f9eae..0e69346 100644 --- a/app/Console/Commands/RecalculateAchievements.php +++ b/app/Console/Commands/RecalculateAchievements.php @@ -3,19 +3,35 @@ namespace App\Console\Commands; use App\Models\User; +use Illuminate\Console\Attributes\Argument; use Illuminate\Console\Attributes\Description; use Illuminate\Console\Attributes\Signature; use Illuminate\Console\Command; -#[Signature('app:recalculate-achivements')] -#[Description('Recalculate achievements for all users')] +#[Signature('app:recalculate-achievements {username? : The username of a single user to recalculate}')] +#[Description('Recalculate achievements for all users, or a single user by username')] class RecalculateAchievements extends Command { public function handle(): void { - $users = User::all(); - foreach ($users as $user) { + $username = $this->argument('username'); + + if ($username) { + $user = User::where('name', $username)->first(); + + if (! $user) { + $this->error("No user found with username [{$username}]."); + return; + } + $user->calculateAchievements(); + $this->info("Recalculated achievements for {$username}."); + return; } + + $users = User::all(); + $this->withProgressBar($users, fn (User $user) => $user->calculateAchievements()); + $this->newLine(); + $this->info("Recalculated achievements for {$users->count()} users."); } } diff --git a/app/Services/Achievements/AchievementService.php b/app/Services/Achievements/AchievementService.php index b2905ce..f5b869f 100644 --- a/app/Services/Achievements/AchievementService.php +++ b/app/Services/Achievements/AchievementService.php @@ -47,6 +47,7 @@ class AchievementService * @var Collection $flights */ private Collection $flights; + private int $loggedFlightCount; public function calculate(User $user): void { @@ -64,20 +65,24 @@ class AchievementService 'arrivalAirport.region.continent', ])->where('departure_date', '<=', now('UTC'))->get(); + $this->loggedFlightCount = $user->flights()->count(); + foreach ($this->checkers as $checkerClass) { $checker = new $checkerClass($this); $checker->check($user); } } - /** - * @return Collection - */ public function getFlights(): Collection { return $this->flights; } + public function getLoggedFlightCount(): int + { + return $this->loggedFlightCount; + } + // --------------------------------------------------------------- // Award / revoke diff --git a/app/Services/Achievements/Checkers/BaseChecker.php b/app/Services/Achievements/Checkers/BaseChecker.php index 131cdd7..8c824ed 100644 --- a/app/Services/Achievements/Checkers/BaseChecker.php +++ b/app/Services/Achievements/Checkers/BaseChecker.php @@ -15,6 +15,11 @@ abstract class BaseChecker implements AchievementCheckerInterface return $this->service->getFlights(); } + protected function allLoggedFlightsCount(): int + { + return $this->service->getLoggedFlightCount(); + } + /** * Resolve an achievement ID from its internal name. * Results are cached on the service so repeated lookups are free. diff --git a/app/Services/Achievements/Checkers/GeneralFlyingChecker.php b/app/Services/Achievements/Checkers/GeneralFlyingChecker.php index d20b6a2..ff40d52 100644 --- a/app/Services/Achievements/Checkers/GeneralFlyingChecker.php +++ b/app/Services/Achievements/Checkers/GeneralFlyingChecker.php @@ -15,10 +15,11 @@ class GeneralFlyingChecker extends BaseChecker */ $flights = $this->flights(); $count = $flights->count(); + $allLoggedFlightsCount = $this->allLoggedFlightsCount(); // --- Boolean achievements --- - $this->awardIf($count >= 1, 'general_flying.first_flight'); + $this->awardIf($allLoggedFlightsCount >= 1, 'general_flying.first_flight'); $this->awardIf( $flights->contains(fn ($f) => $f->isDomestic()),