phpvms/app/Services/PIREPService.php

274 lines
7.2 KiB
PHP
Raw Normal View History

2017-06-10 14:50:00 +08:00
<?php
namespace App\Services;
2018-01-02 06:01:01 +08:00
use App\Repositories\AcarsRepository;
use Log;
use App\Models\Acars;
use App\Models\Navdata;
2017-07-02 10:06:55 +08:00
use App\Models\Pirep;
use App\Models\PirepFieldValues;
use App\Models\User;
use App\Models\Enums\AcarsType;
use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState;
2017-07-02 10:06:55 +08:00
2017-12-03 00:55:17 +08:00
use App\Events\PirepAccepted;
use App\Events\PirepFiled;
use App\Events\PirepRejected;
use App\Events\UserStatsChanged;
2017-06-10 14:50:00 +08:00
use App\Repositories\NavdataRepository;
use App\Repositories\PirepRepository;
class PIREPService extends BaseService
{
2018-01-02 06:01:01 +08:00
protected $acarsRepo,
$geoSvc,
$navRepo,
$pilotSvc,
$pirepRepo;
2017-06-10 14:50:00 +08:00
/**
* PIREPService constructor.
2017-12-13 04:48:03 +08:00
* @param UserService $pilotSvc
* @param GeoService $geoSvc
* @param NavdataRepository $navRepo
* @param PirepRepository $pirepRepo
2017-06-10 14:50:00 +08:00
*/
public function __construct(
2018-01-02 06:01:01 +08:00
AcarsRepository $acarsRepo,
GeoService $geoSvc,
NavdataRepository $navRepo,
2018-01-02 06:01:01 +08:00
PirepRepository $pirepRepo,
UserService $pilotSvc
)
{
$this->acarsRepo = $acarsRepo;
$this->geoSvc = $geoSvc;
$this->pilotSvc = $pilotSvc;
$this->navRepo = $navRepo;
$this->pirepRepo = $pirepRepo;
2017-06-10 14:50:00 +08:00
}
/**
* Save the route into the ACARS table with AcarsType::ROUTE
* @param Pirep $pirep
* @return Pirep
*/
public function saveRoute(Pirep $pirep): Pirep
{
# Delete all the existing nav points
Acars::where([
2018-01-02 06:01:01 +08:00
'pirep_id' => $pirep->id,
'type' => AcarsType::ROUTE,
])->delete();
# Delete the route
2018-01-02 06:01:01 +08:00
if (empty($pirep->route)) {
return $pirep;
}
2018-01-02 05:04:32 +08:00
$route = $this->geoSvc->getCoordsFromRoute(
$pirep->dpt_airport_id,
$pirep->arr_airport_id,
[$pirep->dpt_airport->lat, $pirep->dpt_airport->lon],
$pirep->route
);
/**
* @var $point Navdata
*/
2018-01-02 06:01:01 +08:00
foreach ($route as $point) {
$acars = new Acars();
$acars->pirep_id = $pirep->id;
$acars->type = AcarsType::ROUTE;
$acars->nav_type = $point->type;
$acars->name = $point->id;
$acars->lat = $point->lat;
$acars->lon = $point->lon;
$acars->save();
}
return $pirep;
}
/**
* Create a new PIREP with some given fields
*
* @param Pirep $pirep
* @param array [PirepFieldValues] $field_values
*
* @return Pirep
*/
2018-01-02 06:01:01 +08:00
public function create(Pirep $pirep, array $field_values = []): Pirep
{
2018-01-02 06:01:01 +08:00
if (empty($field_values)) {
$field_values = [];
}
2017-07-02 10:06:55 +08:00
# Figure out what default state should be. Look at the default
# behavior from the rank that the pilot is assigned to
$default_state = PirepState::PENDING;
2018-01-02 06:01:01 +08:00
if ($pirep->source === PirepSource::ACARS) {
if ($pirep->pilot->rank->auto_approve_acars) {
$default_state = PirepState::ACCEPTED;
}
} else {
2018-01-02 06:01:01 +08:00
if ($pirep->pilot->rank->auto_approve_manual) {
$default_state = PirepState::ACCEPTED;
}
}
2017-07-02 10:06:55 +08:00
# Save the PIREP route
$pirep = $this->saveRoute($pirep);
$pirep->save();
$pirep->refresh();
foreach ($field_values as $fv) {
2017-07-02 10:06:55 +08:00
$v = new PirepFieldValues();
$v->pirep_id = $pirep->id;
2017-07-02 10:06:55 +08:00
$v->name = $fv['name'];
$v->value = $fv['value'];
$v->source = $fv['source'];
$v->save();
}
2017-06-10 14:50:00 +08:00
Log::info('New PIREP filed', [$pirep]);
2017-12-03 00:55:17 +08:00
event(new PirepFiled($pirep));
# only update the pilot last state if they are accepted
if ($default_state === PirepState::ACCEPTED) {
$pirep = $this->accept($pirep);
$this->setPilotState($pirep->pilot, $pirep);
}
return $pirep;
}
/**
* @param Pirep $pirep
* @param int $new_state
* @return Pirep
*/
public function changeState(Pirep $pirep, int $new_state)
{
2018-01-02 06:01:01 +08:00
Log::info('PIREP ' . $pirep->id . ' state change from ' . $pirep->state . ' to ' . $new_state);
if ($pirep->state === $new_state) {
return $pirep;
}
/**
* Move from a PENDING status into either ACCEPTED or REJECTED
*/
if ($pirep->state === PirepState::PENDING) {
if ($new_state === PirepState::ACCEPTED) {
return $this->accept($pirep);
} elseif ($new_state === PirepState::REJECTED) {
return $this->reject($pirep);
} else {
return $pirep;
}
2018-01-02 06:01:01 +08:00
} /*
* Move from a ACCEPTED to REJECTED status
*/
elseif ($pirep->state === PirepState::ACCEPTED) {
$pirep = $this->reject($pirep);
return $pirep;
2018-01-02 06:01:01 +08:00
} /**
* Move from REJECTED to ACCEPTED
*/
elseif ($pirep->state === PirepState::REJECTED) {
$pirep = $this->accept($pirep);
return $pirep;
}
return $pirep->refresh();
}
/**
* @param Pirep $pirep
* @return Pirep
*/
public function accept(Pirep $pirep): Pirep
{
# moving from a REJECTED state to ACCEPTED, reconcile statuses
if ($pirep->state === PirepState::ACCEPTED) {
return $pirep;
}
$ft = $pirep->flight_time;
2017-07-05 02:57:08 +08:00
$pilot = $pirep->pilot;
$this->pilotSvc->adjustFlightTime($pilot, $ft);
$this->pilotSvc->adjustFlightCount($pilot, +1);
$this->pilotSvc->calculatePilotRank($pilot);
$pirep->pilot->refresh();
# Change the status
$pirep->state = PirepState::ACCEPTED;
$pirep->save();
$pirep->refresh();
$this->setPilotState($pilot, $pirep);
2018-01-02 06:01:01 +08:00
Log::info('PIREP ' . $pirep->id . ' state change to ACCEPTED');
2017-12-03 00:55:17 +08:00
event(new PirepAccepted($pirep));
return $pirep;
}
/**
* @param Pirep $pirep
* @return Pirep
*/
public function reject(Pirep $pirep): Pirep
{
# If this was previously ACCEPTED, then reconcile the flight hours
# that have already been counted, etc
if ($pirep->state === PirepState::ACCEPTED) {
$pilot = $pirep->pilot;
$ft = $pirep->flight_time * -1;
$this->pilotSvc->adjustFlightTime($pilot, $ft);
$this->pilotSvc->adjustFlightCount($pilot, -1);
$this->pilotSvc->calculatePilotRank($pilot);
$pirep->pilot->refresh();
}
# Change the status
$pirep->state = PirepState::REJECTED;
$pirep->save();
$pirep->refresh();
Log::info('PIREP ' . $pirep->id . ' state change to REJECTED');
2017-12-03 00:55:17 +08:00
event(new PirepRejected($pirep));
return $pirep;
2017-06-10 14:50:00 +08:00
}
/**
* @param Pirep $pirep
*/
public function setPilotState(User $pilot, Pirep $pirep)
{
$pilot->refresh();
$previous_airport = $pilot->curr_airport_id;
$pilot->curr_airport_id = $pirep->arr_airport_id;
$pilot->last_pirep_id = $pirep->id;
$pilot->save();
$pirep->refresh();
event(new UserStatsChanged($pilot, 'airport', $previous_airport));
}
2017-06-10 14:50:00 +08:00
}