mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
PnL Expense tests
This commit is contained in:
parent
4e8389f72e
commit
e0373006d8
@ -39,6 +39,9 @@ class ExpenseFactory
|
||||
$expense->custom_value2 = '';
|
||||
$expense->custom_value3 = '';
|
||||
$expense->custom_value4 = '';
|
||||
$expense->tax_amount1 = 0;
|
||||
$expense->tax_amount2 = 0;
|
||||
$expense->tax_amount3 = 0;
|
||||
|
||||
return $expense;
|
||||
}
|
||||
|
@ -551,4 +551,17 @@ class Company extends BaseModel
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ class Design extends BaseDesign
|
||||
{
|
||||
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 [
|
||||
['element' => 'tr', 'properties' => ['data-ref' => 'statement-label'], 'elements' => [
|
||||
|
@ -16,7 +16,11 @@ use App\Libraries\MultiDB;
|
||||
use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
class ProfitLoss
|
||||
{
|
||||
@ -127,6 +131,8 @@ class ProfitLoss
|
||||
|
||||
public function getExpenseBreakDown() :array
|
||||
{
|
||||
ksort($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()
|
||||
{
|
||||
@ -392,6 +446,8 @@ class ProfitLoss
|
||||
{
|
||||
$map = new \stdClass;
|
||||
|
||||
$amount = $expense->amount;
|
||||
|
||||
$map->total = $expense->amount;
|
||||
$map->converted_total = $converted_total = $this->getConvertedTotal($expense->amount, $expense->exchange_rate);
|
||||
$map->tax = $tax = $this->getTax($expense);
|
||||
@ -438,11 +494,14 @@ class ProfitLoss
|
||||
private function getTax($expense)
|
||||
{
|
||||
$amount = $expense->amount;
|
||||
|
||||
//is amount tax
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -459,7 +518,6 @@ class ProfitLoss
|
||||
|
||||
}
|
||||
|
||||
|
||||
$exclusive = 0;
|
||||
|
||||
$exclusive += $amount * ($expense->tax_rate1 / 100);
|
||||
|
@ -13,6 +13,7 @@ namespace Tests\Feature\Export;
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Factory\ExpenseCategoryFactory;
|
||||
use App\Factory\ExpenseFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
@ -336,9 +337,86 @@ class ProfitAndLossReportTest extends TestCase
|
||||
|
||||
$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()
|
||||
{
|
||||
$this->buildData();
|
||||
@ -407,13 +485,80 @@ class ProfitAndLossReportTest extends TestCase
|
||||
|
||||
$bd = $pl->getExpenseBreakDown();
|
||||
|
||||
|
||||
nlog($bd);
|
||||
|
||||
$this->assertEquals(array_sum(array_column($bd,'total')), 30);
|
||||
|
||||
$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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user