Implement PIREP deletion #1014 (#1055)

* Implement PIREP deletion #1014

* Style fixes

* Add delete button to PIREP listing page

* Remove extra import
This commit is contained in:
Nabeel S
2021-03-02 15:43:34 -05:00
committed by GitHub
parent e22d6d5996
commit 936cd2efd3
16 changed files with 142 additions and 29 deletions

View File

@@ -13,7 +13,11 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
* Define the application's command schedule. How this works... according to the command
* time, an event gets send out with the appropriate time (e.g, hourly sends an hourly event)
*
* Then the CronServiceProvider has the list of cronjobs which then run according to the events
* and then calls those at the proper times.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
*
@@ -31,6 +35,7 @@ class Kernel extends ConsoleKernel
$schedule->command('backup:run')->daily()->at('02:00');
// Update the last time the cron was run
/** @var CronService $cronSvc */
$cronSvc = app(CronService::class);
$cronSvc->updateLastRunTime();
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Cron\Hourly;
use App\Contracts\Listener;
use App\Events\CronHourly;
use App\Models\Enums\PirepState;
use App\Models\Pirep;
use App\Services\PirepService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
/**
* Remove cancelled/deleted PIREPs. Look for PIREPs that were created before the setting time
* (e.g, 12 hours ago) and are marked with the
*/
class DeletePireps extends Listener
{
/**
* Remove expired bids
*
* @param CronHourly $event
*
* @throws \Exception
*/
public function handle(CronHourly $event): void
{
$this->deletePireps(setting('pireps.delete_rejected_hours'), PirepState::REJECTED);
$this->deletePireps(setting('pireps.delete_cancelled_hours'), PirepState::CANCELLED);
}
/**
* Look for and delete PIREPs which match the criteria
*
* @param int $expire_time_hours The time in hours to look for PIREPs
* @param int $state The PirepState enum value
*/
protected function deletePireps(int $expire_time_hours, int $state)
{
$dt = Carbon::now()->subHours($expire_time_hours);
$pireps = Pirep::whereDate('created_at', '<', $dt)->where(['state' => $state])->get();
/** @var PirepService $pirepSvc */
$pirepSvc = app(PirepService::class);
/** @var Pirep $pirep */
foreach ($pireps as $pirep) {
Log::info('Cron: Deleting PIREP id='.$pirep->id.', state='.PirepState::label($state));
$pirepSvc->delete($pirep);
}
}
}

View File

@@ -6,6 +6,7 @@ use App\Contracts\Listener;
use App\Events\CronMonthly;
use App\Models\Enums\ExpenseType;
use App\Services\Finance\RecurringFinanceService;
use Illuminate\Support\Facades\Log;
/**
* Go through and apply any finances that are daily
@@ -35,6 +36,7 @@ class ApplyExpenses extends Listener
*/
public function handle(CronMonthly $event): void
{
Log::info('Monthly: Applying monthly expenses');
$this->financeSvc->processExpenses(ExpenseType::MONTHLY);
}
}

View File

