mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Improved implementation of liability accounts and the option to add or remove accounts from the net-worth calculations.
This commit is contained in:
parent
7dc72a2894
commit
8c1d1d1db0
148
app/Helpers/Report/NetWorth.php
Normal file
148
app/Helpers/Report/NetWorth.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* NetWorth.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class NetWorth
|
||||
*/
|
||||
class NetWorth implements NetWorthInterface
|
||||
{
|
||||
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepos;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Returns the user's net worth in an array with the following layout:
|
||||
*
|
||||
* -
|
||||
* - currency: TransactionCurrency object
|
||||
* - date: the current date
|
||||
* - amount: the user's net worth in that currency.
|
||||
*
|
||||
* This repeats for each currency the user has transactions in.
|
||||
* Result of this method is cached.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNetWorthByCurrency(Collection $accounts, Carbon $date): array
|
||||
{
|
||||
|
||||
// start in the past, end in the future? use $date
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($date);
|
||||
$cache->addProperty('net-worth-by-currency');
|
||||
$cache->addProperty(implode(',', $accounts->pluck('id')->toArray()));
|
||||
if ($cache->has()) {
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$netWorth = [];
|
||||
$result = [];
|
||||
Log::debug(sprintf('Now in getNetWorthByCurrency(%s)', $date->format('Y-m-d')));
|
||||
|
||||
// get default currency
|
||||
$default = app('amount')->getDefaultCurrencyByUser($this->user);
|
||||
|
||||
// get all balances:
|
||||
$balances = app('steam')->balancesByAccounts($accounts, $date);
|
||||
|
||||
// get the preferred currency for this account
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Now at account #%d: "%s"', $account->id, $account->name));
|
||||
$currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id');
|
||||
$currencyId = 0 === $currencyId ? $default->id : $currencyId;
|
||||
|
||||
Log::debug(sprintf('Currency ID is #%d', $currencyId));
|
||||
|
||||
// balance in array:
|
||||
$balance = $balances[$account->id] ?? '0';
|
||||
|
||||
Log::debug(sprintf('Balance is %s', $balance));
|
||||
|
||||
// if the account is a credit card, subtract the virtual balance from the balance,
|
||||
// to better reflect that this is not money that is actually "yours".
|
||||
$role = (string)$this->accountRepository->getMetaValue($account, 'accountRole');
|
||||
$virtualBalance = (string)$account->virtual_balance;
|
||||
if ('ccAsset' === $role && '' !== $virtualBalance && (float)$virtualBalance > 0) {
|
||||
$balance = bcsub($balance, $virtualBalance);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Balance corrected to %s', $balance));
|
||||
|
||||
if (!isset($netWorth[$currencyId])) {
|
||||
$netWorth[$currencyId] = '0';
|
||||
}
|
||||
$netWorth[$currencyId] = bcadd($balance, $netWorth[$currencyId]);
|
||||
|
||||
Log::debug(sprintf('Total net worth for currency #%d is %s', $currencyId, $netWorth[$currencyId]));
|
||||
}
|
||||
ksort($netWorth);
|
||||
|
||||
// loop results and add currency information:
|
||||
foreach ($netWorth as $currencyId => $balance) {
|
||||
$result[] = [
|
||||
'currency' => $this->currencyRepos->findNull($currencyId),
|
||||
'balance' => $balance,
|
||||
];
|
||||
}
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
// make repository:
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->accountRepository->setUser($this->user);
|
||||
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->currencyRepos->setUser($this->user);
|
||||
}
|
||||
}
|
60
app/Helpers/Report/NetWorthInterface.php
Normal file
60
app/Helpers/Report/NetWorthInterface.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* NetWorthInterface.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface NetWorthInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Report
|
||||
*/
|
||||
interface NetWorthInterface
|
||||
{
|
||||
/**
|
||||
* Returns the user's net worth in an array with the following layout:
|
||||
*
|
||||
* -
|
||||
* - currency: TransactionCurrency object
|
||||
* - date: the current date
|
||||
* - amount: the user's net worth in that currency.
|
||||
*
|
||||
* This repeats for each currency the user has transactions in.
|
||||
* Result of this method is cached.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNetWorthByCurrency(Collection $accounts, Carbon $date): array;
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void;
|
||||
|
||||
}
|
@ -99,7 +99,13 @@ class CreateController extends Controller
|
||||
];
|
||||
|
||||
// pre fill some data
|
||||
$request->session()->flash('preFilled', ['currency_id' => $defaultCurrency->id]);
|
||||
$hasOldInput = null !== $request->old('_token');
|
||||
$request->session()->flash(
|
||||
'preFilled', [
|
||||
'currency_id' => $defaultCurrency->id,
|
||||
'include_net_worth' => $hasOldInput ? (bool)$request->old('include_net_worth') : true,
|
||||
]
|
||||
);
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('accounts.create.fromStore')) {
|
||||
|
@ -116,6 +116,11 @@ class EditController extends Controller
|
||||
$openingBalanceDate = $repository->getOpeningBalanceDate($account);
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
$currency = $this->currencyRepos->findNull((int)$repository->getMetaValue($account, 'currency_id'));
|
||||
|
||||
// include this account in net-worth charts?
|
||||
$includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
|
||||
$includeNetWorth = null === $includeNetWorth ? true : '1' === $includeNetWorth;
|
||||
|
||||
if (null === $currency) {
|
||||
$currency = $default;
|
||||
}
|
||||
@ -133,6 +138,7 @@ class EditController extends Controller
|
||||
'openingBalance' => $openingBalanceAmount,
|
||||
'virtualBalance' => $account->virtual_balance,
|
||||
'currency_id' => $currency->id,
|
||||
'include_net_worth' => $includeNetWorth,
|
||||
'interest' => $repository->getMetaValue($account, 'interest'),
|
||||
'interest_period' => $repository->getMetaValue($account, 'interest_period'),
|
||||
'notes' => $this->repository->getNoteText($account),
|
||||
|
@ -24,6 +24,7 @@ namespace FireflyIII\Http\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
@ -67,22 +68,41 @@ class ReportController extends Controller
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('chart.report.net-worth');
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty(implode(',', $accounts->pluck('id')->toArray()));
|
||||
$cache->addProperty($end);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$current = clone $start;
|
||||
$chartData = [];
|
||||
/** @var NetWorthInterface $helper */
|
||||
$helper = app(NetWorthInterface::class);
|
||||
$helper->setUser(auth()->user());
|
||||
|
||||
while ($current < $end) {
|
||||
$balances = app('steam')->balancesByAccounts($accounts, $current);
|
||||
$sum = $this->arraySum($balances);
|
||||
$label = $current->formatLocalized((string)trans('config.month_and_day'));
|
||||
$chartData[$label] = $sum;
|
||||
// get balances by date, grouped by currency.
|
||||
$result = $helper->getNetWorthByCurrency($accounts, $current);
|
||||
|
||||
// loop result, add to array.
|
||||
/** @var array $netWorthItem */
|
||||
foreach ($result as $netWorthItem) {
|
||||
$currencyId = $netWorthItem['currency']->id;
|
||||
$label = $current->formatLocalized((string)trans('config.month_and_day'));
|
||||
if (!isset($chartData[$currencyId])) {
|
||||
$chartData[$currencyId] = [
|
||||
'label' => 'Net worth in ' . $netWorthItem['currency']->name,
|
||||
'type' => 'line',
|
||||
'currency_symbol' => $netWorthItem['currency']->symbol,
|
||||
'entries' => [],
|
||||
];
|
||||
}
|
||||
$chartData[$currencyId]['entries'][$label] = $netWorthItem['balance'];
|
||||
|
||||
}
|
||||
$current->addDays(7);
|
||||
}
|
||||
|
||||
$data = $this->generator->singleSet((string)trans('firefly.net_worth'), $chartData);
|
||||
$data = $this->generator->multiSet($chartData);
|
||||
$cache->store($data);
|
||||
|
||||
return response()->json($data);
|
||||
|
@ -24,6 +24,7 @@ namespace FireflyIII\Http\Controllers\Json;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
@ -37,6 +38,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Http\Controllers\RequestInformation;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class BoxController.
|
||||
@ -235,16 +237,13 @@ class BoxController extends Controller
|
||||
/**
|
||||
* Total user net worth.
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function netWorth(AccountRepositoryInterface $repository): JsonResponse
|
||||
public function netWorth(): JsonResponse
|
||||
{
|
||||
$date = new Carbon(date('Y-m-d')); // needed so its per day.
|
||||
$date = Carbon::create()->startOfDay();
|
||||
|
||||
// start and end in the future? use $end
|
||||
if ($this->notInSessionRange($date)) {
|
||||
@ -252,48 +251,43 @@ class BoxController extends Controller
|
||||
$date = session('end', Carbon::now()->endOfMonth());
|
||||
}
|
||||
|
||||
// start in the past, end in the future? use $date
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($date);
|
||||
$cache->addProperty('box-net-worth');
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$netWorth = [];
|
||||
$accounts = $repository->getActiveAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
/** @var NetWorthInterface $netWorthHelper */
|
||||
$netWorthHelper = app(NetWorthInterface::class);
|
||||
$netWorthHelper->setUser(auth()->user());
|
||||
|
||||
$balances = app('steam')->balancesByAccounts($accounts, $date);
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$allAccounts = $accountRepository->getActiveAccountsByType(
|
||||
[AccountType::DEFAULT, AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]
|
||||
);
|
||||
Log::debug(sprintf('Found %d accounts.', $allAccounts->count()));
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountCurrency = $this->getCurrencyOrDefault($account);
|
||||
$balance = $balances[$account->id] ?? '0';
|
||||
// filter list on preference of being included.
|
||||
$filtered = $allAccounts->filter(
|
||||
function (Account $account) use ($accountRepository) {
|
||||
$includeNetWorth = $accountRepository->getMetaValue($account, 'include_net_worth');
|
||||
$result = null === $includeNetWorth ? true : '1' === $includeNetWorth;
|
||||
if (false === $result) {
|
||||
Log::debug(sprintf('Will not include "%s" in net worth charts.', $account->name));
|
||||
}
|
||||
|
||||
// if the account is a credit card, subtract the virtual balance from the balance,
|
||||
// to better reflect that this is not money that is actually "yours".
|
||||
$role = (string)$repository->getMetaValue($account, 'accountRole');
|
||||
$virtualBalance = (string)$account->virtual_balance;
|
||||
if ('ccAsset' === $role && '' !== $virtualBalance && (float)$virtualBalance > 0) {
|
||||
$balance = bcsub($balance, $virtualBalance);
|
||||
return $result;
|
||||
}
|
||||
);
|
||||
|
||||
$netWorthSet = $netWorthHelper->getNetWorthByCurrency($filtered, $date);
|
||||
|
||||
if (!isset($netWorth[$accountCurrency->id])) {
|
||||
$netWorth[$accountCurrency->id]['currency'] = $accountCurrency;
|
||||
$netWorth[$accountCurrency->id]['sum'] = '0';
|
||||
}
|
||||
$netWorth[$accountCurrency->id]['sum'] = bcadd($netWorth[$accountCurrency->id]['sum'], $balance);
|
||||
}
|
||||
|
||||
$return = [];
|
||||
foreach ($netWorth as $currencyId => $data) {
|
||||
$return[$currencyId] = app('amount')->formatAnything($data['currency'], $data['sum'], false);
|
||||
foreach ($netWorthSet as $index => $data) {
|
||||
/** @var TransactionCurrency $currency */
|
||||
$currency = $data['currency'];
|
||||
$return[$currency->id] = app('amount')->formatAnything($currency, $data['balance'], false);
|
||||
}
|
||||
$return = [
|
||||
'net_worths' => array_values($return),
|
||||
];
|
||||
|
||||
$cache->store($return);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,11 @@ class AccountFormRequest extends Request
|
||||
'notes' => $this->string('notes'),
|
||||
'interest' => $this->string('interest'),
|
||||
'interest_period' => $this->string('interest_period'),
|
||||
'include_net_worth' => '1',
|
||||
];
|
||||
if (false === $this->boolean('include_net_worth')) {
|
||||
$data['include_net_worth'] = '0';
|
||||
}
|
||||
|
||||
// if the account type is "liabilities" there are actually four types of liability
|
||||
// that could have been selected.
|
||||
|
@ -38,6 +38,8 @@ use FireflyIII\Helpers\Report\BalanceReportHelper;
|
||||
use FireflyIII\Helpers\Report\BalanceReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\BudgetReportHelper;
|
||||
use FireflyIII\Helpers\Report\BudgetReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorth;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Helpers\Report\PopupReport;
|
||||
use FireflyIII\Helpers\Report\PopupReportInterface;
|
||||
use FireflyIII\Helpers\Report\ReportHelper;
|
||||
@ -188,5 +190,8 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
|
||||
// IP thing:
|
||||
$this->app->bind(IPRetrievalInterface::class, IpifyOrg::class);
|
||||
|
||||
// net worth thing.
|
||||
$this->app->bind(NetWorthInterface::class, NetWorth::class);
|
||||
}
|
||||
}
|
||||
|
@ -45,11 +45,11 @@ use Validator;
|
||||
trait AccountServiceTrait
|
||||
{
|
||||
/** @var array */
|
||||
public $validAssetFields = ['accountRole', 'accountNumber', 'currency_id', 'BIC'];
|
||||
public $validAssetFields = ['accountRole', 'accountNumber', 'currency_id', 'BIC', 'include_net_worth'];
|
||||
/** @var array */
|
||||
public $validCCFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber', 'currency_id', 'BIC'];
|
||||
public $validCCFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber', 'currency_id', 'BIC', 'include_net_worth'];
|
||||
/** @var array */
|
||||
public $validFields = ['accountNumber', 'currency_id', 'BIC', 'interest', 'interest_period'];
|
||||
public $validFields = ['accountNumber', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth'];
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
@ -332,6 +332,7 @@ trait AccountServiceTrait
|
||||
* @param string $note
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function updateNote(Account $account, string $note): bool
|
||||
{
|
||||
|
@ -185,17 +185,11 @@ return [
|
||||
'Config',
|
||||
'Request',
|
||||
'ExpandedForm' => [
|
||||
'is_safe' => [
|
||||
'date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer', 'textarea', 'location',
|
||||
'file', 'staticText', 'password', 'nonSelectableAmount',
|
||||
'number', 'assetAccountList', 'amountNoCurrency', 'currencyList', 'ruleGroupList', 'assetAccountCheckList', 'ruleGroupListWithEmpty',
|
||||
'piggyBankList', 'currencyListEmpty', 'activeAssetAccountList', 'percentage', 'activeLongAccountList', 'longAccountList',
|
||||
],
|
||||
],
|
||||
'Form' => [
|
||||
'is_safe' => [
|
||||
'input', 'select', 'checkbox', 'model', 'open', 'radio', 'textarea', 'file',
|
||||
],
|
||||
'is_safe' => ['date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer', 'textarea', 'location', 'file',
|
||||
'staticText', 'password', 'nonSelectableAmount', 'number', 'assetAccountList', 'amountNoCurrency', 'currencyList',
|
||||
'ruleGroupList', 'assetAccountCheckList', 'ruleGroupListWithEmpty', 'piggyBankList', 'currencyListEmpty',
|
||||
'activeAssetAccountList', 'percentage', 'activeLongAccountList', 'longAccountList',],],
|
||||
'Form' => ['is_safe' => ['input', 'select', 'checkbox', 'model', 'open', 'radio', 'textarea', 'file',],
|
||||
],
|
||||
],
|
||||
|
||||
|
@ -50,7 +50,8 @@
|
||||
{{ ExpandedForm.select('accountRole', roles,null,{helpText : 'asset_account_role_help'|_}) }}
|
||||
{{ ExpandedForm.amountNoCurrency('virtualBalance') }}
|
||||
{% endif %}
|
||||
|
||||
{# only correct way to do active checkbox #}
|
||||
{{ ExpandedForm.checkbox('include_net_worth', 1) }}
|
||||
{{ ExpandedForm.textarea('notes',null,{helpText: trans('firefly.field_supports_markdown')}) }}
|
||||
|
||||
</div>
|
||||
|
@ -56,10 +56,14 @@
|
||||
{{ ExpandedForm.amountNoCurrency('virtualBalance',null) }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
{{ ExpandedForm.textarea('notes',preFilled.notes,{helpText: trans('firefly.field_supports_markdown')}) }}
|
||||
|
||||
{# only correct way to do active checkbox #}
|
||||
{{ ExpandedForm.checkbox('active', 1) }}
|
||||
{# only correct way to do active checkbox #}
|
||||
{{ ExpandedForm.checkbox('include_net_worth', 1) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -27,11 +27,6 @@
|
||||
<div>
|
||||
<canvas id="overview-chart" style="width:100%;height:400px;" height="400" width="100%"></canvas>
|
||||
</div>
|
||||
<p>
|
||||
{% if isLiability %}
|
||||
<em>This chart pre-calculates rent starting from the last transaction you've entered. It's just an estimation.</em>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -199,7 +199,6 @@ class AttachmentControllerTest extends TestCase
|
||||
// test API
|
||||
$response = $this->get('/api/v1/attachments/' . $attachment->id);
|
||||
$response->assertStatus(200);
|
||||
$response->assertStatus(200);
|
||||
$response->assertJson(['data' => ['type' => 'attachments', 'links' => true],]);
|
||||
$response->assertSee($attachment->filename); // attachment file name
|
||||
$response->assertHeader('Content-Type', 'application/vnd.api+json');
|
||||
|
@ -70,6 +70,7 @@ class EditControllerTest extends TestCase
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('123');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccType'])->andReturn('');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccMonthlyPaymentDate'])->andReturn('');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
|
||||
@ -113,6 +114,7 @@ class EditControllerTest extends TestCase
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccType'])->andReturn('');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccMonthlyPaymentDate'])->andReturn('');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
|
||||
|
@ -50,7 +50,7 @@ class ReportControllerTest extends TestCase
|
||||
$generator = $this->mock(GeneratorInterface::class);
|
||||
|
||||
Steam::shouldReceive('balancesByAccounts')->andReturn(['5', '10']);
|
||||
$generator->shouldReceive('singleSet')->andReturn([]);
|
||||
$generator->shouldReceive('multiSet')->andReturn([]);
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('chart.report.net-worth', [1, '20120101', '20120131']));
|
||||
|
@ -24,6 +24,7 @@ namespace Tests\Feature\Controllers\Json;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
@ -155,12 +156,26 @@ class BoxControllerTest extends TestCase
|
||||
*/
|
||||
public function testNetWorth(): void
|
||||
{
|
||||
$result = [
|
||||
[
|
||||
'currency' => TransactionCurrency::find(1),
|
||||
'balance' => '3',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
$netWorthHelper = $this->mock(NetWorthInterface::class);
|
||||
$netWorthHelper->shouldReceive('setUser')->once();
|
||||
$netWorthHelper->shouldReceive('getNetWorthByCurrency')->once()->andReturn($result);
|
||||
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$accountRepos->shouldReceive('getActiveAccountsByType')->andReturn(new Collection([$this->user()->accounts()->first()]));
|
||||
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('ccAsset');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('json.box.net-worth'));
|
||||
@ -172,12 +187,25 @@ class BoxControllerTest extends TestCase
|
||||
*/
|
||||
public function testNetWorthFuture(): void
|
||||
{
|
||||
$result = [
|
||||
[
|
||||
'currency' => TransactionCurrency::find(1),
|
||||
'balance' => '3',
|
||||
],
|
||||
];
|
||||
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
|
||||
$netWorthHelper = $this->mock(NetWorthInterface::class);
|
||||
$netWorthHelper->shouldReceive('setUser')->once();
|
||||
$netWorthHelper->shouldReceive('getNetWorthByCurrency')->once()->andReturn($result);
|
||||
|
||||
$accountRepos->shouldReceive('getActiveAccountsByType')->andReturn(new Collection([$this->user()->accounts()->first()]));
|
||||
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('ccAsset');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
|
||||
|
||||
$start = new Carbon;
|
||||
$start->addMonths(6)->startOfMonth();
|
||||
@ -194,12 +222,25 @@ class BoxControllerTest extends TestCase
|
||||
*/
|
||||
public function testNetWorthNoCurrency(): void
|
||||
{
|
||||
$result = [
|
||||
[
|
||||
'currency' => TransactionCurrency::find(1),
|
||||
'balance' => '3',
|
||||
],
|
||||
];
|
||||
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
|
||||
$netWorthHelper = $this->mock(NetWorthInterface::class);
|
||||
$netWorthHelper->shouldReceive('setUser')->once();
|
||||
$netWorthHelper->shouldReceive('getNetWorthByCurrency')->once()->andReturn($result);
|
||||
|
||||
$accountRepos->shouldReceive('getActiveAccountsByType')->andReturn(new Collection([$this->user()->accounts()->first()]));
|
||||
$currencyRepos->shouldReceive('findNull')->andReturn(null);
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('ccAsset');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('json.box.net-worth'));
|
||||
@ -211,14 +252,27 @@ class BoxControllerTest extends TestCase
|
||||
*/
|
||||
public function testNetWorthVirtual(): void
|
||||
{
|
||||
$result = [
|
||||
[
|
||||
'currency' => TransactionCurrency::find(1),
|
||||
'balance' => '3',
|
||||
],
|
||||
];
|
||||
|
||||
$account = $this->user()->accounts()->first();
|
||||
$account->virtual_balance = '1000';
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
|
||||
$netWorthHelper = $this->mock(NetWorthInterface::class);
|
||||
$netWorthHelper->shouldReceive('setUser')->once();
|
||||
$netWorthHelper->shouldReceive('getNetWorthByCurrency')->once()->andReturn($result);
|
||||
|
||||
$accountRepos->shouldReceive('getActiveAccountsByType')->andReturn(new Collection([$account]));
|
||||
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('ccAsset');
|
||||
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('json.box.net-worth'));
|
||||
|
@ -249,7 +249,7 @@ class SingleControllerTest extends TestCase
|
||||
// mock new account list:
|
||||
$currency = TransactionCurrency::first();
|
||||
$accountRepos->shouldReceive('getAccountsByType')
|
||||
->withArgs([[AccountType::ASSET, AccountType::DEFAULT]])->andReturn(new Collection([$account]))->once();
|
||||
->withArgs([[AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,]])->andReturn(new Collection([$account]))->once();
|
||||
Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->times(6);
|
||||
|
||||
$this->be($this->user());
|
||||
|
@ -1037,7 +1037,7 @@ class TransactionFactoryTest extends TestCase
|
||||
try {
|
||||
$factory->createPair($withdrawal, $data);
|
||||
} catch (FireflyException $e) {
|
||||
$this->assertEquals('At least one of the accounts must be an asset account.', $e->getMessage());
|
||||
$this->assertEquals('At least one of the accounts must be an asset account (Expense account, Revenue account).', $e->getMessage());
|
||||
}
|
||||
|
||||
$newCount = $withdrawal->transactions()->count();
|
||||
|
@ -28,8 +28,8 @@ use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Tests\TestCase;
|
||||
use Log;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Class AttachmentHelperTest
|
||||
@ -114,15 +114,31 @@ class AttachmentHelperTest extends TestCase
|
||||
public function testSaveAttachmentFromApi(): void
|
||||
{
|
||||
// mock calls:
|
||||
Crypt::shouldReceive('encrypt')->times(2)->andReturn('Some encrypted content');
|
||||
Crypt::shouldReceive('encrypt')->times(6)->andReturn('Some encrypted content');
|
||||
Storage::fake('upload');
|
||||
|
||||
$path = public_path('apple-touch-icon.png');
|
||||
$helper = new AttachmentHelper;
|
||||
$attachment = Attachment::first();
|
||||
$path = public_path('apple-touch-icon.png');
|
||||
$helper = new AttachmentHelper;
|
||||
|
||||
// make new attachment:
|
||||
$journal = $this->user()->transactionJournals()->inRandomOrder()->first();
|
||||
$attachment = Attachment::create(
|
||||
[
|
||||
'attachable_id' => $journal->id,
|
||||
'user_id' => $this->user()->id,
|
||||
'attachable_type' => TransactionJournal::class,
|
||||
'md5' => md5('Hello' . random_int(1, 10000)),
|
||||
'filename' => 'file.txt',
|
||||
'title' => 'Some title',
|
||||
'description' => 'Some descr',
|
||||
'mime' => 'text/plain',
|
||||
'size' => 30,
|
||||
'uploaded' => true,
|
||||
]
|
||||
);
|
||||
|
||||
// call helper
|
||||
$result = $helper->saveAttachmentFromApi($attachment, file_get_contents($path));
|
||||
$result = $helper->saveAttachmentFromApi($attachment, file_get_contents($path));
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
@ -138,10 +154,26 @@ class AttachmentHelperTest extends TestCase
|
||||
|
||||
$path = public_path('browserconfig.xml');
|
||||
$helper = new AttachmentHelper;
|
||||
$attachment = Attachment::first();
|
||||
|
||||
// make new attachment:
|
||||
$journal = $this->user()->transactionJournals()->inRandomOrder()->first();
|
||||
$attachment = Attachment::create(
|
||||
[
|
||||
'attachable_id' => $journal->id,
|
||||
'user_id' => $this->user()->id,
|
||||
'attachable_type' => TransactionJournal::class,
|
||||
'md5' => md5('Hello' . random_int(1, 10000)),
|
||||
'filename' => 'file.txt',
|
||||
'title' => 'Some title',
|
||||
'description' => 'Some descr',
|
||||
'mime' => 'text/plain',
|
||||
'size' => 30,
|
||||
'uploaded' => true,
|
||||
]
|
||||
);
|
||||
|
||||
// call helper
|
||||
$result = $helper->saveAttachmentFromApi($attachment, file_get_contents($path));
|
||||
$result = $helper->saveAttachmentFromApi($attachment, file_get_contents($path));
|
||||
|
||||
$this->assertFalse($result);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user