mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-15 16:57:09 +00:00
Expand currency view in accounts.
This commit is contained in:
@@ -27,6 +27,7 @@ use Carbon\Carbon;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Controllers\BasicDataSupport;
|
use FireflyIII\Support\Http\Controllers\BasicDataSupport;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
@@ -70,22 +71,22 @@ class IndexController extends Controller
|
|||||||
* */
|
* */
|
||||||
public function inactive(Request $request, string $objectType)
|
public function inactive(Request $request, string $objectType)
|
||||||
{
|
{
|
||||||
$inactivePage = true;
|
$inactivePage = true;
|
||||||
$subTitle = (string) trans(sprintf('firefly.%s_accounts_inactive', $objectType));
|
$subTitle = (string) trans(sprintf('firefly.%s_accounts_inactive', $objectType));
|
||||||
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
|
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
|
||||||
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
|
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
|
||||||
$collection = $this->repository->getInactiveAccountsByType($types);
|
$collection = $this->repository->getInactiveAccountsByType($types);
|
||||||
$total = $collection->count();
|
$total = $collection->count();
|
||||||
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
|
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
|
||||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||||
$accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
|
$accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
|
||||||
unset($collection);
|
unset($collection);
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$start->subDay();
|
$start->subDay();
|
||||||
|
|
||||||
$ids = $accounts->pluck('id')->toArray();
|
$ids = $accounts->pluck('id')->toArray();
|
||||||
@@ -94,13 +95,13 @@ class IndexController extends Controller
|
|||||||
$activities = app('steam')->getLastActivities($ids);
|
$activities = app('steam')->getLastActivities($ids);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$accounts->each(
|
$accounts->each(
|
||||||
function (Account $account) use ($activities, $startBalances, $endBalances): void {
|
function (Account $account) use ($activities, $startBalances, $endBalances): void {
|
||||||
|
$currency = $this->repository->getAccountCurrency($account);
|
||||||
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
|
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
|
||||||
$account->startBalance = $this->isInArray($startBalances, $account->id);
|
$account->startBalances = $this->getBalance($account, $currency, $startBalances);
|
||||||
$account->endBalance = $this->isInArray($endBalances, $account->id);
|
$account->endBalances = $this->getBalance($account, $currency, $endBalances);
|
||||||
$account->difference = bcsub($account->endBalance, $account->startBalance);
|
$account->differences = $this->subtract($account->startBalances, $account->endBalances);
|
||||||
$account->interest = app('steam')->bcround($this->repository->getMetaValue($account, 'interest'), 4);
|
$account->interest = app('steam')->bcround($this->repository->getMetaValue($account, 'interest'), 4);
|
||||||
$account->interestPeriod = (string) trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')));
|
$account->interestPeriod = (string) trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')));
|
||||||
$account->accountTypeString = (string) trans(sprintf('firefly.account_type_%s', $account->accountType->type));
|
$account->accountTypeString = (string) trans(sprintf('firefly.account_type_%s', $account->accountType->type));
|
||||||
@@ -110,7 +111,7 @@ class IndexController extends Controller
|
|||||||
);
|
);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
|
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
|
||||||
$accounts->setPath(route('accounts.inactive.index', [$objectType]));
|
$accounts->setPath(route('accounts.inactive.index', [$objectType]));
|
||||||
|
|
||||||
return view('accounts.index', compact('objectType', 'inactivePage', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
|
return view('accounts.index', compact('objectType', 'inactivePage', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
|
||||||
@@ -126,9 +127,9 @@ class IndexController extends Controller
|
|||||||
public function index(Request $request, string $objectType)
|
public function index(Request $request, string $objectType)
|
||||||
{
|
{
|
||||||
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
||||||
$subTitle = (string) trans(sprintf('firefly.%s_accounts', $objectType));
|
$subTitle = (string) trans(sprintf('firefly.%s_accounts', $objectType));
|
||||||
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
|
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
|
||||||
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
|
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
|
||||||
|
|
||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
|
|
||||||
@@ -144,10 +145,10 @@ class IndexController extends Controller
|
|||||||
unset($collection);
|
unset($collection);
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$start->subDay();
|
$start->subDay();
|
||||||
|
|
||||||
$ids = $accounts->pluck('id')->toArray();
|
$ids = $accounts->pluck('id')->toArray();
|
||||||
@@ -155,16 +156,17 @@ class IndexController extends Controller
|
|||||||
$endBalances = app('steam')->finalAccountsBalance($accounts, $end);
|
$endBalances = app('steam')->finalAccountsBalance($accounts, $end);
|
||||||
$activities = app('steam')->getLastActivities($ids);
|
$activities = app('steam')->getLastActivities($ids);
|
||||||
|
|
||||||
|
|
||||||
$accounts->each(
|
$accounts->each(
|
||||||
function (Account $account) use ($activities, $startBalances, $endBalances): void {
|
function (Account $account) use ($activities, $startBalances, $endBalances): void {
|
||||||
$interest = (string) $this->repository->getMetaValue($account, 'interest');
|
$interest = (string) $this->repository->getMetaValue($account, 'interest');
|
||||||
$interest = '' === $interest ? '0' : $interest;
|
$interest = '' === $interest ? '0' : $interest;
|
||||||
|
$currency = $this->repository->getAccountCurrency($account);
|
||||||
|
|
||||||
// See reference nr. 68
|
$account->startBalances = $this->getBalance($account, $currency, $startBalances);
|
||||||
|
$account->endBalances = $this->getBalance($account, $currency, $endBalances);
|
||||||
|
$account->differences = $this->subtract($account->startBalances, $account->endBalances);
|
||||||
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
|
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
|
||||||
$account->startBalance = $this->isInArray($startBalances, $account->id);
|
|
||||||
$account->endBalance = $this->isInArray($endBalances, $account->id);
|
|
||||||
$account->difference = bcsub($account->endBalance, $account->startBalance);
|
|
||||||
$account->interest = app('steam')->bcround($interest, 4);
|
$account->interest = app('steam')->bcround($interest, 4);
|
||||||
$account->interestPeriod = (string) trans(
|
$account->interestPeriod = (string) trans(
|
||||||
sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period'))
|
sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period'))
|
||||||
@@ -173,14 +175,17 @@ class IndexController extends Controller
|
|||||||
$account->location = $this->repository->getLocation($account);
|
$account->location = $this->repository->getLocation($account);
|
||||||
$account->liability_direction = $this->repository->getMetaValue($account, 'liability_direction');
|
$account->liability_direction = $this->repository->getMetaValue($account, 'liability_direction');
|
||||||
$account->current_debt = $this->repository->getMetaValue($account, 'current_debt') ?? '-';
|
$account->current_debt = $this->repository->getMetaValue($account, 'current_debt') ?? '-';
|
||||||
|
$account->currency = $currency;
|
||||||
$account->iban = implode(' ', str_split((string) $account->iban, 4));
|
$account->iban = implode(' ', str_split((string) $account->iban, 4));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// make paginator:
|
// make paginator:
|
||||||
app('log')->debug(sprintf('Count of accounts before LAP: %d', $accounts->count()));
|
app('log')->debug(sprintf('Count of accounts before LAP: %d', $accounts->count()));
|
||||||
|
|
||||||
/** @var LengthAwarePaginator $accounts */
|
/** @var LengthAwarePaginator $accounts */
|
||||||
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
|
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
|
||||||
$accounts->setPath(route('accounts.index', [$objectType]));
|
$accounts->setPath(route('accounts.index', [$objectType]));
|
||||||
|
|
||||||
app('log')->debug(sprintf('Count of accounts after LAP (1): %d', $accounts->count()));
|
app('log')->debug(sprintf('Count of accounts after LAP (1): %d', $accounts->count()));
|
||||||
@@ -188,4 +193,30 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
return view('accounts.index', compact('objectType', 'inactiveCount', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
|
return view('accounts.index', compact('objectType', 'inactiveCount', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getBalance(Account $account, ?TransactionCurrency $currency = null, array $balances): array
|
||||||
|
{
|
||||||
|
if (!array_key_exists($account->id, $balances)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$set = $balances[$account->id];
|
||||||
|
|
||||||
|
if ($this->convertToNative && $this->defaultCurrency->id === $currency?->id) {
|
||||||
|
unset($set['native_balance'], $set[$this->defaultCurrency->code]);
|
||||||
|
}
|
||||||
|
if ($this->convertToNative && null !== $currency && $this->defaultCurrency->id !== $currency->id) {
|
||||||
|
unset($set['balance']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $set;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function subtract(array $startBalances, array $endBalances)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($endBalances as $key => $value) {
|
||||||
|
$result[$key] = bcsub($value, $startBalances[$key] ?? '0');
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers;
|
namespace FireflyIII\Http\Controllers;
|
||||||
|
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Controllers\RequestInformation;
|
use FireflyIII\Support\Http\Controllers\RequestInformation;
|
||||||
use FireflyIII\Support\Http\Controllers\UserNavigation;
|
use FireflyIII\Support\Http\Controllers\UserNavigation;
|
||||||
@@ -53,6 +54,7 @@ abstract class Controller extends BaseController
|
|||||||
protected string $dateTimeFormat;
|
protected string $dateTimeFormat;
|
||||||
protected string $monthAndDayFormat;
|
protected string $monthAndDayFormat;
|
||||||
protected bool $convertToNative = false;
|
protected bool $convertToNative = false;
|
||||||
|
protected TransactionCurrency $defaultCurrency;
|
||||||
protected string $monthFormat;
|
protected string $monthFormat;
|
||||||
protected string $redirectUrl = '/';
|
protected string $redirectUrl = '/';
|
||||||
|
|
||||||
@@ -111,6 +113,7 @@ abstract class Controller extends BaseController
|
|||||||
$this->monthFormat = (string) trans('config.month_js', [], $locale);
|
$this->monthFormat = (string) trans('config.month_js', [], $locale);
|
||||||
$this->monthAndDayFormat = (string) trans('config.month_and_day_js', [], $locale);
|
$this->monthAndDayFormat = (string) trans('config.month_and_day_js', [], $locale);
|
||||||
$this->dateTimeFormat = (string) trans('config.date_time_js', [], $locale);
|
$this->dateTimeFormat = (string) trans('config.date_time_js', [], $locale);
|
||||||
|
$this->defaultCurrency = app('amount')->getDefaultCurrency();
|
||||||
$darkMode = 'browser';
|
$darkMode = 'browser';
|
||||||
// get shown-intro-preference:
|
// get shown-intro-preference:
|
||||||
if (auth()->check()) {
|
if (auth()->check()) {
|
||||||
|
@@ -336,11 +336,11 @@ class Steam
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the currency is the same as the native currency, set the native_balance to the balance for consistency.
|
// if the currency is the same as the native currency, set the native_balance to the balance for consistency.
|
||||||
if($currency->id === $native->id) {
|
// if($currency->id === $native->id) {
|
||||||
$return['native_balance'] = $return['balance'];
|
// $return['native_balance'] = $return['balance'];
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!$hasCurrency) {
|
if (!$hasCurrency && array_key_exists('balance', $return) && array_key_exists('native_balance', $return)) {
|
||||||
Log::debug('Account has no currency preference, dropping balance in favor of native balance.');
|
Log::debug('Account has no currency preference, dropping balance in favor of native balance.');
|
||||||
$sum = bcadd($return['balance'], $return['native_balance']);
|
$sum = bcadd($return['balance'], $return['native_balance']);
|
||||||
Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum));
|
Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum));
|
||||||
|
@@ -75,6 +75,7 @@ class AmountFormat extends AbstractExtension
|
|||||||
$this->formatAmountByAccount(),
|
$this->formatAmountByAccount(),
|
||||||
$this->formatAmountBySymbol(),
|
$this->formatAmountBySymbol(),
|
||||||
$this->formatAmountByCurrency(),
|
$this->formatAmountByCurrency(),
|
||||||
|
$this->formatAmountByCode()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +101,25 @@ class AmountFormat extends AbstractExtension
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the code to format a currency.
|
||||||
|
*/
|
||||||
|
protected function formatAmountByCode(): TwigFunction
|
||||||
|
{
|
||||||
|
// formatAmountByCode
|
||||||
|
return new TwigFunction(
|
||||||
|
'formatAmountByCode',
|
||||||
|
static function (string $amount, string $code, ?bool $coloured = null): string {
|
||||||
|
$coloured ??= true;
|
||||||
|
/** @var TransactionCurrency $currency */
|
||||||
|
$currency = TransactionCurrency::whereCode($code)->first();
|
||||||
|
|
||||||
|
return app('amount')->formatAnything($currency, $amount, $coloured);
|
||||||
|
},
|
||||||
|
['is_safe' => ['html']]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will format the amount by the currency related to the given account.
|
* Will format the amount by the currency related to the given account.
|
||||||
*/
|
*/
|
||||||
@@ -108,8 +128,8 @@ class AmountFormat extends AbstractExtension
|
|||||||
return new TwigFunction(
|
return new TwigFunction(
|
||||||
'formatAmountBySymbol',
|
'formatAmountBySymbol',
|
||||||
static function (string $amount, string $symbol, ?int $decimalPlaces = null, ?bool $coloured = null): string {
|
static function (string $amount, string $symbol, ?int $decimalPlaces = null, ?bool $coloured = null): string {
|
||||||
$decimalPlaces ??= 2;
|
$decimalPlaces ??= 2;
|
||||||
$coloured ??= true;
|
$coloured ??= true;
|
||||||
$currency = new TransactionCurrency();
|
$currency = new TransactionCurrency();
|
||||||
$currency->symbol = $symbol;
|
$currency->symbol = $symbol;
|
||||||
$currency->decimal_places = $decimalPlaces;
|
$currency->decimal_places = $decimalPlaces;
|
||||||
|
@@ -66,14 +66,22 @@
|
|||||||
{% if objectType != 'liabilities' %}
|
{% if objectType != 'liabilities' %}
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<span style="margin-right:5px;">
|
<span style="margin-right:5px;">
|
||||||
{{ formatAmountByAccount(account, account.endBalance) }}
|
{% for key, balance in account.endBalances %}
|
||||||
|
{% if 'balance' == key or 'native_balance' == key %}
|
||||||
|
{{ formatAmountBySymbol(balance, defaultCurrency.symbol, defaultCurrency.currency.decimal_places) }}
|
||||||
|
{% else %}
|
||||||
|
({{ formatAmountByCode(balance, key) }})
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if objectType == 'liabilities' %}
|
{% if objectType == 'liabilities' %}
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
{% if '-' != account.current_debt %}
|
{% if '-' != account.current_debt %}
|
||||||
<span class="text-info money-transfer">{{ formatAmountByAccount(account, account.current_debt, false) }}</span>
|
<span class="text-info money-transfer">
|
||||||
|
{{ formatAmountBySymbol(account.current_debt, account.currency.symbol, account.currency.decimal_places, false) }}
|
||||||
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -99,7 +107,13 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="hidden-sm hidden-xs hidden-md" style="text-align: right;">
|
<td class="hidden-sm hidden-xs hidden-md" style="text-align: right;">
|
||||||
<span style="margin-right:5px;">
|
<span style="margin-right:5px;">
|
||||||
{{ formatAmountByAccount(account, account.difference) }}
|
{% for key, balance in account.differences %}
|
||||||
|
{% if 'balance' == key or 'native_balance' == key %}
|
||||||
|
{{ formatAmountBySymbol(balance, defaultCurrency.symbol, defaultCurrency.currency.decimal_places) }}
|
||||||
|
{% else %}
|
||||||
|
({{ formatAmountByCode(balance, key) }})
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden-sm hidden-xs">
|
<td class="hidden-sm hidden-xs">
|
||||||
|
Reference in New Issue
Block a user