From 5b16c88bcbeb39d4b193313804ba6d75691b9543 Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Tue, 26 May 2020 18:41:25 -0400 Subject: [PATCH] Fix for all airport expenses being applied #729 --- app/Repositories/ExpenseRepository.php | 13 ++-- app/Services/Finance/PirepFinanceService.php | 57 +++++++++++++++-- tests/FinanceTest.php | 66 ++++++++++++++++++-- 3 files changed, 122 insertions(+), 14 deletions(-) diff --git a/app/Repositories/ExpenseRepository.php b/app/Repositories/ExpenseRepository.php index cc7c0448..668b098d 100644 --- a/app/Repositories/ExpenseRepository.php +++ b/app/Repositories/ExpenseRepository.php @@ -24,13 +24,14 @@ class ExpenseRepository extends Repository implements CacheableInterface * Get all of the expenses for a given type, and also * include expenses for a given airline ID * - * @param $type - * @param null $airline_id - * @param null $ref_model + * @param $type + * @param int $airline_id + * @param string $ref_model + * @param mixed $ref_model_id * * @return Collection */ - public function getAllForType($type, $airline_id = null, $ref_model = null) + public function getAllForType($type, $airline_id = null, $ref_model = null, $ref_model_id = null) { $where = [ 'type' => $type, @@ -47,6 +48,10 @@ class ExpenseRepository extends Repository implements CacheableInterface if ($ref_model) { $where['ref_model'] = $ref_model_type; } + + if ($ref_model_id) { + $where['ref_model_id'] = $ref_model_id; + } } $expenses = $this->findWhere($where); diff --git a/app/Services/Finance/PirepFinanceService.php b/app/Services/Finance/PirepFinanceService.php index a5d03854..1fbefef9 100644 --- a/app/Services/Finance/PirepFinanceService.php +++ b/app/Services/Finance/PirepFinanceService.php @@ -80,6 +80,7 @@ class PirepFinanceService extends Service $this->payFaresForPirep($pirep); $this->payExpensesForSubfleet($pirep); $this->payExpensesForPirep($pirep); + $this->payAirportExpensesForPirep($pirep); $this->payExpensesEventsForPirep($pirep); $this->payGroundHandlingForPirep($pirep); $this->payPilotForPirep($pirep); @@ -228,7 +229,12 @@ class PirepFinanceService extends Service /* * Go through the expenses and apply a mulitplier if present */ - $expenses->map(function (/** @var \App\Models\Expense */ $expense, $i) use ($pirep) { + $expenses->map(function (Expense $expense, $i) use ($pirep) { + // Airport expenses are paid out separately + if ($expense->ref_model === Airport::class) { + return; + } + Log::info('Finance: PIREP: '.$pirep->id.', expense:', $expense->toArray()); // Check to see if there is a certain fleet or flight type set on this expense @@ -251,13 +257,14 @@ class PirepFinanceService extends Service } // Form the memo, with some specific ones depending on the group - if ($expense->ref_model === Airport::class) { - $memo = "Airport Expense: {$expense->name} ({$expense->ref_model_id})"; - $transaction_group = "Airport: {$expense->ref_model_id}"; - } elseif ($expense->ref_model === Subfleet::class) { + if ($expense->ref_model === Subfleet::class + && $expense->ref_model_id === $pirep->aircraft->subfleet->id + ) { $memo = "Subfleet Expense: {$expense->name} ({$pirep->aircraft->subfleet->name})"; $transaction_group = "Subfleet: {$expense->name} ({$pirep->aircraft->subfleet->name})"; - } elseif ($expense->ref_model === Aircraft::class) { + } elseif ($expense->ref_model === Aircraft::class + && $expense->ref_model_id === $pirep->aircraft->id + ) { $memo = "Aircraft Expense: {$expense->name} ({$pirep->aircraft->name})"; $transaction_group = "Aircraft: {$expense->name} " ."({$pirep->aircraft->name}-{$pirep->aircraft->registration})"; @@ -286,6 +293,44 @@ class PirepFinanceService extends Service }); } + /** + * Pay the airport-specific expenses for a PIREP + * + * @param \App\Models\Pirep $pirep + */ + public function payAirportExpensesForPirep(Pirep $pirep): void + { + $expenses = $this->expenseRepo->getAllForType( + ExpenseType::FLIGHT, + $pirep->airline_id, + Airport::class, + $pirep->arr_airport_id, + ); + + /* + * Go through the expenses and apply a mulitplier if present + */ + $expenses->map(function (Expense $expense, $i) use ($pirep) { + Log::info('Finance: PIREP: '.$pirep->id.', airport expense:', $expense->toArray()); + + $memo = "Airport Expense: {$expense->name} ({$expense->ref_model_id})"; + $transaction_group = "Airport: {$expense->ref_model_id}"; + + $debit = Money::createFromAmount($expense->amount); + + // Charge to the airlines journal + $journal = $pirep->airline->journal; + $this->financeSvc->debitFromJournal( + $journal, + $debit, + $pirep, + $memo, + $transaction_group, + 'airport' + ); + }); + } + /** * Collect all of the expenses from the listeners and apply those to the journal * diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php index 9731f7a2..890e4580 100644 --- a/tests/FinanceTest.php +++ b/tests/FinanceTest.php @@ -26,10 +26,19 @@ use Exception; class FinanceTest extends TestCase { + /** @var \App\Repositories\ExpenseRepository */ private $expenseRepo; + + /** @var \App\Services\FareService */ private $fareSvc; + + /** @var \App\Services\FinanceService */ private $financeSvc; + + /** @var FleetService */ private $fleetSvc; + + /** @var PirepService */ private $pirepSvc; /** @@ -137,6 +146,19 @@ class FinanceTest extends TestCase 'amount' => 200, ]); + // Add expenses for airports + factory(Expense::class)->create([ + 'ref_model' => Airport::class, + 'ref_model_id' => $dpt_apt->id, + 'amount' => 50, + ]); + + factory(Expense::class)->create([ + 'ref_model' => Airport::class, + 'ref_model_id' => $arr_apt->id, + 'amount' => 100, + ]); + $pirep = $this->pirepSvc->create($pirep, []); return [$user, $pirep, $fares]; @@ -694,6 +716,39 @@ class FinanceTest extends TestCase $this->assertEquals($obj->id, $expense->ref_model_id); } + public function testAirportExpenses() + { + $apt1 = factory(Airport::class)->create(); + $apt2 = factory(Airport::class)->create(); + $apt3 = factory(Airport::class)->create(); + + factory(Expense::class)->create([ + 'airline_id' => null, + 'ref_model' => Airport::class, + 'ref_model_id' => $apt1->id, + ]); + + factory(Expense::class)->create([ + 'airline_id' => null, + 'ref_model' => Airport::class, + 'ref_model_id' => $apt2->id, + ]); + + factory(Expense::class)->create([ + 'airline_id' => null, + 'ref_model' => Airport::class, + 'ref_model_id' => $apt3->id, + ]); + + $expenses = $this->expenseRepo->getAllForType( + ExpenseType::FLIGHT, + null, + Airport::class + ); + + $this->assertCount(3, $expenses); + } + /** * @throws Exception */ @@ -721,14 +776,15 @@ class FinanceTest extends TestCase $transactions = $journalRepo->getAllForObject($pirep); -// $this->assertCount(9, $transactions['transactions']); + // $this->assertCount(9, $transactions['transactions']); $this->assertEquals(3020, $transactions['credits']->getValue()); - $this->assertEquals(1960, $transactions['debits']->getValue()); + $this->assertEquals(2060, $transactions['debits']->getValue()); // Check that all the different transaction types are there // test by the different groups that exist $transaction_tags = [ 'fuel' => 1, + 'airport' => 1, 'expense' => 1, 'subfleet' => 2, 'fare' => 3, @@ -778,12 +834,13 @@ class FinanceTest extends TestCase // $this->assertCount(9, $transactions['transactions']); $this->assertEquals(3020, $transactions['credits']->getValue()); - $this->assertEquals(1960, $transactions['debits']->getValue()); + $this->assertEquals(2060, $transactions['debits']->getValue()); // Check that all the different transaction types are there // test by the different groups that exist $transaction_tags = [ 'fuel' => 1, + 'airport' => 1, 'expense' => 1, 'subfleet' => 2, 'fare' => 3, @@ -816,12 +873,13 @@ class FinanceTest extends TestCase $transactions = $journalRepo->getAllForObject($pirep2); $this->assertEquals(3020, $transactions['credits']->getValue()); - $this->assertEquals(2060, $transactions['debits']->getValue()); + $this->assertEquals(2160, $transactions['debits']->getValue()); // Check that all the different transaction types are there // test by the different groups that exist $transaction_tags = [ 'fuel' => 1, + 'airport' => 1, 'expense' => 2, 'subfleet' => 2, 'fare' => 3,