accept/reject pireps in admin; cleanup and refactoring

This commit is contained in:
Nabeel Shahzad
2017-12-03 00:48:33 -06:00
parent 0272f7e729
commit 4c8fca39eb
17 changed files with 253 additions and 180 deletions

View File

@@ -6,19 +6,25 @@ use App\Http\Requests\CreatePirepRequest;
use App\Http\Requests\UpdatePirepRequest;
use App\Repositories\AircraftRepository;
use App\Repositories\PirepRepository;
use App\Services\PIREPService;
use Illuminate\Http\Request;
use Flash;
use Log;
use Prettus\Repository\Criteria\RequestCriteria;
use Response;
class PirepController extends BaseController
{
private $pirepRepo, $aircraftRepo;
private $pirepRepo, $aircraftRepo, $pirepSvc;
public function __construct(PirepRepository $pirepRepo, AircraftRepository $aircraftRepo)
{
public function __construct(
AircraftRepository $aircraftRepo,
PirepRepository $pirepRepo,
PIREPService $pirepSvc
) {
$this->aircraftRepo = $aircraftRepo;
$this->pirepRepo = $pirepRepo;
$this->pirepSvc = $pirepSvc;
}
public function aircraftList()
@@ -43,7 +49,8 @@ class PirepController extends BaseController
$criterea = new RequestCriteria($request);
$this->pirepRepo->pushCriteria($criterea);
$pireps = $this->pirepRepo->orderBy('created_at', 'desc')
$pireps = $this->pirepRepo
->orderBy('created_at', 'desc')
->paginate();
return view('admin.pireps.index', [
@@ -53,7 +60,6 @@ class PirepController extends BaseController
/**
* Show the form for creating a new Pirep.
*
* @return Response
*/
public function create()
@@ -77,7 +83,6 @@ class PirepController extends BaseController
/**
* Display the specified Pirep.
*
* @param int $id
* @return Response
*/
@@ -97,7 +102,6 @@ class PirepController extends BaseController
/**
* Show the form for editing the specified Pirep.
*
* @param int $id
* @return Response
*/
@@ -139,9 +143,7 @@ class PirepController extends BaseController
/**
* Remove the specified Pirep from storage.
*
* @param int $id
*
* @return Response
*/
public function destroy($id)
@@ -158,4 +160,23 @@ class PirepController extends BaseController
Flash::success('Pirep deleted successfully.');
return redirect(route('admin.pireps.index'));
}
/**
* Change or update the PIREP status
* @param Request $request
* @return \Illuminate\View\View
*/
public function status(Request $request)
{
Log::info('PIREP status update call', [$request->toArray()]);
$pirep = $this->pirepRepo->findWithoutFail($request->id);
if($request->isMethod('post')) {
$new_status = (int) $request->new_status;
$pirep = $this->pirepSvc->changeStatus($pirep, $new_status);
}
$pirep->refresh();
return view('admin.pireps.pirep_card', ['pirep' => $pirep]);
}
}

View File

@@ -29,9 +29,9 @@ class Rank extends Model
protected $casts = [
'name' => 'string',
'hours' => 'integer',
'auto_approve_acars' => 'boolean',
'auto_approve_manual' => 'boolean',
'auto_promote' => 'boolean',
'auto_approve_acars' => 'integer',
'auto_approve_manual' => 'integer',
'auto_promote' => 'integer',
];
/**

View File

@@ -81,7 +81,7 @@ class User extends Authenticatable
protected $casts
= [
'flights' => 'integer',
'flight_hours' => 'integer',
'flight_time' => 'integer',
'balance' => 'double',
'timezone' => 'integer',
];

View File

@@ -9,8 +9,6 @@ class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
@@ -27,27 +25,9 @@ class AppServiceProvider extends ServiceProvider
/**
* Register any application services.
*
* @return void
*/
public function register()
{
// bind all the app services...
$this->app->bind('App\Services\AircraftService', function($app) {
return new \App\Services\AircraftService();
});
$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();
});
}
}

View File

@@ -12,7 +12,9 @@ class PirepRepository extends BaseRepository implements CacheableInterface
use CacheableRepository;
protected $fieldSearchable = [
'user_id'
'user_id',
'flight_id',
'status',
];
public function model()

View File

