mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 10:33:30 +00:00
Merge pull request #9952 from firefly-iii/speed-up-account-show
Speed up account show
This commit is contained in:
@@ -29,10 +29,11 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Transaction;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Debug\Timer;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Controllers\PeriodOverview;
|
use FireflyIII\Support\Http\Controllers\PeriodOverview;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -114,23 +115,45 @@ class ShowController extends Controller
|
|||||||
$subTitle = (string) trans('firefly.journals_in_period_for_account', ['name' => $account->name, 'start' => $fStart, 'end' => $fEnd]);
|
$subTitle = (string) trans('firefly.journals_in_period_for_account', ['name' => $account->name, 'start' => $fStart, 'end' => $fEnd]);
|
||||||
$chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
$chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
||||||
$firstTransaction = $this->repository->oldestJournalDate($account) ?? $start;
|
$firstTransaction = $this->repository->oldestJournalDate($account) ?? $start;
|
||||||
|
|
||||||
|
Log::debug('Start period overview');
|
||||||
|
Timer::start('period-overview');
|
||||||
|
|
||||||
$periods = $this->getAccountPeriodOverview($account, $firstTransaction, $end);
|
$periods = $this->getAccountPeriodOverview($account, $firstTransaction, $end);
|
||||||
|
|
||||||
|
Log::debug('End period overview');
|
||||||
|
Timer::stop('period-overview');
|
||||||
|
|
||||||
// if layout = v2, overrule the page title.
|
// if layout = v2, overrule the page title.
|
||||||
if ('v1' !== config('view.layout')) {
|
if ('v1' !== config('view.layout')) {
|
||||||
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
||||||
}
|
}
|
||||||
|
Log::debug('Collect transactions');
|
||||||
|
Timer::start('collection');
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation()->setRange($start, $end);
|
$collector
|
||||||
|
->setAccounts(new Collection([$account]))
|
||||||
|
->setLimit($pageSize)
|
||||||
|
->setPage($page)
|
||||||
|
->withAPIInformation()
|
||||||
|
->setRange($start, $end);
|
||||||
// this search will not include transaction groups where this asset account (or liability)
|
// this search will not include transaction groups where this asset account (or liability)
|
||||||
// is just part of ONE of the journals. To force this:
|
// is just part of ONE of the journals. To force this:
|
||||||
$collector->setExpandGroupSearch(true);
|
$collector->setExpandGroupSearch(true);
|
||||||
|
|
||||||
$groups = $collector->getPaginatedGroups();
|
$groups = $collector->getPaginatedGroups();
|
||||||
|
|
||||||
|
Log::debug('End collect transactions');
|
||||||
|
Timer::stop('collection');
|
||||||
|
|
||||||
|
// enrich data in arrays.
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
// $enrichment = new TransactionGroupEnrichment();
|
||||||
|
// $enrichment->setUser(auth()->user());
|
||||||
|
// $groups->setCollection($enrichment->enrich($groups->getCollection()));
|
||||||
|
|
||||||
|
|
||||||
$groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
|
$groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
|
||||||
$showAll = false;
|
$showAll = false;
|
||||||
// correct
|
// correct
|
||||||
@@ -184,7 +207,7 @@ class ShowController extends Controller
|
|||||||
$today = today(config('app.timezone'));
|
$today = today(config('app.timezone'));
|
||||||
$accountCurrency = $this->repository->getAccountCurrency($account);
|
$accountCurrency = $this->repository->getAccountCurrency($account);
|
||||||
$start = $this->repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth();
|
$start = $this->repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth();
|
||||||
$subTitleIcon = config('firefly.subIconsByIdentifier.'.$account->accountType->type);
|
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type);
|
||||||
$page = (int) $request->get('page');
|
$page = (int) $request->get('page');
|
||||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||||
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
|
@@ -641,4 +641,34 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
|
|||||||
|
|
||||||
return $factory->create($data);
|
return $factory->create($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\Override] public function periodCollection(Account $account, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
return $account->transactions()
|
||||||
|
->leftJoin('transaction_journals','transaction_journals.id','=','transactions.transaction_journal_id')
|
||||||
|
->leftJoin('transaction_types','transaction_types.id','=','transaction_journals.transaction_type_id')
|
||||||
|
->leftJoin('transaction_currencies','transaction_currencies.id','=','transactions.transaction_currency_id')
|
||||||
|
->leftJoin('transaction_currencies as foreign_currencies','foreign_currencies.id','=','transactions.foreign_currency_id')
|
||||||
|
->where('transaction_journals.date','>=',$start)
|
||||||
|
->where('transaction_journals.date','<=',$end)
|
||||||
|
->get([
|
||||||
|
// currencies
|
||||||
|
'transaction_currencies.id as currency_id',
|
||||||
|
'transaction_currencies.code as currency_code',
|
||||||
|
'transaction_currencies.name as currency_name',
|
||||||
|
'transaction_currencies.symbol as currency_symbol',
|
||||||
|
'transaction_currencies.decimal_places as currency_decimal_places',
|
||||||
|
|
||||||
|
// foreign
|
||||||
|
'foreign_currencies.id as foreign_currency_id',
|
||||||
|
'foreign_currencies.code as foreign_currency_code',
|
||||||
|
'foreign_currencies.name as foreign_currency_name',
|
||||||
|
'foreign_currencies.symbol as foreign_currency_symbol',
|
||||||
|
'foreign_currencies.decimal_places as foreign_decimal_places',
|
||||||
|
|
||||||
|
// fields
|
||||||
|
'transaction_journals.date', 'transaction_types.type', 'transaction_journals.transaction_currency_id', 'transactions.amount'])
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -71,6 +71,8 @@ interface AccountRepositoryInterface
|
|||||||
|
|
||||||
public function findByName(string $name, array $types): ?Account;
|
public function findByName(string $name, array $types): ?Account;
|
||||||
|
|
||||||
|
public function periodCollection(Account $account, Carbon $start, Carbon $end): array;
|
||||||
|
|
||||||
public function getAccountBalances(Account $account): Collection;
|
public function getAccountBalances(Account $account): Collection;
|
||||||
|
|
||||||
public function getAccountCurrency(Account $account): ?TransactionCurrency;
|
public function getAccountCurrency(Account $account): ?TransactionCurrency;
|
||||||
|
@@ -305,9 +305,15 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
|
|||||||
|
|
||||||
public function getPiggyBanks(): Collection
|
public function getPiggyBanks(): Collection
|
||||||
{
|
{
|
||||||
return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
$query = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id');
|
||||||
->where('accounts.user_id', $this->user->id)
|
if (null === $this->user) {
|
||||||
|
$query->where('accounts.user_group_id', $this->userGroup->id);
|
||||||
|
}
|
||||||
|
if (null !== $this->user) {
|
||||||
|
$query->where('accounts.user_id', $this->user->id);
|
||||||
|
}
|
||||||
|
return $query
|
||||||
->with(
|
->with(
|
||||||
[
|
[
|
||||||
'objectGroups',
|
'objectGroups',
|
||||||
|
46
app/Support/Debug/Timer.php
Normal file
46
app/Support/Debug/Timer.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Timer.php
|
||||||
|
* Copyright (c) 2025 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Support\Debug;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class Timer
|
||||||
|
{
|
||||||
|
private static array $times = [];
|
||||||
|
|
||||||
|
public static function start(string $title): void
|
||||||
|
{
|
||||||
|
self::$times[$title] = microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function stop(string $title): void
|
||||||
|
{
|
||||||
|
$start = self::$times[$title] ?? 0;
|
||||||
|
$end = microtime(true);
|
||||||
|
$diff = $end - $start;
|
||||||
|
unset(self::$times[$title]);
|
||||||
|
Log::debug(sprintf('Timer "%s" took %f seconds', $title, $diff));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -31,9 +31,12 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
|
use FireflyIII\Support\Debug\Timer;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait PeriodOverview.
|
* Trait PeriodOverview.
|
||||||
@@ -65,6 +68,7 @@ use Illuminate\Support\Collection;
|
|||||||
trait PeriodOverview
|
trait PeriodOverview
|
||||||
{
|
{
|
||||||
protected JournalRepositoryInterface $journalRepos;
|
protected JournalRepositoryInterface $journalRepos;
|
||||||
|
protected AccountRepositoryInterface $accountRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns "period entries", so nov-2015, dec-2015, etc etc (this depends on the users session range)
|
* This method returns "period entries", so nov-2015, dec-2015, etc etc (this depends on the users session range)
|
||||||
@@ -75,6 +79,8 @@ trait PeriodOverview
|
|||||||
*/
|
*/
|
||||||
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
|
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
|
Timer::start('account-period-total');
|
||||||
|
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||||
$range = app('navigation')->getViewRange(true);
|
$range = app('navigation')->getViewRange(true);
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
|
|
||||||
@@ -92,42 +98,20 @@ trait PeriodOverview
|
|||||||
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
// collect all expenses in this period:
|
// run a custom query because doing this with the collector is MEGA slow.
|
||||||
/** @var GroupCollectorInterface $collector */
|
$transactions = $this->accountRepository->periodCollection($account, $start, $end);
|
||||||
$collector = app(GroupCollectorInterface::class);
|
|
||||||
$collector->setAccounts(new Collection([$account]));
|
|
||||||
$collector->setRange($start, $end);
|
|
||||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
|
||||||
$earnedSet = $collector->getExtractedJournals();
|
|
||||||
|
|
||||||
// collect all income in this period:
|
|
||||||
/** @var GroupCollectorInterface $collector */
|
|
||||||
$collector = app(GroupCollectorInterface::class);
|
|
||||||
$collector->setAccounts(new Collection([$account]));
|
|
||||||
$collector->setRange($start, $end);
|
|
||||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
|
||||||
$spentSet = $collector->getExtractedJournals();
|
|
||||||
|
|
||||||
// collect all transfers in this period:
|
|
||||||
/** @var GroupCollectorInterface $collector */
|
|
||||||
$collector = app(GroupCollectorInterface::class);
|
|
||||||
$collector->setAccounts(new Collection([$account]));
|
|
||||||
$collector->setRange($start, $end);
|
|
||||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
|
||||||
$transferSet = $collector->getExtractedJournals();
|
|
||||||
|
|
||||||
// loop dates
|
// loop dates
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
$title = app('navigation')->periodShow($currentDate['start'], $currentDate['period']);
|
$title = app('navigation')->periodShow($currentDate['start'], $currentDate['period']);
|
||||||
$earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']);
|
[$transactions, $spent] = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $transactions, $currentDate['start'], $currentDate['end']);
|
||||||
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
|
[$transactions, $earned] = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $transactions, $currentDate['start'], $currentDate['end']);
|
||||||
$transferredAway = $this->filterTransferredAway($account, $this->filterJournalsByDate($transferSet, $currentDate['start'], $currentDate['end']));
|
[$transactions, $transferredAway] = $this->filterTransfers('away',$transactions, $currentDate['start'], $currentDate['end']);
|
||||||
$transferredIn = $this->filterTransferredIn($account, $this->filterJournalsByDate($transferSet, $currentDate['start'], $currentDate['end']));
|
[$transactions, $transferredIn] = $this->filterTransfers('in',$transactions, $currentDate['start'], $currentDate['end']);
|
||||||
$entries[]
|
$entries[]
|
||||||
= [
|
= [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
|
|
||||||
'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
|
'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
|
||||||
'spent' => $this->groupByCurrency($spent),
|
'spent' => $this->groupByCurrency($spent),
|
||||||
'earned' => $this->groupByCurrency($earned),
|
'earned' => $this->groupByCurrency($earned),
|
||||||
@@ -136,9 +120,50 @@ trait PeriodOverview
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
$cache->store($entries);
|
$cache->store($entries);
|
||||||
|
Timer::stop('account-period-total');
|
||||||
|
|
||||||
return $entries;
|
return $entries;
|
||||||
}
|
}
|
||||||
|
private function filterTransfers(string $direction, array $transactions, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
/**
|
||||||
|
* @var int $index
|
||||||
|
* @var array $item
|
||||||
|
*/
|
||||||
|
foreach ($transactions as $index => $item) {
|
||||||
|
$date = Carbon::parse($item['date']);
|
||||||
|
if ($date >= $start && $date <= $end) {
|
||||||
|
if ($direction === 'away' && bccomp($item['amount'], '0') === -1) {
|
||||||
|
$result[] = $item;
|
||||||
|
unset($transactions[$index]);
|
||||||
|
}
|
||||||
|
if ($direction === 'in' && bccomp($item['amount'], '0') === 1) {
|
||||||
|
$result[] = $item;
|
||||||
|
unset($transactions[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [$transactions, $result];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function filterTransactionsByType(TransactionTypeEnum $type, array $transactions, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
/**
|
||||||
|
* @var int $index
|
||||||
|
* @var array $item
|
||||||
|
*/
|
||||||
|
foreach ($transactions as $index => $item) {
|
||||||
|
$date = Carbon::parse($item['date']);
|
||||||
|
if($item['type'] === $type->value && $date >= $start && $date <= $end) {
|
||||||
|
$result[] = $item;
|
||||||
|
unset($transactions[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$transactions, $result];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter a list of journals by a set of dates, and then group them by currency.
|
* Filter a list of journals by a set of dates, and then group them by currency.
|
||||||
|
@@ -72,7 +72,7 @@ class Preferences
|
|||||||
|
|
||||||
public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
|
public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('getForUser(#%d, "%s")', $user->id, $name));
|
//Log::debug(sprintf('getForUser(#%d, "%s")', $user->id, $name));
|
||||||
// don't care about user group ID, except for some specific preferences.
|
// don't care about user group ID, except for some specific preferences.
|
||||||
$userGroupId = $this->getUserGroupId($user, $name);
|
$userGroupId = $this->getUserGroupId($user, $name);
|
||||||
$query = Preference::where('user_id', $user->id)->where('name', $name);
|
$query = Preference::where('user_id', $user->id)->where('name', $name);
|
||||||
@@ -90,7 +90,7 @@ class Preferences
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $preference) {
|
if (null !== $preference) {
|
||||||
Log::debug(sprintf('Found preference #%d for user #%d: %s', $preference->id, $user->id, $name));
|
//Log::debug(sprintf('Found preference #%d for user #%d: %s', $preference->id, $user->id, $name));
|
||||||
|
|
||||||
return $preference;
|
return $preference;
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,11 @@
|
|||||||
<td style="width:33%;">{{ 'earned'|_ }}</td>
|
<td style="width:33%;">{{ 'earned'|_ }}</td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<span title="{{ entry.count }}">
|
<span title="{{ entry.count }}">
|
||||||
|
{% if entry.amount < 0 %}
|
||||||
{{ formatAmountBySymbol(entry.amount*-1, entry.currency_symbol, entry.currency_decimal_places) }}
|
{{ formatAmountBySymbol(entry.amount*-1, entry.currency_symbol, entry.currency_decimal_places) }}
|
||||||
|
{% else %}
|
||||||
|
{{ formatAmountBySymbol(entry.amount, entry.currency_symbol, entry.currency_decimal_places) }}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -58,7 +62,11 @@
|
|||||||
<td style="width:33%;">{{ 'transferred_away'|_ }}</td>
|
<td style="width:33%;">{{ 'transferred_away'|_ }}</td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<span title="{{ entry.count }}">
|
<span title="{{ entry.count }}">
|
||||||
|
{% if entry.amount < 0 %}
|
||||||
|
{{ formatAmountBySymbol(entry.amount, entry.currency_symbol, entry.currency_decimal_places) }}
|
||||||
|
{% else %}
|
||||||
{{ formatAmountBySymbol(entry.amount*-1, entry.currency_symbol, entry.currency_decimal_places) }}
|
{{ formatAmountBySymbol(entry.amount*-1, entry.currency_symbol, entry.currency_decimal_places) }}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -71,7 +79,11 @@
|
|||||||
<td style="width:33%;">{{ 'transferred_in'|_ }}</td>
|
<td style="width:33%;">{{ 'transferred_in'|_ }}</td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<span title="{{ entry.count }}">
|
<span title="{{ entry.count }}">
|
||||||
|
{% if entry.amount < 0 %}
|
||||||
{{ formatAmountBySymbol(entry.amount*-1, entry.currency_symbol, entry.currency_decimal_places) }}
|
{{ formatAmountBySymbol(entry.amount*-1, entry.currency_symbol, entry.currency_decimal_places) }}
|
||||||
|
{% else %}
|
||||||
|
{{ formatAmountBySymbol(entry.amount, entry.currency_symbol, entry.currency_decimal_places) }}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Reference in New Issue
Block a user