From aedb1f22b6a4422959f0c0112ba00efd8383fad0 Mon Sep 17 00:00:00 2001 From: Nabeel S Date: Mon, 16 Sep 2019 13:08:26 -0400 Subject: [PATCH] Don't allow cancels from certain states (#396) * Don't allow cancels from certain states * Unused imports * Don't reset the state doubly * Move SetUserActive into listener; code cleanup * Unused imports * Add missing files into htaccess * Move Command contract to correct folder --- .htaccess | 2 + app/Console/Commands/AcarsReplay.php | 2 +- app/Console/Commands/ComposerCommand.php | 2 +- app/Console/Commands/CreateDatabase.php | 2 +- app/Console/Commands/DevCommands.php | 2 +- app/Console/Commands/DevInstall.php | 2 +- app/Console/Commands/ImportCsv.php | 2 +- app/Console/Commands/ImportFromClassic.php | 2 +- app/Console/Commands/NavdataImport.php | 2 +- app/Console/Commands/TestApi.php | 2 +- app/Console/Commands/Version.php | 2 +- app/Console/Commands/YamlExport.php | 2 +- app/Console/Commands/YamlImport.php | 2 +- app/Console/Cron/Hourly.php | 2 +- app/Console/Cron/Monthly.php | 2 +- app/Console/Cron/Nightly.php | 2 +- app/Console/Cron/Weekly.php | 2 +- app/{Console => Contracts}/Command.php | 15 +++-- app/Contracts/Model.php | 2 + ..._09_16_141152_pireps_change_state_type.php | 36 +++++++++++ app/Exceptions/PirepCancelNotAllowed.php | 40 ++++++++++++ app/Http/Controllers/Api/PirepController.php | 6 +- app/Http/Routes/api.php | 1 + app/Listeners/SetUserActive.php | 23 +++++++ app/Models/Aircraft.php | 3 + app/Models/Enums/AcarsType.php | 3 - app/Models/Enums/ActiveState.php | 3 - app/Models/Enums/AircraftState.php | 3 - app/Models/Enums/AircraftStatus.php | 3 - app/Models/Enums/AnalyticsDimensions.php | 3 - app/Models/Enums/AnalyticsMetrics.php | 1 - app/Models/Enums/Days.php | 1 - app/Models/Enums/ExpenseType.php | 3 - app/Models/Enums/FlightType.php | 3 - app/Models/Enums/FuelType.php | 3 - app/Models/Enums/JournalType.php | 3 - app/Models/Enums/PirepFieldSource.php | 3 - app/Models/Enums/PirepSource.php | 3 - app/Models/Enums/PirepState.php | 4 +- app/Models/Enums/UserState.php | 3 - app/Models/Pirep.php | 13 +++- app/Models/PirepFieldValue.php | 2 + app/Models/Rank.php | 2 + app/Models/User.php | 1 + app/Providers/EventServiceProvider.php | 6 ++ app/Services/AirportService.php | 3 - app/Services/AnalyticsService.php | 7 +-- app/Services/AwardService.php | 5 +- app/Services/DatabaseService.php | 3 - app/Services/ExportService.php | 5 +- app/Services/FareService.php | 3 - app/Services/FlightService.php | 3 - app/Services/GeoService.php | 3 - app/Services/ImportService.php | 3 - app/Services/ModuleService.php | 3 - app/Services/PirepService.php | 61 ++++++++++++------- app/Services/UserService.php | 3 - tests/AcarsTest.php | 28 ++++++--- tests/ImporterTest.php | 4 +- tests/PIREPTest.php | 5 ++ tests/UserTest.php | 4 +- 61 files changed, 231 insertions(+), 138 deletions(-) rename app/{Console => Contracts}/Command.php (96%) create mode 100644 app/Database/migrations/2019_09_16_141152_pireps_change_state_type.php create mode 100644 app/Exceptions/PirepCancelNotAllowed.php create mode 100644 app/Listeners/SetUserActive.php diff --git a/.htaccess b/.htaccess index d8b312ce3..b0112ed52 100755 --- a/.htaccess +++ b/.htaccess @@ -20,6 +20,7 @@ RedirectMatch 403 ^/storage/.*?$ RedirectMatch 403 ^/tests/.*?$ RedirectMatch 403 ^/vendor/.*?$ RedirectMatch 403 ^/.bowerrc$ +RedirectMatch 403 ^/.env RedirectMatch 403 ^/artisan$ RedirectMatch 403 ^/composer.json RedirectMatch 403 ^/composer.lock @@ -32,6 +33,7 @@ RedirectMatch 403 ^/package.json RedirectMatch 403 ^/package-lock.json RedirectMatch 403 ^/phpunit.xml RedirectMatch 403 ^/webpack.mix.js +RedirectMatch 403 ^/yarn.lock # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d diff --git a/app/Console/Commands/AcarsReplay.php b/app/Console/Commands/AcarsReplay.php index e52e2f275..0fef140f1 100644 --- a/app/Console/Commands/AcarsReplay.php +++ b/app/Console/Commands/AcarsReplay.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use App\Facades\Utils; use GuzzleHttp\Client; use Illuminate\Database\Eloquent\Collection; diff --git a/app/Console/Commands/ComposerCommand.php b/app/Console/Commands/ComposerCommand.php index 167d99594..cbebb7ba8 100644 --- a/app/Console/Commands/ComposerCommand.php +++ b/app/Console/Commands/ComposerCommand.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use Illuminate\Support\Facades\Artisan; class ComposerCommand extends Command diff --git a/app/Console/Commands/CreateDatabase.php b/app/Console/Commands/CreateDatabase.php index 6f269ff42..03402c82a 100644 --- a/app/Console/Commands/CreateDatabase.php +++ b/app/Console/Commands/CreateDatabase.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use Illuminate\Support\Facades\Log; use Tivie\OS\Detector; diff --git a/app/Console/Commands/DevCommands.php b/app/Console/Commands/DevCommands.php index 6ac208578..836f23247 100644 --- a/app/Console/Commands/DevCommands.php +++ b/app/Console/Commands/DevCommands.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use App\Models\Acars; use App\Models\Airline; use App\Models\Pirep; diff --git a/app/Console/Commands/DevInstall.php b/app/Console/Commands/DevInstall.php index 489c77991..5856899cd 100644 --- a/app/Console/Commands/DevInstall.php +++ b/app/Console/Commands/DevInstall.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use Modules\Installer\Services\ConfigService; /** diff --git a/app/Console/Commands/ImportCsv.php b/app/Console/Commands/ImportCsv.php index 10cdbe605..feb185010 100644 --- a/app/Console/Commands/ImportCsv.php +++ b/app/Console/Commands/ImportCsv.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use App\Services\ImportService; class ImportCsv extends Command diff --git a/app/Console/Commands/ImportFromClassic.php b/app/Console/Commands/ImportFromClassic.php index 35183f78b..fbad3f503 100644 --- a/app/Console/Commands/ImportFromClassic.php +++ b/app/Console/Commands/ImportFromClassic.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; class ImportFromClassic extends Command { diff --git a/app/Console/Commands/NavdataImport.php b/app/Console/Commands/NavdataImport.php index dae591694..58e54220e 100644 --- a/app/Console/Commands/NavdataImport.php +++ b/app/Console/Commands/NavdataImport.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use App\Models\Enums\NavaidType; use App\Models\Navdata; diff --git a/app/Console/Commands/TestApi.php b/app/Console/Commands/TestApi.php index 66d841ca9..9f80d81a0 100644 --- a/app/Console/Commands/TestApi.php +++ b/app/Console/Commands/TestApi.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use GuzzleHttp\Client; class TestApi extends Command diff --git a/app/Console/Commands/Version.php b/app/Console/Commands/Version.php index 89b7066e6..623c5426f 100644 --- a/app/Console/Commands/Version.php +++ b/app/Console/Commands/Version.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use App\Services\VersionService; use Symfony\Component\Yaml\Yaml; diff --git a/app/Console/Commands/YamlExport.php b/app/Console/Commands/YamlExport.php index 0182bf09e..f15acb5b9 100644 --- a/app/Console/Commands/YamlExport.php +++ b/app/Console/Commands/YamlExport.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use DB; use Symfony\Component\Yaml\Yaml; diff --git a/app/Console/Commands/YamlImport.php b/app/Console/Commands/YamlImport.php index 552edb5da..13ac1751c 100644 --- a/app/Console/Commands/YamlImport.php +++ b/app/Console/Commands/YamlImport.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Console\Command; +use App\Contracts\Command; use App\Services\DatabaseService; /** diff --git a/app/Console/Cron/Hourly.php b/app/Console/Cron/Hourly.php index f1f5bc458..f0c894c24 100644 --- a/app/Console/Cron/Hourly.php +++ b/app/Console/Cron/Hourly.php @@ -2,7 +2,7 @@ namespace App\Console\Cron; -use App\Console\Command; +use App\Contracts\Command; use App\Events\CronHourly; /** diff --git a/app/Console/Cron/Monthly.php b/app/Console/Cron/Monthly.php index ddf2fa81c..33b21768a 100644 --- a/app/Console/Cron/Monthly.php +++ b/app/Console/Cron/Monthly.php @@ -2,7 +2,7 @@ namespace App\Console\Cron; -use App\Console\Command; +use App\Contracts\Command; use App\Events\CronMonthly; /** diff --git a/app/Console/Cron/Nightly.php b/app/Console/Cron/Nightly.php index c6e881612..368949f56 100644 --- a/app/Console/Cron/Nightly.php +++ b/app/Console/Cron/Nightly.php @@ -2,7 +2,7 @@ namespace App\Console\Cron; -use App\Console\Command; +use App\Contracts\Command; use App\Events\CronNightly; /** diff --git a/app/Console/Cron/Weekly.php b/app/Console/Cron/Weekly.php index e3a998a92..3ae11ca86 100644 --- a/app/Console/Cron/Weekly.php +++ b/app/Console/Cron/Weekly.php @@ -2,7 +2,7 @@ namespace App\Console\Cron; -use App\Console\Command; +use App\Contracts\Command; use App\Events\CronWeekly; /** diff --git a/app/Console/Command.php b/app/Contracts/Command.php similarity index 96% rename from app/Console/Command.php rename to app/Contracts/Command.php index 4b7c101a1..ec3a9c8f2 100644 --- a/app/Console/Command.php +++ b/app/Contracts/Command.php @@ -1,6 +1,6 @@ unsignedSmallInteger('state')->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + } +} diff --git a/app/Exceptions/PirepCancelNotAllowed.php b/app/Exceptions/PirepCancelNotAllowed.php new file mode 100644 index 000000000..a84728ca2 --- /dev/null +++ b/app/Exceptions/PirepCancelNotAllowed.php @@ -0,0 +1,40 @@ +pirep = $pirep; + parent::__construct( + 400, + 'This PIREP can\'t be cancelled' + ); + } + + /** + * Return the RFC 7807 error type (without the URL root) + */ + public function getErrorType(): string + { + return 'pirep-cancel-not-allowed'; + } + + public function getErrorDetails(): string + { + return $this->getMessage(); + } + + public function getErrorMetadata(): array + { + return [ + 'pirep_id' => $this->pirep->id, + 'state' => $this->pirep->state, + ]; + } +} diff --git a/app/Http/Controllers/Api/PirepController.php b/app/Http/Controllers/Api/PirepController.php index 4f39c8b1e..445b1f1cc 100644 --- a/app/Http/Controllers/Api/PirepController.php +++ b/app/Http/Controllers/Api/PirepController.php @@ -363,10 +363,8 @@ public function cancel($pirep_id, Request $request) { Log::info('PIREP Cancel, user '.Auth::id(), $request->post()); - $pirep = $this->pirepRepo->update([ - 'state' => PirepState::CANCELLED, - 'status' => PirepStatus::CANCELLED, - ], $pirep_id); + $pirep = Pirep::find($pirep_id); + $this->pirepSvc->cancel($pirep); return new PirepResource($pirep); } diff --git a/app/Http/Routes/api.php b/app/Http/Routes/api.php index adf6ee2b5..6da61a844 100755 --- a/app/Http/Routes/api.php +++ b/app/Http/Routes/api.php @@ -46,6 +46,7 @@ Route::post('pireps/{pirep_id}/update', 'PirepController@update'); Route::post('pireps/{pirep_id}/file', 'PirepController@file'); Route::post('pireps/{pirep_id}/comments', 'PirepController@comments_post'); + Route::put('pireps/{pirep_id}/cancel', 'PirepController@cancel'); Route::delete('pireps/{pirep_id}/cancel', 'PirepController@cancel'); Route::get('pireps/{pirep_id}/fields', 'PirepController@fields_get'); diff --git a/app/Listeners/SetUserActive.php b/app/Listeners/SetUserActive.php new file mode 100644 index 000000000..2a484bf9f --- /dev/null +++ b/app/Listeners/SetUserActive.php @@ -0,0 +1,23 @@ +pirep->user->state !== UserState::ACTIVE) { + $old_state = $event->pirep->user->state; + $event->pirep->user->state = UserState::ACTIVE; + $event->pirep->user->save(); + + event(new UserStateChanged($event->pirep->user, $old_state)); + } + } +} diff --git a/app/Models/Aircraft.php b/app/Models/Aircraft.php index c2d75f4d8..d8bfd8cf0 100644 --- a/app/Models/Aircraft.php +++ b/app/Models/Aircraft.php @@ -10,14 +10,17 @@ /** * @property int id * @property mixed subfleet_id + * @property string airport_id The apt where the aircraft is * @property string name * @property string icao * @property string registration + * @property int flight_time * @property string hex_code * @property Airport airport * @property Subfleet subfleet * @property int status * @property int state + * @property Carbon landing_time */ class Aircraft extends Model { diff --git a/app/Models/Enums/AcarsType.php b/app/Models/Enums/AcarsType.php index 980e57c21..13b37d299 100644 --- a/app/Models/Enums/AcarsType.php +++ b/app/Models/Enums/AcarsType.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class AcarsType - */ class AcarsType extends Enum { public const FLIGHT_PATH = 0; diff --git a/app/Models/Enums/ActiveState.php b/app/Models/Enums/ActiveState.php index 031ee2a23..a8f323e2f 100644 --- a/app/Models/Enums/ActiveState.php +++ b/app/Models/Enums/ActiveState.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class ActiveState - */ class ActiveState extends Enum { public const INACTIVE = 0; diff --git a/app/Models/Enums/AircraftState.php b/app/Models/Enums/AircraftState.php index 2179a5ed1..9020a33da 100644 --- a/app/Models/Enums/AircraftState.php +++ b/app/Models/Enums/AircraftState.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class AircraftState - */ class AircraftState extends Enum { public const PARKED = 0; diff --git a/app/Models/Enums/AircraftStatus.php b/app/Models/Enums/AircraftStatus.php index 9c60765c5..60eec9979 100644 --- a/app/Models/Enums/AircraftStatus.php +++ b/app/Models/Enums/AircraftStatus.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class AircraftState - */ class AircraftStatus extends Enum { public const ACTIVE = 'A'; diff --git a/app/Models/Enums/AnalyticsDimensions.php b/app/Models/Enums/AnalyticsDimensions.php index 506fc06f5..6966d790e 100644 --- a/app/Models/Enums/AnalyticsDimensions.php +++ b/app/Models/Enums/AnalyticsDimensions.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class AnalyticsDimensions - */ class AnalyticsDimensions extends Enum { public const PHP_VERSION = 1; diff --git a/app/Models/Enums/AnalyticsMetrics.php b/app/Models/Enums/AnalyticsMetrics.php index 550f2e6c6..d212c5dbf 100644 --- a/app/Models/Enums/AnalyticsMetrics.php +++ b/app/Models/Enums/AnalyticsMetrics.php @@ -5,7 +5,6 @@ use App\Contracts\Enum; /** - * Class AnalyticsMetrics * Metrics IDs used in Google Analytics */ class AnalyticsMetrics extends Enum diff --git a/app/Models/Enums/Days.php b/app/Models/Enums/Days.php index e0ff59864..04013a1c5 100644 --- a/app/Models/Enums/Days.php +++ b/app/Models/Enums/Days.php @@ -5,7 +5,6 @@ use App\Contracts\Enum; /** - * Class Days * Start on Monday - ISO8601 */ class Days extends Enum diff --git a/app/Models/Enums/ExpenseType.php b/app/Models/Enums/ExpenseType.php index 5154885ec..7d4245407 100644 --- a/app/Models/Enums/ExpenseType.php +++ b/app/Models/Enums/ExpenseType.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class ExpenseType - */ class ExpenseType extends Enum { public const FLIGHT = 'F'; diff --git a/app/Models/Enums/FlightType.php b/app/Models/Enums/FlightType.php index c3254e347..aaaa2b878 100644 --- a/app/Models/Enums/FlightType.php +++ b/app/Models/Enums/FlightType.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class FlightType - */ class FlightType extends Enum { public const SCHED_PAX = 'J'; diff --git a/app/Models/Enums/FuelType.php b/app/Models/Enums/FuelType.php index d5d1c3ae5..afd52ef8f 100644 --- a/app/Models/Enums/FuelType.php +++ b/app/Models/Enums/FuelType.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class FuelType - */ class FuelType extends Enum { public const LOW_LEAD = 0; diff --git a/app/Models/Enums/JournalType.php b/app/Models/Enums/JournalType.php index 6321cb498..ff46c8d43 100644 --- a/app/Models/Enums/JournalType.php +++ b/app/Models/Enums/JournalType.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class JournalType - */ class JournalType extends Enum { public const AIRLINE = 0; diff --git a/app/Models/Enums/PirepFieldSource.php b/app/Models/Enums/PirepFieldSource.php index 7270fd97f..fc09f14a4 100644 --- a/app/Models/Enums/PirepFieldSource.php +++ b/app/Models/Enums/PirepFieldSource.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class AcarsType - */ class PirepFieldSource extends Enum { public const MANUAL = 0; diff --git a/app/Models/Enums/PirepSource.php b/app/Models/Enums/PirepSource.php index 9b837ba63..bbcd003e6 100644 --- a/app/Models/Enums/PirepSource.php +++ b/app/Models/Enums/PirepSource.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class PirepSource - */ class PirepSource extends Enum { public const MANUAL = 0; diff --git a/app/Models/Enums/PirepState.php b/app/Models/Enums/PirepState.php index 50f7ec055..0d35d7b3b 100644 --- a/app/Models/Enums/PirepState.php +++ b/app/Models/Enums/PirepState.php @@ -9,21 +9,21 @@ */ class PirepState extends Enum { - public const REJECTED = -1; public const IN_PROGRESS = 0; // flight is ongoing public const PENDING = 1; // waiting admin approval public const ACCEPTED = 2; public const CANCELLED = 3; public const DELETED = 4; public const DRAFT = 5; + public const REJECTED = 6; protected static $labels = [ - self::REJECTED => 'pireps.state.rejected', self::IN_PROGRESS => 'pireps.state.in_progress', self::PENDING => 'pireps.state.pending', self::ACCEPTED => 'pireps.state.accepted', self::CANCELLED => 'pireps.state.cancelled', self::DELETED => 'pireps.state.deleted', self::DRAFT => 'pireps.state.draft', + self::REJECTED => 'pireps.state.rejected', ]; } diff --git a/app/Models/Enums/UserState.php b/app/Models/Enums/UserState.php index 516b43994..5f8ef478b 100644 --- a/app/Models/Enums/UserState.php +++ b/app/Models/Enums/UserState.php @@ -4,9 +4,6 @@ use App\Contracts\Enum; -/** - * Class UserState - */ class UserState extends Enum { public const PENDING = 0; diff --git a/app/Models/Pirep.php b/app/Models/Pirep.php index 305509afb..f3de24673 100644 --- a/app/Models/Pirep.php +++ b/app/Models/Pirep.php @@ -42,6 +42,7 @@ * @property Collection fields * @property int status * @property bool state + * @property string source * @property Carbon submitted_at * @property Carbon created_at * @property Carbon updated_at @@ -130,7 +131,7 @@ class Pirep extends Model 'route' => 'nullable', ]; - /** + /* * If a PIREP is in these states, then it can't be changed. */ public static $read_only_states = [ @@ -139,6 +140,16 @@ class Pirep extends Model PirepState::CANCELLED, ]; + /* + * If a PIREP is in one of these states, it can't be cancelled + */ + public static $cancel_states = [ + PirepState::ACCEPTED, + PirepState::REJECTED, + PirepState::CANCELLED, + PirepState::DELETED, + ]; + /** * Get the flight ident, e.,g JBU1900 * diff --git a/app/Models/PirepFieldValue.php b/app/Models/PirepFieldValue.php index 76a3ebe19..cf885b221 100644 --- a/app/Models/PirepFieldValue.php +++ b/app/Models/PirepFieldValue.php @@ -11,6 +11,8 @@ * @property string slug * @property string value * @property string source + * + * @method static updateOrCreate(array $array, array $array1) */ class PirepFieldValue extends Model { diff --git a/app/Models/Rank.php b/app/Models/Rank.php index cb4340518..f49d271d5 100644 --- a/app/Models/Rank.php +++ b/app/Models/Rank.php @@ -10,6 +10,8 @@ * @property float manual_base_pay_rate * @property float acars_base_pay_rate * @property bool auto_promote + * @property bool auto_approve_acars + * @property bool auto_approve_manual */ class Rank extends Model { diff --git a/app/Models/User.php b/app/Models/User.php index 66f790ef5..0aeef63b3 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -32,6 +32,7 @@ * @property int rank_id * @property int state * @property bool opt_in + * @property string last_pirep_id * @mixin \Illuminate\Notifications\Notifiable * @mixin \Laratrust\Traits\LaratrustUserTrait */ diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 6e28cee27..f2758991d 100755 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -3,12 +3,14 @@ namespace App\Providers; use App\Events\Expenses; +use App\Events\PirepFiled; use App\Events\UserStatsChanged; use App\Listeners\AwardListener; use App\Listeners\BidEvents; use App\Listeners\ExpenseListener; use App\Listeners\FinanceEvents; use App\Listeners\NotificationEvents; +use App\Listeners\SetUserActive; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; @@ -20,6 +22,10 @@ class EventServiceProvider extends ServiceProvider ExpenseListener::class, ], + PirepFiled::class => [ + SetUserActive::class, + ], + Registered::class => [ SendEmailVerificationNotification::class, ], diff --git a/app/Services/AirportService.php b/app/Services/AirportService.php index 156b83e0c..2d644e4cb 100644 --- a/app/Services/AirportService.php +++ b/app/Services/AirportService.php @@ -15,9 +15,6 @@ use PhpUnitsOfMeasure\Exception\NonNumericValue; use PhpUnitsOfMeasure\Exception\NonStringUnitName; -/** - * Class AnalyticsService - */ class AirportService extends Service { private $airportRepo; diff --git a/app/Services/AnalyticsService.php b/app/Services/AnalyticsService.php index 05dd47ede..b25c61194 100644 --- a/app/Services/AnalyticsService.php +++ b/app/Services/AnalyticsService.php @@ -4,14 +4,11 @@ use App\Contracts\Service; use App\Models\Enums\AnalyticsDimensions; -use DB; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Irazasyed\LaravelGAMP\Facades\GAMP; -use Log; use PDO; -/** - * Class AnalyticsService - */ class AnalyticsService extends Service { /** diff --git a/app/Services/AwardService.php b/app/Services/AwardService.php index d42a1ad81..6fad93169 100644 --- a/app/Services/AwardService.php +++ b/app/Services/AwardService.php @@ -4,11 +4,8 @@ use App\Contracts\Service; use App\Support\ClassLoader; -use Module; +use Nwidart\Modules\Facades\Module; -/** - * Class AwardService - */ class AwardService extends Service { /** diff --git a/app/Services/DatabaseService.php b/app/Services/DatabaseService.php index 0168e06ef..c0fdc626d 100644 --- a/app/Services/DatabaseService.php +++ b/app/Services/DatabaseService.php @@ -7,9 +7,6 @@ use Carbon\Carbon; use Webpatser\Uuid\Uuid; -/** - * Class DatabaseService - */ class DatabaseService extends Service { protected $time_fields = [ diff --git a/app/Services/ExportService.php b/app/Services/ExportService.php index 87a5366d5..e41b429da 100644 --- a/app/Services/ExportService.php +++ b/app/Services/ExportService.php @@ -11,14 +11,11 @@ use App\Services\ImportExport\FlightExporter; use App\Services\ImportExport\SubfleetExporter; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; use League\Csv\CharsetConverter; use League\Csv\Writer; -use Log; -/** - * Class ExportService - */ class ExportService extends Service { /** diff --git a/app/Services/FareService.php b/app/Services/FareService.php index 12a299193..00bbade74 100644 --- a/app/Services/FareService.php +++ b/app/Services/FareService.php @@ -11,9 +11,6 @@ use App\Support\Math; use Illuminate\Support\Collection; -/** - * Class FareService - */ class FareService extends Service { /** diff --git a/app/Services/FlightService.php b/app/Services/FlightService.php index 3b0587718..5ca53650e 100644 --- a/app/Services/FlightService.php +++ b/app/Services/FlightService.php @@ -15,9 +15,6 @@ use App\Support\Units\Time; use Illuminate\Support\Facades\Log; -/** - * Class FlightService - */ class FlightService extends Service { private $airportSvc; diff --git a/app/Services/GeoService.php b/app/Services/GeoService.php index ce555fbc8..41a43f953 100644 --- a/app/Services/GeoService.php +++ b/app/Services/GeoService.php @@ -16,9 +16,6 @@ use League\Geotools\Coordinate\Coordinate; use League\Geotools\Geotools; -/** - * Class GeoService - */ class GeoService extends Service { private $acarsRepo; diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php index 956a94dd0..4f68311b9 100644 --- a/app/Services/ImportService.php +++ b/app/Services/ImportService.php @@ -19,9 +19,6 @@ use League\Csv\Exception; use League\Csv\Reader; -/** - * Class ImportService - */ class ImportService extends Service { protected $flightRepo; diff --git a/app/Services/ModuleService.php b/app/Services/ModuleService.php index b1e9cf220..61f69f239 100644 --- a/app/Services/ModuleService.php +++ b/app/Services/ModuleService.php @@ -4,9 +4,6 @@ use App\Contracts\Service; -/** - * Class ModuleService - */ class ModuleService extends Service { protected static $adminLinks = []; diff --git a/app/Services/PirepService.php b/app/Services/PirepService.php index 87b30ff39..1a41b78c6 100644 --- a/app/Services/PirepService.php +++ b/app/Services/PirepService.php @@ -6,20 +6,19 @@ use App\Events\PirepAccepted; use App\Events\PirepFiled; use App\Events\PirepRejected; -use App\Events\UserStateChanged; use App\Events\UserStatsChanged; +use App\Exceptions\PirepCancelNotAllowed; use App\Models\Acars; -use App\Models\Aircraft; use App\Models\Bid; use App\Models\Enums\AcarsType; use App\Models\Enums\PirepSource; use App\Models\Enums\PirepState; use App\Models\Enums\PirepStatus; -use App\Models\Enums\UserState; use App\Models\Navdata; use App\Models\Pirep; use App\Models\PirepFieldValue; use App\Models\User; +use App\Repositories\PirepRepository; use Carbon\Carbon; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Support\Facades\Log; @@ -31,19 +30,23 @@ class PirepService extends Service { private $geoSvc; private $pilotSvc; + private $pirepRepo; /** * PirepService constructor. * - * @param GeoService $geoSvc - * @param UserService $pilotSvc + * @param GeoService $geoSvc + * @param PirepRepository $pirepRepo + * @param UserService $pilotSvc */ public function __construct( GeoService $geoSvc, + PirepRepository $pirepRepo, UserService $pilotSvc ) { $this->geoSvc = $geoSvc; $this->pilotSvc = $pilotSvc; + $this->pirepRepo = $pirepRepo; } /** @@ -207,11 +210,11 @@ public function submit(Pirep $pirep) // behavior from the rank that the pilot is assigned to $default_state = PirepState::PENDING; if ($pirep->source === PirepSource::ACARS) { - if ($pirep->pilot->rank->auto_approve_acars) { + if ($pirep->user->rank->auto_approve_acars) { $default_state = PirepState::ACCEPTED; } } else { - if ($pirep->pilot->rank->auto_approve_manual) { + if ($pirep->user->rank->auto_approve_manual) { $default_state = PirepState::ACCEPTED; } } @@ -222,21 +225,36 @@ public function submit(Pirep $pirep) // only update the pilot last state if they are accepted if ($default_state === PirepState::ACCEPTED) { $pirep = $this->accept($pirep); - $this->setPilotState($pirep->pilot, $pirep); } else { $pirep->state = $default_state; } $pirep->save(); + } - // Check the user state, set them to ACTIVE if on leave - if ($pirep->user->state !== UserState::ACTIVE) { - $old_state = $pirep->user->state; - $pirep->user->state = UserState::ACTIVE; - $pirep->user->save(); + /** + * Cancel a PIREP + * + * @param Pirep $pirep + * + * @throws \Prettus\Validator\Exceptions\ValidatorException + * + * @return Pirep + */ + public function cancel(Pirep $pirep): Pirep + { + if (in_array($pirep->state, Pirep::$cancel_states, true)) { + Log::info('PIREP '.$pirep->id.' can\'t be cancelled, state='.$pirep->state); - event(new UserStateChanged($pirep->user, $old_state)); + throw new PirepCancelNotAllowed($pirep); } + + $pirep = $this->pirepRepo->update([ + 'state' => PirepState::CANCELLED, + 'status' => PirepStatus::CANCELLED, + ], $pirep->id); + + return $pirep; } /** @@ -324,12 +342,12 @@ public function accept(Pirep $pirep): Pirep } $ft = $pirep->flight_time; - $pilot = $pirep->pilot; + $pilot = $pirep->user; $this->pilotSvc->adjustFlightTime($pilot, $ft); $this->pilotSvc->adjustFlightCount($pilot, +1); $this->pilotSvc->calculatePilotRank($pilot); - $pirep->pilot->refresh(); + $pirep->user->refresh(); // Change the status $pirep->state = PirepState::ACCEPTED; @@ -362,13 +380,13 @@ public function reject(Pirep $pirep): Pirep // If this was previously ACCEPTED, then reconcile the flight hours // that have already been counted, etc if ($pirep->state === PirepState::ACCEPTED) { - $pilot = $pirep->pilot; + $user = $pirep->user; $ft = $pirep->flight_time * -1; - $this->pilotSvc->adjustFlightTime($pilot, $ft); - $this->pilotSvc->adjustFlightCount($pilot, -1); - $this->pilotSvc->calculatePilotRank($pilot); - $pirep->pilot->refresh(); + $this->pilotSvc->adjustFlightTime($user, $ft); + $this->pilotSvc->adjustFlightCount($user, -1); + $this->pilotSvc->calculatePilotRank($user); + $pirep->user->refresh(); } // Change the status @@ -387,6 +405,7 @@ public function reject(Pirep $pirep): Pirep } /** + * @param User $pilot * @param Pirep $pirep */ public function setPilotState(User $pilot, Pirep $pirep) diff --git a/app/Services/UserService.php b/app/Services/UserService.php index 1e2dcc537..bc233a7ab 100644 --- a/app/Services/UserService.php +++ b/app/Services/UserService.php @@ -21,9 +21,6 @@ use Illuminate\Support\Facades\Log; use function is_array; -/** - * Class UserService - */ class UserService extends Service { private $aircraftRepo; diff --git a/tests/AcarsTest.php b/tests/AcarsTest.php index f4640817d..635ecdc35 100644 --- a/tests/AcarsTest.php +++ b/tests/AcarsTest.php @@ -2,6 +2,7 @@ use App\Models\Enums\PirepState; use App\Models\Enums\PirepStatus; +use App\Models\PirepFare; use App\Repositories\SettingRepository; /** @@ -217,7 +218,7 @@ public function testPrefileAndUpdates() $pirep = $response->json('data'); // See that the fields and fares were set - $fares = \App\Models\PirepFare::where('pirep_id', $pirep['id'])->get(); + $fares = PirepFare::where('pirep_id', $pirep['id'])->get(); $this->assertCount(1, $fares); $saved_fare = $fares->first(); @@ -246,16 +247,30 @@ public function testPrefileAndUpdates() ]; $response = $this->post($uri, $update); - $response->assertStatus(200); - $updated_pirep = $response->json('data'); + $response->assertOk(); // Make sure there are no duplicates - $fares = \App\Models\PirepFare::where('pirep_id', $pirep['id'])->get(); + $fares = PirepFare::where('pirep_id', $pirep['id'])->get(); $this->assertCount(1, $fares); $saved_fare = $fares->first(); $this->assertEquals($fare->id, $saved_fare['fare_id']); $this->assertEquals($fare->capacity, $saved_fare['count']); + + /* + * Try cancelling the PIREP now + */ + $uri = '/api/pireps/'.$pirep['id'].'/cancel'; + $response = $this->put($uri, []); + $response->assertOk(); + + // Read it + $uri = '/api/pireps/'.$pirep['id']; + $response = $this->get($uri); + $response->assertOk(); + $body = $response->json('data'); + + $this->assertEquals($body['state'], PirepState::CANCELLED); } /** @@ -460,11 +475,6 @@ public function testFilePirepApi(): void $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);*/ } /** diff --git a/tests/ImporterTest.php b/tests/ImporterTest.php index 8c598b712..ac6a5b652 100644 --- a/tests/ImporterTest.php +++ b/tests/ImporterTest.php @@ -17,6 +17,7 @@ use App\Services\ImportExport\AirportExporter; use App\Services\ImportExport\FlightExporter; use App\Services\ImportService; +use Illuminate\Validation\ValidationException; /** * Class ImporterTest @@ -358,11 +359,10 @@ public function testFlightExporter(): void /** * Try importing the aicraft in the airports. Should fail - * - * @expectedException \Illuminate\Validation\ValidationException */ public function testInvalidFileImport(): void { + $this->expectException(ValidationException::class); $file_path = base_path('tests/data/aircraft.csv'); $this->importSvc->importAirports($file_path); } diff --git a/tests/PIREPTest.php b/tests/PIREPTest.php index bdf90d1f0..771a1054e 100644 --- a/tests/PIREPTest.php +++ b/tests/PIREPTest.php @@ -95,6 +95,11 @@ public function testAddPirep() $this->get('/api/fleet/aircraft/'.$pirep->aircraft_id, [], $user) ->assertJson(['data' => ['airport_id' => $pirep->arr_airport_id]]); + // Try cancelling it + $uri = '/api/pireps/'.$pirep->id.'/cancel'; + $response = $this->put($uri, [], [], $user); + $response->assertStatus(400); + /** * Now go from ACCEPTED to REJECTED */ diff --git a/tests/UserTest.php b/tests/UserTest.php index 374f49f6c..c25c67ec6 100644 --- a/tests/UserTest.php +++ b/tests/UserTest.php @@ -1,5 +1,6 @@ expectException(UserPilotIdExists::class); $user1 = factory(App\Models\User::class)->create(['id' => 1]); $user2 = factory(App\Models\User::class)->create(['id' => 2]);