2017-12-13 06:58:27 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
2019-07-16 03:44:31 +08:00
|
|
|
use App\Contracts\Service;
|
2019-08-27 00:32:46 +08:00
|
|
|
use App\Exceptions\DuplicateFlight;
|
2018-03-20 09:50:40 +08:00
|
|
|
use App\Models\Bid;
|
2019-08-27 00:32:46 +08:00
|
|
|
use App\Models\Enums\Days;
|
2017-12-13 06:58:27 +08:00
|
|
|
use App\Models\Flight;
|
2018-03-21 02:06:06 +08:00
|
|
|
use App\Models\FlightFieldValue;
|
2018-02-21 02:06:52 +08:00
|
|
|
use App\Repositories\FlightRepository;
|
|
|
|
use App\Repositories\NavdataRepository;
|
2019-08-27 00:32:46 +08:00
|
|
|
use App\Support\Units\Time;
|
2017-12-13 06:58:27 +08:00
|
|
|
|
2018-03-20 09:50:40 +08:00
|
|
|
class FlightService extends Service
|
2017-12-13 06:58:27 +08:00
|
|
|
{
|
2019-08-27 00:32:46 +08:00
|
|
|
private $airportSvc;
|
2018-08-27 00:40:04 +08:00
|
|
|
private $flightRepo;
|
|
|
|
private $navDataRepo;
|
|
|
|
private $userSvc;
|
2018-02-10 04:36:36 +08:00
|
|
|
|
2018-03-20 09:50:40 +08:00
|
|
|
/**
|
|
|
|
* FlightService constructor.
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2019-08-27 00:32:46 +08:00
|
|
|
* @param AirportService $airportSvc
|
2018-03-20 09:50:40 +08:00
|
|
|
* @param FlightRepository $flightRepo
|
|
|
|
* @param NavdataRepository $navdataRepo
|
|
|
|
* @param UserService $userSvc
|
|
|
|
*/
|
2018-02-21 02:06:52 +08:00
|
|
|
public function __construct(
|
2019-08-27 00:32:46 +08:00
|
|
|
AirportService $airportSvc,
|
2018-02-21 02:06:52 +08:00
|
|
|
FlightRepository $flightRepo,
|
|
|
|
NavdataRepository $navdataRepo,
|
|
|
|
UserService $userSvc
|
2018-08-27 00:40:04 +08:00
|
|
|
) {
|
2019-08-27 00:32:46 +08:00
|
|
|
$this->airportSvc = $airportSvc;
|
2018-02-10 05:36:13 +08:00
|
|
|
$this->flightRepo = $flightRepo;
|
2018-02-21 02:06:52 +08:00
|
|
|
$this->navDataRepo = $navdataRepo;
|
2018-02-10 04:36:36 +08:00
|
|
|
$this->userSvc = $userSvc;
|
|
|
|
}
|
|
|
|
|
2019-08-27 00:32:46 +08:00
|
|
|
/**
|
|
|
|
* Create a new flight
|
|
|
|
*
|
|
|
|
* @param array $fields
|
|
|
|
*
|
|
|
|
* @throws \Prettus\Validator\Exceptions\ValidatorException
|
|
|
|
*
|
|
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
|
|
*/
|
|
|
|
public function createFlight($fields)
|
|
|
|
{
|
2019-10-24 00:01:31 +08:00
|
|
|
$fields['dpt_airport_id'] = strtoupper($fields['dpt_airport_id']);
|
|
|
|
$fields['arr_airport_id'] = strtoupper($fields['arr_airport_id']);
|
|
|
|
|
2019-08-27 00:32:46 +08:00
|
|
|
$flightTmp = new Flight($fields);
|
|
|
|
if ($this->isFlightDuplicate($flightTmp)) {
|
|
|
|
throw new DuplicateFlight($flightTmp);
|
|
|
|
}
|
|
|
|
|
2019-10-24 00:01:31 +08:00
|
|
|
$this->airportSvc->lookupAirportIfNotFound($fields['dpt_airport_id']);
|
|
|
|
$this->airportSvc->lookupAirportIfNotFound($fields['arr_airport_id']);
|
|
|
|
|
2019-08-27 00:32:46 +08:00
|
|
|
$fields = $this->transformFlightFields($fields);
|
|
|
|
$flight = $this->flightRepo->create($fields);
|
|
|
|
|
|
|
|
return $flight;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update a flight with values from the given fields
|
|
|
|
*
|
|
|
|
* @param Flight $flight
|
|
|
|
* @param array $fields
|
|
|
|
*
|
|
|
|
* @throws \Prettus\Validator\Exceptions\ValidatorException
|
|
|
|
*
|
|
|
|
* @return \App\Models\Flight|mixed
|
|
|
|
*/
|
|
|
|
public function updateFlight($flight, $fields)
|
|
|
|
{
|
|
|
|
// apply the updates here temporarily, don't save
|
|
|
|
// the repo->update() call will actually do it
|
|
|
|
$flight->fill($fields);
|
|
|
|
|
|
|
|
if ($this->isFlightDuplicate($flight)) {
|
|
|
|
throw new DuplicateFlight($flight);
|
|
|
|
}
|
|
|
|
|
|
|
|
$fields = $this->transformFlightFields($fields);
|
|
|
|
$flight = $this->flightRepo->update($fields, $flight->id);
|
|
|
|
|
|
|
|
return $flight;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check the fields for a flight and transform them
|
|
|
|
*
|
|
|
|
* @param array $fields
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function transformFlightFields($fields)
|
|
|
|
{
|
|
|
|
if (array_key_exists('days', $fields) && filled($fields['days'])) {
|
|
|
|
$fields['days'] = Days::getDaysMask($fields['days']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$fields['flight_time'] = Time::init($fields['minutes'], $fields['hours'])->getMinutes();
|
|
|
|
$fields['active'] = get_truth_state($fields['active']);
|
|
|
|
|
|
|
|
// Figure out a distance if not found
|
|
|
|
if (empty($fields['distance'])) {
|
|
|
|
$fields['distance'] = $this->airportSvc->calculateDistance(
|
|
|
|
$fields['dpt_airport_id'],
|
|
|
|
$fields['arr_airport_id']
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $fields;
|
|
|
|
}
|
|
|
|
|
2018-02-10 04:36:36 +08:00
|
|
|
/**
|
|
|
|
* Filter out subfleets to only include aircraft that a user has access to
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-02-10 04:36:36 +08:00
|
|
|
* @param $user
|
|
|
|
* @param $flight
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-02-10 04:36:36 +08:00
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function filterSubfleets($user, $flight)
|
|
|
|
{
|
2020-03-23 21:31:35 +08:00
|
|
|
/** @var \Illuminate\Support\Collection $subfleets */
|
2018-02-10 05:07:34 +08:00
|
|
|
$subfleets = $flight->subfleets;
|
2020-03-23 21:31:35 +08:00
|
|
|
if ($subfleets === null || $subfleets->count() === 0) {
|
|
|
|
return $flight;
|
|
|
|
}
|
2018-02-10 05:07:34 +08:00
|
|
|
|
2018-08-27 00:40:04 +08:00
|
|
|
/*
|
2018-02-10 05:07:34 +08:00
|
|
|
* Only allow aircraft that the user has access to in their rank
|
|
|
|
*/
|
2018-02-10 04:36:36 +08:00
|
|
|
if (setting('pireps.restrict_aircraft_to_rank', false)) {
|
|
|
|
$allowed_subfleets = $this->userSvc->getAllowableSubfleets($user)->pluck('id');
|
2018-02-10 05:07:34 +08:00
|
|
|
$subfleets = $subfleets->filter(function ($subfleet, $i) use ($allowed_subfleets) {
|
|
|
|
if ($allowed_subfleets->contains($subfleet->id)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-08-27 00:40:04 +08:00
|
|
|
/*
|
2018-02-10 05:07:34 +08:00
|
|
|
* Only allow aircraft that are at the current departure airport
|
|
|
|
*/
|
2018-03-31 00:08:53 +08:00
|
|
|
if (setting('pireps.only_aircraft_at_dpt_airport', false)) {
|
2018-02-25 05:38:25 +08:00
|
|
|
foreach ($subfleets as $subfleet) {
|
2018-02-10 05:07:34 +08:00
|
|
|
$subfleet->aircraft = $subfleet->aircraft->filter(
|
|
|
|
function ($aircraft, $i) use ($flight) {
|
|
|
|
if ($aircraft->airport_id === $flight->dpt_airport_id) {
|
|
|
|
return true;
|
|
|
|
}
|
2018-02-10 04:36:36 +08:00
|
|
|
}
|
2018-02-10 05:07:34 +08:00
|
|
|
);
|
|
|
|
}
|
2018-02-10 04:36:36 +08:00
|
|
|
}
|
|
|
|
|
2018-02-10 05:07:34 +08:00
|
|
|
$flight->subfleets = $subfleets;
|
|
|
|
|
2018-02-10 04:36:36 +08:00
|
|
|
return $flight;
|
|
|
|
}
|
|
|
|
|
2018-04-26 00:53:32 +08:00
|
|
|
/**
|
|
|
|
* Check if this flight has a duplicate already
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-04-26 00:53:32 +08:00
|
|
|
* @param Flight $flight
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-04-26 00:53:32 +08:00
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isFlightDuplicate(Flight $flight)
|
|
|
|
{
|
|
|
|
$where = [
|
|
|
|
['id', '<>', $flight->id],
|
|
|
|
'airline_id' => $flight->airline_id,
|
|
|
|
'flight_number' => $flight->flight_number,
|
|
|
|
];
|
|
|
|
|
|
|
|
$found_flights = $this->flightRepo->findWhere($where);
|
2018-07-25 03:50:50 +08:00
|
|
|
if ($found_flights->count() === 0) {
|
2018-04-26 00:53:32 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find within all the flights with the same flight number
|
|
|
|
// Return any flights that have the same route code and leg
|
|
|
|
// If this list is > 0, then this has a duplicate
|
2018-07-25 03:50:50 +08:00
|
|
|
$found_flights = $found_flights->filter(function ($value, $key) use ($flight) {
|
2018-08-27 02:50:08 +08:00
|
|
|
return $flight->route_code === $value->route_code
|
|
|
|
&& $flight->route_leg === $value->route_leg;
|
2018-04-26 00:53:32 +08:00
|
|
|
});
|
|
|
|
|
2018-08-27 02:50:08 +08:00
|
|
|
return !($found_flights->count() === 0);
|
2018-04-26 00:53:32 +08:00
|
|
|
}
|
|
|
|
|
2018-01-01 23:32:04 +08:00
|
|
|
/**
|
|
|
|
* Delete a flight, and all the user bids, etc associated with it
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-01-01 23:32:04 +08:00
|
|
|
* @param Flight $flight
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-01-01 23:32:04 +08:00
|
|
|
* @throws \Exception
|
|
|
|
*/
|
2018-03-21 02:06:06 +08:00
|
|
|
public function deleteFlight(Flight $flight): void
|
2018-01-01 23:32:04 +08:00
|
|
|
{
|
|
|
|
$where = ['flight_id' => $flight->id];
|
2018-02-28 03:25:32 +08:00
|
|
|
Bid::where($where)->delete();
|
2018-01-01 23:32:04 +08:00
|
|
|
$flight->delete();
|
|
|
|
}
|
|
|
|
|
2018-03-21 02:06:06 +08:00
|
|
|
/**
|
|
|
|
* Update any custom PIREP fields
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-21 08:17:11 +08:00
|
|
|
* @param Flight $flight
|
|
|
|
* @param array $field_values
|
2018-03-21 02:06:06 +08:00
|
|
|
*/
|
2018-03-21 08:17:11 +08:00
|
|
|
public function updateCustomFields(Flight $flight, array $field_values): void
|
2018-03-21 02:06:06 +08:00
|
|
|
{
|
|
|
|
foreach ($field_values as $fv) {
|
|
|
|
FlightFieldValue::updateOrCreate(
|
|
|
|
[
|
2018-03-21 08:17:11 +08:00
|
|
|
'flight_id' => $flight->id,
|
2018-07-25 03:50:50 +08:00
|
|
|
'name' => $fv['name'],
|
2018-03-21 02:06:06 +08:00
|
|
|
],
|
|
|
|
[
|
2018-08-27 00:40:04 +08:00
|
|
|
'value' => $fv['value'],
|
2018-03-21 02:06:06 +08:00
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-21 02:06:52 +08:00
|
|
|
/**
|
|
|
|
* Return all of the navaid points as a collection
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-02-21 02:06:52 +08:00
|
|
|
* @param Flight $flight
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-02-21 02:06:52 +08:00
|
|
|
* @return \Illuminate\Support\Collection
|
|
|
|
*/
|
|
|
|
public function getRoute(Flight $flight)
|
|
|
|
{
|
2018-02-25 05:38:25 +08:00
|
|
|
if (!$flight->route) {
|
2018-02-21 02:06:52 +08:00
|
|
|
return collect();
|
|
|
|
}
|
|
|
|
|
2018-08-27 02:50:08 +08:00
|
|
|
$route_points = array_map('strtoupper', explode(' ', $flight->route));
|
2018-02-21 02:06:52 +08:00
|
|
|
|
|
|
|
$route = $this->navDataRepo->findWhereIn('id', $route_points);
|
|
|
|
|
|
|
|
// Put it back into the original order the route is in
|
|
|
|
$return_points = [];
|
2018-02-25 05:38:25 +08:00
|
|
|
foreach ($route_points as $rp) {
|
2018-02-21 02:06:52 +08:00
|
|
|
$return_points[] = $route->where('id', $rp)->first();
|
|
|
|
}
|
|
|
|
|
|
|
|
return collect($return_points);
|
|
|
|
}
|
2017-12-13 06:58:27 +08:00
|
|
|
}
|