Add addtl fields to pirep - block_off and block_on times, calculate block_off time if not there

This commit is contained in:
Nabeel Shahzad
2018-04-04 13:03:10 -05:00
parent 052813ba4a
commit e27f6f1b14
12 changed files with 130 additions and 26 deletions

View File

@@ -39,13 +39,18 @@ $factory->define(App\Models\Pirep::class, function (Faker $faker) {
'zfw' => $faker->randomFloat(2), 'zfw' => $faker->randomFloat(2),
'block_fuel' => $faker->randomFloat(2, 0, 30000), 'block_fuel' => $faker->randomFloat(2, 0, 30000),
'fuel_used' => $faker->randomFloat(2, 0, 30000), 'fuel_used' => $faker->randomFloat(2, 0, 30000),
'block_on_time' => Carbon::now('UTC'),
'block_off_time' => function (array $pirep) {
return $pirep['block_on_time']->subMinutes($pirep['flight_time']);
},
'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]),
'source_name' => 'Test Factory', 'source_name' => 'Test Factory',
'state' => PirepState::PENDING, 'state' => PirepState::PENDING,
'status' => PirepStatus::SCHEDULED, 'status' => PirepStatus::SCHEDULED,
'created_at' => Carbon::now()->toDateTimeString(), 'submitted_at' => Carbon::now('UTC')->toDateTimeString(),
'created_at' => Carbon::now('UTC')->toDateTimeString(),
'updated_at' => function (array $pirep) { 'updated_at' => function (array $pirep) {
return $pirep['created_at']; return $pirep['created_at'];
}, },

View File

@@ -39,9 +39,10 @@ class CreatePirepTables extends Migration
$table->text('route')->nullable(); $table->text('route')->nullable();
$table->text('notes')->nullable(); $table->text('notes')->nullable();
$table->unsignedTinyInteger('source')->nullable()->default(0); $table->unsignedTinyInteger('source')->nullable()->default(0);
$table->string('source_name', 25)->nullable(); $table->string('source_name', 50)->nullable();
$table->tinyInteger('state')->default(PirepState::PENDING); $table->tinyInteger('state')->default(PirepState::PENDING);
$table->char('status', 3)->default(PirepStatus::SCHEDULED); $table->char('status', 3)->default(PirepStatus::SCHEDULED);
$table->dateTime('submitted_at')->nullable();
$table->dateTime('block_off_time')->nullable(); $table->dateTime('block_off_time')->nullable();
$table->dateTime('block_on_time')->nullable(); $table->dateTime('block_on_time')->nullable();
$table->timestamps(); $table->timestamps();

View File

@@ -386,6 +386,8 @@ pireps:
aircraft_id: 1 aircraft_id: 1
dpt_airport_id: KAUS dpt_airport_id: KAUS
arr_airport_id: KJFK arr_airport_id: KJFK
block_off_time: 2018-04-04T12:42:36+00:00
block_on_time: 2018-04-04T16:42:36+00:00
flight_time: 180 # 6 hours flight_time: 180 # 6 hours
state: 1 # accepted state: 1 # accepted
status: 0 status: 0
@@ -393,8 +395,9 @@ pireps:
flight_type: J flight_type: J
route: KAUS SID TNV J87 IAH J2 LCH J22 MEI J239 ATL J52 AJFEB J14 BYJAC Q60 JAXSN J14 COLIN J61 HUBBS J55 SIE STAR KJFK route: KAUS SID TNV J87 IAH J2 LCH J22 MEI J239 ATL J52 AJFEB J14 BYJAC Q60 JAXSN J14 COLIN J61 HUBBS J55 SIE STAR KJFK
notes: just a pilot report notes: just a pilot report
created_at: NOW submitted_at: 2018-04-04T16:50:36+00:00
updated_at: NOW created_at: 2018-04-04T16:50:36+00:00
updated_at: 2018-04-04T17:00:36+00:00
- id: pirepid_2 - id: pirepid_2
user_id: 1 user_id: 1
airline_id: 1 airline_id: 1
@@ -409,6 +412,7 @@ pireps:
notes: just a pilot report notes: just a pilot report
source: 1 # pending source: 1 # pending
source_name: sample source_name: sample
submitted_at: NOW
created_at: NOW created_at: NOW
updated_at: NOW updated_at: NOW
- id: pirepid_3 - id: pirepid_3
@@ -424,6 +428,7 @@ pireps:
flight_type: J flight_type: J
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3 route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
notes: just a pilot report notes: just a pilot report
submitted_at: NOW
created_at: NOW created_at: NOW
updated_at: NOW updated_at: NOW

View File

@@ -35,6 +35,7 @@ use App\Services\GeoService;
use App\Services\PirepService; use App\Services\PirepService;
use App\Services\UserService; use App\Services\UserService;
use Auth; use Auth;
use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Log; use Log;
@@ -237,7 +238,7 @@ class PirepController extends Controller
Log::info('PIREP Update, user '.Auth::id(), $request->post()); Log::info('PIREP Update, user '.Auth::id(), $request->post());
$user = Auth::user(); $user = Auth::user();
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
$attrs = $request->post(); $attrs = $request->post();
@@ -277,7 +278,7 @@ class PirepController extends Controller
$user = Auth::user(); $user = Auth::user();
# Check if the status is cancelled... # Check if the status is cancelled...
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
$attrs = $request->post(); $attrs = $request->post();
@@ -294,9 +295,11 @@ class PirepController extends Controller
$attrs['state'] = PirepState::PENDING; $attrs['state'] = PirepState::PENDING;
$attrs['status'] = PirepStatus::ARRIVED; $attrs['status'] = PirepStatus::ARRIVED;
$attrs['submitted_at'] = Carbon::now('UTC');
$pirep = $this->pirepRepo->update($attrs, $id);
try { try {
$pirep = $this->pirepRepo->update($attrs, $id);
$pirep = $this->pirepSvc->create($pirep); $pirep = $this->pirepSvc->create($pirep);
$this->updateFields($pirep, $request); $this->updateFields($pirep, $request);
$this->updateFares($pirep, $request); $this->updateFares($pirep, $request);
@@ -343,7 +346,7 @@ class PirepController extends Controller
*/ */
public function acars_geojson($id, Request $request) public function acars_geojson($id, Request $request)
{ {
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$geodata = $this->geoSvc->getFeatureFromAcars($pirep); $geodata = $this->geoSvc->getFeatureFromAcars($pirep);
return response(\json_encode($geodata), 200, [ return response(\json_encode($geodata), 200, [
@@ -378,7 +381,7 @@ class PirepController extends Controller
public function acars_store($id, PositionRequest $request) public function acars_store($id, PositionRequest $request)
{ {
# Check if the status is cancelled... # Check if the status is cancelled...
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
Log::debug( Log::debug(
@@ -420,7 +423,7 @@ class PirepController extends Controller
public function acars_logs($id, LogRequest $request) public function acars_logs($id, LogRequest $request)
{ {
# Check if the status is cancelled... # Check if the status is cancelled...
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
Log::debug('Posting ACARS log, PIREP: '.$id, $request->post()); Log::debug('Posting ACARS log, PIREP: '.$id, $request->post());
@@ -451,7 +454,7 @@ class PirepController extends Controller
public function acars_events($id, EventRequest $request) public function acars_events($id, EventRequest $request)
{ {
# Check if the status is cancelled... # Check if the status is cancelled...
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
Log::debug('Posting ACARS event, PIREP: '.$id, $request->post()); Log::debug('Posting ACARS event, PIREP: '.$id, $request->post());
@@ -479,8 +482,7 @@ class PirepController extends Controller
*/ */
public function comments_get($id, Request $request) public function comments_get($id, Request $request)
{ {
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
return PirepCommentResource::collection($pirep->comments); return PirepCommentResource::collection($pirep->comments);
} }
@@ -493,7 +495,7 @@ class PirepController extends Controller
*/ */
public function comments_post($id, CommentRequest $request) public function comments_post($id, CommentRequest $request)
{ {
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
Log::debug('Posting comment, PIREP: '.$id, $request->post()); Log::debug('Posting comment, PIREP: '.$id, $request->post());
@@ -516,9 +518,8 @@ class PirepController extends Controller
*/ */
public function finances_get($id, Request $request) public function finances_get($id, Request $request)
{ {
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$transactions = $this->journalRepo->getAllForObject($pirep); $transactions = $this->journalRepo->getAllForObject($pirep);
return JournalTransactionResource::collection($transactions); return JournalTransactionResource::collection($transactions);
} }
@@ -533,12 +534,12 @@ class PirepController extends Controller
*/ */
public function finances_recalculate($id, Request $request) public function finances_recalculate($id, Request $request)
{ {
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->financeSvc->processFinancesForPirep($pirep); $this->financeSvc->processFinancesForPirep($pirep);
$pirep->refresh(); $pirep->refresh();
$transactions = $this->journalRepo->getAllForObject($pirep);
$transactions = $this->journalRepo->getAllForObject($pirep);
return JournalTransactionResource::collection($transactions['transactions']); return JournalTransactionResource::collection($transactions['transactions']);
} }
@@ -549,8 +550,7 @@ class PirepController extends Controller
*/ */
public function route_get($id, Request $request) public function route_get($id, Request $request)
{ {
$this->pirepRepo->find($id); $pirep = Pirep::find($id);
return AcarsRouteResource::collection(Acars::where([ return AcarsRouteResource::collection(Acars::where([
'pirep_id' => $id, 'pirep_id' => $id,
'type' => AcarsType::ROUTE 'type' => AcarsType::ROUTE
@@ -568,7 +568,7 @@ class PirepController extends Controller
public function route_post($id, RouteRequest $request) public function route_post($id, RouteRequest $request)
{ {
# Check if the status is cancelled... # Check if the status is cancelled...
$pirep = $this->pirepRepo->find($id); $pirep = Pirep::find($id);
$this->checkCancelled($pirep); $this->checkCancelled($pirep);
Log::info('Posting ROUTE, PIREP: '.$id, $request->post()); Log::info('Posting ROUTE, PIREP: '.$id, $request->post());
@@ -596,7 +596,7 @@ class PirepController extends Controller
*/ */
public function route_delete($id, Request $request) public function route_delete($id, Request $request)
{ {
$this->pirepRepo->find($id); $pirep = Pirep::find($id);
Acars::where([ Acars::where([
'pirep_id' => $id, 'pirep_id' => $id,

View File

@@ -21,6 +21,7 @@ use App\Services\GeoService;
use App\Services\PirepService; use App\Services\PirepService;
use App\Services\UserService; use App\Services\UserService;
use App\Support\Units\Time; use App\Support\Units\Time;
use Carbon\Carbon;
use Flash; use Flash;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@@ -283,6 +284,9 @@ class PirepController extends Controller
$minutes = (int) $request->input('minutes', 0); $minutes = (int) $request->input('minutes', 0);
$pirep->flight_time = Utils::hoursToMinutes($hours) + $minutes; $pirep->flight_time = Utils::hoursToMinutes($hours) + $minutes;
// Put the time that this is currently submitted
$attrs['submitted_at'] = Carbon::now('UTC');
$pirep = $this->pirepSvc->create($pirep); $pirep = $this->pirepSvc->create($pirep);
$this->saveCustomFields($pirep, $request); $this->saveCustomFields($pirep, $request);
$this->saveFares($pirep, $request); $this->saveFares($pirep, $request);

View File

@@ -41,7 +41,7 @@ class FileRequest extends FormRequest
'block_fuel' => 'nullable|numeric', 'block_fuel' => 'nullable|numeric',
'route' => 'nullable', 'route' => 'nullable',
'notes' => 'nullable', 'notes' => 'nullable',
'source_name' => 'nullable|max:25', 'source_name' => 'nullable',
'landing_rate' => 'nullable|numeric', 'landing_rate' => 'nullable|numeric',
'flight_type' => 'nullable|integer', 'flight_type' => 'nullable|integer',
'block_off_time' => 'nullable|date', 'block_off_time' => 'nullable|date',

View File

@@ -23,7 +23,7 @@ class PrefileRequest extends FormRequest
'flight_number' => 'required', 'flight_number' => 'required',
'dpt_airport_id' => 'required', 'dpt_airport_id' => 'required',
'arr_airport_id' => 'required', 'arr_airport_id' => 'required',
'source_name' => 'required|max:25', 'source_name' => 'required',
'level' => 'nullable|numeric', 'level' => 'nullable|numeric',
'route_code' => 'nullable', 'route_code' => 'nullable',

View File

@@ -31,7 +31,7 @@ class UpdateRequest extends FormRequest
'route_leg' => 'nullable', 'route_leg' => 'nullable',
'distance' => 'nullable|numeric', 'distance' => 'nullable|numeric',
'planned_distance' => 'nullable|numeric', 'planned_distance' => 'nullable|numeric',
'block_time' => 'nullable|integer', 'block_time' => 'nullable|integer',
'flight_time' => 'nullable|integer', 'flight_time' => 'nullable|integer',
'planned_flight_time' => 'nullable|integer', 'planned_flight_time' => 'nullable|integer',
'level' => 'nullable|numeric', 'level' => 'nullable|numeric',
@@ -47,6 +47,7 @@ class UpdateRequest extends FormRequest
'block_on_time' => 'nullable|date', 'block_on_time' => 'nullable|date',
'created_at' => 'nullable|date', 'created_at' => 'nullable|date',
'status' => 'nullable', 'status' => 'nullable',
'source_name' => 'nullable',
# See if the fare objects are included and formatted properly # See if the fare objects are included and formatted properly
'fares' => 'nullable|array', 'fares' => 'nullable|array',

View File

@@ -8,6 +8,7 @@ use App\Models\Enums\PirepState;
use App\Models\Traits\HashIdTrait; use App\Models\Traits\HashIdTrait;
use App\Support\Units\Distance; use App\Support\Units\Distance;
use App\Support\Units\Fuel; use App\Support\Units\Fuel;
use Carbon\Carbon;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use PhpUnitsOfMeasure\Exception\NonNumericValue; use PhpUnitsOfMeasure\Exception\NonNumericValue;
use PhpUnitsOfMeasure\Exception\NonStringUnitName; use PhpUnitsOfMeasure\Exception\NonStringUnitName;
@@ -27,11 +28,16 @@ use PhpUnitsOfMeasure\Exception\NonStringUnitName;
* @property string arr_airport_id * @property string arr_airport_id
* @property Airport dpt_airport * @property Airport dpt_airport
* @property string dpt_airport_id * @property string dpt_airport_id
* @property Carbon block_off_time
* @property Carbon block_on_time
* @property integer block_time * @property integer block_time
* @property integer flight_time In minutes * @property integer flight_time In minutes
* @property User user * @property User user
* @property Flight|null flight * @property Flight|null flight
* @property Collection fields * @property Collection fields
* @property Carbon submitted_at
* @property Carbon created_at
* @property Carbon updated_at
* @package App\Models * @package App\Models
*/ */
class Pirep extends Model class Pirep extends Model
@@ -73,6 +79,7 @@ class Pirep extends Model
'status', 'status',
'block_off_time', 'block_off_time',
'block_on_time', 'block_on_time',
'submitted_at',
'created_at', 'created_at',
'updated_at', 'updated_at',
]; ];
@@ -95,6 +102,7 @@ class Pirep extends Model
'state' => 'integer', 'state' => 'integer',
'block_off_time' => 'datetime', 'block_off_time' => 'datetime',
'block_on_time' => 'datetime', 'block_on_time' => 'datetime',
'submitted_at' => 'datetime',
]; ];
public static $rules = [ public static $rules = [

View File

@@ -7,6 +7,8 @@ use App\Interfaces\Model;
/** /**
* Class PirepEvent * Class PirepEvent
* *
* @property string pirep_id
* @property int user_id
* @package App\Models * @package App\Models
*/ */
class PirepComment extends Model class PirepComment extends Model

View File

@@ -185,6 +185,28 @@ class PirepService extends Service
} }
} }
# Check the block times. If a block on (arrival) time isn't
# specified, then use the time that it was submitted. It won't
# be the most accurate, but that might be OK
if(!$pirep->block_on_time) {
if($pirep->submitted_at) {
$pirep->block_on_time = $pirep->submitted_at;
} else {
$pirep->block_on_time = Carbon::now('UTC');
}
}
# If the depart time isn't set, then try to calculate it by
# subtracting the flight time from the block_on (arrival) time
if(!$pirep->block_off_time && $pirep->flight_time > 0) {
$pirep->block_off_time = $pirep->block_on_time->subMinutes($pirep->flight_time);
}
# Check that there's a submit time
if (!$pirep->submitted_at) {
$pirep->submitted_at = Carbon::now('UTC');
}
$pirep->save(); $pirep->save();
$pirep->refresh(); $pirep->refresh();

View File

@@ -288,7 +288,7 @@ class AcarsTest extends TestCase
'planned_distance' => 400, 'planned_distance' => 400,
'planned_flight_time' => 120, 'planned_flight_time' => 120,
'route' => 'POINTA POINTB', 'route' => 'POINTA POINTB',
'source_name' => 'UnitTest', 'source_name' => 'AcarsTest::testAcarsUpdates',
'fields' => [ 'fields' => [
'custom_field' => 'custom_value', 'custom_field' => 'custom_value',
], ],
@@ -410,6 +410,62 @@ class AcarsTest extends TestCase
$this->assertCount(1, $comments); $this->assertCount(1, $comments);
} }
/**
* Post a PIREP into a PREFILE state and post ACARS
*/
public function testFilePirepApi(): void
{
$subfleet = $this->createSubfleetWithAircraft(2);
$rank = $this->createRank(10, [$subfleet['subfleet']->id]);
$this->user = factory(App\Models\User::class)->create([
'rank_id' => $rank->id,
]);
$airport = factory(App\Models\Airport::class)->create();
$airline = factory(App\Models\Airline::class)->create();
$aircraft = $subfleet['aircraft']->random();
$uri = '/api/pireps/prefile';
$pirep = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->id,
'dpt_airport_id' => $airport->icao,
'arr_airport_id' => $airport->icao,
'flight_number' => '6000',
'level' => 38000,
'source_name' => 'AcarsTest::testFilePirepApi',
];
$response = $this->post($uri, $pirep);
$response->assertStatus(201);
# Get the PIREP ID
$body = $response->json();
$pirep_id = $body['data']['id'];
# File the PIREP now
$uri = '/api/pireps/'.$pirep_id.'/file';
$response = $this->post($uri, [
'flight_time' => 130,
'fuel_used' => 8000.19,
'distance' => 400,
]);
$response->assertStatus(200);
# Check the block_off_time and block_on_time being set
$body = $this->get('/api/pireps/'.$pirep_id)->json('data');
$this->assertNotNull($body['block_off_time']);
$this->assertNotNull($body['block_on_time']);
# make sure the time matches up
$block_on = new Carbon($body['block_on_time'], 'UTC');
$block_off = new Carbon($body['block_off_time'], 'UTC');
$this->assertEquals($block_on->subMinutes($body['flight_time']), $block_off);
}
/** /**
* Test aircraft is allowed * Test aircraft is allowed
*/ */