diff --git a/app/Database/factories/RankFactory.php b/app/Database/factories/RankFactory.php index bbc8676c..39911df4 100644 --- a/app/Database/factories/RankFactory.php +++ b/app/Database/factories/RankFactory.php @@ -14,6 +14,8 @@ $factory->define(App\Models\Rank::class, function (Faker $faker) { 'id' => null, 'name' => $faker->unique()->text(50), 'hours' => $faker->numberBetween(10, 50), + 'acars_base_pay_rate' => $faker->numberBetween(10, 100), + 'manual_base_pay_rate' => $faker->numberBetween(10, 100), 'auto_approve_acars' => 0, 'auto_approve_manual' => 0, 'auto_promote' => 0, diff --git a/app/Services/FinanceService.php b/app/Services/FinanceService.php index a299c255..6404c9ee 100644 --- a/app/Services/FinanceService.php +++ b/app/Services/FinanceService.php @@ -7,6 +7,9 @@ namespace App\Services; use App\Models\Enums\PirepSource; use App\Models\Pirep; +use App\Support\Math; +use Money\Currency; +use Money\Money; class FinanceService extends BaseService { @@ -29,15 +32,51 @@ class FinanceService extends BaseService /** * Return the pilot's hourly pay for the given PIREP * @param Pirep $pirep + * @return float */ - public function getPayForPirep(Pirep $pirep) + public function getPayRateForPirep(Pirep $pirep) { # Get the base rate for the rank $rank = $pirep->user->rank; + $subfleet_id = $pirep->aircraft->subfleet_id; + + # find the right subfleet + $override_rate = $rank->subfleets() + ->where('subfleet_id', $subfleet_id) + ->first() + ->pivot; + if($pirep->source === PirepSource::ACARS) { $base_rate = $rank->acars_base_pay_rate; + $override_rate = $override_rate->acars_pay; } else { $base_rate = $rank->manual_base_pay_rate; + $override_rate = $override_rate->manual_pay; } + + if(!$override_rate) { + return $base_rate; + } + + # Not a percentage override + if(substr_count($override_rate, '%') === 0) { + return $override_rate; + } + + return Math::addPercent($base_rate, $override_rate); + } + + /** + * Get the user's payment amount for a PIREP + * @param Pirep $pirep + * @return Money + * @throws \InvalidArgumentException + */ + public function getPilotPilotPay(Pirep $pirep) + { + $pilot_rate = $this->getPayRateForPirep($pirep) / 60; + $payment = $pirep->flight_time * $pilot_rate; + + return new Money($payment, new Currency(config('phpvms.currency'))); } } diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php index 6422950c..0e351dac 100644 --- a/tests/FinanceTest.php +++ b/tests/FinanceTest.php @@ -1,19 +1,24 @@ addData('base'); + $this->fareSvc = app(FareService::class); + $this->financeSvc = app(FinanceService::class); + $this->fleetSvc = app(FleetService::class); } public function testFlightFaresNoOverride() @@ -272,11 +277,112 @@ class FinanceTest extends TestCase } /** - * Get the pilot pay, derived from the rank, and then if there - * are any overrides from a PIREP + * Get the pilot pay, derived from the rank */ - public function testGetPilotPay() + public function testGetPilotPayNoOverride() { + $subfleet = $this->createSubfleetWithAircraft(2); + $rank = $this->createRank(10, [$subfleet['subfleet']->id]); + $this->fleetSvc->addSubfleetToRank($subfleet['subfleet'], $rank); + $this->user = factory(App\Models\User::class)->create([ + 'rank_id' => $rank->id, + ]); + + $pirep = factory(App\Models\Pirep::class)->create([ + 'user_id' => $this->user->id, + 'aircraft_id' => $subfleet['aircraft']->random(), + 'source' => PirepSource::ACARS, + ]); + + $rate = $this->financeSvc->getPayRateForPirep($pirep); + $this->assertEquals($rank->acars_base_pay_rate, $rate); + } + + /** + * Get the pilot pay, but include different overrides + */ + public function testGetPilotPayWithOverride() + { + $acars_pay_rate = 100; + + $subfleet = $this->createSubfleetWithAircraft(2); + $rank = $this->createRank(10, [$subfleet['subfleet']->id]); + $this->fleetSvc->addSubfleetToRank($subfleet['subfleet'], $rank, [ + 'acars_pay' => $acars_pay_rate, + ]); + + $this->user = factory(App\Models\User::class)->create([ + 'rank_id' => $rank->id, + ]); + + $pirep_acars = factory(App\Models\Pirep::class)->create([ + 'user_id' => $this->user->id, + 'aircraft_id' => $subfleet['aircraft']->random(), + 'source' => PirepSource::ACARS, + ]); + + $rate = $this->financeSvc->getPayRateForPirep($pirep_acars); + $this->assertEquals($acars_pay_rate, $rate); + + # Change to a percentage + $manual_pay_rate = '50%'; + $manual_pay_adjusted = Math::addPercent( + $rank->manual_base_pay_rate, $manual_pay_rate); + + $this->fleetSvc->addSubfleetToRank($subfleet['subfleet'], $rank, [ + 'manual_pay' => $manual_pay_rate, + ]); + + $pirep_manual = factory(App\Models\Pirep::class)->create([ + 'user_id' => $this->user->id, + 'aircraft_id' => $subfleet['aircraft']->random(), + 'source' => PirepSource::MANUAL, + ]); + + $rate = $this->financeSvc->getPayRateForPirep($pirep_manual); + $this->assertEquals($manual_pay_adjusted, $rate); + + # And make sure the original acars override still works + $rate = $this->financeSvc->getPayRateForPirep($pirep_acars); + $this->assertEquals($acars_pay_rate, $rate); + } + + /** + * Get the payment for a pilot + */ + public function testGetPirepPilotPay() + { + $acars_pay_rate = 100; + + $subfleet = $this->createSubfleetWithAircraft(2); + $rank = $this->createRank(10, [$subfleet['subfleet']->id]); + $this->fleetSvc->addSubfleetToRank($subfleet['subfleet'], $rank, [ + 'acars_pay' => $acars_pay_rate, + ]); + + $this->user = factory(App\Models\User::class)->create([ + 'rank_id' => $rank->id, + ]); + + $pirep_acars = factory(App\Models\Pirep::class)->create([ + 'user_id' => $this->user->id, + 'aircraft_id' => $subfleet['aircraft']->random(), + 'source' => PirepSource::ACARS, + 'flight_time' => 60, + ]); + + $payment = $this->financeSvc->getPilotPilotPay($pirep_acars); + $this->assertEquals($payment->getAmount(), 100); + + $pirep_acars = factory(App\Models\Pirep::class)->create([ + 'user_id' => $this->user->id, + 'aircraft_id' => $subfleet['aircraft']->random(), + 'source' => PirepSource::ACARS, + 'flight_time' => 90, + ]); + + $payment = $this->financeSvc->getPilotPilotPay($pirep_acars); + $this->assertEquals($payment->getAmount(), 150); } }