diff --git a/app/Models/Vatsim/NetworkAircraft.php b/app/Models/Vatsim/NetworkAircraft.php index 3e4407eb7..2b93d5b85 100644 --- a/app/Models/Vatsim/NetworkAircraft.php +++ b/app/Models/Vatsim/NetworkAircraft.php @@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasOne; use Location\Coordinate; +use Location\Distance\Haversine; class NetworkAircraft extends Model { @@ -168,4 +169,23 @@ public function aircraft(): BelongsTo { return $this->belongsTo(Aircraft::class); } + + public function isNearDestination(float $thresholdNauticalMiles = 5.0): bool + { + if (!$this->destinationAirfield?->latitude || !$this->destinationAirfield?->longitude) { + return false; + } + + $distanceToAirfieldInNm = LocationService::metersToNauticalMiles( + $this->latLong->getDistance($this->coordinate, new Haversine()) + ); + + return $distanceToAirfieldInNm <= $thresholdNauticalMiles; + } + + public function hasLanded(): bool + { + $isOnGround = $this->groundSpeed < 50; + return $isOnGround && $this->isNearDestination(); + } } diff --git a/app/Services/Stand/StandOccupationService.php b/app/Services/Stand/StandOccupationService.php index 28b21184e..b1fd1186b 100644 --- a/app/Services/Stand/StandOccupationService.php +++ b/app/Services/Stand/StandOccupationService.php @@ -165,16 +165,22 @@ private function occupyStands(Collection $standsToOccupy): void } /** - * Given some stands that have been recently occupied, remove any conflicting stand assignments. + * Given some stands that have been recently occupied, remove any conflicting stand assignments, unless the + * aircraft has already landed. */ private function deleteConflictingAssignmentsFollowingOccupation(Collection $newOccupations): void { - StandAssignment::whereNotIn('callsign', $newOccupations->pluck('callsign')) + $conflictingAssignments = StandAssignment::with('aircraft') + ->whereNotIn('callsign', $newOccupations->pluck('callsign')) ->whereIn('stand_id', $newOccupations->pluck('stand_id')) - ->get() - ->each(function (StandAssignment $assignment) { - $this->assignmentsService->deleteStandAssignment($assignment); - }); + ->get(); + + foreach ($conflictingAssignments as $assignment) { + if ($assignment->aircraft && $assignment->aircraft->hasLanded()) { + continue; + } + $this->assignmentsService->deleteStandAssignment($assignment); + } } /**