205 lines
5.4 KiB
PHP
205 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class UserFlight extends Model
|
|
{
|
|
protected $table = 'user_flights';
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'departure_date',
|
|
'arrival_date',
|
|
'flight_number',
|
|
'departure_airport_id',
|
|
'arrival_airport_id',
|
|
'airline_id',
|
|
'aircraft_id',
|
|
'aircraft_registration',
|
|
'seat_number',
|
|
'seat_type_id',
|
|
'flight_class_id',
|
|
'flight_reason_id',
|
|
'crew_type_id',
|
|
'note',
|
|
'auto_update',
|
|
];
|
|
|
|
protected $casts = [
|
|
'departure_date' => 'immutable_datetime',
|
|
'arrival_date' => 'immutable_datetime',
|
|
'auto_update' => 'boolean',
|
|
];
|
|
|
|
protected $appends = [
|
|
'departure_date_display',
|
|
'departure_time_display',
|
|
'arrival_date_display',
|
|
'arrival_time_display',
|
|
'arrival_day_difference',
|
|
'duration',
|
|
'duration_display',
|
|
'distance',
|
|
];
|
|
|
|
public function calculateGreatCircleDistance(): float{
|
|
$earthRadiusKm = 6371;
|
|
[$depLat, $depLong] = [$this->departureAirport->latitude_deg, $this->departureAirport->longitude_deg];
|
|
[$arrLat, $arrLong] = [$this->arrivalAirport->latitude_deg, $this->arrivalAirport->longitude_deg];
|
|
|
|
|
|
$latDelta = deg2rad($arrLat - $depLat);
|
|
$longDelta = deg2rad($arrLong - $depLong);
|
|
|
|
$a = sin($latDelta / 2) * sin($latDelta / 2)
|
|
+ cos(deg2rad($depLat)) * cos(deg2rad($arrLat))
|
|
* sin($longDelta / 2) * sin($longDelta / 2);
|
|
|
|
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
|
|
|
return $earthRadiusKm * $c;
|
|
}
|
|
|
|
protected function departureDateDisplay(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn() => $this->departure_date
|
|
->toMutable()
|
|
->setTimezone($this->departureAirport->timezone)
|
|
->format('j M Y')
|
|
);
|
|
}
|
|
|
|
protected function departureTimeDisplay(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn() => $this->departure_date
|
|
->toMutable()
|
|
->setTimezone($this->departureAirport->timezone)
|
|
->format('g:iA')
|
|
);
|
|
}
|
|
|
|
protected function arrivalDateDisplay(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn() => $this->arrival_date
|
|
?->copy()
|
|
->setTimezone($this->arrivalAirport->timezone)
|
|
->format('j M Y')
|
|
);
|
|
}
|
|
|
|
protected function arrivalTimeDisplay(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn() => $this->arrival_date
|
|
?->copy()
|
|
->setTimezone($this->arrivalAirport->timezone)
|
|
->format('g:iA')
|
|
);
|
|
}
|
|
|
|
protected function arrivalDayDifference(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: function () {
|
|
if (!$this->arrival_date) return 0;
|
|
|
|
$departureLocal = $this->departure_date->copy()->setTimezone($this->departureAirport->timezone);
|
|
$arrivalLocal = $this->arrival_date->copy()->setTimezone($this->arrivalAirport->timezone);
|
|
|
|
return (int) abs(
|
|
Carbon::parse($arrivalLocal->toDateString())
|
|
->diffInDays(Carbon::parse($departureLocal->toDateString()))
|
|
);
|
|
}
|
|
);
|
|
}
|
|
|
|
protected function duration(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn() => $this->departure_date->diffInMinutes($this->arrival_date)
|
|
);
|
|
}
|
|
|
|
protected function durationDisplay(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: function () {
|
|
$hours = intdiv($this->duration, 60);
|
|
$minutes = $this->duration % 60;
|
|
|
|
return $hours . 'h ' . str_pad($minutes, 2, '0', STR_PAD_LEFT) . 'm';
|
|
}
|
|
);
|
|
}
|
|
|
|
protected function distance(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn() => $this->calculateGreatCircleDistance()
|
|
);
|
|
}
|
|
|
|
public function isDomestic() : bool{
|
|
return $this->departureAirport->region->country_id == $this->arrivalAirport->region->country_id;
|
|
}
|
|
|
|
public function isInternational() : bool{
|
|
return !$this->isDomestic();
|
|
}
|
|
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
public function departureAirport(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Airport::class, 'departure_airport_id');
|
|
}
|
|
|
|
public function arrivalAirport(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Airport::class, 'arrival_airport_id');
|
|
}
|
|
|
|
public function crewType(): BelongsTo
|
|
{
|
|
return $this->belongsTo(CrewType::class);
|
|
}
|
|
|
|
public function airline(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Airline::class);
|
|
}
|
|
|
|
|
|
public function aircraft(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Aircraft::class);
|
|
}
|
|
|
|
public function seatType(): BelongsTo
|
|
{
|
|
return $this->belongsTo(SeatType::class);
|
|
}
|
|
|
|
public function flightClass(): BelongsTo
|
|
{
|
|
return $this->belongsTo(FlightClass::class);
|
|
}
|
|
|
|
public function flightReason(): BelongsTo
|
|
{
|
|
return $this->belongsTo(FlightReason::class);
|
|
}
|
|
}
|