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
This commit is contained in:
parent
41baefbf4a
commit
aedb1f22b6
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use Modules\Installer\Services\ConfigService;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use App\Services\ImportService;
|
||||
|
||||
class ImportCsv extends Command
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
|
||||
class ImportFromClassic extends Command
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class TestApi extends Command
|
||||
|
@ -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;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use DB;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use App\Services\DatabaseService;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Cron;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use App\Events\CronHourly;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Cron;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use App\Events\CronMonthly;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Cron;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use App\Events\CronNightly;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Cron;
|
||||
|
||||
use App\Console\Command;
|
||||
use App\Contracts\Command;
|
||||
use App\Events\CronWeekly;
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
namespace App\Contracts;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\Process\Process;
|
||||
@ -10,6 +10,14 @@ use Symfony\Component\Process\Process;
|
||||
*/
|
||||
abstract class Command extends \Illuminate\Console\Command
|
||||
{
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function handle();
|
||||
|
||||
/**
|
||||
* Adjust the logging depending on where we're running from
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@ -20,11 +28,6 @@ abstract class Command extends \Illuminate\Console\Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function handle();
|
||||
|
||||
/**
|
||||
* Splice the logger and replace the active handlers with the handlers from the
|
||||
* a stack in config/logging.php
|
@ -7,6 +7,8 @@ namespace App\Contracts;
|
||||
*
|
||||
* @property mixed $id
|
||||
* @property bool $skip_mutator
|
||||
*
|
||||
* @method static where(array $array)
|
||||
*/
|
||||
abstract class Model extends \Illuminate\Database\Eloquent\Model
|
||||
{
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Enums\PirepState;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class PirepsChangeStateType extends Migration
|
||||
{
|
||||
/**
|
||||
* Change the PIREP state column to be a TINYINT
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
// Migrate the old rejected state
|
||||
DB::update('UPDATE `pireps` SET `state`='.PirepState::REJECTED
|
||||
.' WHERE state=-1');
|
||||
|
||||
// Change the column type to an unsigned small int (tinyint not supported on all)
|
||||
Schema::table('pireps', function (Blueprint $table) {
|
||||
$table->unsignedSmallInteger('state')->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
}
|
||||
}
|
40
app/Exceptions/PirepCancelNotAllowed.php
Normal file
40
app/Exceptions/PirepCancelNotAllowed.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use App\Models\Pirep;
|
||||
|
||||
class PirepCancelNotAllowed extends HttpException
|
||||
{
|
||||
private $pirep;
|
||||
|
||||
public function __construct(Pirep $pirep)
|
||||
{
|
||||
$this->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,
|
||||
];
|
||||
}
|
||||
}
|
@ -363,10 +363,8 @@ class PirepController extends Controller
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ Route::group(['middleware' => ['api.auth']], function () {
|
||||
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');
|
||||
|
23
app/Listeners/SetUserActive.php
Normal file
23
app/Listeners/SetUserActive.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Contracts\Listener;
|
||||
use App\Events\PirepFiled;
|
||||
use App\Events\UserStateChanged;
|
||||
use App\Models\Enums\UserState;
|
||||
|
||||
class SetUserActive extends Listener
|
||||
{
|
||||
public function handle(PirepFiled $event): void
|
||||
{
|
||||
// Check the user state, set them to ACTIVE if on leave
|
||||
if ($event->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));
|
||||
}
|
||||
}
|
||||
}
|
@ -10,14 +10,17 @@ use App\Models\Traits\FilesTrait;
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class AcarsType
|
||||
*/
|
||||
class AcarsType extends Enum
|
||||
{
|
||||
public const FLIGHT_PATH = 0;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class ActiveState
|
||||
*/
|
||||
class ActiveState extends Enum
|
||||
{
|
||||
public const INACTIVE = 0;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class AircraftState
|
||||
*/
|
||||
class AircraftState extends Enum
|
||||
{
|
||||
public const PARKED = 0;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class AircraftState
|
||||
*/
|
||||
class AircraftStatus extends Enum
|
||||
{
|
||||
public const ACTIVE = 'A';
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class AnalyticsDimensions
|
||||
*/
|
||||
class AnalyticsDimensions extends Enum
|
||||
{
|
||||
public const PHP_VERSION = 1;
|
||||
|
@ -5,7 +5,6 @@ namespace App\Models\Enums;
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class AnalyticsMetrics
|
||||
* Metrics IDs used in Google Analytics
|
||||
*/
|
||||
class AnalyticsMetrics extends Enum
|
||||
|
@ -5,7 +5,6 @@ namespace App\Models\Enums;
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class Days
|
||||
* Start on Monday - ISO8601
|
||||
*/
|
||||
class Days extends Enum
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class ExpenseType
|
||||
*/
|
||||
class ExpenseType extends Enum
|
||||
{
|
||||
public const FLIGHT = 'F';
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class FlightType
|
||||
*/
|
||||
class FlightType extends Enum
|
||||
{
|
||||
public const SCHED_PAX = 'J';
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class FuelType
|
||||
*/
|
||||
class FuelType extends Enum
|
||||
{
|
||||
public const LOW_LEAD = 0;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class JournalType
|
||||
*/
|
||||
class JournalType extends Enum
|
||||
{
|
||||
public const AIRLINE = 0;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class AcarsType
|
||||
*/
|
||||
class PirepFieldSource extends Enum
|
||||
{
|
||||
public const MANUAL = 0;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class PirepSource
|
||||
*/
|
||||
class PirepSource extends Enum
|
||||
{
|
||||
public const MANUAL = 0;
|
||||
|
@ -9,21 +9,21 @@ use App\Contracts\Enum;
|
||||
*/
|
||||
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',
|
||||
];
|
||||
}
|
||||
|
@ -4,9 +4,6 @@ namespace App\Models\Enums;
|
||||
|
||||
use App\Contracts\Enum;
|
||||
|
||||
/**
|
||||
* Class UserState
|
||||
*/
|
||||
class UserState extends Enum
|
||||
{
|
||||
public const PENDING = 0;
|
||||
|
@ -42,6 +42,7 @@ use Illuminate\Support\Collection;
|
||||
* @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
|
||||
*
|
||||
|
@ -11,6 +11,8 @@ use App\Models\Enums\PirepFieldSource;
|
||||
* @property string slug
|
||||
* @property string value
|
||||
* @property string source
|
||||
*
|
||||
* @method static updateOrCreate(array $array, array $array1)
|
||||
*/
|
||||
class PirepFieldValue extends Model
|
||||
{
|
||||
|
@ -10,6 +10,8 @@ use App\Contracts\Model;
|
||||
* @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
|
||||
{
|
||||
|
@ -32,6 +32,7 @@ use Laratrust\Traits\LaratrustUserTrait;
|
||||
* @property int rank_id
|
||||
* @property int state
|
||||
* @property bool opt_in
|
||||
* @property string last_pirep_id
|
||||
* @mixin \Illuminate\Notifications\Notifiable
|
||||
* @mixin \Laratrust\Traits\LaratrustUserTrait
|
||||
*/
|
||||
|
@ -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,
|
||||
],
|
||||
|
@ -15,9 +15,6 @@ use League\Geotools\Geotools;
|
||||
use PhpUnitsOfMeasure\Exception\NonNumericValue;
|
||||
use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
||||
|
||||
/**
|
||||
* Class AnalyticsService
|
||||
*/
|
||||
class AirportService extends Service
|
||||
{
|
||||
private $airportRepo;
|
||||
|
@ -4,14 +4,11 @@ namespace App\Services;
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
|
@ -4,11 +4,8 @@ namespace App\Services;
|
||||
|
||||
use App\Contracts\Service;
|
||||
use App\Support\ClassLoader;
|
||||
use Module;
|
||||
use Nwidart\Modules\Facades\Module;
|
||||
|
||||
/**
|
||||
* Class AwardService
|
||||
*/
|
||||
class AwardService extends Service
|
||||
{
|
||||
/**
|
||||
|
@ -7,9 +7,6 @@ use App\Support\Database;
|
||||
use Carbon\Carbon;
|
||||
use Webpatser\Uuid\Uuid;
|
||||
|
||||
/**
|
||||
* Class DatabaseService
|
||||
*/
|
||||
class DatabaseService extends Service
|
||||
{
|
||||
protected $time_fields = [
|
||||
|
@ -11,14 +11,11 @@ use App\Services\ImportExport\FareExporter;
|
||||
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
|
||||
{
|
||||
/**
|
||||
|
@ -11,9 +11,6 @@ use App\Models\Subfleet;
|
||||
use App\Support\Math;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class FareService
|
||||
*/
|
||||
class FareService extends Service
|
||||
{
|
||||
/**
|
||||
|
@ -15,9 +15,6 @@ use App\Repositories\NavdataRepository;
|
||||
use App\Support\Units\Time;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class FlightService
|
||||
*/
|
||||
class FlightService extends Service
|
||||
{
|
||||
private $airportSvc;
|
||||
|
@ -16,9 +16,6 @@ use Illuminate\Support\Facades\Log;
|
||||
use League\Geotools\Coordinate\Coordinate;
|
||||
use League\Geotools\Geotools;
|
||||
|
||||
/**
|
||||
* Class GeoService
|
||||
*/
|
||||
class GeoService extends Service
|
||||
{
|
||||
private $acarsRepo;
|
||||
|
@ -19,9 +19,6 @@ use Illuminate\Validation\ValidationException;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\Reader;
|
||||
|
||||
/**
|
||||
* Class ImportService
|
||||
*/
|
||||
class ImportService extends Service
|
||||
{
|
||||
protected $flightRepo;
|
||||
|
@ -4,9 +4,6 @@ namespace App\Services;
|
||||
|
||||
use App\Contracts\Service;
|
||||
|
||||
/**
|
||||
* Class ModuleService
|
||||
*/
|
||||
class ModuleService extends Service
|
||||
{
|
||||
protected static $adminLinks = [];
|
||||
|
@ -6,20 +6,19 @@ use App\Contracts\Service;
|
||||
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 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 @@ class PirepService extends Service
|
||||
// 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 @@ class PirepService extends Service
|
||||
// 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();
|
||||
|
||||
event(new UserStateChanged($pirep->user, $old_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
throw new PirepCancelNotAllowed($pirep);
|
||||
}
|
||||
|
||||
$pirep = $this->pirepRepo->update([
|
||||
'state' => PirepState::CANCELLED,
|
||||
'status' => PirepStatus::CANCELLED,
|
||||
], $pirep->id);
|
||||
|
||||
return $pirep;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -324,12 +342,12 @@ class PirepService extends Service
|
||||
}
|
||||
|
||||
$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 @@ class PirepService extends Service
|
||||
// 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 @@ class PirepService extends Service
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $pilot
|
||||
* @param Pirep $pirep
|
||||
*/
|
||||
public function setPilotState(User $pilot, Pirep $pirep)
|
||||
|
@ -21,9 +21,6 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* Class UserService
|
||||
*/
|
||||
class UserService extends Service
|
||||
{
|
||||
private $aircraftRepo;
|
||||
|
@ -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 @@ class AcarsTest extends TestCase
|
||||
$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 @@ class AcarsTest extends TestCase
|
||||
];
|
||||
|
||||
$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 @@ class AcarsTest extends TestCase
|
||||
$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);*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@ use App\Services\ImportExport\AircraftExporter;
|
||||
use App\Services\ImportExport\AirportExporter;
|
||||
use App\Services\ImportExport\FlightExporter;
|
||||
use App\Services\ImportService;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* Class ImporterTest
|
||||
@ -358,11 +359,10 @@ class ImporterTest extends TestCase
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
@ -95,6 +95,11 @@ class PIREPTest extends TestCase
|
||||
$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
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Exceptions\UserPilotIdExists;
|
||||
use App\Models\User;
|
||||
use App\Repositories\SettingRepository;
|
||||
use App\Services\UserService;
|
||||
@ -191,11 +192,10 @@ class UserTest extends TestCase
|
||||
|
||||
/**
|
||||
* Test the pilot ID being added when a new user is created
|
||||
*
|
||||
* @expectedException \App\Exceptions\UserPilotIdExists
|
||||
*/
|
||||
public function testUserPilotIdChangeAlreadyExists()
|
||||
{
|
||||
$this->expectException(UserPilotIdExists::class);
|
||||
$user1 = factory(App\Models\User::class)->create(['id' => 1]);
|
||||
$user2 = factory(App\Models\User::class)->create(['id' => 2]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user