#406 Refactor bids (#432)

* Add flight_id column to pireps table

* Refactor PIREPs and bids closes 406

* Formatting
This commit is contained in:
Nabeel S
2019-11-05 11:44:31 -05:00
committed by GitHub
parent db087d0ccb
commit f5183babf6
35 changed files with 967 additions and 798 deletions

View File

@@ -1,5 +1,8 @@
<?php
use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use Carbon\Carbon;
use Faker\Generator as Faker;
@@ -7,10 +10,15 @@ use Faker\Generator as Faker;
* Create a new PIREP
*/
$factory->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(),

View File

@@ -1,6 +1,7 @@
<?php
use App\Contracts\Migration;
use App\Contracts\Model;
use App\Models\Enums\FlightType;
use Illuminate\Database\Schema\Blueprint;
@@ -14,7 +15,7 @@ class CreateFlightTables extends Migration
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->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']);

View File

@@ -1,6 +1,7 @@
<?php
use App\Contracts\Migration;
use App\Contracts\Model;
use App\Models\Enums\FlightType;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
@@ -16,7 +17,7 @@ class CreatePirepTables extends Migration
public function up()
{
Schema::create('pireps', function (Blueprint $table) {
$table->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();

View File

@@ -1,6 +1,7 @@
<?php
use App\Contracts\Migration;
use App\Contracts\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
@@ -16,7 +17,7 @@ class CreateBidsTable extends Migration
Schema::create('bids', function (Blueprint $table) {
$table->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');

View File

@@ -0,0 +1,31 @@
<?php
use App\Contracts\Model;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class PirepsAddFlightId extends Migration
{
/**
* Add a `flight_id` column to the PIREPs table
*/
public function up()
{
Schema::table('pireps', function (Blueprint $table) {
$table->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');
});
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Exceptions;
use App\Models\User;
class UserBidLimit extends HttpException
{
private $user;
public function __construct(User $user)
{
$this->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,
];
}
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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),

View File

@@ -4,9 +4,6 @@ namespace App\Http\Requests\Acars;
use App\Contracts\FormRequest;
/**
* Class CommentRequest
*/
class CommentRequest extends FormRequest
{
public function rules(): array

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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');

View File

@@ -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

145
app/Services/BidService.php Normal file
View File

@@ -0,0 +1,145 @@
<?php
namespace App\Services;
use App\Contracts\Service;
use App\Exceptions\BidExistsForFlight;
use App\Exceptions\UserBidLimit;
use App\Models\Bid;
use App\Models\Flight;
use App\Models\Pirep;
use App\Models\User;
use Illuminate\Support\Facades\Log;
class BidService extends Service
{
/**
* Find all of the bids for a given user
*
* @param \App\Models\User $user
*
* @return mixed
*/
public function findBidsForUser(User $user)
{
$bids = Bid::where(['user_id' => $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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}