PnL Expense tests

This commit is contained in:
David Bomba 2022-05-13 16:42:04 +10:00
parent 4e8389f72e
commit e0373006d8
5 changed files with 226 additions and 7 deletions

View File

@ -39,6 +39,9 @@ class ExpenseFactory
$expense->custom_value2 = ''; $expense->custom_value2 = '';
$expense->custom_value3 = ''; $expense->custom_value3 = '';
$expense->custom_value4 = ''; $expense->custom_value4 = '';
$expense->tax_amount1 = 0;
$expense->tax_amount2 = 0;
$expense->tax_amount3 = 0;
return $expense; return $expense;
} }

View File

@ -551,4 +551,17 @@ class Company extends BaseModel
{ {
return ctrans('texts.company'); return ctrans('texts.company');
} }
public function date_format()
{
$date_formats = Cache::get('date_formats');
if(!$date_formats)
$this->buildCache(true);
return $date_formats->filter(function ($item) {
return $item->id == $this->getSetting('date_format_id');
})->first()->format;
}
} }

View File

@ -226,7 +226,7 @@ class Design extends BaseDesign
{ {
if ($this->type === 'statement') { if ($this->type === 'statement') {
$s_date = $this->translateDate(now()->format('Y-m-d'), $this->client->date_format(), $this->client->locale()); $s_date = $this->translateDate(now()->format($client->company->date_format()), $this->client->date_format(), $this->client->locale());
return [ return [
['element' => 'tr', 'properties' => ['data-ref' => 'statement-label'], 'elements' => [ ['element' => 'tr', 'properties' => ['data-ref' => 'statement-label'], 'elements' => [

View File

@ -16,7 +16,11 @@ use App\Libraries\MultiDB;
use App\Models\Company; use App\Models\Company;
use App\Models\Expense; use App\Models\Expense;
use App\Models\Payment; use App\Models\Payment;
use App\Utils\Ninja;
use App\Utils\Number;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
class ProfitLoss class ProfitLoss
{ {
@ -126,7 +130,9 @@ class ProfitLoss
} }
public function getExpenseBreakDown() :array public function getExpenseBreakDown() :array
{ {
ksort($this->expense_break_down);
return $this->expense_break_down; return $this->expense_break_down;
} }
@ -325,6 +331,54 @@ class ProfitLoss
] ]
*/ */
public function getCsv()
{
MultiDB::setDb($this->company->db);
App::forgetInstance('translator');
App::setLocale($this->company->locale());
$t = app('translator');
$t->replace(Ninja::transformTranslations($this->company->settings));
$csv = Writer::createFromString();
$csv->insertOne([ctrans('texts.profit_and_loss')]);
$csv->insertOne([ctrans('texts.company_name'), $this->company->present()->name()]);
$csv->insertOne([ctrans('texts.date_range'), Carbon::parse($this->start_date)->format($this->company->date_format()), Carbon::parse($this->end_date)->format($this->company->date_format())]);
//gross sales ex tax
$csv->insertOne(['--------------------']);
$csv->insertOne([ctrans('texts.total_revenue'), Number::formatMoney($this->income, $this->company)]);
//total taxes
$csv->insertOne([ctrans('texts.total_taxes'), Number::formatMoney($this->income_taxes, $this->company)]);
//expense
$csv->insertOne(['--------------------']);
foreach($this->expense_break_down as $expense_breakdown)
{
$csv->insertOne([$expense_breakdown['category_name'], Number::formatMoney($expense_breakdown['total'], $this->company)]);
}
//total expense taxes
$csv->insertOne(['--------------------']);
$csv->insertOne([ctrans('texts.total_expenses'), Number::formatMoney(array_sum(array_column($this->expense_break_down, 'total')), $this->company)]);
$csv->insertOne([ctrans('texts.total_taxes'), Number::formatMoney(array_sum(array_column($this->expense_break_down, 'tax')), $this->company)]);
$csv->insertOne(['--------------------']);
$csv->insertOne([ctrans('texts.total_profit'), Number::formatMoney($this->income - array_sum(array_column($this->expense_break_down, 'total')), $this->company)]);
//net profit
return $csv->toString();
}
private function invoicePaymentIncome() private function invoicePaymentIncome()
{ {
@ -392,6 +446,8 @@ class ProfitLoss
{ {
$map = new \stdClass; $map = new \stdClass;
$amount = $expense->amount;
$map->total = $expense->amount; $map->total = $expense->amount;
$map->converted_total = $converted_total = $this->getConvertedTotal($expense->amount, $expense->exchange_rate); $map->converted_total = $converted_total = $this->getConvertedTotal($expense->amount, $expense->exchange_rate);
$map->tax = $tax = $this->getTax($expense); $map->tax = $tax = $this->getTax($expense);
@ -438,11 +494,14 @@ class ProfitLoss
private function getTax($expense) private function getTax($expense)
{ {
$amount = $expense->amount; $amount = $expense->amount;
//is amount tax //is amount tax
if($expense->calculate_tax_by_amount) if($expense->calculate_tax_by_amount)
{ {
nlog($expense->tax_amount1);
nlog($expense->tax_amount2);
nlog($expense->tax_amount3);
return $expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3; return $expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3;
} }
@ -459,7 +518,6 @@ class ProfitLoss
} }
$exclusive = 0; $exclusive = 0;
$exclusive += $amount * ($expense->tax_rate1 / 100); $exclusive += $amount * ($expense->tax_rate1 / 100);

View File

@ -13,6 +13,7 @@ namespace Tests\Feature\Export;
use App\DataMapper\ClientSettings; use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings; use App\DataMapper\CompanySettings;
use App\Factory\ExpenseCategoryFactory; use App\Factory\ExpenseCategoryFactory;
use App\Factory\ExpenseFactory;
use App\Factory\InvoiceFactory; use App\Factory\InvoiceFactory;
use App\Models\Account; use App\Models\Account;
use App\Models\Client; use App\Models\Client;
@ -336,9 +337,86 @@ class ProfitAndLossReportTest extends TestCase
$this->account->delete(); $this->account->delete();
}
public function testSimpleExpenseAmountTax()
{
$this->buildData();
$e = ExpenseFactory::create($this->company->id, $this->user->id);
$e->amount = 10;
$e->date = '2022-01-01';
$e->calculate_tax_by_amount = true;
$e->tax_amount1 = 10;
$e->save();
$pl = new ProfitLoss($this->company, $this->payload);
$pl->build();
$expenses = $pl->getExpenses();
$expense = $expenses[0];
$this->assertEquals(10, $expense->total);
$this->assertEquals(10, $expense->tax);
$this->account->delete();
} }
public function testSimpleExpenseTaxRateExclusive()
{
$this->buildData();
$e = ExpenseFactory::create($this->company->id, $this->user->id);
$e->amount = 10;
$e->date = '2022-01-01';
$e->tax_rate1 = 10;
$e->tax_name1 = 'GST';
$e->uses_inclusive_taxes = false;
$e->save();
$pl = new ProfitLoss($this->company, $this->payload);
$pl->build();
$expenses = $pl->getExpenses();
$expense = $expenses[0];
$this->assertEquals(10, $expense->total);
$this->assertEquals(1, $expense->tax);
$this->account->delete();
}
public function testSimpleExpenseTaxRateInclusive()
{
$this->buildData();
$e = ExpenseFactory::create($this->company->id, $this->user->id);
$e->amount = 10;
$e->date = '2022-01-01';
$e->tax_rate1 = 10;
$e->tax_name1 = 'GST';
$e->uses_inclusive_taxes = false;
$e->save();
$pl = new ProfitLoss($this->company, $this->payload);
$pl->build();
$expenses = $pl->getExpenses();
$expense = $expenses[0];
$this->assertEquals(10, $expense->total);
$this->assertEquals(1, $expense->tax);
$this->account->delete();
}
public function testSimpleExpenseBreakdown() public function testSimpleExpenseBreakdown()
{ {
$this->buildData(); $this->buildData();
@ -407,13 +485,80 @@ class ProfitAndLossReportTest extends TestCase
$bd = $pl->getExpenseBreakDown(); $bd = $pl->getExpenseBreakDown();
nlog($bd);
$this->assertEquals(array_sum(array_column($bd,'total')), 30); $this->assertEquals(array_sum(array_column($bd,'total')), 30);
$this->account->delete(); $this->account->delete();
} }
public function testCsvGeneration()
{
$this->buildData();
$client = Client::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'is_deleted' => 0,
]);
Invoice::factory()->count(1)->create([
'client_id' => $client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 10,
'balance' => 10,
'status_id' => 2,
'total_taxes' => 1,
'date' => '2022-01-01',
'terms' => 'nada',
'discount' => 0,
'tax_rate1' => 10,
'tax_rate2' => 0,
'tax_rate3' => 0,
'tax_name1' => "GST",
'tax_name2' => '',
'tax_name3' => '',
'uses_inclusive_taxes' => true,
]);
$ec = ExpenseCategoryFactory::create($this->company->id, $this->user->id);
$ec->name = 'Accounting';
$ec->save();
$e = Expense::factory()->create([
'category_id' => $ec->id,
'amount' => 10,
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'date' => '2022-01-01',
'exchange_rate' => 1,
'currency_id' => $this->company->settings->currency_id
]);
$ec = ExpenseCategoryFactory::create($this->company->id, $this->user->id);
$ec->name = 'Fuel';
$ec->save();
$e = Expense::factory(2)->create([
'category_id' => $ec->id,
'amount' => 10,
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'date' => '2022-01-01',
'exchange_rate' => 1,
'currency_id' => $this->company->settings->currency_id
]);
$pl = new ProfitLoss($this->company, $this->payload);
$pl->build();
$this->assertNotNull($pl->getCsv());
$this->account->delete();
}
} }