@@ -10,16 +10,24 @@ use App\Events\PirepFiled;
use App\Events\PirepRejected;
use App\Events\UserStateChanged;
use App\Repositories\PirepRepository;
use Log;
class PIREPService extends BaseService
{
protected $pilotSvc;
protected $pilotSvc, $pirepRepo;
/**
* return a PIREP model
* PIREPService constructor.
* @param PilotService $pilotSvc
* @param PirepRepository $pirepRepo
*/
public function __construct()
{
$this->pilotSvc = app('App\Services\PilotService');
public function __construct(
PilotService $pilotSvc,
PirepRepository $pirepRepo
) {
$this->pilotSvc = $pilotSvc;
$this->pirepRepo = $pirepRepo;
}
/**
@@ -30,15 +38,15 @@ class PIREPService extends BaseService
*
* @return Pirep
*/
public function create(Pirep $pirep, array $field_values): Pirep {
if($field_values == null) {
public function create(Pirep &$pirep, array $field_values): Pirep
{
if($field_values === null) {
$field_values = [];
}
# Figure out what default state should be. Look at the default
# behavior from the rank that the pilot is assigned to
if($pirep->source == config('enums.sources.ACARS')) {
if($pirep->source === config('enums.sources.ACARS')) {
$default_status = $pirep->pilot->rank->auto_approve_acars;
} else {
$default_status = $pirep->pilot->rank->auto_approve_manual;
@@ -56,24 +64,31 @@ class PIREPService extends BaseService
$v->save();
}
Log::info('New PIREP filed', [$pirep]);
event(new PirepFiled($pirep));
if ($default_status == config('enums.pirep_status.ACCEPTED')) {
if ($default_status === config('enums.pirep_status.ACCEPTED')) {
$pirep = $this->accept($pirep);
}
# only update the pilot last state if they are accepted
if ($default_status == config('enums.pirep_status.ACCEPTED')) {
if ($default_status === config('enums.pirep_status.ACCEPTED')) {
$this->setPilotState($pirep);
}
# TODO: Emit filed event. Do financials through that
return $pirep;
}
/**
* @param Pirep $pirep
* @param int $new_status
* @return Pirep
*/
public function changeStatus(Pirep &$pirep, int $new_status): Pirep
{
Log::info('PIREP ' . $pirep->id . ' status change from '.$pirep->status.' to ' . $new_status);
if ($pirep->status === $new_status) {
return $pirep;
}
@@ -81,10 +96,10 @@ class PIREPService extends BaseService
/**
* Move from a PENDING status into either ACCEPTED or REJECTED
*/
if ($pirep->status == config('enums.pirep_status.PENDING')) {
if ($new_status == config('enums.pirep_status.ACCEPTED')) {
if ($pirep->status === config('enums.pirep_status.PENDING')) {
if ($new_status === config('enums.pirep_status.ACCEPTED')) {
return $this->accept($pirep);
} elseif ($new_status == config('enums.pirep_status.REJECTED')) {
} elseif ($new_status === config('enums.pirep_status.REJECTED')) {
return $this->reject($pirep);
} else {
return $pirep;
@@ -94,7 +109,7 @@ class PIREPService extends BaseService
/*
* Move from a ACCEPTED to REJECTED status
*/
elseif ($pirep->status == config('enums.pirep_status.ACCEPTED')) {
elseif ($pirep->status === config('enums.pirep_status.ACCEPTED')) {
$pirep = $this->reject($pirep);
return $pirep;
}
@@ -102,7 +117,7 @@ class PIREPService extends BaseService
/**
* Move from REJECTED to ACCEPTED
*/
elseif ($pirep->status == config('enums.pirep_status.REJECTED')) {
elseif ($pirep->status === config('enums.pirep_status.REJECTED')) {
$pirep = $this->accept($pirep);
return $pirep;
}
@@ -115,7 +130,7 @@ class PIREPService extends BaseService
public function accept(Pirep &$pirep): Pirep
{
# moving from a REJECTED state to ACCEPTED, reconcile statuses
if ($pirep->status == config('enums.pirep_status.ACCEPTED')) {
if ($pirep->status === config('enums.pirep_status.ACCEPTED')) {
return $pirep;
}
@@ -134,6 +149,8 @@ class PIREPService extends BaseService
$this->setPilotState($pirep);
Log::info('PIREP '.$pirep->id.' status change to ACCEPTED');
event(new PirepAccepted($pirep));
return $pirep;
@@ -147,7 +164,7 @@ class PIREPService extends BaseService
{
# If this was previously ACCEPTED, then reconcile the flight hours
# that have already been counted, etc
if ($pirep->status == config('enums.pirep_status.ACCEPTED')) {
if ($pirep->status === config('enums.pirep_status.ACCEPTED')) {
$pilot = $pirep->pilot;
$ft = $pirep->flight_time * -1;
@@ -162,14 +179,21 @@ class PIREPService extends BaseService
$pirep->save();
$pirep->refresh();
Log::info('PIREP ' . $pirep->id . ' status change to REJECTED');
event(new PirepRejected($pirep));
return $pirep;
}
public function setPilotState($pirep) {
/**
* @param Pirep $pirep
*/
public function setPilotState(Pirep &$pirep)
{
$pilot = $pirep->pilot;
$pilot->refresh();
$pilot->curr_airport_id = $pirep->arr_airport_id;
$pilot->last_pirep_id = $pirep->id;
$pilot->save();

View File

@@ -13,7 +13,8 @@ class DatabaseSeeder extends Seeder
{
$env = App::environment();
$path = database_path('seeds/'.$env.'.yml');
print "Seeding seeds/$env.yml";
print("Seeding seeds/$env.yml\n");
if(!file_exists($path)) {
$path = database_path('seeds/prod.yml');
}

View File

@@ -331,7 +331,7 @@ pireps:
dpt_airport_id: KAUS
arr_airport_id: KJFK
flight_time: 21600 # 6 hours
status: -1
status: 0
notes: just a pilot report
- id: pirepid_2
user_id: 1
@@ -341,7 +341,17 @@ pireps:
dpt_airport_id: KJFK
arr_airport_id: KAUS
flight_time: 21600 # 6 hours
status: -1
status: 0
notes: just a pilot report
- id: pirepid_3
user_id: 1
airline_id: 1
flight_id: flightid_2
aircraft_id: 1
dpt_airport_id: KJFK
arr_airport_id: KAUS
flight_time: 21600 # 6 hours
status: 0
notes: just a pilot report
pirep_fields:

View File

@@ -77,4 +77,4 @@ function __draw_base_map(opts) {
attrib.addTo(map);
return map;
}
}

View File

@@ -123,12 +123,29 @@
<script src="/vendor/select2/dist/js/select2.js"></script>
<script src="/vendor/pjax/jquery.pjax.js"></script>
<script src="/vendor/icheck/icheck.js"></script>
<script src="/vendor/rivets/dist/rivets.bundled.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
<script src="/js/admin/admin.js"></script>
<script>
rivets.configure({
prefix: 'rv',
preloadData: true,
rootInterface: '.',
templateDelimiters: ['{', '}'],
iterationAlias: function (modelName) {
return '%' + modelName + '%';
},
// Augment the event handler of the on-* binder
handler: function (target, event, binding) {
this.call(target, event, binding.view.models)
},
executeFunctions: false
});
var getStorage = function(key) {
var st = window.localStorage.getItem(key);
console.log('storage: ', key, st);

View File

@@ -1,7 +1,10 @@
@extends('admin.app')
@section('title', 'Pilot Reports')
@section('actions')
<li><a href="{!! route('admin.pireps.index') !!}"><i class="ti-plus"></i>View All</a></li>
<li><a href="{!! route('admin.pireps.index') !!}"><i class="ti-plus"></i>Pending</a></li>
@endsection
@section('content')
@include('admin.pireps.table')
@@ -11,4 +14,4 @@
</div>
</div>
@endsection
@include('admin.pireps.script')

View File

@@ -0,0 +1,94 @@
<div id="pirep_{!! $pirep->id !!}_container">
<div class="card border-blue-bottom pirep_card_container">
<div class="card-block" style="min-height: 0px">
<div class="row">
<div class="col-sm-2 text-center">
<h5>
<a class="text-c"
href="{!! route('admin.pireps.show', [$pirep->id]) !!}">
{!! $pirep->airline->code !!}
@if($pirep->flight_id)
{!! $pirep->flight->flight_number !!}
@else
{!! $pirep->flight_number !!}
@endif
</a>
</h5>
<div>
@if($pirep->status == config('enums.pirep_status.PENDING'))
<div class="badge badge-warning">Pending</div>
@elseif($pirep->status == config('enums.pirep_status.ACCEPTED'))
<div class="badge badge-success">Accepted</div>
@else
<div class="badge badge-danger">Rejected</div>
@endif
</div>
</div>
<div class="col-sm-10">
<div class="row">
<div class="col-sm-4">
<div>
<span class="description">DEP&nbsp;</span>
{!! $pirep->dpt_airport->icao !!}&nbsp;
<span class="description">ARR&nbsp;</span>
{!! $pirep->arr_airport->icao !!}&nbsp;
</div>
<div><span class="description">Flight Time&nbsp;</span>
{!! Utils::secondsToTime($pirep->flight_time) !!}
</div>
<div><span class="description">Aircraft&nbsp;</span>
{!! $pirep->aircraft->registration !!}
({!! $pirep->aircraft->name !!})
</div>
<div>
<span class="description">Flight Level&nbsp;</span>
{!! $pirep->level !!}
</div>
<div>
<span class="description">File Date&nbsp;</span>
{!! $pirep->created_at !!}
</div>
</div>
<div class="col-sm-4">
<span class="description">more data&nbsp;</span>
</div>
<div class="col-sm-4">
<span class="description">more data&nbsp;</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 ">
<table class="pull-right">
<tr><td>
@if($pirep->status == config('enums.pirep_status.PENDING')
|| $pirep->status == config('enums.pirep_status.REJECTED'))
{!! Form::open(['url' => '/admin/pireps/'.$pirep->id.'/status', 'method' => 'post',
'name' => 'accept_'.$pirep->id,
'id' => $pirep->id.'_accept',
'pirep_id' => $pirep->id,
'new_status' => config('enums.pirep_status.ACCEPTED'),
'class' => 'pirep_submit_status']) !!}
{!! Form::button('Accept', ['type' => 'submit', 'class' => 'btn btn-info']) !!}
{!! Form::close() !!}
@endif
</td><td>&nbsp;</td><td>
@if($pirep->status == config('enums.pirep_status.PENDING')
|| $pirep->status == config('enums.pirep_status.ACCEPTED'))
{!! Form::open(['url' => '/admin/pireps/'.$pirep->id.'/status', 'method' => 'post',
'name' => 'reject_'.$pirep->id,
'id' => $pirep->id.'_reject',
'pirep_id' => $pirep->id,
'new_status' => config('enums.pirep_status.REJECTED'),
'class' => 'pirep_submit_status']) !!}
{!! Form::button('Reject', ['type' => 'submit', 'class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
@endif
</td></tr>
</table>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
@section('scripts')
<script>
function changeStatus(values) {
var destContainer = '#pirep_' + values.pirep_id + '_container';
$.ajax({
url: '/admin/pireps/' + values.pirep_id + '/status',
data: values,
type: 'POST',
success: function (data) {
// console.log(data);
$(destContainer).replaceWith(data);
}
});
}
//$(document).ready(function() {
$(document).on('submit', 'form.pirep_submit_status', function (event) {
console.log(event);
event.preventDefault();
var values = {
pirep_id: $(this).attr('pirep_id'),
new_status: $(this).attr('new_status')
};
console.log(values);
console.log('Changing PIREP ' + values.pirep_id + ' to state ' + values.new_status);
//var destContainer = '#pirep_' + pirep_id + '_container';
//$.pjax.submit(event, destContainer, { push: false, maxCacheLength: 0 });
changeStatus(values);
});
//});
</script>
@endsection

View File

@@ -1,116 +1 @@
@foreach($pireps as $pirep)
<div class="card border-blue-bottom">
<div class="card-block" style="min-height: 0px">
<div class="row">
<div class="col-sm-2 text-center">
<h5>
<a class="text-c"
href="{!! route('admin.pireps.show', [$pirep->id]) !!}">
{!! $pirep->airline->code !!}
@if($pirep->flight_id)
{!! $pirep->flight->flight_number !!}
@else
{!! $pirep->flight_number !!}
@endif
</a>
</h5>
<div>
@if($pirep->status == config('enums.pirep_status.PENDING'))
<div class="badge badge-warning">Pending</div>
@elseif($pirep->status == config('enums.pirep_status.ACCEPTED'))
<div class="badge badge-success">Accepted</div>
@else
<div class="badge badge-danger">Rejected</div>
@endif
</div>
</div>
<div class="col-sm-10">
<div class="row">
<div class="col-sm-4">
<div>
<span class="description">DEP&nbsp;</span>
{!! $pirep->dpt_airport->icao !!}&nbsp;
<span class="description">ARR&nbsp;</span>
{!! $pirep->arr_airport->icao !!}&nbsp;
</div>
<div><span class="description">Flight Time&nbsp;</span>
{!! Utils::secondsToTime($pirep->flight_time) !!}
</div>
<div><span class="description">Aircraft&nbsp;</span>
{!! $pirep->aircraft->registration !!}
({!! $pirep->aircraft->name !!})
</div>
<div>
<span class="description">Flight Level&nbsp;</span>
{!! $pirep->level !!}
</div>
<div>
<span class="description">File Date&nbsp;</span>
{!! $pirep->created_at !!}
</div>
</div>
<div class="col-sm-4">
<span class="description">more data&nbsp;</span>
</div>
<div class="col-sm-4">
<span class="description">more data&nbsp;</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 text-right">
<button href="#" class="btn btn-info">Accept</button>
<button href="#" class="btn btn-danger">Reject</button>
</div>
</div>
</div>
</div>
@endforeach
{{--
<table class="table table-hover table-responsive" id="pireps-table">
<thead>
<th>Pilot</th>
<th>Flight</th>
<th>Aircraft</th>
<th>Flight Time</th>
<th>Level</th>
<th></th>
</thead>
<tbody>
@foreach($pireps as $pirep)
<tr>
<td>{!! $pirep->user->name !!}</td>
<td>
@if($pirep->flight)
<a href="{!! route('admin.flights.show', ['id' => $pirep->flight_id]) !!}">
{!! $pirep->flight->airline->code !!}{!! $pirep->flight->flight_number !!}
</a>
@else
-
@endif
</td>
<td>{!! $pirep->aircraft->registration !!} ({!! $pirep->aircraft->name !!})</td>
<td>{!! Utils::secondsToTime($pirep->flight_time) !!}</td>
<td>{!! $pirep->level !!}</td>
<td style="text-align: right;">
{!! Form::open(['route' => ['admin.pireps.destroy', $pirep->id], 'method' => 'delete']) !!}
<div class='btn-group'>
<a href="{!! route('admin.pireps.show', [$pirep->id]) !!}" class='btn btn-default btn-xs'><i class="glyphicon glyphicon-eye-open"></i></a>
<a href="{!! route('admin.pireps.edit', [$pirep->id]) !!}" class='btn btn-default btn-xs'><i class="glyphicon glyphicon-edit"></i></a>
{!! Form::button('<i class="glyphicon glyphicon-trash"></i>', ['type' => 'submit', 'class' => 'btn btn-danger btn-xs', 'onclick' => "return confirm('Are you sure?')"]) !!}
</div>
{!! Form::close() !!}
</td>
</tr>
@if($pirep->notes)
<tr>
<td>&nbsp;</td>
<td colspan="8"><strong>Notes:</strong> {!! $pirep->notes !!}</td>
</tr>
@endif
@endforeach
</tbody>
</table>
--}}
@each('admin.pireps.pirep_card', $pireps, 'pirep')

View File

@@ -6,7 +6,6 @@
<a href="{!! route('admin.subfleets.create') !!}">
<i class="ti-plus"></i>Add New</a>
</li>
@endsection
@section('content')
<div class="card">
@@ -14,4 +13,3 @@
@include('admin.subfleets.table')
</div>
@endsection

View File

@@ -36,6 +36,8 @@ Route::group([
# pirep related routes
Route::resource('pireps', 'PirepController');
Route::match(['post', 'put'], 'pireps/{id}/status', 'PirepController@status');
Route::resource('pirepfields', 'PirepFieldController');
Route::resource('users', 'UserController');

View File

@@ -73,7 +73,7 @@ class PIREPTest extends TestCase
/**
* Now set the PIREP state to ACCEPTED
*/
$this->pirepSvc->changeStatus($pirep, config('enums.pirep_status.ACCEPTED'));
$this->pirepSvc->changeStatus($pirep, "1");
$this->assertEquals(1, $pirep->pilot->flights);
$this->assertEquals(21600, $pirep->pilot->flight_time);
$this->assertEquals(1, $pirep->pilot->rank_id);