add PIREP pre-file and ACARS updates; removing caching from ACARS/Pirep/User repositories; adjust PirepState enum values; add additional columns

This commit is contained in:
Nabeel Shahzad 2017-12-25 15:19:34 -06:00
parent 70b1476e93
commit 3bd97b4d37
41 changed files with 688 additions and 192 deletions

View File

@ -0,0 +1,159 @@
<?php
namespace App\Console\Commands;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Collection;
use App\Facades\Utils;
class AcarsReplay extends Command
{
protected $signature = 'phpvms:replay {files} {--manual}';
protected $description = 'Replay an ACARS file';
/**
* API Key to post as
* @var string
*/
protected $apiKey = 'testadminapikey';
/**
* For automatic updates, how many seconds to sleep between updates
* @var int
*/
protected $sleepTime = 10;
/**
* @var array key == update[callsign]
* value == PIREP ID
*/
protected $pirepList = [];
/**
* @var Client
*/
protected $httpClient;
/**
* Return an instance of an HTTP client all ready to post
*/
public function __construct()
{
parent::__construct();
$this->httpClient = new Client([
'base_uri' => config('app.url'),
'headers' => [
'Authorization' => $this->apiKey,
]
]);
}
/**
* Make a request to start a PIREP
* @param \stdClass $flight
* @return string
*/
protected function startPirep($flight)
{
# convert the planned flight time to be completely in minutes
$pft = Utils::hoursToMinutes($flight->planned_hrsenroute,
$flight->planned_minenroute);
$response = $this->httpClient->post('/api/pirep/prefile', [
'json' => [
'airline_id' => 1,
'aircraft_id' => 1, # TODO: Lookup
'dpt_airport' => $flight->planned_depairport,
'arr_airport' => $flight->planned_destairport,
'altitude' => $flight->planned_altitude,
'planned_flight_time' => $pft,
'route' => $flight->planned_route,
]
]);
$body = \json_decode($response->getBody()->getContents());
return $body->id;
}
/**
* Parse this file and run the updates
* @param array $files
*/
protected function runUpdates(array $files)
{
/**
* @var $flights Collection
*/
$flights = collect($files)->transform(function ($f) {
$file = storage_path('/replay/' . $f . '.json');
if (file_exists($file)) {
$this->info('Loading ' . $file);
$contents = file_get_contents($file);
$contents = \json_decode($contents);
return collect($contents->updates);
} else {
$this->error($file . ' not found, skipping');
return false;
}
})
# remove any of errored file entries
->filter(function ($value, $key) {
return $value !== false;
});
$this->info('Starting playback');
/**
* File the initial pirep to get a "preflight" status
*/
$flights->each(function ($updates, $idx) {
$update = $updates->first();
$pirep_id = $this->startPirep($update);
$this->pirepList[$update->callsign] = $pirep_id;
$this->info('Prefiled ' . $update->callsign . ', ID: ' . $pirep_id);
});
/**
* Iterate through all of the flights, retrieving the updates
* from each individual flight. Remove the update. Continue through
* until there are no updates left, at which point we remove the flight
* and updates.
*
* Continue until we have no more flights and updates left
*/
while ($flights->count() > 0) {
$flights = $flights->each(function ($updates, $idx) {
$update = $updates->shift();
})->filter(function ($updates, $idx) {
return $updates->count() > 0;
});
}
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$files = $this->argument('files');
$manual_mode = $this->option('manual');
if(!$manual_mode) {
$this->info('Going to send updates every 10s');
} else {
$this->info('In "manual advance" mode');
}
$this->runUpdates(explode(',', $files));
$this->info('Done!');
}
}

View File

@ -0,0 +1,20 @@
<?php
use Faker\Generator as Faker;
$factory->define(App\Models\Acars::class, function (Faker $faker) {
return [
'id' => substr($faker->unique()->sha1, 0, 12),
'pirep_id' => '', # TODO: Fill this out
'lat' => $faker->latitude,
'lon' => $faker->longitude,
'heading' => $faker->numberBetween(0, 359),
'altitude' => $faker->numberBetween(20, 400),
'vs' => $faker->numberBetween(-5000, 5000),
'gs' => $faker->numberBetween(300, 500),
'transponder' => $faker->numberBetween(200, 9999),
'autopilot' => $faker->text(10),
'fuel_flow' => $faker->randomFloat(2, 100, 1000),
'sim_time' => $faker->dateTime('now', 'UTC'),
];
});

View File

