diff --git a/.env.dev.example b/.env.dev.example index 09583387..8f71600a 100644 --- a/.env.dev.example +++ b/.env.dev.example @@ -14,5 +14,6 @@ DB_USERNAME= DB_PASSWORD= CACHE_DRIVER=array +CACHE_PREFIX= PHPVMS_CURRENCY=dollar diff --git a/app/Http/Controllers/Admin/RankController.php b/app/Http/Controllers/Admin/RankController.php index 3695e741..a4273f3c 100644 --- a/app/Http/Controllers/Admin/RankController.php +++ b/app/Http/Controllers/Admin/RankController.php @@ -76,6 +76,8 @@ class RankController extends BaseController $model = $this->rankRepository->create($input); Flash::success('Ranking saved successfully.'); + Cache::forget(config('phpvms.cache_keys.RANKS_PILOT_LIST')['key']); + return redirect(route('admin.ranks.edit', ['id' => $model->id])); } @@ -141,6 +143,7 @@ class RankController extends BaseController } $rank = $this->rankRepository->update($request->all(), $id); + Cache::forget(config('phpvms.cache_keys.RANKS_PILOT_LIST')['key']); Flash::success('Ranking updated successfully.'); return redirect(route('admin.ranks.index')); diff --git a/app/Models/Pirep.php b/app/Models/Pirep.php index d5a35aea..973b1ff0 100644 --- a/app/Models/Pirep.php +++ b/app/Models/Pirep.php @@ -29,6 +29,7 @@ class Pirep extends Model 'route_leg', 'dpt_airport_id', 'arr_airport_id', + 'source', 'level', 'route', 'notes', @@ -43,14 +44,10 @@ class Pirep extends Model */ protected $casts = [ - 'user_id' => 'integer', - 'flight_id' => 'string', - 'aircraft_id' => 'integer', 'flight_time' => 'integer', 'level' => 'integer', - 'route' => 'string', - 'notes' => 'string', - 'raw_data' => 'string', + 'source' => 'integer', + 'status' => 'integer', ]; /** @@ -92,6 +89,11 @@ class Pirep extends Model return $this->belongsTo('App\Models\Flight', 'flight_id'); } + public function pilot() + { + return $this->user(); + } + public function user() { return $this->belongsTo('App\Models\User', 'user_id'); diff --git a/app/Models/User.php b/app/Models/User.php index 2c2ca687..f445390f 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -11,22 +11,38 @@ use Illuminate\Contracts\Auth\CanResetPassword; /** * App\User * - * @property integer $id - * @property string $name - * @property string $email - * @property string $password - * @property string $remember_token - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications - * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $unreadNotifications - * @method static \Illuminate\Database\Query\Builder|\App\Models\User whereId($value) - * @method static \Illuminate\Database\Query\Builder|\App\Models\User whereName($value) - * @method static \Illuminate\Database\Query\Builder|\App\Models\User whereEmail($value) - * @method static \Illuminate\Database\Query\Builder|\App\Models\User wherePassword($value) - * @method static \Illuminate\Database\Query\Builder|\App\Models\User whereRememberToken($value) - * @method static \Illuminate\Database\Query\Builder|\App\Models\User whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\App\Models\User whereUpdatedAt($value) + * @property integer + * $id + * @property string + * $name + * @property string + * $email + * @property string + * $password + * @property string + * $remember_token + * @property \Carbon\Carbon + * $created_at + * @property \Carbon\Carbon + * $updated_at + * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] + * $notifications + * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] + * $unreadNotifications + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * whereId($value) + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * whereName($value) + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * whereEmail($value) + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * wherePassword($value) + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * whereRememberToken($value) + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\App\Models\User + * whereUpdatedAt($value) * @mixin \Eloquent */ class User extends Authenticatable @@ -39,22 +55,35 @@ class User extends Authenticatable * * @var array */ - protected $fillable = [ - 'name', 'email', 'password', - ]; + protected $fillable + = [ + 'name', + 'email', + 'password', + ]; /** * The attributes that should be hidden for arrays. * * @var array */ - protected $hidden = [ - 'password', 'remember_token', - ]; + protected $hidden + = [ + 'password', + 'remember_token', + ]; + + protected $casts + = [ + 'flights' => 'integer', + 'flight_hours' => 'integer', + 'balance' => 'double', + 'timezone' => 'integer', + ]; public function pilot_id() { - return $this->airline->code . str_pad($this->id, 3, '0', STR_PAD_LEFT); + return $this->airline->code.str_pad($this->id, 3, '0', STR_PAD_LEFT); } /** diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index c4379642..d414b185 100755 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -33,5 +33,14 @@ class AppServiceProvider extends ServiceProvider $this->app->bind('App\Services\AircraftFareService', function($app) { return new \App\Services\AircraftFareService(); }); + + $this->app->bind('App\Services\PilotService', function($app) { + return new \App\Services\PilotService(); + }); + + $this->app->bind('App\Services\PIREPService', function($app) { + return new \App\Services\PIREPService(); + }); + } } diff --git a/app/Services/AircraftService.php b/app/Services/AircraftService.php index 0a03510c..0b70437f 100644 --- a/app/Services/AircraftService.php +++ b/app/Services/AircraftService.php @@ -9,8 +9,7 @@ class AircraftService extends BaseService { public function create( - array $attributes, - AircraftClass $class = null + array $attributes ) { $repo = app('App\Repositories\SubfleetRepository'); @@ -20,10 +19,10 @@ class AircraftService extends BaseService return false; } - if ($class != null) { + /*if ($class != null) { $model->class()->associate($class); $model->save(); - } + }*/ return $model; } diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index 3c80d020..da589486 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -2,6 +2,7 @@ namespace App\Services; -class BaseService { + +class BaseService { } diff --git a/app/Services/PIREPService.php b/app/Services/PIREPService.php index bc36bea6..f66902e5 100644 --- a/app/Services/PIREPService.php +++ b/app/Services/PIREPService.php @@ -5,33 +5,45 @@ namespace App\Services; use App\Models\Pirep; use App\Models\PirepFieldValues; -use App\Repositories\PirepRepository; -use App\Repositories\SubfleetRepository; - -class PIREPService extends BaseService { - - protected $aircraftRepo, $pirepRepo; +class PIREPService extends BaseService +{ + protected $pilotSvc; /** * return a PIREP model */ - public function __construct( - SubfleetRepository $aircraftRepo, - PirepRepository $pirepRepo - ) { - $this->aircraftRepo = $aircraftRepo; - $this->pirepRepo = $pirepRepo; + public function __construct() + { + $this->pilotSvc = app('App\Services\PilotService'); } + /** + * Create a new PIREP with some given fields + * + * @param Pirep $pirep + * @param array [PirepFieldValues] $field_values + * + * @return Pirep + */ public function create( Pirep $pirep, - array $field_values # PirepFieldValues - ) { + array $field_values=[] + ): Pirep { - $pirep->save(); + # Figure out what default state should be. Look at the default + # behavior from the rank that the pilot is assigned to + if($pirep->source == \VMSEnums::$sources['ACARS']) { + $default_status = $pirep->pilot->rank->auto_approve_acars; + } else { + $default_status = $pirep->pilot->rank->auto_approve_manual; + } - foreach($field_values as $fv) { + if ($default_status == \VMSEnums::$pirep_status['ACCEPTED']) { + $pirep = $this->accept($pirep); + } + + foreach ($field_values as $fv) { $v = new PirepFieldValues(); $v->name = $fv['name']; $v->value = $fv['value']; @@ -39,6 +51,105 @@ class PIREPService extends BaseService { $v->save(); } - # TODO: Financials + # TODO: Financials even if it's rejected, log the expenses + + $pirep->save(); + + # update pilot information + $pilot = $pirep->pilot; + $pilot->refresh(); + + $pilot->curr_airport_id = $pirep->arr_airport_id; + $pilot->last_pirep_id = $pirep->id; + $pilot->save(); + + return $pirep; + } + + public function changeStatus(Pirep &$pirep, int $new_status): Pirep + { + if ($pirep->status === $new_status) { + return $pirep; + } + + /** + * Move from a PENDING status into either ACCEPTED or REJECTED + */ + if ($pirep->status == \VMSEnums::$pirep_status['PENDING']) { + if ($new_status == \VMSEnums::$pirep_status['ACCEPTED']) { + return $this->accept($pirep); + } elseif ($new_status == \VMSEnums::$pirep_status['REJECTED']) { + return $this->reject($pirep); + } else { + return $pirep; + } + } + + /* + * Move from a ACCEPTED to REJECTED status + */ + elseif ($pirep->status == \VMSEnums::$pirep_status['ACCEPTED']) { + $pirep = $this->reject($pirep); + return $pirep; + } + + /** + * Move from REJECTED to ACCEPTED + */ + elseif ($pirep->status == \VMSEnums::$pirep_status['REJECTED']) { + $pirep = $this->accept($pirep); + return $pirep; + } + } + + /** + * @param Pirep $pirep + * @return Pirep + */ + public function accept(Pirep &$pirep): Pirep + { + # moving from a REJECTED state to ACCEPTED, reconcile statuses + if ($pirep->status == \VMSEnums::$pirep_status['ACCEPTED']) { + return $pirep; + } + + $pilot = $pirep->pilot; + $ft = $pirep->flight_time; + + $this->pilotSvc->adjustFlightHours($pilot, $ft); + $this->pilotSvc->adjustFlightCount($pilot, +1); + $this->pilotSvc->calculatePilotRank($pilot); + $pirep->pilot->refresh(); + + # Change the status + $pirep->status = \VMSEnums::$pirep_status['ACCEPTED']; + $pirep->save(); + + 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->status == \VMSEnums::$pirep_status['ACCEPTED']) { + $pilot = $pirep->pilot; + $ft = $pirep->flight_time * -1; + + $this->pilotSvc->adjustFlightHours($pilot, $ft); + $this->pilotSvc->adjustFlightCount($pilot, -1); + $this->pilotSvc->calculatePilotRank($pilot); + $pirep->pilot->refresh(); + } + + # Change the status + $pirep->status = \VMSEnums::$pirep_status['REJECTED']; + $pirep->save(); + + return $pirep; } } diff --git a/app/Services/PilotService.php b/app/Services/PilotService.php new file mode 100644 index 00000000..d0be2344 --- /dev/null +++ b/app/Services/PilotService.php @@ -0,0 +1,58 @@ +refresh(); + $pilot->flights = $pilot->flights + $count; + $pilot->save(); + + return $pilot; + } + + public function adjustFlightHours(User &$pilot, int $hours): User + { + $pilot->refresh(); + $pilot->flight_time = $pilot->flight_time + $hours; + $pilot->save(); + + return $pilot; + } + + public function calculatePilotRank(User &$pilot): User + { + $pilot->refresh(); + $pilot_hours = $pilot->flight_time / 3600; + + # TODO: Cache + $ranks = Cache::remember( + config('phpvms.cache_keys.RANKS_PILOT_LIST')['key'], + config('phpvms.cache_keys.RANKS_PILOT_LIST')['time'], + function () { + return Rank::where('auto_promote', true)->orderBy('hours', 'asc')->get(); + }); + + foreach ($ranks as $rank) { + if($rank->hours > $pilot_hours) { + break; + } else { + $pilot->rank_id = $rank->id; + } + } + + $pilot->save(); + + return $pilot; + } + +} diff --git a/config/cache.php b/config/cache.php index 10492f9f..8b1fd7fc 100755 --- a/config/cache.php +++ b/config/cache.php @@ -86,6 +86,5 @@ return [ | */ - 'prefix' => 'phpvms', - + 'prefix' => env('CACHE_PREFIX', ''), ]; diff --git a/config/enums.php b/config/enums.php index a5b4aeb7..1f8305d4 100644 --- a/config/enums.php +++ b/config/enums.php @@ -1,11 +1,18 @@ 0, - 'MANUAL' => 1, + 'MANUAL' => 0, + 'ACARS' => 1, ]; public static $pirep_status diff --git a/config/phpvms.php b/config/phpvms.php index 0cdba974..4903fa14 100644 --- a/config/phpvms.php +++ b/config/phpvms.php @@ -7,4 +7,11 @@ return [ * dollar, euro, gbp, yen, jpy, rupee, ruble */ 'currency' => env('PHPVMS_CURRENCY', 'dollar'), + + 'cache_keys' => [ + 'RANKS_PILOT_LIST' => [ + 'key' => 'ranks::pilot_list', + 'time' => 1440, + ] + ] ]; diff --git a/database/migrations/2017_06_08_0000_create_users_table.php b/database/migrations/2017_06_08_0000_create_users_table.php index 198ed863..fb540c71 100755 --- a/database/migrations/2017_06_08_0000_create_users_table.php +++ b/database/migrations/2017_06_08_0000_create_users_table.php @@ -23,8 +23,8 @@ class CreateUsersTable extends Migration $table->integer('home_airport_id')->nullable()->unsigned(); $table->integer('curr_airport_id')->nullable()->unsigned(); $table->uuid('last_pirep_id')->nullable(); - $table->bigInteger('flights')->nullable()->unsigned(); - $table->bigInteger('flight_time')->nullable()->unsigned(); + $table->bigInteger('flights')->unsigned()->default(0); + $table->bigInteger('flight_time')->unsigned()->default(0); $table->decimal('balance', 19, 2)->nullable(); $table->tinyInteger('timezone')->default(0); $table->boolean('active')->nullable(); diff --git a/database/migrations/2017_06_28_195426_create_pireps_table.php b/database/migrations/2017_06_28_195426_create_pireps_table.php index df687d5e..b2b5579a 100644 --- a/database/migrations/2017_06_28_195426_create_pireps_table.php +++ b/database/migrations/2017_06_28_195426_create_pireps_table.php @@ -26,7 +26,8 @@ class CreatePirepsTable extends Migration $table->integer('level')->unsigned(); $table->string('route')->nullable(); $table->string('notes')->nullable(); - $table->tinyInteger('status'); + $table->tinyInteger('source')->default(0); + $table->tinyInteger('status')->default(0); $table->string('raw_data')->nullable(); $table->timestamps(); $table->softDeletes();