diff --git a/app/Database/factories/PirepFactory.php b/app/Database/factories/PirepFactory.php index 6268e7d0..b4f8cfe5 100644 --- a/app/Database/factories/PirepFactory.php +++ b/app/Database/factories/PirepFactory.php @@ -1,5 +1,8 @@ define(App\Models\Pirep::class, function (Faker $faker) { + $airline = factory(App\Models\Airline::class)->create(); + $flight = factory(App\Models\Flight::class)->create([ + 'airline_id' => $airline->id, + ]); + return [ 'id' => $faker->unique()->numberBetween(10, 10000000), - 'airline_id' => function () { - return factory(App\Models\Airline::class)->create()->id; + 'airline_id' => function () use ($airline) { + return $airline->id; }, 'user_id' => function () { return factory(App\Models\User::class)->create()->id; @@ -18,18 +26,19 @@ $factory->define(App\Models\Pirep::class, function (Faker $faker) { 'aircraft_id' => function () { return factory(App\Models\Aircraft::class)->create()->id; }, - 'flight_number' => function (array $pirep) { - return factory(App\Models\Flight::class)->create([ - 'airline_id' => $pirep['airline_id'], - ])->flight_number; + 'flight_id' => function () use ($flight) { + return $flight->id; + }, + 'flight_number' => function () use ($flight) { + return $flight->flight_number; }, 'route_code' => null, 'route_leg' => null, - 'dpt_airport_id' => function () { - return factory(App\Models\Airport::class)->create()->id; + 'dpt_airport_id' => function () use ($flight) { + return $flight->dpt_airport_id; }, - 'arr_airport_id' => function () { - return factory(App\Models\Airport::class)->create()->id; + 'arr_airport_id' => function () use ($flight) { + return $flight->arr_airport_id; }, 'level' => $faker->numberBetween(20, 400), 'distance' => $faker->randomFloat(2, 0, 6000), @@ -48,7 +57,7 @@ $factory->define(App\Models\Pirep::class, function (Faker $faker) { 'route' => $faker->text(200), 'notes' => $faker->text(200), 'source' => $faker->randomElement([PirepSource::MANUAL, PirepSource::ACARS]), - 'source_name' => 'Test Factory', + 'source_name' => 'TestFactory', 'state' => PirepState::PENDING, 'status' => PirepStatus::SCHEDULED, 'submitted_at' => Carbon::now('UTC')->toDateTimeString(), diff --git a/app/Database/migrations/2017_06_17_214650_create_flight_tables.php b/app/Database/migrations/2017_06_17_214650_create_flight_tables.php index b249bdd9..bde9c08d 100644 --- a/app/Database/migrations/2017_06_17_214650_create_flight_tables.php +++ b/app/Database/migrations/2017_06_17_214650_create_flight_tables.php @@ -1,6 +1,7 @@ string('id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('id', Model::ID_MAX_LENGTH); $table->unsignedInteger('airline_id'); $table->unsignedInteger('flight_number'); $table->string('route_code', 5)->nullable(); @@ -47,7 +48,7 @@ class CreateFlightTables extends Migration }); Schema::create('flight_fare', function (Blueprint $table) { - $table->string('flight_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('flight_id', Model::ID_MAX_LENGTH); $table->unsignedInteger('fare_id'); $table->string('price', 10)->nullable(); $table->string('cost', 10)->nullable(); @@ -71,7 +72,7 @@ class CreateFlightTables extends Migration */ Schema::create('flight_field_values', function (Blueprint $table) { $table->bigIncrements('id'); - $table->string('flight_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('flight_id', Model::ID_MAX_LENGTH); $table->string('name', 50); $table->string('slug', 50)->nullable(); $table->text('value'); @@ -83,7 +84,7 @@ class CreateFlightTables extends Migration Schema::create('flight_subfleet', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('subfleet_id'); - $table->string('flight_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('flight_id', Model::ID_MAX_LENGTH); $table->index(['subfleet_id', 'flight_id']); $table->index(['flight_id', 'subfleet_id']); diff --git a/app/Database/migrations/2017_06_28_195426_create_pirep_tables.php b/app/Database/migrations/2017_06_28_195426_create_pirep_tables.php index 5041485a..00c2c818 100644 --- a/app/Database/migrations/2017_06_28_195426_create_pirep_tables.php +++ b/app/Database/migrations/2017_06_28_195426_create_pirep_tables.php @@ -1,6 +1,7 @@ string('id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('id', Model::ID_MAX_LENGTH); $table->unsignedInteger('user_id'); $table->unsignedInteger('airline_id'); $table->unsignedInteger('aircraft_id')->nullable(); @@ -57,7 +58,7 @@ class CreatePirepTables extends Migration Schema::create('pirep_comments', function (Blueprint $table) { $table->bigIncrements('id'); - $table->string('pirep_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('pirep_id', Model::ID_MAX_LENGTH); $table->unsignedInteger('user_id'); $table->text('comment'); $table->timestamps(); @@ -65,7 +66,7 @@ class CreatePirepTables extends Migration Schema::create('pirep_fares', function (Blueprint $table) { $table->bigIncrements('id'); - $table->string('pirep_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('pirep_id', Model::ID_MAX_LENGTH); $table->unsignedInteger('fare_id'); $table->unsignedInteger('count')->nullable()->default(0); @@ -81,7 +82,7 @@ class CreatePirepTables extends Migration Schema::create('pirep_field_values', function (Blueprint $table) { $table->bigIncrements('id'); - $table->string('pirep_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('pirep_id', Model::ID_MAX_LENGTH); $table->string('name', 50); $table->string('slug', 50)->nullable(); $table->string('value')->nullable(); diff --git a/app/Database/migrations/2017_12_12_174519_create_bids_table.php b/app/Database/migrations/2017_12_12_174519_create_bids_table.php index 5682ac60..adc321de 100644 --- a/app/Database/migrations/2017_12_12_174519_create_bids_table.php +++ b/app/Database/migrations/2017_12_12_174519_create_bids_table.php @@ -1,6 +1,7 @@ increments('id'); $table->unsignedInteger('user_id'); - $table->string('flight_id', \App\Contracts\Model::ID_MAX_LENGTH); + $table->string('flight_id', Model::ID_MAX_LENGTH); $table->timestamps(); $table->index('user_id'); diff --git a/app/Database/migrations/2019_10_30_141152_pireps_add_flight_id.php b/app/Database/migrations/2019_10_30_141152_pireps_add_flight_id.php new file mode 100644 index 00000000..ca8be667 --- /dev/null +++ b/app/Database/migrations/2019_10_30_141152_pireps_add_flight_id.php @@ -0,0 +1,31 @@ +string('flight_id', Model::ID_MAX_LENGTH)->nullable()->after('aircraft_id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('pireps', function (Blueprint $table) { + $table->dropColumn('flight_id'); + }); + } +} diff --git a/app/Exceptions/UserBidLimit.php b/app/Exceptions/UserBidLimit.php new file mode 100644 index 00000000..22b82809 --- /dev/null +++ b/app/Exceptions/UserBidLimit.php @@ -0,0 +1,45 @@ +user = $user; + parent::__construct( + 409, + 'User '.$user->ident.' has the maximum number of bids' + ); + } + + /** + * Return the RFC 7807 error type (without the URL root) + */ + public function getErrorType(): string + { + return 'user-bid-limit'; + } + + /** + * Get the detailed error string + */ + public function getErrorDetails(): string + { + return $this->getMessage(); + } + + /** + * Return an array with the error details, merged with the RFC7807 response + */ + public function getErrorMetadata(): array + { + return [ + 'user_id' => $this->user->id, + ]; + } +} diff --git a/app/Http/Controllers/Api/FlightController.php b/app/Http/Controllers/Api/FlightController.php index 8ef5a922..12f21557 100644 --- a/app/Http/Controllers/Api/FlightController.php +++ b/app/Http/Controllers/Api/FlightController.php @@ -8,8 +8,8 @@ use App\Http\Resources\Navdata as NavdataResource; use App\Repositories\Criteria\WhereCriteria; use App\Repositories\FlightRepository; use App\Services\FlightService; -use Auth; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; use Prettus\Repository\Criteria\RequestCriteria; use Prettus\Repository\Exceptions\RepositoryException; @@ -44,6 +44,9 @@ class FlightController extends Controller */ public function index(Request $request) { + /** + * @var $user \App\Models\User + */ $user = Auth::user(); $where = [ @@ -52,7 +55,7 @@ class FlightController extends Controller ]; if (setting('pilots.restrict_to_company')) { - $where['airline_id'] = Auth::user()->airline_id; + $where['airline_id'] = $user->airline_id; } if (setting('pilots.only_flights_from_current', false)) { $where['dpt_airport_id'] = $user->curr_airport_id; diff --git a/app/Http/Controllers/Api/PirepController.php b/app/Http/Controllers/Api/PirepController.php index 445b1f1c..9571f214 100644 --- a/app/Http/Controllers/Api/PirepController.php +++ b/app/Http/Controllers/Api/PirepController.php @@ -20,6 +20,7 @@ use App\Http\Resources\PirepComment as PirepCommentResource; use App\Http\Resources\PirepFieldCollection; use App\Models\Acars; use App\Models\Enums\AcarsType; +use App\Models\Enums\FlightType; use App\Models\Enums\PirepFieldSource; use App\Models\Enums\PirepSource; use App\Models\Enums\PirepState; @@ -93,6 +94,10 @@ class PirepController extends Controller $attrs['created_at'] = Carbon::createFromTimeString($attrs['created_at']); } + if (array_key_exists('updated_at', $attrs)) { + $attrs['updated_at'] = Carbon::createFromTimeString($attrs['updated_at']); + } + return $attrs; } @@ -186,6 +191,9 @@ class PirepController extends Controller { Log::info('PIREP Prefile, user '.Auth::id(), $request->post()); + /** + * @var $user \App\Models\User + */ $user = Auth::user(); $attrs = $this->parsePirep($request); @@ -228,7 +236,7 @@ class PirepController extends Controller // Default to a scheduled passenger flight if (!array_key_exists('flight_type', $attrs)) { - $attrs['flight_type'] = 'J'; + $attrs['flight_type'] = FlightType::SCHED_PAX; } $pirep->save(); diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 491e7d37..092399a0 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -13,18 +13,17 @@ use App\Repositories\Criteria\WhereCriteria; use App\Repositories\FlightRepository; use App\Repositories\PirepRepository; use App\Repositories\UserRepository; +use App\Services\BidService; use App\Services\FlightService; use App\Services\UserService; -use Auth; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; use Prettus\Repository\Criteria\RequestCriteria; use Prettus\Repository\Exceptions\RepositoryException; -/** - * Class UserController - */ class UserController extends Controller { + private $bidSvc; private $flightRepo; private $flightSvc; private $pirepRepo; @@ -32,8 +31,7 @@ class UserController extends Controller private $userSvc; /** - * UserController constructor. - * + * @param BidService $bidSvc * @param FlightRepository $flightRepo * @param FlightService $flightSvc * @param PirepRepository $pirepRepo @@ -41,12 +39,14 @@ class UserController extends Controller * @param UserService $userSvc */ public function __construct( + BidService $bidSvc, FlightRepository $flightRepo, FlightService $flightSvc, PirepRepository $pirepRepo, UserRepository $userRepo, UserService $userSvc ) { + $this->bidSvc = $bidSvc; $this->flightRepo = $flightRepo; $this->flightSvc = $flightSvc; $this->pirepRepo = $pirepRepo; @@ -61,11 +61,11 @@ class UserController extends Controller */ protected function getUserId(Request $request) { - if ($request->id === null) { + if ($request->get('id') === null) { return Auth::user()->id; } - return $request->id; + return $request->get('id'); } /** @@ -110,7 +110,7 @@ class UserController extends Controller if ($request->isMethod('PUT') || $request->isMethod('POST')) { $flight_id = $request->input('flight_id'); $flight = $this->flightRepo->find($flight_id); - $bid = $this->flightSvc->addBid($flight, $user); + $bid = $this->bidSvc->addBid($flight, $user); return new BidResource($bid); } @@ -124,11 +124,11 @@ class UserController extends Controller } $flight = $this->flightRepo->find($flight_id); - $this->flightSvc->removeBid($flight, $user); + $this->bidSvc->removeBid($flight, $user); } // Return the flights they currently have bids on - $bids = Bid::where(['user_id' => $user->id])->get(); + $bids = $this->bidSvc->findBidsForUser($user); return BidResource::collection($bids); } diff --git a/app/Http/Controllers/Frontend/PirepController.php b/app/Http/Controllers/Frontend/PirepController.php index 0ebfde17..2ab1113e 100644 --- a/app/Http/Controllers/Frontend/PirepController.php +++ b/app/Http/Controllers/Frontend/PirepController.php @@ -14,6 +14,7 @@ use App\Repositories\AircraftRepository; use App\Repositories\AirlineRepository; use App\Repositories\AirportRepository; use App\Repositories\Criteria\WhereCriteria; +use App\Repositories\FlightRepository; use App\Repositories\PirepFieldRepository; use App\Repositories\PirepRepository; use App\Services\FareService; @@ -35,6 +36,7 @@ class PirepController extends Controller private $aircraftRepo; private $airlineRepo; private $fareSvc; + private $flightRepo; private $geoSvc; private $pirepRepo; private $airportRepo; @@ -43,12 +45,11 @@ class PirepController extends Controller private $userSvc; /** - * PirepController constructor. - * * @param AircraftRepository $aircraftRepo * @param AirlineRepository $airlineRepo * @param AirportRepository $airportRepo * @param FareService $fareSvc + * @param FlightRepository $flightRepo * @param GeoService $geoSvc * @param PirepRepository $pirepRepo * @param PirepFieldRepository $pirepFieldRepo @@ -60,6 +61,7 @@ class PirepController extends Controller AirlineRepository $airlineRepo, AirportRepository $airportRepo, FareService $fareSvc, + FlightRepository $flightRepo, GeoService $geoSvc, PirepRepository $pirepRepo, PirepFieldRepository $pirepFieldRepo, @@ -73,6 +75,7 @@ class PirepController extends Controller $this->pirepFieldRepo = $pirepFieldRepo; $this->fareSvc = $fareSvc; + $this->flightRepo = $flightRepo; $this->geoSvc = $geoSvc; $this->pirepSvc = $pirepSvc; $this->userSvc = $userSvc; @@ -231,12 +234,24 @@ class PirepController extends Controller /** * Create a new flight report * + * @param \Illuminate\Http\Request $request + * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ - public function create() + public function create(Request $request) { + $pirep = null; + + // See if request has a ?flight_id, so we can pre-populate the fields from the flight + // Makes filing easier, but we can also more easily find a bid and close it + if ($request->has('flight_id')) { + $flight = $this->flightRepo->find($request->get('flight_id')); + $pirep = Pirep::fromFlight($flight); + } + return view('pireps.create', [ 'aircraft' => null, + 'pirep' => $pirep, 'read_only' => false, 'airline_list' => $this->airlineRepo->selectBoxList(true), 'aircraft_list' => $this->aircraftList(true), diff --git a/app/Http/Requests/Acars/CommentRequest.php b/app/Http/Requests/Acars/CommentRequest.php index c8052b7b..380ad66c 100644 --- a/app/Http/Requests/Acars/CommentRequest.php +++ b/app/Http/Requests/Acars/CommentRequest.php @@ -4,9 +4,6 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; -/** - * Class CommentRequest - */ class CommentRequest extends FormRequest { public function rules(): array diff --git a/app/Http/Requests/Acars/EventRequest.php b/app/Http/Requests/Acars/EventRequest.php index da747e45..3d49e9b6 100644 --- a/app/Http/Requests/Acars/EventRequest.php +++ b/app/Http/Requests/Acars/EventRequest.php @@ -4,25 +4,17 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; use App\Models\Pirep; -use Auth; +use Illuminate\Support\Facades\Auth; -/** - * Class EventRequest - */ class EventRequest extends FormRequest { - /** - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException - * - * @return bool - */ - public function authorize() + public function authorize(): bool { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); return $pirep->user_id === Auth::id(); } - public function rules() + public function rules(): array { $rules = [ 'events' => 'required|array', diff --git a/app/Http/Requests/Acars/FieldsRequest.php b/app/Http/Requests/Acars/FieldsRequest.php index f5045bf2..76d0a935 100644 --- a/app/Http/Requests/Acars/FieldsRequest.php +++ b/app/Http/Requests/Acars/FieldsRequest.php @@ -9,10 +9,7 @@ use App\Contracts\FormRequest; */ class FieldsRequest extends FormRequest { - /** - * @return array - */ - public function rules() + public function rules(): array { return [ 'fields' => 'required|array', diff --git a/app/Http/Requests/Acars/FileRequest.php b/app/Http/Requests/Acars/FileRequest.php index 1c7a54f0..725961b5 100644 --- a/app/Http/Requests/Acars/FileRequest.php +++ b/app/Http/Requests/Acars/FileRequest.php @@ -4,26 +4,22 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; use App\Models\Pirep; -use Auth; +use Illuminate\Support\Facades\Auth; -/** - * Class FileRequest - */ class FileRequest extends FormRequest { - public function authorize() + public function authorize(): bool { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); return $pirep->user_id === Auth::id(); } - public function rules() + public function rules(): array { $rules = [ - 'distance' => 'required|numeric', - 'flight_time' => 'required|integer', - 'fuel_used' => 'required|numeric', - + 'distance' => 'required|numeric', + 'flight_time' => 'required|integer', + 'fuel_used' => 'required|numeric', 'block_time' => 'nullable|integer', 'airline_id' => 'nullable|exists:airlines,id', 'aircraft_id' => 'nullable|exists:aircraft,id', diff --git a/app/Http/Requests/Acars/LogRequest.php b/app/Http/Requests/Acars/LogRequest.php index a0ddaf4e..bc179cf5 100644 --- a/app/Http/Requests/Acars/LogRequest.php +++ b/app/Http/Requests/Acars/LogRequest.php @@ -4,20 +4,17 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; use App\Models\Pirep; -use Auth; +use Illuminate\Support\Facades\Auth; -/** - * Class LogRequest - */ class LogRequest extends FormRequest { - public function authorize() + public function authorize(): bool { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); return $pirep->user_id === Auth::id(); } - public function rules() + public function rules(): array { $rules = [ 'logs' => 'required|array', diff --git a/app/Http/Requests/Acars/PositionRequest.php b/app/Http/Requests/Acars/PositionRequest.php index f46e2836..977371ac 100644 --- a/app/Http/Requests/Acars/PositionRequest.php +++ b/app/Http/Requests/Acars/PositionRequest.php @@ -4,36 +4,20 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; use App\Models\Pirep; -use Auth; +use Illuminate\Support\Facades\Auth; -/** - * Class PositionRequest - */ class PositionRequest extends FormRequest { /** - * @return bool + * Is the user allowed to do this? */ - public function authorize() + public function authorize(): bool { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); return $pirep->user_id === Auth::id(); } - /** - * @return array - */ - /*public function sanitize() - { - return [ - 'positions.*.sim_time' => Acars::$sanitize['sim_time'], - ]; - }*/ - - /** - * @return array - */ - public function rules() + public function rules(): array { $rules = [ 'positions' => 'required|array', diff --git a/app/Http/Requests/Acars/PrefileRequest.php b/app/Http/Requests/Acars/PrefileRequest.php index 9c2c81de..fae3aa5f 100644 --- a/app/Http/Requests/Acars/PrefileRequest.php +++ b/app/Http/Requests/Acars/PrefileRequest.php @@ -4,32 +4,18 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; -/** - * Class PrefileRequest - */ class PrefileRequest extends FormRequest { - /** - * @return array|void - */ - /*public function sanitize() - { - return Pirep::$sanitize; - }*/ - - /** - * @return array - */ - public function rules() + public function rules(): array { $rules = [ - 'airline_id' => 'required|exists:airlines,id', - 'aircraft_id' => 'required|exists:aircraft,id', - 'flight_number' => 'required', - 'dpt_airport_id' => 'required', - 'arr_airport_id' => 'required', - 'source_name' => 'required', - + 'airline_id' => 'required|exists:airlines,id', + 'aircraft_id' => 'required|exists:aircraft,id', + 'flight_number' => 'required', + 'dpt_airport_id' => 'required', + 'arr_airport_id' => 'required', + 'flight_id' => 'nullable', + 'source_name' => 'required', 'alt_airport_id' => 'nullable', 'status' => 'nullable', 'level' => 'nullable|numeric', diff --git a/app/Http/Requests/Acars/RouteRequest.php b/app/Http/Requests/Acars/RouteRequest.php index 7195a947..84a7439c 100644 --- a/app/Http/Requests/Acars/RouteRequest.php +++ b/app/Http/Requests/Acars/RouteRequest.php @@ -4,20 +4,17 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; use App\Models\Pirep; -use Auth; +use Illuminate\Support\Facades\Auth; -/** - * Class RouteRequest - */ class RouteRequest extends FormRequest { - public function authorize() + public function authorize(): bool { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); return $pirep->user_id === Auth::id(); } - public function rules() + public function rules(): array { $rules = [ 'route' => 'required|array', diff --git a/app/Http/Requests/Acars/UpdateRequest.php b/app/Http/Requests/Acars/UpdateRequest.php index 320ecab7..67d4c87d 100644 --- a/app/Http/Requests/Acars/UpdateRequest.php +++ b/app/Http/Requests/Acars/UpdateRequest.php @@ -4,20 +4,17 @@ namespace App\Http\Requests\Acars; use App\Contracts\FormRequest; use App\Models\Pirep; -use Auth; +use Illuminate\Support\Facades\Auth; -/** - * Class UpdateRequest - */ class UpdateRequest extends FormRequest { - public function authorize() + public function authorize(): bool { $pirep = Pirep::findOrFail($this->route('pirep_id'), ['user_id']); return $pirep->user_id === Auth::id(); } - public function rules() + public function rules(): array { $rules = [ 'airline_id' => 'nullable|exists:airlines,id', diff --git a/app/Listeners/BidEvents.php b/app/Listeners/BidEvents.php index 9e208f3e..2aed462d 100644 --- a/app/Listeners/BidEvents.php +++ b/app/Listeners/BidEvents.php @@ -4,7 +4,7 @@ namespace App\Listeners; use App\Contracts\Listener; use App\Events\PirepAccepted; -use App\Services\PirepService; +use App\Services\BidService; use Illuminate\Contracts\Events\Dispatcher; /** @@ -12,17 +12,11 @@ use Illuminate\Contracts\Events\Dispatcher; */ class BidEvents extends Listener { - private $pirepSvc; + private $bidSvc; - /** - * FinanceEvents constructor. - * - * @param PirepService $pirepSvc - */ - public function __construct( - PirepService $pirepSvc - ) { - $this->pirepSvc = $pirepSvc; + public function __construct(BidService $bidSvc) + { + $this->bidSvc = $bidSvc; } /** @@ -44,10 +38,9 @@ class BidEvents extends Listener * @throws \UnexpectedValueException * @throws \InvalidArgumentException * @throws \Exception - * @throws \Prettus\Validator\Exceptions\ValidatorException */ public function onPirepAccept(PirepAccepted $event): void { - $this->pirepSvc->removeBid($event->pirep); + $this->bidSvc->removeBidForPirep($event->pirep); } } diff --git a/app/Models/Flight.php b/app/Models/Flight.php index b3c22230..13457a65 100644 --- a/app/Models/Flight.php +++ b/app/Models/Flight.php @@ -22,7 +22,10 @@ use Illuminate\Support\Collection; * @property Collection fares * @property Collection subfleets * @property int days + * @property int distance + * @property int flight_time * @property string route + * @property int level * @property Airport dpt_airport * @property Airport arr_airport * @property Airport alt_airport diff --git a/app/Models/Pirep.php b/app/Models/Pirep.php index f3de2467..f19221b5 100644 --- a/app/Models/Pirep.php +++ b/app/Models/Pirep.php @@ -150,6 +150,28 @@ class Pirep extends Model PirepState::DELETED, ]; + /** + * Create a new PIREP model from a given flight. Pre-populates the fields + * + * @param \App\Models\Flight $flight + * + * @return \App\Models\Pirep + */ + public static function fromFlight(Flight $flight) + { + return new self([ + 'flight_id' => $flight->id, + 'airline_id' => $flight->airline_id, + 'flight_number' => $flight->flight_number, + 'route_code' => $flight->route_code, + 'route_leg' => $flight->route_leg, + 'dpt_airport_id' => $flight->dpt_airport_id, + 'arr_airport_id' => $flight->arr_airport_id, + 'route' => $flight->route, + 'level' => $flight->level, + ]); + } + /** * Get the flight ident, e.,g JBU1900 * @@ -277,10 +299,16 @@ class Pirep extends Model /** * Look up the flight, based on the PIREP flight info * + * @param mixed $value + * * @return Flight|null */ - public function getFlightAttribute(): ?Flight + /*public function getFlightAttribute(): ?Flight { + if (!empty($this->flight_id)) { + return Flight::find($this->flight_id); + } + $where = [ 'airline_id' => $this->airline_id, 'flight_number' => $this->flight_number, @@ -296,7 +324,7 @@ class Pirep extends Model } return Flight::where($where)->first(); - } + }*/ /** * Set the amount of fuel used @@ -412,6 +440,11 @@ class Pirep extends Model return $this->belongsTo(Airline::class, 'airline_id'); } + public function flight() + { + return $this->belongsTo(Flight::class, 'flight_id'); + } + public function arr_airport() { return $this->belongsTo(Airport::class, 'arr_airport_id'); diff --git a/app/Models/User.php b/app/Models/User.php index 0aeef63b..69a1f67d 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -12,6 +12,7 @@ use Laratrust\Traits\LaratrustUserTrait; /** * @property int id * @property int pilot_id + * @property int airline_id * @property string name * @property string email * @property string password diff --git a/app/Services/BidService.php b/app/Services/BidService.php new file mode 100644 index 00000000..9e3e5ef6 --- /dev/null +++ b/app/Services/BidService.php @@ -0,0 +1,145 @@ + $user->id])->get(); + return $bids; + } + + /** + * Allow a user to bid on a flight. Check settings and all that good stuff + * + * @param Flight $flight + * @param User $user + * + * @throws \App\Exceptions\BidExistsForFlight + * + * @return mixed + */ + public function addBid(Flight $flight, User $user) + { + // Get all of the bids for this user. See if they're allowed to have multiple + // bids + $bid_count = Bid::where(['user_id' => $user->id])->count(); + if ($bid_count > 0 && setting('bids.allow_multiple_bids') === false) { + throw new UserBidLimit($user); + } + + // Get all of the bids for this flight + $bids = Bid::where(['flight_id' => $flight->id])->get(); + if ($bids->count() > 0) { + // Does the flight have a bid set? + if ($flight->has_bid === false) { + $flight->has_bid = true; + $flight->save(); + } + + // Check all the bids for one of this user + foreach ($bids as $bid) { + if ($bid->user_id === $user->id) { + Log::info('Bid exists, user='.$user->ident.', flight='.$flight->id); + + return $bid; + } + } + + // Check if the flight should be blocked off + if (setting('bids.disable_flight_on_bid') === true) { + throw new BidExistsForFlight($flight); + } + + if (setting('bids.allow_multiple_bids') === false) { + throw new BidExistsForFlight($flight); + } + } else { + /* @noinspection NestedPositiveIfStatementsInspection */ + if ($flight->has_bid === true) { + Log::info('Bid exists, flight='.$flight->id.'; no entry in bids table, cleaning up'); + } + } + + $bid = Bid::firstOrCreate([ + 'user_id' => $user->id, + 'flight_id' => $flight->id, + ]); + + $flight->has_bid = true; + $flight->save(); + + return $bid; + } + + /** + * Remove a bid from a given flight + * + * @param Flight $flight + * @param User $user + */ + public function removeBid(Flight $flight, User $user) + { + $bids = Bid::where([ + 'flight_id' => $flight->id, + 'user_id' => $user->id, + ])->get(); + + foreach ($bids as $bid) { + $bid->forceDelete(); + } + + // Only flip the flag if there are no bids left for this flight + $bid_count = Bid::where(['flight_id' => $flight->id])->count(); + if ($bid_count === 0) { + $flight->has_bid = false; + $flight->save(); + } + } + + /** + * If the setting is enabled, remove the bid + * + * @param Pirep $pirep + * + * @throws \Exception + */ + public function removeBidForPirep(Pirep $pirep) + { + if (!setting('pireps.remove_bid_on_accept')) { + return; + } + + $flight = $pirep->flight; + if (!$flight) { + return; + } + + $bid = Bid::where([ + 'user_id' => $pirep->user->id, + 'flight_id' => $flight->id, + ]); + + if ($bid) { + Log::info('Bid for user: '.$pirep->user->ident.' on flight '.$flight->ident); + $bid->delete(); + } + } +} diff --git a/app/Services/FlightService.php b/app/Services/FlightService.php index d30cbc2f..14786a3f 100644 --- a/app/Services/FlightService.php +++ b/app/Services/FlightService.php @@ -3,17 +3,14 @@ namespace App\Services; use App\Contracts\Service; -use App\Exceptions\BidExistsForFlight; use App\Exceptions\DuplicateFlight; use App\Models\Bid; use App\Models\Enums\Days; use App\Models\Flight; use App\Models\FlightFieldValue; -use App\Models\User; use App\Repositories\FlightRepository; use App\Repositories\NavdataRepository; use App\Support\Units\Time; -use Illuminate\Support\Facades\Log; class FlightService extends Service { @@ -123,24 +120,6 @@ class FlightService extends Service return $fields; } - /** - * Filter out any flights according to different settings - * - * @param $user - * - * @return FlightRepository - */ - public function filterFlights($user) - { - $where = []; - if (setting('pilots.only_flights_from_current', false)) { - $where['dpt_airport_id'] = $user->curr_airport_id; - } - - return $this->flightRepo - ->whereOrder($where, 'flight_number', 'asc'); - } - /** * Filter out subfleets to only include aircraft that a user has access to * @@ -276,91 +255,4 @@ class FlightService extends Service return collect($return_points); } - - /** - * Allow a user to bid on a flight. Check settings and all that good stuff - * - * @param Flight $flight - * @param User $user - * - *@throws \App\Exceptions\BidExistsForFlight - * - * @return mixed - */ - public function addBid(Flight $flight, User $user) - { - // Get all of the bids for this user. See if they're allowed to have multiple - // bids - $bids = Bid::where('user_id', $user->id)->get(); - if ($bids->count() > 0 && setting('bids.allow_multiple_bids') === false) { - throw new BidExistsForFlight('User "'.$user->ident.'" already has bids, skipping'); - } - - // Get all of the bids for this flight - $bids = Bid::where('flight_id', $flight->id)->get(); - if ($bids->count() > 0) { - // Does the flight have a bid set? - if ($flight->has_bid === false) { - $flight->has_bid = true; - $flight->save(); - } - - // Check all the bids for one of this user - foreach ($bids as $bid) { - if ($bid->user_id === $user->id) { - Log::info('Bid exists, user='.$user->ident.', flight='.$flight->id); - return $bid; - } - } - - // Check if the flight should be blocked off - if (setting('bids.disable_flight_on_bid') === true) { - throw new BidExistsForFlight($flight); - } - - if (setting('bids.allow_multiple_bids') === false) { - throw new BidExistsForFlight($flight); - } - } else { - /* @noinspection NestedPositiveIfStatementsInspection */ - if ($flight->has_bid === true) { - Log::info('Bid exists, flight='.$flight->id.'; no entry in bids table, cleaning up'); - } - } - - $bid = Bid::firstOrCreate([ - 'user_id' => $user->id, - 'flight_id' => $flight->id, - ]); - - $flight->has_bid = true; - $flight->save(); - - return $bid; - } - - /** - * Remove a bid from a given flight - * - * @param Flight $flight - * @param User $user - */ - public function removeBid(Flight $flight, User $user) - { - $bids = Bid::where([ - 'flight_id' => $flight->id, - 'user_id' => $user->id, - ])->get(); - - foreach ($bids as $bid) { - $bid->forceDelete(); - } - - // Only flip the flag if there are no bids left for this flight - $bids = Bid::where('flight_id', $flight->id)->get(); - if ($bids->count() === 0) { - $flight->has_bid = false; - $flight->save(); - } - } } diff --git a/app/Services/PirepService.php b/app/Services/PirepService.php index 1a41b78c..0602087c 100644 --- a/app/Services/PirepService.php +++ b/app/Services/PirepService.php @@ -9,7 +9,6 @@ use App\Events\PirepRejected; use App\Events\UserStatsChanged; use App\Exceptions\PirepCancelNotAllowed; use App\Models\Acars; -use App\Models\Bid; use App\Models\Enums\AcarsType; use App\Models\Enums\PirepSource; use App\Models\Enums\PirepState; @@ -20,12 +19,10 @@ use App\Models\PirepFieldValue; use App\Models\User; use App\Repositories\PirepRepository; use Carbon\Carbon; +use function count; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Support\Facades\Log; -/** - * Class PirepService - */ class PirepService extends Service { private $geoSvc; @@ -33,8 +30,6 @@ class PirepService extends Service private $pirepRepo; /** - * PirepService constructor. - * * @param GeoService $geoSvc * @param PirepRepository $pirepRepo * @param UserService $pilotSvc @@ -49,6 +44,60 @@ class PirepService extends Service $this->pirepRepo = $pirepRepo; } + /** + * Create a new PIREP with some given fields + * + * @param Pirep $pirep + * @param array PirepFieldValue[] $field_values + * + * @return Pirep + */ + public function create(Pirep $pirep, array $field_values = []): Pirep + { + if (empty($field_values)) { + $field_values = []; + } + + // Check the block times. If a block on (arrival) time isn't + // specified, then use the time that it was submitted. It won't + // be the most accurate, but that might be OK + if (!$pirep->block_on_time) { + if ($pirep->submitted_at) { + $pirep->block_on_time = $pirep->submitted_at; + } else { + $pirep->block_on_time = Carbon::now('UTC'); + } + } + + // If the depart time isn't set, then try to calculate it by + // subtracting the flight time from the block_on (arrival) time + if (!$pirep->block_off_time && $pirep->flight_time > 0) { + $pirep->block_off_time = $pirep->block_on_time->subMinutes($pirep->flight_time); + } + + // Check that there's a submit time + if (!$pirep->submitted_at) { + $pirep->submitted_at = Carbon::now('UTC'); + } + + $pirep->status = PirepStatus::ARRIVED; + + // Copy some fields over from Flight if we have it + if ($pirep->flight) { + $pirep->planned_distance = $pirep->flight->distance; + $pirep->planned_flight_time = $pirep->flight->flight_time; + } + + $pirep->save(); + $pirep->refresh(); + + if (count($field_values) > 0) { + $this->updateCustomFields($pirep->id, $field_values); + } + + return $pirep; + } + /** * Find if there are duplicates to a given PIREP. Ideally, the passed * in PIREP hasn't been saved or gone through the create() method @@ -149,54 +198,6 @@ class PirepService extends Service return $pirep; } - /** - * Create a new PIREP with some given fields - * - * @param Pirep $pirep - * @param array PirepFieldValue[] $field_values - * - * @return Pirep - */ - public function create(Pirep $pirep, array $field_values = []): Pirep - { - if (empty($field_values)) { - $field_values = []; - } - - // Check the block times. If a block on (arrival) time isn't - // specified, then use the time that it was submitted. It won't - // be the most accurate, but that might be OK - if (!$pirep->block_on_time) { - if ($pirep->submitted_at) { - $pirep->block_on_time = $pirep->submitted_at; - } else { - $pirep->block_on_time = Carbon::now('UTC'); - } - } - - // If the depart time isn't set, then try to calculate it by - // subtracting the flight time from the block_on (arrival) time - if (!$pirep->block_off_time && $pirep->flight_time > 0) { - $pirep->block_off_time = $pirep->block_on_time->subMinutes($pirep->flight_time); - } - - // Check that there's a submit time - if (!$pirep->submitted_at) { - $pirep->submitted_at = Carbon::now('UTC'); - } - - $pirep->status = PirepStatus::ARRIVED; - - $pirep->save(); - $pirep->refresh(); - - if (\count($field_values) > 0) { - $this->updateCustomFields($pirep->id, $field_values); - } - - return $pirep; - } - /** * Submit the PIREP. Figure out its default state * @@ -421,33 +422,4 @@ class PirepService extends Service event(new UserStatsChanged($pilot, 'airport', $previous_airport)); } - - /** - * If the setting is enabled, remove the bid - * - * @param Pirep $pirep - * - * @throws \Exception - */ - public function removeBid(Pirep $pirep) - { - if (!setting('pireps.remove_bid_on_accept')) { - return; - } - - $flight = $pirep->flight; - if (!$flight) { - return; - } - - $bid = Bid::where([ - 'user_id' => $pirep->user->id, - 'flight_id' => $flight->id, - ]); - - if ($bid) { - Log::info('Bid for user: '.$pirep->user->ident.' on flight '.$flight->ident); - $bid->delete(); - } - } } diff --git a/resources/lang/en/pireps.php b/resources/lang/en/pireps.php index 3d56b983..1b734d72 100644 --- a/resources/lang/en/pireps.php +++ b/resources/lang/en/pireps.php @@ -7,6 +7,7 @@ return [ 'submitpirep' => 'Submit PIREP', 'fileflightreport' => 'File New Report', 'filenewpirep' => 'File New PIREP', + 'newpirep' => 'New PIREP', 'pilotreport' => 'Pilot Report|Pilot Reports', 'arrived' => 'Arrived', 'source' => 'Source', diff --git a/resources/lang/es/pireps.php b/resources/lang/es/pireps.php index c0de6599..234652c2 100644 --- a/resources/lang/es/pireps.php +++ b/resources/lang/es/pireps.php @@ -7,6 +7,7 @@ return [ 'submitpirep' => 'Enviar PIREP', 'fileflightreport' => 'Archivo informe de vuelo', 'filenewpirep' => 'Archivo nuevo PIREP', + 'newpirep' => 'Nuevo PIREP', 'pilotreport' => 'Informe de piloto|Informes de piloto', 'arrived' => 'Llegó', 'source' => 'Origen', diff --git a/resources/lang/it/pireps.php b/resources/lang/it/pireps.php index 2f8e506c..283dc3b6 100644 --- a/resources/lang/it/pireps.php +++ b/resources/lang/it/pireps.php @@ -2,6 +2,7 @@ return [ 'filenewpirep' => 'Inserici Nuovo PIREP', + 'newpirep' => 'Nuovo PIREP', 'pilotreport' => 'Rapporto Pilota|Rapporti Pilota', 'arrived' => 'Arrivato', 'source' => 'Fonte', diff --git a/resources/views/layouts/default/flights/table.blade.php b/resources/views/layouts/default/flights/table.blade.php index fd1ee42a..3a20885a 100644 --- a/resources/views/layouts/default/flights/table.blade.php +++ b/resources/views/layouts/default/flights/table.blade.php @@ -23,8 +23,7 @@ x-id="{{ $flight->id }}" x-saved-class="btn-info" type="button" - title="@lang('flights.addremovebid')" - > + title="@lang('flights.addremovebid')"> @endif @@ -64,6 +63,14 @@ @endif +
{{ $pirep->airline->name }}
- {{ Form::hidden('airline_id') }} - @else -{{ $errors->first('airline_id') }}
- @endif -{{ $pirep->ident }} - {{ Form::hidden('flight_number') }} - {{ Form::hidden('flight_code') }} - {{ Form::hidden('flight_leg') }} -
- @else -{{ $errors->first('flight_number') }}
-{{ $errors->first('route_code') }}
-{{ $errors->first('route_leg') }}
- @endif -{{ \App\Models\Enums\FlightType::label($pirep->flight_type) }}
- {{ Form::hidden('flight_type') }} - @else -{{ $errors->first('flight_type') }}
- @endif -- {{ $pirep->hours.' '.trans_choice('common.hour', $pirep->hours) }}, {{ $pirep->minutes.' '.trans_choice('common.minute', $pirep->minutes) }} - {{ Form::hidden('hours') }} - {{ Form::hidden('minutes') }} -
- @else -{{ $errors->first('hours') }}
-{{ $errors->first('minutes') }}
- @endif -{{ $pirep->airline->name }}
+ {{ Form::hidden('airline_id') }} + @else +{{ $errors->first('airline_id') }}
+ @endif +{{ $pirep->ident }} + {{ Form::hidden('flight_number') }} + {{ Form::hidden('flight_code') }} + {{ Form::hidden('flight_leg') }} +
+ @else +{{ $errors->first('flight_number') }}
+{{ $errors->first('route_code') }}
+{{ $errors->first('route_leg') }}
+ @endif +{{ \App\Models\Enums\FlightType::label($pirep->flight_type) }}
+ {{ Form::hidden('flight_type') }} + @else +{{ $errors->first('flight_type') }}
+ @endif ++ {{ $pirep->hours.' '.trans_choice('common.hour', $pirep->hours) }} + , {{ $pirep->minutes.' '.trans_choice('common.minute', $pirep->minutes) }} + {{ Form::hidden('hours') }} + {{ Form::hidden('minutes') }} +
+ @else +{{ $errors->first('minutes') }}
+ @endif +{{ $errors->first('dpt_airport_id') }}
- @endif -{{ $errors->first('dpt_airport_id') }}
+ @endif +{{ $errors->first('arr_airport_id') }}
- @endif -{{ $pirep->aircraft->name }}
- {{ Form::hidden('aircraft_id') }} - @else -{{ $errors->first('aircraft_id') }}
- @endif -{{ $pirep->block_fuel }}
- @else -{{ $errors->first('block_fuel') }}
- @endif -{{ $pirep->fuel_used }}
- @else -{{ $errors->first('fuel_used') }}
- @endif -{{ $errors->first('route') }}
-{{ $errors->first('notes') }}
-{{ $errors->first('arr_airport_id') }}
+ @endif +{{ $pirep->aircraft->name }}
+ {{ Form::hidden('aircraft_id') }} + @else +{{ $errors->first('aircraft_id') }}
+ @endif +{{ $pirep->block_fuel }}
+ @else +{{ $errors->first('block_fuel') }}
+ @endif +{{ $pirep->fuel_used }}
+ @else +{{ $errors->first('fuel_used') }}
+ @endif +{{ $errors->first('route') }}
+{{ $errors->first('notes') }}
+