@@ -6,6 +6,7 @@ use App\Contracts\Listener;
use App\Events\CronNightly;
use App\Models\Enums\ExpenseType;
use App\Services\Finance\RecurringFinanceService;
use Illuminate\Support\Facades\Log;
/**
* Go through and apply any finances that are daily
@@ -35,6 +36,7 @@ class ApplyExpenses extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Nightly: Applying daily expenses');
$this->financeSvc->processExpenses(ExpenseType::DAILY);
}
}

View File

@@ -5,6 +5,7 @@ namespace App\Cron\Nightly;
use App\Contracts\Listener;
use App\Events\CronNightly;
use App\Services\SimBriefService;
use Illuminate\Support\Facades\Log;
/**
* Clear any expired SimBrief flight briefs that aren't attached to a PIREP
@@ -23,6 +24,7 @@ class ClearExpiredSimbrief extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Nightly: Removing expired Simbrief entries');
$this->simbriefSvc->removeExpiredEntries();
}
}

View File

@@ -5,6 +5,7 @@ namespace App\Cron\Nightly;
use App\Contracts\Listener;
use App\Events\CronNightly;
use App\Services\VersionService;
use Illuminate\Support\Facades\Log;
/**
* Determine if any pilots should be set to ON LEAVE status
@@ -28,6 +29,7 @@ class NewVersionCheck extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Nightly: Checking for new version');
$this->versionSvc->isNewVersionAvailable();
}
}

View File

@@ -34,7 +34,10 @@ class PilotLeave extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Cron: Running pilot leave check');
$users = $this->userSvc->findUsersOnLeave();
Log::info('Found '.count($users).' users on leave');
foreach ($users as $user) {
Log::info('Setting user '.$user->ident.' to ON LEAVE status');
$this->userSvc->setStatusOnLeave($user);

View File

@@ -35,7 +35,7 @@ class RecalculateBalances extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Recalculating balances');
Log::info('Nightly: Recalculating balances');
$journals = Journal::all();
foreach ($journals as $journal) {

View File

@@ -32,10 +32,10 @@ class RecalculateStats extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Recalculating user stats');
Log::info('Nightly: Recalculating user stats');
$this->userSvc->recalculateAllUserStats();
Log::info('Recalcuating aircraft status');
Log::info('Nightly: Recalcuating aircraft status');
$this->aircraftSvc->recalculateStats();
}
}

View File

@@ -19,6 +19,8 @@ class SetActiveFlights extends Listener
*/
public function handle(CronNightly $event): void
{
Log::info('Nightly: Setting active flights');
$this->checkFlights();
}

View File

@@ -180,12 +180,12 @@
type: number
description: 'How much the load factor can vary per-flight'
- key: simbrief.api_key
name: 'SimBrief API Key'
name: 'Simbrief API Key'
group: simbrief
value: ''
options: ''
type: string
description: 'Your SimBrief API key'
description: 'Your Simbrief API key'
- key: simbrief.only_bids
name: 'Only allow for bids'
group: simbrief
@@ -194,47 +194,47 @@
type: boolean
description: 'Only allow briefs to be created for bidded flights'
- key: simbrief.expire_days
name: 'SimBrief Expire Time'
name: 'Simbrief Expire Time'
group: simbrief
value: 5
options: ''
type: number
description: 'Days after how long to remove unused briefs'
- key: simbrief.noncharter_pax_weight
name: 'SimBrief Passenger Weight for Non-Charter (Scheduled etc) Flights'
name: 'Non-Charter Passenger Weight'
group: simbrief
value: 185
options: ''
type: number
description: 'Passenger weight for Non-Charter flights excluding baggage (lbs)'
description: 'Passenger weight for non-charter flights excluding baggage (lbs)'
- key: simbrief.noncharter_baggage_weight
name: 'SimBrief Baggage Weight per Pax for Non-Charter (Scheduled etc) Flights'
name: 'Non-Charter Baggage Weight'
group: simbrief
value: 35
options: ''
type: number
description: 'Passenger baggage weight for Non-Charter flights (lbs)'
description: 'Passenger baggage weight for non-charter flights (lbs)'
- key: simbrief.charter_pax_weight
name: 'SimBrief Passenger Weight for Charter Flights'
name: 'Charter Passenger Weight'
group: simbrief
value: 168
options: ''
type: number
description: 'Passenger weight for Charter flights excluding baggage (lbs)'
description: 'Passenger weight for charter flights excluding baggage (lbs)'
- key: simbrief.charter_baggage_weight
name: 'SimBrief Baggage Weight per Pax for Charter Flights'
name: 'Charter Baggage Weight'
group: simbrief
value: 28
options: ''
type: number
description: 'Passenger baggage weight for Charter flights (lbs)'
description: 'Passenger baggage weight for charter flights (lbs)'
- key: simbrief.callsign
name: 'SimBrief ATC Callsign'
name: 'Use ATC Callsign'
group: simbrief
value: false
options: ''
type: boolean
description: 'Use pilot ident as SimBrief ATC Callsign'
description: 'Use pilot ident as Simbrief ATC Callsign'
- key: pireps.duplicate_check_time
name: 'PIREP duplicate time check'
group: pireps
@@ -270,6 +270,20 @@
options: ''
type: boolean
description: 'Enables remaining fuel amounts to be considered for fuel expenses'
- key: pireps.delete_cancelled_hours
name: 'Delete cancelled PIREPs'
group: pireps
value: 12
options: ''
type: int
description: 'The time in hours to delete a cancelled PIREP'
- key: pireps.delete_rejected_hours
name: 'Delete rejected PIREPs'
group: pireps
value: 12
options: ''
type: int
description: 'The time in hours to delete a rejected PIREP'
- key: pilots.id_length
name: 'Pilot ID Length'
group: pilots
@@ -347,4 +361,3 @@
options: ''
type: 'text'
description: 'Discord public channel ID for broadcasat notifications'

