From 7e45291b27b25b3258c38e0820e0255e6dc68e88 Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Sun, 7 Jan 2018 09:19:46 -0600 Subject: [PATCH] Add pivot table for flight_fare to override fare #125 --- ...2017_06_17_214650_create_flight_tables.php | 15 ++- .../Controllers/Admin/SubfleetController.php | 2 +- app/Models/Flight.php | 8 ++ app/Services/FareService.php | 92 ++++++++++++-- app/Services/FlightService.php | 2 +- app/Services/PIREPService.php | 3 +- tests/FinanceTest.php | 118 ++++++++++++++++++ tests/SubfleetTest.php | 4 +- 8 files changed, 226 insertions(+), 18 deletions(-) create mode 100644 tests/FinanceTest.php 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 237a46a8..6d4c59fb 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 @@ -42,6 +42,18 @@ class CreateFlightTables extends Migration $table->index('arr_airport_id'); }); + Schema::create('flight_fare', function (Blueprint $table) { + $table->string('flight_id', 12); + $table->unsignedInteger('fare_id'); + $table->unsignedDecimal('price', 19)->nullable(); + $table->unsignedDecimal('cost', 19)->nullable(); + $table->unsignedInteger('capacity')->nullable(); + $table->timestamps(); + + $table->primary(['flight_id', 'fare_id']); + $table->index(['flight_id', 'subfleet_id']); + }); + Schema::create('flight_fields', function (Blueprint $table) { $table->increments('id'); $table->string('flight_id', 12); @@ -60,7 +72,8 @@ class CreateFlightTables extends Migration */ public function down() { - Schema::drop('flights'); Schema::drop('flight_fields'); + Schema::drop('flight_fare'); + Schema::drop('flights'); } } diff --git a/app/Http/Controllers/Admin/SubfleetController.php b/app/Http/Controllers/Admin/SubfleetController.php index 6f9bf895..0d2ea7ec 100644 --- a/app/Http/Controllers/Admin/SubfleetController.php +++ b/app/Http/Controllers/Admin/SubfleetController.php @@ -242,7 +242,7 @@ class SubfleetController extends BaseController // dissassociate fare from teh aircraft elseif ($request->isMethod('delete')) { $fare = $this->fareRepo->findWithoutFail($request->fare_id); - $fare_svc->delFromAircraft($subfleet, $fare); + $fare_svc->delFareFromSubfleet($subfleet, $fare); } return $this->return_fares_view($subfleet); diff --git a/app/Models/Flight.php b/app/Models/Flight.php index f19ca70e..02905890 100644 --- a/app/Models/Flight.php +++ b/app/Models/Flight.php @@ -82,6 +82,14 @@ class Flight extends BaseModel return $this->belongsTo('App\Models\Airport', 'alt_airport_id'); } + public function fares() + { + return $this->belongsToMany( + Fare::class, + 'flight_fare' + )->withPivot('price', 'cost', 'capacity'); + } + public function fields() { return $this->hasMany('App\Models\FlightFields', 'flight_id'); diff --git a/app/Services/FareService.php b/app/Services/FareService.php index ff2100b9..b13c4949 100644 --- a/app/Services/FareService.php +++ b/app/Services/FareService.php @@ -2,21 +2,83 @@ namespace App\Services; -use App\Models\Subfleet; use App\Models\Fare; +use App\Models\Flight; +use App\Models\Subfleet; -class FareService extends BaseService { +class FareService extends BaseService +{ + /** + * Attach a fare to an flight + * + * @param Flight $flight + * @param Fare $fare + * @param array set the price/cost/capacity + * @return Flight + */ + public function setForFlight(Flight $flight, Fare $fare, array $override = []): Flight + { + $flight->fares()->syncWithoutDetaching([$fare->id]); + + # modify any pivot values? + if (\count($override) > 0) { + $flight->fares()->updateExistingPivot($fare->id, $override); + } + + $flight->save(); + $flight->refresh(); + return $flight; + } /** - * Attach a fare to an aircraft + * return all the fares for a flight. check the pivot + * table to see if the price/cost/capacity has been overridden + * and return the correct amounts. + * @param Flight $flight + * @return Fare[] + */ + public function getForFlight(Flight $flight) + { + $fares = $flight->fares->map(function ($fare) { + if (null !== $fare->pivot->price) { + $fare->price = $fare->pivot->price; + } + + if (null !== $fare->pivot->cost) { + $fare->cost = $fare->pivot->cost; + } + + if (null !== $fare->pivot->capacity) { + $fare->capacity = $fare->pivot->capacity; + } + + return $fare; + }); + + return $fares; + } + + /** + * @param Flight $flight + * @param Fare $fare + * @return Flight + */ + public function delFareFromFlight(Flight $flight, Fare $fare) + { + $flight->fares()->detach($fare->id); + $flight->refresh(); + return $flight; + } + + /** + * Attach a fare to a subfleet * - * @param Aircraft $subfleet + * @param Subfleet $subfleet * @param Fare $fare * @param array set the price/cost/capacity - * - * @return Aircraft + * @return Subfleet */ - public function setForSubfleet(Subfleet &$subfleet, Fare &$fare, array $override=[]) + public function setForSubfleet(Subfleet $subfleet, Fare $fare, array $override=[]): Subfleet { $subfleet->fares()->syncWithoutDetaching([$fare->id]); @@ -26,7 +88,7 @@ class FareService extends BaseService { } $subfleet->save(); - $subfleet = $subfleet->fresh(); + $subfleet->refresh(); return $subfleet; } @@ -34,10 +96,10 @@ class FareService extends BaseService { * return all the fares for an aircraft. check the pivot * table to see if the price/cost/capacity has been overridden * and return the correct amounts. - * @param Aircraft $subfleet + * @param Subfleet $subfleet * @return Fare[] */ - public function getForSubfleet(Subfleet &$subfleet) + public function getForSubfleet(Subfleet $subfleet) { $fares = $subfleet->fares->map(function($fare) { if(!is_null($fare->pivot->price)) { @@ -58,10 +120,16 @@ class FareService extends BaseService { return $fares; } - public function delFromAircraft(Subfleet &$subfleet, Fare &$fare) + /** + * Delete the fare from a subfleet + * @param Subfleet $subfleet + * @param Fare $fare + * @return Subfleet|null|static + */ + public function delFareFromSubfleet(Subfleet &$subfleet, Fare &$fare) { $subfleet->fares()->detach($fare->id); - $subfleet = $subfleet->fresh(); + $subfleet->refresh(); return $subfleet; } } diff --git a/app/Services/FlightService.php b/app/Services/FlightService.php index b40d1631..5a1f251a 100644 --- a/app/Services/FlightService.php +++ b/app/Services/FlightService.php @@ -34,7 +34,7 @@ class FlightService extends BaseService * @param User $user * @return UserBid|null */ - public function addBid(Flight $flight, User $user) + public function addBid(Flight $flight, User $user): UserBid { # If it's already been bid on, then it can't be bid on again if($flight->has_bid && setting('bids.disable_flight_on_bid')) { diff --git a/app/Services/PIREPService.php b/app/Services/PIREPService.php index 54e0e031..9d29470b 100644 --- a/app/Services/PIREPService.php +++ b/app/Services/PIREPService.php @@ -35,10 +35,11 @@ class PIREPService extends BaseService /** * PIREPService constructor. - * @param UserService $pilotSvc + * @param AcarsRepository $acarsRepo * @param GeoService $geoSvc * @param NavdataRepository $navRepo * @param PirepRepository $pirepRepo + * @param UserService $pilotSvc */ public function __construct( AcarsRepository $acarsRepo, diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php new file mode 100644 index 00000000..88a8b60b --- /dev/null +++ b/tests/FinanceTest.php @@ -0,0 +1,118 @@ +addData('base'); + } + + public function testFlightFaresNoOverride() + { + $fare_svc = app('App\Services\FareService'); + + $flight = factory(App\Models\Flight::class)->create(); + $fare = factory(App\Models\Fare::class)->create(); + + $fare_svc->setForFlight($flight, $fare); + $subfleet_fares = $fare_svc->getForFlight($flight); + + $this->assertCount(1, $subfleet_fares); + $this->assertEquals($fare->price, $subfleet_fares->get(0)->price); + $this->assertEquals($fare->capacity, $subfleet_fares->get(0)->capacity); + + # + # set an override now + # + $fare_svc->setForFlight($flight, $fare, [ + 'price' => 50, 'capacity' => 400 + ]); + + # look for them again + $subfleet_fares = $fare_svc->getForFlight($flight); + + $this->assertCount(1, $subfleet_fares); + $this->assertEquals(50, $subfleet_fares[0]->price); + $this->assertEquals(400, $subfleet_fares[0]->capacity); + + # delete + $fare_svc->delFareFromFlight($flight, $fare); + $this->assertCount(0, $fare_svc->getForFlight($flight)); + } + + public function testSubfleetFaresNoOverride() + { + $fare_svc = app('App\Services\FareService'); + + $subfleet = factory(App\Models\Subfleet::class)->create(); + $fare = factory(App\Models\Fare::class)->create(); + + $fare_svc->setForSubfleet($subfleet, $fare); + $subfleet_fares = $fare_svc->getForSubfleet($subfleet); + + $this->assertCount(1, $subfleet_fares); + $this->assertEquals($fare->price, $subfleet_fares->get(0)->price); + $this->assertEquals($fare->capacity, $subfleet_fares->get(0)->capacity); + + # + # set an override now + # + $fare_svc->setForSubfleet($subfleet, $fare, [ + 'price' => 50, 'capacity' => 400 + ]); + + # look for them again + $subfleet_fares = $fare_svc->getForSubfleet($subfleet); + + $this->assertCount(1, $subfleet_fares); + $this->assertEquals(50, $subfleet_fares[0]->price); + $this->assertEquals(400, $subfleet_fares[0]->capacity); + + # delete + $fare_svc->delFareFromSubfleet($subfleet, $fare); + $this->assertCount(0, $fare_svc->getForSubfleet($subfleet)); + } + + public function testSubfleetFaresOverride() + { + $fare_svc = app('App\Services\FareService'); + + $subfleet = factory(App\Models\Subfleet::class)->create(); + $fare = factory(App\Models\Fare::class)->create(); + + $fare_svc->setForSubfleet($subfleet, $fare, [ + 'price' => 50, 'capacity' => 400 + ]); + + $ac_fares = $fare_svc->getForSubfleet($subfleet); + + $this->assertCount(1, $ac_fares); + $this->assertEquals(50, $ac_fares[0]->price); + $this->assertEquals(400, $ac_fares[0]->capacity); + + # + # update the override to a different amount and make sure it updates + # + + $fare_svc->setForSubfleet($subfleet, $fare, [ + 'price' => 150, 'capacity' => 50 + ]); + + $ac_fares = $fare_svc->getForSubfleet($subfleet); + + $this->assertCount(1, $ac_fares); + $this->assertEquals(150, $ac_fares[0]->price); + $this->assertEquals(50, $ac_fares[0]->capacity); + + # delete + $fare_svc->delFareFromSubfleet($subfleet, $fare); + $this->assertCount(0, $fare_svc->getForSubfleet($subfleet)); + } +} diff --git a/tests/SubfleetTest.php b/tests/SubfleetTest.php index 83fb2edc..9da40738 100644 --- a/tests/SubfleetTest.php +++ b/tests/SubfleetTest.php @@ -43,7 +43,7 @@ class SubfleetTest extends TestCase $this->assertEquals(400, $subfleet_fares[0]->capacity); # delete - $fare_svc->delFromAircraft($subfleet, $fare); + $fare_svc->delFareFromSubfleet($subfleet, $fare); $this->assertCount(0, $fare_svc->getForSubfleet($subfleet)); } @@ -79,7 +79,7 @@ class SubfleetTest extends TestCase $this->assertEquals(50, $ac_fares[0]->capacity); # delete - $fare_svc->delFromAircraft($subfleet, $fare); + $fare_svc->delFareFromSubfleet($subfleet, $fare); $this->assertCount(0, $fare_svc->getForSubfleet($subfleet)); } }