From d5aef6fb87107afcba68706082fe4e12ca3310b6 Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Fri, 23 Feb 2018 15:12:09 -0600 Subject: [PATCH] Allow setting percent for fare overrides against base fare #125 --- ...17_06_23_011011_create_subfleet_tables.php | 6 +- app/Services/FareService.php | 63 +++++----- app/Support/Math.php | 32 +++++ composer.json | 3 +- composer.lock | 105 +++++++++++++---- tests/FinanceTest.php | 109 ++++++++++++++---- tests/MathTest.php | 33 ++++++ 7 files changed, 276 insertions(+), 75 deletions(-) create mode 100644 app/Support/Math.php create mode 100644 tests/MathTest.php diff --git a/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php b/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php index 72ade186..194e18a3 100644 --- a/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php +++ b/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php @@ -36,9 +36,9 @@ class CreateSubfleetTables extends Migration Schema::create('subfleet_fare', function (Blueprint $table) { $table->unsignedInteger('subfleet_id'); $table->unsignedInteger('fare_id'); - $table->unsignedDecimal('price')->nullable(); - $table->unsignedDecimal('cost')->nullable(); - $table->unsignedInteger('capacity')->nullable(); + $table->string('price')->nullable(); + $table->string('cost')->nullable(); + $table->string('capacity')->nullable(); $table->timestamps(); $table->primary(['subfleet_id', 'fare_id']); diff --git a/app/Services/FareService.php b/app/Services/FareService.php index b13c4949..ad022740 100644 --- a/app/Services/FareService.php +++ b/app/Services/FareService.php @@ -5,9 +5,44 @@ namespace App\Services; use App\Models\Fare; use App\Models\Flight; use App\Models\Subfleet; +use App\Support\Math; class FareService extends BaseService { + /** + * Get fares + * @param $fare + * @return mixed + */ + protected function getFares($fare) + { + if (filled($fare->pivot->price)) { + if (substr_count($fare->pivot->price, '%', -1)) { + $fare->price = Math::addPercent($fare->price, $fare->pivot->price); + } else { + $fare->price = $fare->pivot->price; + } + } + + if (filled($fare->pivot->cost)) { + if (substr_count($fare->pivot->cost, '%', -1)) { + $fare->cost = Math::addPercent($fare->cost, $fare->pivot->cost); + } else { + $fare->cost = $fare->pivot->cost; + } + } + + if (filled($fare->pivot->capacity)) { + if (substr_count($fare->pivot->capacity, '%', -1)) { + $fare->capacity = Math::addPercent($fare->capacity, $fare->pivot->capacity); + } else { + $fare->capacity = $fare->pivot->capacity; + } + } + + return $fare; + } + /** * Attach a fare to an flight * @@ -40,19 +75,7 @@ class FareService extends BaseService 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 $this->getFares($fare); }); return $fares; @@ -102,19 +125,7 @@ class FareService extends BaseService public function getForSubfleet(Subfleet $subfleet) { $fares = $subfleet->fares->map(function($fare) { - if(!is_null($fare->pivot->price)) { - $fare->price = $fare->pivot->price; - } - - if(!is_null($fare->pivot->cost)) { - $fare->cost = $fare->pivot->cost; - } - - if(!is_null($fare->pivot->capacity)) { - $fare->capacity = $fare->pivot->capacity; - } - - return $fare; + return $this->getFares($fare); }); return $fares; diff --git a/app/Support/Math.php b/app/Support/Math.php new file mode 100644 index 00000000..c1c0829c --- /dev/null +++ b/app/Support/Math.php @@ -0,0 +1,32 @@ +=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "5.*", + "satooshi/php-coveralls": "dev-master", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MathPHP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Rogoyski", + "email": "mark@rogoyski.com", + "homepage": "https://github.com/markrogoyski", + "role": "Developer" + }, + { + "name": "Kevin Nowaczyk", + "role": "Contributor" + }, + { + "name": "Jakob Sandberg", + "role": "Contributor" + } + ], + "description": "Math Library for PHP. Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra", + "homepage": "https://github.com/markrogoyski/math-php/", + "keywords": [ + "algebra", + "combinatorics", + "distributions", + "linear algebra", + "math", + "mathematics", + "matrix", + "numerical analysis", + "probability", + "regressions", + "statistics" + ], + "time": "2017-12-11T05:05:12+00:00" + }, { "name": "monolog/monolog", "version": "1.23.0", @@ -2110,7 +2175,7 @@ "lib/random.php" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -2225,7 +2290,7 @@ "Http\\Client\\": "src/" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -2276,7 +2341,7 @@ "Http\\Promise\\": "src/" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -2649,7 +2714,7 @@ "Prettus\\Validator\\": "src/Prettus/Validator/" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "authors": [ { "name": "Anderson Andrade", @@ -2738,7 +2803,7 @@ "Psr\\Container\\": "src/" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -2884,7 +2949,7 @@ "Psr\\SimpleCache\\": "src/" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -3293,7 +3358,7 @@ "lib/swift_required.php" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -5241,7 +5306,7 @@ "Faker\\": "src/Faker/" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -5593,7 +5658,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -5640,7 +5705,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -5697,7 +5762,7 @@ ] } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -6460,7 +6525,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6512,7 +6577,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6580,7 +6645,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6630,7 +6695,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6675,7 +6740,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6720,7 +6785,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], @@ -6909,7 +6974,7 @@ "src/" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php index 295a7a7b..83d83e5f 100644 --- a/tests/FinanceTest.php +++ b/tests/FinanceTest.php @@ -1,25 +1,28 @@ addData('base'); + $this->fareSvc = app(FareService::class); } 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->fareSvc->setForFlight($flight, $fare); + $subfleet_fares = $this->fareSvc->getForFlight($flight); $this->assertCount(1, $subfleet_fares); $this->assertEquals($fare->price, $subfleet_fares->get(0)->price); @@ -28,31 +31,59 @@ class FinanceTest extends TestCase # # set an override now # - $fare_svc->setForFlight($flight, $fare, [ + $this->fareSvc->setForFlight($flight, $fare, [ 'price' => 50, 'capacity' => 400 ]); # look for them again - $subfleet_fares = $fare_svc->getForFlight($flight); + $subfleet_fares = $this->fareSvc->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)); + $this->fareSvc->delFareFromFlight($flight, $fare); + $this->assertCount(0, $this->fareSvc->getForFlight($flight)); + } + + /** + * Assign percentage values and make sure they're valid + */ + public function testFlightFareOverrideAsPercent() + { + $flight = factory(App\Models\Flight::class)->create(); + $fare = factory(App\Models\Fare::class)->create(); + + $percent_incr = '20%'; + $percent_decr = '-20%'; + $percent_200 = '200%'; + + $new_price = Math::addPercent($fare->price, $percent_incr); + $new_cost = Math::addPercent($fare->cost, $percent_decr); + $new_capacity = Math::addPercent($fare->capacity, $percent_200); + + $this->fareSvc->setForFlight($flight, $fare, [ + 'price' => $percent_incr, + 'cost' => $percent_decr, + 'capacity' => $percent_200, + ]); + + $ac_fares = $this->fareSvc->getForFlight($flight); + + $this->assertCount(1, $ac_fares); + $this->assertEquals($new_price, $ac_fares[0]->price); + $this->assertEquals($new_cost, $ac_fares[0]->cost); + $this->assertEquals($new_capacity, $ac_fares[0]->capacity); } 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->fareSvc->setForSubfleet($subfleet, $fare); + $subfleet_fares = $this->fareSvc->getForSubfleet($subfleet); $this->assertCount(1, $subfleet_fares); $this->assertEquals($fare->price, $subfleet_fares->get(0)->price); @@ -61,34 +92,32 @@ class FinanceTest extends TestCase # # set an override now # - $fare_svc->setForSubfleet($subfleet, $fare, [ + $this->fareSvc->setForSubfleet($subfleet, $fare, [ 'price' => 50, 'capacity' => 400 ]); # look for them again - $subfleet_fares = $fare_svc->getForSubfleet($subfleet); + $subfleet_fares = $this->fareSvc->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)); + $this->fareSvc->delFareFromSubfleet($subfleet, $fare); + $this->assertCount(0, $this->fareSvc->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, [ + $this->fareSvc->setForSubfleet($subfleet, $fare, [ 'price' => 50, 'capacity' => 400 ]); - $ac_fares = $fare_svc->getForSubfleet($subfleet); + $ac_fares = $this->fareSvc->getForSubfleet($subfleet); $this->assertCount(1, $ac_fares); $this->assertEquals(50, $ac_fares[0]->price); @@ -98,18 +127,48 @@ class FinanceTest extends TestCase # update the override to a different amount and make sure it updates # - $fare_svc->setForSubfleet($subfleet, $fare, [ + $this->fareSvc->setForSubfleet($subfleet, $fare, [ 'price' => 150, 'capacity' => 50 ]); - $ac_fares = $fare_svc->getForSubfleet($subfleet); + $ac_fares = $this->fareSvc->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)); + $this->fareSvc->delFareFromSubfleet($subfleet, $fare); + $this->assertCount(0, $this->fareSvc->getForSubfleet($subfleet)); + } + + /** + * Assign percentage values and make sure they're valid + */ + public function testSubfleetFareOverrideAsPercent() + { + $subfleet = factory(App\Models\Subfleet::class)->create(); + $fare = factory(App\Models\Fare::class)->create(); + + $percent_incr = '20%'; + $percent_decr = '-20%'; + $percent_200 = '200%'; + + $new_price = Math::addPercent($fare->price, $percent_incr); + $new_cost = Math::addPercent($fare->cost, $percent_decr); + $new_capacity = Math::addPercent($fare->capacity, $percent_200); + + $this->fareSvc->setForSubfleet($subfleet, $fare, [ + 'price' => $percent_incr, + 'cost' => $percent_decr, + 'capacity' => $percent_200, + ]); + + $ac_fares = $this->fareSvc->getForSubfleet($subfleet); + + $this->assertCount(1, $ac_fares); + $this->assertEquals($new_price, $ac_fares[0]->price); + $this->assertEquals($new_cost, $ac_fares[0]->cost); + $this->assertEquals($new_capacity, $ac_fares[0]->capacity); } } diff --git a/tests/MathTest.php b/tests/MathTest.php new file mode 100644 index 00000000..53fff42f --- /dev/null +++ b/tests/MathTest.php @@ -0,0 +1,33 @@ + 112, 'fn' => Math::addPercent(100, 12)], + ['expected' => 112, 'fn' => Math::addPercent(100, '12')], + ['expected' => 112, 'fn' => Math::addPercent(100, '12%')], + ['expected' => 112, 'fn' => Math::addPercent(100, '12 %')], + ['expected' => 112, 'fn' => Math::addPercent('100 ', '12')], + ['expected' => 112.5, 'fn' => Math::addPercent('100', '12.5')], + ['expected' => 88, 'fn' => Math::addPercent('100', -12)], + ['expected' => 88, 'fn' => Math::addPercent('100', '-12')], + ['expected' => 88, 'fn' => Math::addPercent('100', '-12 %')], + ['expected' => 88, 'fn' => Math::addPercent('100', '-12%')], + ]; + + foreach($tests as $test) { + $this->assertEquals($test['expected'], $test['fn']); + } + } + +}