View File

@@ -394,10 +394,10 @@ class PirepController extends Controller
return redirect(route('admin.pireps.index'));
}
$this->pirepRepo->delete($id);
$this->pirepSvc->delete($pirep);
Flash::success('Pirep deleted successfully.');
return redirect(route('admin.pireps.index'));
return redirect()->back();
}
/**

View File

@@ -7,7 +7,6 @@ use App\Http\Requests\CreatePirepRequest;
use App\Http\Requests\UpdatePirepRequest;
use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use App\Models\Fare;
use App\Models\Pirep;
use App\Models\SimBrief;
@@ -519,12 +518,8 @@ class PirepController extends Controller
$this->pirepSvc->submit($pirep);
Flash::success('PIREP submitted!');
} elseif ($attrs['submit'] === 'delete' || $attrs['submit'] === 'cancel') {
$this->pirepRepo->update([
'state' => PirepState::CANCELLED,
'status' => PirepStatus::CANCELLED,
], $pirep->id);
Flash::success('PIREP cancelled!');
$this->pirepSvc->delete($pirep);
Flash::success('PIREP deleted!');
return redirect(route('frontend.pireps.index'));
}

View File

@@ -2,6 +2,7 @@
namespace App\Providers;
use App\Cron\Hourly\DeletePireps;
use App\Cron\Hourly\RemoveExpiredBids;
use App\Cron\Hourly\RemoveExpiredLiveFlights;
use App\Cron\Nightly\ApplyExpenses;
@@ -41,6 +42,7 @@ class CronServiceProvider extends ServiceProvider
],
CronHourly::class => [
DeletePireps::class,
RemoveExpiredBids::class,
RemoveExpiredLiveFlights::class,
],

View File

@@ -23,6 +23,8 @@ use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use App\Models\Navdata;
use App\Models\Pirep;
use App\Models\PirepComment;
use App\Models\PirepFare;
use App\Models\PirepFieldValue;
use App\Models\SimBrief;
use App\Models\User;
@@ -436,6 +438,29 @@ class PirepService extends Service
return $pirep;
}
/**
* Delete the PIREP and all of the associated data. Does a force delete to make sure that we
* don't run into problems with foreign keys. Models/tables affected:
*
* acars
* bids
* pirep_comments
* pirep_fares
* pirep_field_values
* simbrief
*
* @param Pirep $pirep
*/
public function delete(Pirep $pirep): void
{
$w = ['pirep_id' => $pirep->id];
PirepComment::where($w)->forceDelete();
PirepFare::where($w)->forceDelete();
PirepFieldValue::where($w)->forceDelete();
SimBrief::where($w)->forceDelete();
$pirep->forceDelete();
}
/**
* Update any custom PIREP fields
*

View File

@@ -23,11 +23,19 @@
'pirep_id' => $pirep->id,
'new_status' => PirepState::REJECTED,
'class' => $on_edit_page ? 'pirep_change_status': 'pirep_submit_status']) }}
{{ Form::button('Reject', ['type' => 'submit', 'class' => 'btn btn-danger']) }}
{{ Form::button('Reject', ['type' => 'submit', 'class' => 'btn btn-warning']) }}
{{ Form::close() }}
@endif
</td>
<td>&nbsp;</td>
<td>
{{ Form::open(['url' => route('admin.pireps.destroy', [$pirep->id]),
'method' => 'delete',
'name' => 'delete_'.$pirep->id,
'id' => $pirep->id.'_delete'
]) }}
{{ Form::button('Delete', ['type' => 'submit', 'class' => 'btn btn-danger']) }}
{{ Form::close() }}
</td>
@if ($on_edit_page === false)
<td>
<form action="{{ route('admin.pireps.edit', [$pirep->id]) }}">