@ -1,23 +1,19 @@
<?php <?php
use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState;
use Faker\Generator as Faker; use Faker\Generator as Faker;
# Match the list available in tests/data/*.yml
$airlinesAvailable = [1];
/** /**
* Create a new PIREP * Create a new PIREP
*/ */
$factory->define(App\Models\Pirep::class, function (Faker $faker) use ($airlinesAvailable) { $factory->define(App\Models\Pirep::class, function (Faker $faker) {
static $raw_data; static $raw_data;
return [ return [
'id' => substr($faker->unique()->sha1, 0, 12), 'id' => substr($faker->unique()->sha1, 0, 12),
'airline_id' => 1, #$faker->randomElement($airlinesAvailable), 'airline_id' => function () { # OVERRIDE THIS IF NEEDED
return factory(App\Models\Airline::class)->create()->id;
},
'user_id' => function () { # OVERRIDE THIS IF NEEDED 'user_id' => function () { # OVERRIDE THIS IF NEEDED
return factory(App\Models\User::class)->create()->id; return factory(App\Models\User::class)->create()->id;
}, },
@ -39,11 +35,15 @@ $factory->define(App\Models\Pirep::class, function (Faker $faker) use ($airlines
'arr_airport_id' => function () { 'arr_airport_id' => function () {
return factory(App\Models\Airport::class)->create()->id; return factory(App\Models\Airport::class)->create()->id;
}, },
'altitude' => $faker->numberBetween(20, 400),
'flight_time' => $faker->randomFloat(2), 'flight_time' => $faker->randomFloat(2),
'planned_flight_time' => $faker->randomFloat(2),
'gross_weight' => $faker->randomFloat(2),
'route' => $faker->text(200), 'route' => $faker->text(200),
'notes' => $faker->text(200), 'notes' => $faker->text(200),
'source' => $faker->randomElement([PirepSource::MANUAL, PirepSource::ACARS]), 'source' => $faker->randomElement([PirepSource::MANUAL, PirepSource::ACARS]),
'state' => PirepState::PENDING, //$faker->randomElement([-1, 0, 1]), # REJECTED/PENDING/ACCEPTED 'state' => PirepState::PENDING,
'status' => PirepStatus::SCHEDULED,
'raw_data' => $raw_data ?: $raw_data = json_encode(['key' => 'value']), 'raw_data' => $raw_data ?: $raw_data = json_encode(['key' => 'value']),
'created_at' => $faker->dateTimeBetween('-1 week', 'now'), 'created_at' => $faker->dateTimeBetween('-1 week', 'now'),
'updated_at' => function(array $pirep) { 'updated_at' => function(array $pirep) {

View File

@ -22,10 +22,10 @@ class CreateFlightTables extends Migration
$table->string('dpt_airport_id', 5); $table->string('dpt_airport_id', 5);
$table->string('arr_airport_id', 5); $table->string('arr_airport_id', 5);
$table->string('alt_airport_id', 5)->nullable(); $table->string('alt_airport_id', 5)->nullable();
$table->text('route')->nullable();
$table->string('dpt_time', 10)->nullable(); $table->string('dpt_time', 10)->nullable();
$table->string('arr_time', 10)->nullable(); $table->string('arr_time', 10)->nullable();
$table->unsignedDecimal('flight_time', 19)->nullable(); $table->unsignedDecimal('flight_time', 19)->nullable();
$table->text('route')->nullable();
$table->text('notes')->nullable(); $table->text('notes')->nullable();
$table->boolean('has_bid')->default(false); $table->boolean('has_bid')->default(false);
$table->boolean('active')->default(true); $table->boolean('active')->default(true);

View File

@ -1,5 +1,8 @@
<?php <?php
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
@ -24,14 +27,16 @@ class CreatePirepTables extends Migration
$table->string('route_leg', 5)->nullable(); $table->string('route_leg', 5)->nullable();
$table->string('dpt_airport_id', 5); $table->string('dpt_airport_id', 5);
$table->string('arr_airport_id', 5); $table->string('arr_airport_id', 5);
$table->unsignedDecimal('flight_time', 19); $table->unsignedInteger('altitude')->nullable();
$table->unsignedDecimal('flight_time', 19)->nullable();
$table->unsignedDecimal('planned_flight_time', 19)->nullable();
$table->unsignedDecimal('gross_weight', 19)->nullable(); $table->unsignedDecimal('gross_weight', 19)->nullable();
$table->unsignedDecimal('fuel_used', 19)->nullable(); $table->unsignedDecimal('fuel_used', 19)->nullable();
$table->string('route', 250)->nullable(); $table->text('route')->nullable();
$table->string('notes', 250)->nullable(); $table->text('notes')->nullable();
$table->unsignedTinyInteger('source')->default(0); $table->unsignedTinyInteger('source')->default(0);
$table->tinyInteger('state')->default(0); # -1 rejected, 0 pending, 1 accepted $table->tinyInteger('state')->default(PirepState::PENDING);
#$table->tinyInteger('status')->default(0); # -1 rejected, 0 pending, 1 accepted $table->tinyInteger('status')->default(PirepStatus::SCHEDULED);
$table->longText('raw_data')->nullable(); $table->longText('raw_data')->nullable();
$table->timestamps(); $table->timestamps();
$table->softDeletes(); $table->softDeletes();

View File

@ -14,22 +14,24 @@ class CreateAcarsTables extends Migration
public function up() public function up()
{ {
Schema::create('acars', function (Blueprint $table) { Schema::create('acars', function (Blueprint $table) {
$table->bigIncrements('id'); $table->string('id', 12);
$table->string('pirep_id', 12); $table->string('pirep_id', 12);
$table->string('name', 10)->nullable(); $table->string('name', 10)->nullable();
$table->float('lat', 7, 4)->default(0.0); $table->float('lat', 7, 4)->default(0.0);
$table->float('lon', 7, 4)->default(0.0); $table->float('lon', 7, 4)->default(0.0);
$table->unsignedInteger('heading')->nullable();
# TODO: More columns here for what might be required $table->unsignedInteger('altitude')->nullable();
$table->integer('vs')->nullable();
# polymorphic relation columns. $table->unsignedInteger('gs')->nullable();
# parent_type can be flight, pirep or acars $table->unsignedInteger('transponder')->nullable();
# once $table->string('autopilot')->nullable();
#$table->unsignedBigInteger('parent_id'); $table->decimal('fuel_flow')->nullable();
#$table->string('parent_type'); $table->dateTimeTz('sim_time')->nullable();
$table->timestamps(); $table->timestamps();
$table->primary('id');
$table->index('pirep_id');
$table->index('created_at'); $table->index('created_at');
}); });
} }

View File

@ -346,7 +346,7 @@ pireps:
dpt_airport_id: KAUS dpt_airport_id: KAUS
arr_airport_id: KJFK arr_airport_id: KJFK
flight_time: 180 # 6 hours flight_time: 180 # 6 hours
state: 0 state: 1
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3 route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
notes: just a pilot report notes: just a pilot report
created_at: NOW created_at: NOW
@ -359,7 +359,7 @@ pireps:
dpt_airport_id: KJFK dpt_airport_id: KJFK
arr_airport_id: KAUS arr_airport_id: KAUS
flight_time: 180 # 6 hours flight_time: 180 # 6 hours
state: 0 state: 1
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3 route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
notes: just a pilot report notes: just a pilot report
created_at: NOW created_at: NOW
@ -372,7 +372,7 @@ pireps:
dpt_airport_id: KJFK dpt_airport_id: KJFK
arr_airport_id: KAUS arr_airport_id: KAUS
flight_time: 180 # 6 hours flight_time: 180 # 6 hours
state: 0 state: 1
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3 route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
notes: just a pilot report notes: just a pilot report
created_at: NOW created_at: NOW

View File

@ -103,11 +103,17 @@ class Utils extends Facade
/** /**
* @param $hours * @param $hours
* @param null $minutes
* @return float|int * @return float|int
*/ */
public static function hoursToMinutes($hours) public static function hoursToMinutes($hours, $minutes=null)
{ {
return $hours * 60; $total = (int) $hours * 60;
if($minutes) {
$total += (int) $minutes;
}
return $total;
} }
/** /**

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Api;
use Log;
use App\Models\Acars;
use Illuminate\Http\Request;
use App\Http\Controllers\AppBaseController;
use App\Repositories\AcarsRepository;
use App\Repositories\PirepRepository;
use App\Http\Resources\Acars as AcarsResource;
class AcarsController extends AppBaseController
{
protected $acarsRepo, $pirepRepo;
public function __construct(
AcarsRepository $acarsRepo,
PirepRepository $pirepRepo
) {
$this->acarsRepo = $acarsRepo;
$this->pirepRepo = $pirepRepo;
}
public function index(Request $request)
{
/*PirepResource::withoutWrapping();
return new PirepResource($this->pirepRepo->find($id));*/
}
/**
* Return the current ACARS map data in GeoJSON format
* @param Request $request
*/
public function geojson(Request $request)
{
}
}

View File

@ -2,17 +2,31 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use Log;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Acars;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use App\Http\Resources\Acars as AcarsResource;
use App\Http\Resources\Pirep as PirepResource; use App\Http\Resources\Pirep as PirepResource;
use App\Http\Controllers\AppBaseController;
use App\Repositories\AcarsRepository;
use App\Repositories\PirepRepository; use App\Repositories\PirepRepository;
use App\Http\Controllers\AppBaseController;
class PirepController extends AppBaseController class PirepController extends AppBaseController
{ {
protected $pirepRepo; protected $acarsRepo, $pirepRepo;
public function __construct(PirepRepository $pirepRepo) public function __construct(
{ AcarsRepository $acarsRepo,
PirepRepository $pirepRepo
) {
$this->acarsRepo = $acarsRepo;
$this->pirepRepo = $pirepRepo; $this->pirepRepo = $pirepRepo;
} }
@ -21,4 +35,88 @@ class PirepController extends AppBaseController
PirepResource::withoutWrapping(); PirepResource::withoutWrapping();
return new PirepResource($this->pirepRepo->find($id)); return new PirepResource($this->pirepRepo->find($id));
} }
/**
* Create a new PIREP and place it in a "inprogress" and "prefile" state
* Once ACARS updates are being processed, then it can go into an 'ENROUTE'
* status, and whatever other statuses may be defined
*
* TODO: Allow extra fields, etc to be set. Aircraft, etc
*/
public function prefile(Request $request)
{
Log::info('PIREP Prefile, user '. Auth::user()->pilot_id,
$request->toArray());
/*$validator = Validator::make($request, [
'aircraft_id' => 'required',
'dpt_airport_id' => 'required',
'arr_airport_id' => 'required',
'altitude' => 'nullable|integer',
'route' => 'nullable',
'notes' => 'nullable',
]);*/
$attr = [];
$attr['user_id'] = Auth::user()->id;
$attr['airline_id'] = $request->get('airline_id');
$attr['aircraft_id'] = $request->get('aircraft_id');
$attr['dpt_airport_id'] = $request->get('dpt_airport');
$attr['arr_airport_id'] = $request->get('arr_airport');
$attr['altitude'] = $request->get('altitude');
$attr['route'] = $request->get('route');
$attr['notes'] = $request->get('notes');
$attr['state'] = PirepState::IN_PROGRESS;
$attr['status'] = PirepStatus::PREFILE;
try {
$pirep = $this->pirepRepo->create($attr);
} catch(\Exception $e) {
Log::error($e);
}
Log::info('PIREP PREFILED');
Log::info($pirep->id);
PirepResource::withoutWrapping();
return new PirepResource($pirep);
}
/**
* Get all of the ACARS updates for a PIREP
* @param $id
* @return AcarsResource
*/
public function acars_get($id)
{
$pirep = $this->pirepRepo->find($id);
$updates = $this->acarsRepo->forPirep($id);
return new AcarsResource($updates);
}
/**
* Post ACARS updates for a PIREP
* @param $id
* @param Request $request
* @return AcarsResource
*/
public function acars_store($id, Request $request)
{
$pirep = $this->pirepRepo->find($id);
Log::info('Posting ACARS update', $request->toArray());
$attrs = $request->toArray();
$attrs['pirep_id'] = $id;
$update = Acars::create($attrs);
$update->save();
# Change the PIREP status
$pirep->status = PirepStatus::ENROUTE;
$pirep->save();
AcarsResource::withoutWrapping();
return new AcarsResource($update);
}
} }

View File

@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class Acars extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}

View File

@ -1,10 +1,36 @@
<?php <?php
namespace App; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use App\Models\Traits\HashId;
class Acars extends Model class Acars extends BaseModel
{ {
use HashId;
public $incrementing = false;
public $table = 'acars'; public $table = 'acars';
public $fillable = [
'pirep_id',
'name',
'lat',
'lon',
'altitude',
'vs',
'gs',
'transponder',
'autopilot',
'fuel_flow',
'sim_time',
];
/**
* FKs
*/
public function pirep()
{
return $this->belongsTo('App\Models\Pirep', 'pirep_id');
}
} }

View File

@ -2,9 +2,7 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model; class Aircraft extends BaseModel
class Aircraft extends Model
{ {
public $table = 'aircraft'; public $table = 'aircraft';

View File

@ -2,13 +2,11 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class Airline * Class Airline
* @package App\Models * @package App\Models
*/ */
class Airline extends Model class Airline extends BaseModel
{ {
public $table = 'airlines'; public $table = 'airlines';

View File

@ -2,13 +2,11 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class Airport * Class Airport
* @package App\Models * @package App\Models
*/ */
class Airport extends Model class Airport extends BaseModel
{ {
public $table = 'airports'; public $table = 'airports';
public $timestamps = false; public $timestamps = false;

8
app/Models/BaseModel.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace App\Models;
class BaseModel extends \Illuminate\Database\Eloquent\Model
{
}

View File

@ -5,13 +5,15 @@ namespace App\Models\Enums;
class PirepState extends EnumBase { class PirepState extends EnumBase {
const REJECTED = -1; const REJECTED = -1;
const PENDING = 0; const IN_PROGRESS = 0;
const ACCEPTED = 1; const PENDING = 1;
const ACCEPTED = 2;
protected static $labels = [ protected static $labels = [
PirepState::REJECTED => 'system.pireps.state.rejected', PirepState::REJECTED => 'system.pireps.state.rejected',
PirepState::PENDING => 'system.pireps.state.pending', PirepState::IN_PROGRESS => 'system.pireps.state.in_progress',
PirepState::ACCEPTED => 'system.pireps.state.accepted', PirepState::PENDING => 'system.pireps.state.pending',
PirepState::ACCEPTED => 'system.pireps.state.accepted',
]; ];
} }

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class Fare * Class Fare
* *
* @package App\Models * @package App\Models
*/ */
class Fare extends Model class Fare extends BaseModel
{ {
public $table = 'fares'; public $table = 'fares';

View File

@ -2,11 +2,9 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
use App\Models\Traits\HashId; use App\Models\Traits\HashId;
class Flight extends Model class Flight extends BaseModel
{ {
use HashId; use HashId;

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class Flight * Class Flight
* *
* @package App\Models * @package App\Models
*/ */
class FlightFields extends Model class FlightFields extends BaseModel
{ {
public $table = 'flight_fields'; public $table = 'flight_fields';

View File

@ -2,9 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; class Navdata extends BaseModel
class Navdata extends Model
{ {
public $table = 'navdata'; public $table = 'navdata';
public $timestamps = false; public $timestamps = false;

View File

@ -2,7 +2,6 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
use App\Models\Traits\HashId; use App\Models\Traits\HashId;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
@ -11,7 +10,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* *
* @package App\Models * @package App\Models
*/ */
class Pirep extends Model class Pirep extends BaseModel
{ {
use HashId; use HashId;
use SoftDeletes; use SoftDeletes;
@ -29,7 +28,9 @@ class Pirep extends Model
'route_leg', 'route_leg',
'airline_id', 'airline_id',
'aircraft_id', 'aircraft_id',
'altitude',
'flight_time', 'flight_time',
'planned_flight_time',
'dpt_airport_id', 'dpt_airport_id',
'arr_airport_id', 'arr_airport_id',
'fuel_used', 'fuel_used',
@ -48,13 +49,16 @@ class Pirep extends Model
* @var array * @var array
*/ */
protected $casts = [ protected $casts = [
'id' => 'string', 'id' => 'string',
'flight_time' => 'integer', 'flight_time' => 'integer',
'level' => 'integer', 'planned_flight_time' => 'integer',
'fuel_used' => 'integer', 'level' => 'integer',
'source' => 'integer', 'altitude' => 'integer',
'state' => 'integer', 'fuel_used' => 'float',
'status' => 'integer', 'gross_weight' => 'float',
'source' => 'integer',
'state' => 'integer',
'status' => 'integer',
]; ];
/** /**

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class PirepEvent * Class PirepEvent
* *
* @package App\Models * @package App\Models
*/ */
class PirepComment extends Model class PirepComment extends BaseModel
{ {
public $table = 'pirep_comments'; public $table = 'pirep_comments';

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class PirepEvent * Class PirepEvent
* *
* @package App\Models * @package App\Models
*/ */
class PirepEvent extends Model class PirepEvent extends BaseModel
{ {
public $table = 'pirep_fields'; public $table = 'pirep_fields';

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class PirepField * Class PirepField
* *
* @package App\Models * @package App\Models
*/ */
class PirepField extends Model class PirepField extends BaseModel
{ {
public $table = 'pirep_fields'; public $table = 'pirep_fields';

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class PirepField * Class PirepField
* *
* @package App\Models * @package App\Models
*/ */
class PirepFieldValues extends Model class PirepFieldValues extends BaseModel
{ {
public $table = 'pirep_field_values'; public $table = 'pirep_field_values';

View File

@ -2,13 +2,11 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class Ranking * Class Ranking
* @package App\Models * @package App\Models
*/ */
class Rank extends Model class Rank extends BaseModel
{ {
public $table = 'ranks'; public $table = 'ranks';
@ -29,9 +27,9 @@ class Rank extends Model
protected $casts = [ protected $casts = [
'name' => 'string', 'name' => 'string',
'hours' => 'integer', 'hours' => 'integer',
'auto_approve_acars' => 'integer', 'auto_approve_acars' => 'bool',
'auto_approve_manual' => 'integer', 'auto_approve_manual' => 'bool',
'auto_promote' => 'integer', 'auto_promote' => 'bool',
]; ];
/** /**

View File

@ -8,9 +8,7 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model; class Setting extends BaseModel
class Setting extends Model
{ {
public $table = 'settings'; public $table = 'settings';

View File

@ -2,13 +2,11 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* Class Subfleet * Class Subfleet
* @package App\Models * @package App\Models
*/ */
class Subfleet extends Model class Subfleet extends BaseModel
{ {
public $table = 'subfleets'; public $table = 'subfleets';
protected $dates = ['deleted_at']; protected $dates = ['deleted_at'];

View File

@ -37,6 +37,7 @@ class User extends Authenticatable
'airline_id', 'airline_id',
'home_airport_id', 'home_airport_id',
'curr_airport_id', 'curr_airport_id',
'last_pirep_id',
'rank_id', 'rank_id',
'timezone', 'timezone',
'state', 'state',
@ -96,6 +97,11 @@ class User extends Authenticatable
return $this->belongsTo('App\Models\Airport', 'curr_airport_id'); return $this->belongsTo('App\Models\Airport', 'curr_airport_id');
} }
public function last_pirep()
{
return $this->belongsTo('App\Models\Pirep', 'last_pirep_id');
}
public function bids() public function bids()
{ {
return $this->hasMany('App\Models\UserBid', 'user_id'); return $this->hasMany('App\Models\UserBid', 'user_id');

View File

@ -2,12 +2,10 @@
namespace App\Models; namespace App\Models;
use Eloquent as Model;
/** /**
* @package App\Models * @package App\Models
*/ */
class UserBid extends Model class UserBid extends BaseModel
{ {
public $table = 'user_bids'; public $table = 'user_bids';

View File

@ -0,0 +1,22 @@
<?php
namespace App\Repositories;
use App\Models\Acars;
use App\Repositories\Traits\CacheableRepository;
use Prettus\Repository\Contracts\CacheableInterface;
class AcarsRepository extends BaseRepository implements CacheableInterface
{
use CacheableRepository;
public function model()
{
return Acars::class;
}
public function forPirep($pirep_id)
{
return $this->findWhere(['pirep_id' => $pirep_id]);
}
}

View File

@ -8,10 +8,8 @@ use App\Models\User;
use App\Repositories\Traits\CacheableRepository; use App\Repositories\Traits\CacheableRepository;
use Prettus\Repository\Contracts\CacheableInterface; use Prettus\Repository\Contracts\CacheableInterface;
class PirepRepository extends BaseRepository implements CacheableInterface class PirepRepository extends BaseRepository
{ {
use CacheableRepository;
protected $fieldSearchable = [ protected $fieldSearchable = [
'user_id', 'user_id',
'flight_id', 'flight_id',

View File

@ -2,17 +2,13 @@
namespace App\Repositories; namespace App\Repositories;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Prettus\Repository\Contracts\CacheableInterface;
use App\Models\User; use App\Models\User;
use App\Models\Enums\PilotState; use App\Models\Enums\PilotState;
use App\Repositories\Criteria\WhereCriteria; use App\Repositories\Criteria\WhereCriteria;
use App\Repositories\Traits\CacheableRepository;
class UserRepository extends BaseRepository implements CacheableInterface class UserRepository extends BaseRepository
{ {
use CacheableRepository;
protected $fieldSearchable = [ protected $fieldSearchable = [
'name' => 'like', 'name' => 'like',
'email' => 'like', 'email' => 'like',

View File

@ -24,6 +24,13 @@ Route::group([], function ()
Route::match(['get'], 'flights/{id}', 'FlightController@get'); Route::match(['get'], 'flights/{id}', 'FlightController@get');
Route::match(['get'], 'pirep/{id}', 'PirepController@get'); Route::match(['get'], 'pirep/{id}', 'PirepController@get');
Route::match(['post'], 'pirep/prefile', 'PirepController@prefile');
Route::match(['get'], 'pirep/{id}/acars', 'PirepController@acars_get');
Route::match(['post'], 'pirep/{id}/acars', 'PirepController@acars_store');
Route::match(['get'], 'acars', 'AcarsController@index');
Route::match(['get'], 'acars/geojson', 'AcarsController@geojson');
# This is the info of the user whose token is in use # This is the info of the user whose token is in use
Route::match(['get'], 'user', 'UserController@index'); Route::match(['get'], 'user', 'UserController@index');

View File

@ -12,6 +12,7 @@ use App\Events\PirepFiled;
use App\Events\PirepRejected; use App\Events\PirepRejected;
use App\Events\UserStatsChanged; use App\Events\UserStatsChanged;
use App\Models\User;
use App\Repositories\PirepRepository; use App\Repositories\PirepRepository;
use Log; use Log;
@ -48,10 +49,15 @@ class PIREPService extends BaseService
# Figure out what default state should be. Look at the default # Figure out what default state should be. Look at the default
# behavior from the rank that the pilot is assigned to # behavior from the rank that the pilot is assigned to
$default_state = PirepState::PENDING;
if($pirep->source === PirepSource::ACARS) { if($pirep->source === PirepSource::ACARS) {
$default_state = $pirep->pilot->rank->auto_approve_acars; if($pirep->pilot->rank->auto_approve_acars) {
$default_state = PirepState::ACCEPTED;
}
} else { } else {
$default_state = $pirep->pilot->rank->auto_approve_manual; if($pirep->pilot->rank->auto_approve_manual) {
$default_state = PirepState::ACCEPTED;
}
} }
$pirep->save(); $pirep->save();
@ -70,13 +76,10 @@ class PIREPService extends BaseService
event(new PirepFiled($pirep)); event(new PirepFiled($pirep));
if ($default_state === PirepState::ACCEPTED) {
$pirep = $this->accept($pirep);
}
# only update the pilot last state if they are accepted # only update the pilot last state if they are accepted
if ($default_state === PirepState::ACCEPTED) { if ($default_state === PirepState::ACCEPTED) {
$this->setPilotState($pirep); $pirep = $this->accept($pirep);
$this->setPilotState($pirep->pilot, $pirep);
} }
return $pirep; return $pirep;
@ -151,7 +154,7 @@ class PIREPService extends BaseService
$pirep->save(); $pirep->save();
$pirep->refresh(); $pirep->refresh();
$this->setPilotState($pirep); $this->setPilotState($pilot, $pirep);
Log::info('PIREP '.$pirep->id.' state change to ACCEPTED'); Log::info('PIREP '.$pirep->id.' state change to ACCEPTED');
@ -193,9 +196,8 @@ class PIREPService extends BaseService
/** /**
* @param Pirep $pirep * @param Pirep $pirep
*/ */
public function setPilotState(Pirep $pirep) public function setPilotState(User $pilot, Pirep $pirep)
{ {
$pilot = $pirep->pilot;
$pilot->refresh(); $pilot->refresh();
$previous_airport = $pilot->curr_airport_id; $previous_airport = $pilot->curr_airport_id;
@ -203,6 +205,8 @@ class PIREPService extends BaseService
$pilot->last_pirep_id = $pirep->id; $pilot->last_pirep_id = $pirep->id;
$pilot->save(); $pilot->save();
$pirep->refresh();
event(new UserStatsChanged($pilot, 'airport', $previous_airport)); event(new UserStatsChanged($pilot, 'airport', $previous_airport));
} }
} }

View File

@ -46,8 +46,9 @@
"tivie/php-os-detector": "1.1.0", "tivie/php-os-detector": "1.1.0",
"santigarcor/laratrust": "5.0.3", "santigarcor/laratrust": "5.0.3",
"pragmarx/version": "0.2.2", "pragmarx/version": "0.2.2",
"nabeel/vacentral": "dev-master", "guzzlehttp/guzzle": "6.3.0",
"jmikola/geojson": "1.0.2" "jmikola/geojson": "1.0.2",
"nabeel/vacentral": "dev-master"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "6.4.0", "phpunit/phpunit": "6.4.0",

147
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "99850757675507f6225a5bbbe35734aa", "content-hash": "df612ce1827421974b40979645d5debe",
"packages": [ "packages": [
{ {
"name": "composer/semver", "name": "composer/semver",
@ -427,7 +427,7 @@
"Doctrine\\DBAL\\": "lib/" "Doctrine\\DBAL\\": "lib/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -750,7 +750,7 @@
"Egulias\\EmailValidator\\": "EmailValidator" "Egulias\\EmailValidator\\": "EmailValidator"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -796,7 +796,7 @@
"Parsedown": "" "Parsedown": ""
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -856,7 +856,7 @@
"GuzzleHttp\\": "src/" "GuzzleHttp\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -914,7 +914,7 @@
"src/functions_include.php" "src/functions_include.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -969,7 +969,7 @@
"src/functions_include.php" "src/functions_include.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1031,7 +1031,7 @@
"Hashids\\": "src/" "Hashids\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1138,7 +1138,7 @@
"InfyOm\\AdminLTETemplates\\": "src/" "InfyOm\\AdminLTETemplates\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1157,7 +1157,7 @@
"laravel", "laravel",
"templates" "templates"
], ],
"time": "2017-11-25 04:43:54" "time": "2017-11-25T04:43:54+00:00"
}, },
{ {
"name": "infyomlabs/laravel-generator", "name": "infyomlabs/laravel-generator",
@ -1199,7 +1199,7 @@
"src/helpers.php" "src/helpers.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1223,7 +1223,7 @@
"test", "test",
"view" "view"
], ],
"time": "2017-11-25 05:18:22" "time": "2017-11-25T05:18:22+00:00"
}, },
{ {
"name": "jackiedo/timezonelist", "name": "jackiedo/timezonelist",
@ -1249,7 +1249,7 @@
"Jackiedo\\Timezonelist\\": "src/Jackiedo/Timezonelist" "Jackiedo\\Timezonelist\\": "src/Jackiedo/Timezonelist"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1360,7 +1360,7 @@
"stubs/" "stubs/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1406,7 +1406,7 @@
"Traitor\\": "src/" "Traitor\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -1594,7 +1594,7 @@
"Illuminate\\": "src/Illuminate/" "Illuminate\\": "src/Illuminate/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -2017,7 +2017,7 @@
} }
], ],
"description": "Bloom filter implementation", "description": "Bloom filter implementation",
"time": "2017-11-30 17:51:14" "time": "2017-11-30T17:51:14+00:00"
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
@ -2123,7 +2123,7 @@
"Cron\\": "src/Cron/" "Cron\\": "src/Cron/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -2172,7 +2172,7 @@
"src/DeepCopy/deep_copy.php" "src/DeepCopy/deep_copy.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -2217,11 +2217,11 @@
"VaCentral\\": "src/" "VaCentral\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
"time": "2017-12-08 04:00:06" "time": "2017-12-08T04:00:06+00:00"
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
@ -2311,7 +2311,7 @@
"PhpParser\\": "lib/PhpParser" "PhpParser\\": "lib/PhpParser"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"BSD-3-Clause" "BSD-3-Clause"
], ],
@ -2744,7 +2744,7 @@
] ]
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -2897,7 +2897,7 @@
"Prophecy\\": "src/" "Prophecy\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -3015,7 +3015,7 @@
"src/" "src/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"BSD-3-Clause" "BSD-3-Clause"
], ],
@ -3156,7 +3156,7 @@
"src/" "src/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"BSD-3-Clause" "BSD-3-Clause"
], ],
@ -3237,7 +3237,7 @@
"src/" "src/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"BSD-3-Clause" "BSD-3-Clause"
], ],
@ -3358,7 +3358,7 @@
"PragmaRX\\Version\\Tests\\": "tests/" "PragmaRX\\Version\\Tests\\": "tests/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -3418,7 +3418,7 @@
"PragmaRX\\Yaml\\Tests\\": "tests/" "PragmaRX\\Yaml\\Tests\\": "tests/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -3481,7 +3481,7 @@
"Prettus\\Repository\\": "src/Prettus/Repository/" "Prettus\\Repository\\": "src/Prettus/Repository/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -3950,7 +3950,7 @@
"Laratrust\\": "src/" "Laratrust\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -4122,16 +4122,16 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "2.1.0", "version": "2.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "1174d9018191e93cb9d719edec01257fc05f8158" "reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1174d9018191e93cb9d719edec01257fc05f8158", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b11c729f95109b56a0fe9650c6a63a0fcd8c439f",
"reference": "1174d9018191e93cb9d719edec01257fc05f8158", "reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4153,7 +4153,7 @@
"src/" "src/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"BSD-3-Clause" "BSD-3-Clause"
], ],
@ -4182,7 +4182,7 @@
"compare", "compare",
"equality" "equality"
], ],
"time": "2017-11-03T07:16:52+00:00" "time": "2017-12-22T14:50:35+00:00"
}, },
{ {
"name": "sebastian/diff", "name": "sebastian/diff",
@ -4728,7 +4728,7 @@
"src/helpers.php" "src/helpers.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -4911,7 +4911,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -4960,7 +4960,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5020,7 +5020,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5076,7 +5076,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5139,7 +5139,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5188,7 +5188,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5242,7 +5242,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5330,7 +5330,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5379,7 +5379,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5531,7 +5531,7 @@
"bootstrap.php" "bootstrap.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5588,7 +5588,7 @@
"bootstrap.php" "bootstrap.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5647,7 +5647,7 @@
"Resources/stubs" "Resources/stubs"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5699,7 +5699,7 @@
"Symfony\\Polyfill\\Util\\": "" "Symfony\\Polyfill\\Util\\": ""
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5754,7 +5754,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5811,7 +5811,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5894,7 +5894,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -5978,7 +5978,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -6046,7 +6046,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -6111,7 +6111,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -6173,7 +6173,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -6304,7 +6304,7 @@
"Tivie\\OS\\": "src/" "Tivie\\OS\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"APACHE 2.0" "APACHE 2.0"
], ],
@ -6525,7 +6525,7 @@
"Webpatser\\Uuid": "src/" "Webpatser\\Uuid": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -6654,7 +6654,7 @@
"src/helper.php" "src/helper.php"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -6711,7 +6711,7 @@
"Zend\\Diactoros\\": "src/" "Zend\\Diactoros\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"BSD-2-Clause" "BSD-2-Clause"
], ],
@ -6940,7 +6940,7 @@
"Facebook\\WebDriver\\": "lib/" "Facebook\\WebDriver\\": "lib/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"Apache-2.0" "Apache-2.0"
], ],
@ -6992,7 +6992,7 @@
"Whoops\\": "src/Whoops/" "Whoops\\": "src/Whoops/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -7153,7 +7153,7 @@
"Laravel\\Dusk\\": "src/" "Laravel\\Dusk\\": "src/"
} }
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
@ -7294,16 +7294,16 @@
}, },
{ {
"name": "orchestra/testbench-core", "name": "orchestra/testbench-core",
"version": "v3.5.4", "version": "v3.5.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/orchestral/testbench-core.git", "url": "https://github.com/orchestral/testbench-core.git",
"reference": "afecbf0d68c43f0fd7ae53447bb28bcf08faf0ad" "reference": "5fa8871651d054bd1f6eb23bb56c1ec6a5622078"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/orchestral/testbench-core/zipball/afecbf0d68c43f0fd7ae53447bb28bcf08faf0ad", "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/5fa8871651d054bd1f6eb23bb56c1ec6a5622078",
"reference": "afecbf0d68c43f0fd7ae53447bb28bcf08faf0ad", "reference": "5fa8871651d054bd1f6eb23bb56c1ec6a5622078",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7312,15 +7312,16 @@
}, },
"require-dev": { "require-dev": {
"laravel/framework": "~5.5.0", "laravel/framework": "~5.5.0",
"mockery/mockery": "^0.9.4", "mockery/mockery": "~1.0",
"orchestra/database": "~3.5.0", "orchestra/database": "~3.5.0",
"phpunit/phpunit": "~6.0" "phpunit/phpunit": "~6.0"
}, },
"suggest": { "suggest": {
"laravel/framework": "Required for testing (~5.5.0).", "laravel/framework": "Required for testing (~5.5.0).",
"mockery/mockery": "Allow to use Mockery for testing (^0.9.4).", "mockery/mockery": "Allow to use Mockery for testing (~1.0).",
"orchestra/database": "Allow to use --realpath migration for testing (~3.5).", "orchestra/database": "Allow to use --realpath migration for testing (~3.5).",
"orchestra/testbench-browser-kit": "Allow to use legacy BrowserKit for testing (~3.5).", "orchestra/testbench-browser-kit": "Allow to use legacy BrowserKit for testing (~3.5).",
"orchestra/testbench-dusk": "Allow to use Laravel Dusk for testing (~3.5).",
"phpunit/phpunit": "Allow to use PHPUnit for testing (~6.0)." "phpunit/phpunit": "Allow to use PHPUnit for testing (~6.0)."
}, },
"type": "library", "type": "library",
@ -7355,7 +7356,7 @@
"orchestral", "orchestral",
"testing" "testing"
], ],
"time": "2017-10-08T07:47:55+00:00" "time": "2017-12-25T05:21:42+00:00"
}, },
{ {
"name": "symfony/class-loader", "name": "symfony/class-loader",
@ -7395,7 +7396,7 @@
"/Tests/" "/Tests/"
] ]
}, },
"notification-url": "http://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],

2
storage/replay/.gitignore vendored Executable file
View File

@ -0,0 +1,2 @@
*
!.gitignore

95
tests/AcarsTest.php Normal file
View File

@ -0,0 +1,95 @@
<?php
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
/**
* Test API calls and authentication, etc
*/
class AcarsTest extends TestCase
{
public function setUp()
{
parent::setUp();
$this->addData('base');
}
protected function getPirep($pirep_id)
{
$resp = $this->withHeaders($this->apiHeaders())
->get('/api/pirep/' . $pirep_id);
$resp->assertStatus(200);
return $resp->json();
}
/**
* Post a PIREP into a PREFILE state and post ACARS
*/
public function testAcarsUpdates()
{
$airport = factory(App\Models\Airport::class)->create();
$airline = factory(App\Models\Airline::class)->create();
$aircraft = factory(App\Models\Aircraft::class)->create();
$uri = '/api/pirep/prefile';
$pirep = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->id,
'dpt_airport' => $airport->icao,
'arr_airport' => $airport->icao,
'altitude' => 38000,
'planned_flight_time' => 120,
'route' => 'POINTA POINTB',
];
$response = $this->withHeaders($this->apiHeaders())->post($uri, $pirep);
$response->assertStatus(201);
# Get the PIREP ID
$pirep_id = $response->json()['id'];
$this->assertNotNull($pirep_id);
# Check the PIREP state and status
$pirep = $this->getPirep($pirep_id);
$this->assertEquals(PirepState::IN_PROGRESS, $pirep['state']);
$this->assertEquals(PirepStatus::PREFILE, $pirep['status']);
# Post an ACARS update
$uri = '/api/pirep/' . $pirep_id . '/acars';
$acars = factory(App\Models\Acars::class)->make()->toArray();
$response = $this->withHeaders($this->apiHeaders())->post($uri, $acars);
$response->assertStatus(201);
$body = $response->json();
$this->assertNotNull($body['id']);
$this->assertEquals($pirep_id, $body['pirep_id']);
# Make sure PIREP state moved into ENROUTE
$pirep = $this->getPirep($pirep_id);
$this->assertEquals(PirepState::IN_PROGRESS, $pirep['state']);
$this->assertEquals(PirepStatus::ENROUTE, $pirep['status']);
$uri = '/api/pirep/' . $pirep_id . '/acars';
$response = $this->withHeaders($this->apiHeaders())->get($uri);
$response->assertStatus(200);
$body = $response->json();
$this->assertEquals(1, $this->count($body));
$this->assertEquals($pirep_id, $body[0]['pirep_id']);
}
public function testNonExistentPirepGet()
{
$uri = '/api/pirep/DOESNTEXIST/acars';
$response = $this->withHeaders($this->apiHeaders())->get($uri);
$response->assertStatus(404);
}
public function testNonExistentPirepStore()
{
$uri = '/api/pirep/DOESNTEXIST/acars';
$acars = factory(App\Models\Acars::class)->make()->toArray();
$response = $this->withHeaders($this->apiHeaders())->post($uri, $acars);
$response->assertStatus(404);
}
}

View File

@ -65,6 +65,7 @@ class PIREPTest extends TestCase
# Submit two PIREPs # Submit two PIREPs
$pireps = factory(Pirep::class, 2)->create([ $pireps = factory(Pirep::class, 2)->create([
'airline_id' => 1,
'user_id' => 1, 'user_id' => 1,
# 360min == 6 hours, rank should bump up # 360min == 6 hours, rank should bump up
'flight_time' => 360, 'flight_time' => 360,
@ -87,6 +88,7 @@ class PIREPTest extends TestCase
# it should automatically be accepted # it should automatically be accepted
# #
$pirep = factory(Pirep::class)->create([ $pirep = factory(Pirep::class)->create([
'airline_id' => 1,
'user_id' => 1, 'user_id' => 1,
# 120min == 2 hours, currently at 9 hours # 120min == 2 hours, currently at 9 hours
# Rank bumps up at 10 hours # Rank bumps up at 10 hours