From dd5800eac730eae8ac65e9555a460bd1a891ec20 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 12 May 2022 10:57:58 +1000 Subject: [PATCH] TDD for profit and loss --- app/Models/Expense.php | 2 +- app/Services/Report/ProfitLoss.php | 43 ++++++++++++++----- .../Export/ProfitAndLossReportTest.php | 37 ++++++++++++++-- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/app/Models/Expense.php b/app/Models/Expense.php index f0fdeafca3e6..4258a70dd8a5 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -114,7 +114,7 @@ class Expense extends BaseModel public function category() { - return $this->belongsTo(ExpenseCategory::class); + return $this->belongsTo(ExpenseCategory::class)->withTrashed(); } public function payment_type() diff --git a/app/Services/Report/ProfitLoss.php b/app/Services/Report/ProfitLoss.php index a36765b1613d..74270403d106 100644 --- a/app/Services/Report/ProfitLoss.php +++ b/app/Services/Report/ProfitLoss.php @@ -55,9 +55,9 @@ class ProfitLoss protected Company $company; - public function __construct(Company $company, array $payload, CurrencyApi $currency_api) + public function __construct(Company $company, array $payload) { - $this->currency_api = $currency_api; + $this->currency_api = new CurrencyApi(); $this->company = $company; @@ -167,7 +167,7 @@ class ProfitLoss } - private function calculateExpensesWithoutTaxes($expenses) + private function calculateExpenses($expenses) { $data = []; @@ -177,8 +177,11 @@ class ProfitLoss { $data[] = [ 'total' => $expense->amount, - 'converted_total' => $this->getConvertedTotal($expense->amount, $expense->exchange_rate), - 'tax' => $this->getTax($expense), + 'converted_total' => $converted_total = $this->getConvertedTotal($expense->amount, $expense->exchange_rate), + 'tax' => $tax = $this->getTax($expense), + 'net_converted_total' => $expense->uses_inclusive_taxes ? ( $converted_total - $tax ) : $converted_total, + 'category_id' => $expense->category_id, + 'category_name' => $expense->category ? $expense->category->name : "No Category Defined", ]; } @@ -193,17 +196,37 @@ class ProfitLoss if($expense->calculate_tax_by_amount) { - $total_tax = $expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3; + return $expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3; } - return ($amount - ($amount / (1 + ($tax_rate / 100)))); + if($expense->uses_inclusive_taxes){ + + $inclusive = 0; + + $inclusive += ($amount - ($amount / (1 + ($expense->tax_rate1 / 100)))); + $inclusive += ($amount - ($amount / (1 + ($expense->tax_rate2 / 100)))); + $inclusive += ($amount - ($amount / (1 + ($expense->tax_rate3 / 100)))); + + return round($inclusive,2); + + } + + + $exclusive = 0; + + $exclusive += $amount * ($expense->tax_rate1 / 100); + $exclusive += $amount * ($expense->tax_rate2 / 100); + $exclusive += $amount * ($expense->tax_rate3 / 100); + + + return $exclusive; } - private function getConvertedTotal($amount, $exchange_rate) + private function getConvertedTotal($amount, $exchange_rate = 1) { - return round($amount * $exchange_rate,2); + return round(($amount * $exchange_rate) ,2); } private function expenseCalcWithTax() @@ -231,7 +254,7 @@ class ProfitLoss $this->is_expense_billed = boolval($this->payload['expense_billed']); if(array_key_exists('include_tax', $this->payload)) - $this->is_tax_included = boolval($this->payload['is_tax_included']); + $this->is_tax_included = boolval($this->payload['include_tax']); return $this; diff --git a/tests/Feature/Export/ProfitAndLossReportTest.php b/tests/Feature/Export/ProfitAndLossReportTest.php index 2cd0c7755046..7f8f2351b192 100644 --- a/tests/Feature/Export/ProfitAndLossReportTest.php +++ b/tests/Feature/Export/ProfitAndLossReportTest.php @@ -10,7 +10,9 @@ */ namespace Tests\Feature\Export; +use App\Models\Company; use App\Models\Invoice; +use App\Services\Report\ProfitLoss; use App\Utils\Traits\MakesHash; use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Facades\Storage; @@ -20,6 +22,7 @@ use Tests\TestCase; /** * @test + * @covers App\Services\Report\ProfitLoss */ class ProfitAndLossReportTest extends TestCase { @@ -39,16 +42,42 @@ class ProfitAndLossReportTest extends TestCase $this->withoutExceptionHandling(); } - private function buildReportData() +/** + * + * start_date - Y-m-d + end_date - Y-m-d + date_range - + all + last7 + last30 + this_month + last_month + this_quarter + last_quarter + this_year + custom + income_billed - true = Invoiced || false = Payments + expense_billed - true = Expensed || false = Expenses marked as paid + include_tax - true tax_included || false - tax_excluded + +*/ + public function testProfitLossInstance() { $company = Company::factory()->create([ 'account_id' => $this->account->id, ]); - } + $payload = [ + 'start_date' => '2000-01-01', + 'end_date' => '2030-01-11', + 'date_range' => 'custom', + 'income_billed' => true, + 'include_tax' => false + ]; - public function testExportCsv() - { + $pl = new ProfitLoss($company, $payload); + + $this->assertInstanceOf(ProfitLoss::class, $pl); } }