New method of collecting balance.

This commit is contained in:
James Cole 2024-07-31 13:09:55 +02:00
parent b2954658d8
commit 3560f0388c
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
10 changed files with 273 additions and 209 deletions

View File

@ -1,4 +1,6 @@
parameters: parameters:
scanFiles:
- ../_ide_helper_models.php
universalObjectCratesClasses: universalObjectCratesClasses:
- Illuminate\Database\Eloquent\Model - Illuminate\Database\Eloquent\Model
# TODO: slowly remove these parameters and fix the issues found. # TODO: slowly remove these parameters and fix the issues found.
@ -10,6 +12,7 @@ parameters:
- '#with no value type specified in iterable type array#' # remove this rule when all other issues are solved. - '#with no value type specified in iterable type array#' # remove this rule when all other issues are solved.
- '#has no value type specified in iterable type array#' # remove this rule when all other issues are solved. - '#has no value type specified in iterable type array#' # remove this rule when all other issues are solved.
- '#is not allowed to extend#' - '#is not allowed to extend#'
- '#does not specify its types#'
- '#switch is forbidden to use#' - '#switch is forbidden to use#'
- '#is neither abstract nor final#' - '#is neither abstract nor final#'
- '#on left side of \?\?\= always exists and is not nullable#' - '#on left side of \?\?\= always exists and is not nullable#'

View File

@ -102,6 +102,7 @@ class PreferencesController extends Controller
* TODO This endpoint is not documented. * TODO This endpoint is not documented.
* *
* Return a single preference by name. * Return a single preference by name.
* @param Collection<int, Preference> $collection
*/ */
public function showList(Collection $collection): JsonResponse public function showList(Collection $collection): JsonResponse
{ {

View File

@ -48,7 +48,7 @@ class BalanceController extends Controller
private AccountRepositoryInterface $repository; private AccountRepositoryInterface $repository;
private GroupCollectorInterface $collector; private GroupCollectorInterface $collector;
private ChartData $chartData; private ChartData $chartData;
private TransactionCurrency $default; // private TransactionCurrency $default;
public function __construct() public function __construct()
{ {
@ -61,7 +61,7 @@ class BalanceController extends Controller
$this->repository->setUserGroup($userGroup); $this->repository->setUserGroup($userGroup);
$this->collector->setUserGroup($userGroup); $this->collector->setUserGroup($userGroup);
$this->chartData = new ChartData(); $this->chartData = new ChartData();
$this->default = app('amount')->getDefaultCurrency(); // $this->default = app('amount')->getDefaultCurrency();
return $next($request); return $next($request);
} }

View File

@ -51,7 +51,7 @@ class FixUnevenAmount extends Command
$this->convertOldStyleTransfers(); $this->convertOldStyleTransfers();
$this->fixUnevenAmounts(); $this->fixUnevenAmounts();
$this->matchCurrencies(); $this->matchCurrencies();
AccountBalanceCalculator::recalculateAll(); AccountBalanceCalculator::forceRecalculateAll();
return 0; return 0;
} }

View File

@ -90,7 +90,7 @@ class OtherCurrenciesCorrections extends Command
{ {
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) { if (null !== $configVar) {
return (bool)$configVar->data; return (bool) $configVar->data;
} }
return false; return false;
@ -130,6 +130,7 @@ class OtherCurrenciesCorrections extends Command
$account = $leadTransaction->account; $account = $leadTransaction->account;
$currency = $this->getCurrency($account); $currency = $this->getCurrency($account);
$isMultiCurrency = $this->isMultiCurrency($account);
if (null === $currency) { if (null === $currency) {
$this->friendlyError( $this->friendlyError(
sprintf( sprintf(
@ -145,14 +146,14 @@ class OtherCurrenciesCorrections extends Command
} }
// fix each transaction: // fix each transaction:
$journal->transactions->each( $journal->transactions->each(
static function (Transaction $transaction) use ($currency): void { static function (Transaction $transaction) use ($currency, $isMultiCurrency): void {
if (null === $transaction->transaction_currency_id) { if (null === $transaction->transaction_currency_id) {
$transaction->transaction_currency_id = $currency->id; $transaction->transaction_currency_id = $currency->id;
$transaction->save(); $transaction->save();
} }
// when mismatch in transaction: // when mismatch in transaction:
if ($transaction->transaction_currency_id !== $currency->id) { if ($transaction->transaction_currency_id !== $currency->id && !$isMultiCurrency) {
$transaction->foreign_currency_id = $transaction->transaction_currency_id; $transaction->foreign_currency_id = $transaction->transaction_currency_id;
$transaction->foreign_amount = $transaction->amount; $transaction->foreign_amount = $transaction->amount;
$transaction->transaction_currency_id = $currency->id; $transaction->transaction_currency_id = $currency->id;
@ -161,7 +162,9 @@ class OtherCurrenciesCorrections extends Command
} }
); );
// also update the journal, of course: // also update the journal, of course:
if (!$isMultiCurrency) {
$journal->transaction_currency_id = $currency->id; $journal->transaction_currency_id = $currency->id;
}
++$this->count; ++$this->count;
$journal->save(); $journal->save();
} }
@ -239,4 +242,13 @@ class OtherCurrenciesCorrections extends Command
{ {
app('fireflyconfig')->set(self::CONFIG_NAME, true); app('fireflyconfig')->set(self::CONFIG_NAME, true);
} }
private function isMultiCurrency(Account $account): bool
{
$value = $this->accountRepos->getMetaValue($account, 'is_multi_currency', false);
if (false === $value || null === $value) {
return false;
}
return '1' === $value;
}
} }

View File

@ -45,6 +45,11 @@ class Amount
return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured); return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured);
} }
public function formatByCurrencyId(int $currencyId, string $amount, ?bool $coloured = null): string {
$format = TransactionCurrency::find($currencyId);
return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured);
}
/** /**
* This method will properly format the given number, in color or "black and white", * This method will properly format the given number, in color or "black and white",
* as a currency, given two things: the currency required and the current locale. * as a currency, given two things: the currency required and the current locale.

View File

@ -45,6 +45,16 @@ class AccountBalanceCalculator
// no-op // no-op
} }
/**
* Recalculate all balances.
*/
public static function forceRecalculateAll(): void
{
Transaction::whereNull('deleted_at')->update(['balance_dirty' => true]);
$object = new self();
$object->optimizedCalculation(new Collection());
}
/** /**
* Recalculate all balances. * Recalculate all balances.
*/ */

View File

@ -25,7 +25,6 @@ namespace FireflyIII\Support;
use Carbon\Carbon; use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use Exception;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
@ -46,13 +45,12 @@ class Steam
$repository = app(AccountRepositoryInterface::class); $repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user); $repository->setUser($account->user);
$currencyId = (int)$repository->getMetaValue($account, 'currency_id'); $currencyId = (int) $repository->getMetaValue($account, 'currency_id');
$transactions = $account->transactions() $transactions = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.transaction_currency_id', $currencyId) ->where('transactions.transaction_currency_id', $currencyId)
->get(['transactions.amount'])->toArray() ->get(['transactions.amount'])->toArray();
;
$nativeBalance = $this->sumTransactions($transactions, 'amount'); $nativeBalance = $this->sumTransactions($transactions, 'amount');
// get all balances in foreign currency: // get all balances in foreign currency:
@ -61,8 +59,7 @@ class Steam
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.foreign_currency_id', $currencyId) ->where('transactions.foreign_currency_id', $currencyId)
->where('transactions.transaction_currency_id', '!=', $currencyId) ->where('transactions.transaction_currency_id', '!=', $currencyId)
->get(['transactions.foreign_amount'])->toArray() ->get(['transactions.foreign_amount'])->toArray();
;
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount'); $foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
@ -75,7 +72,7 @@ class Steam
/** @var array $transaction */ /** @var array $transaction */
foreach ($transactions as $transaction) { foreach ($transactions as $transaction) {
$value = (string)($transaction[$key] ?? '0'); $value = (string) ($transaction[$key] ?? '0');
$value = '' === $value ? '0' : $value; $value = '' === $value ? '0' : $value;
$sum = bcadd($sum, $value); $sum = bcadd($sum, $value);
} }
@ -136,22 +133,21 @@ class Steam
'transactions.foreign_currency_id', 'transactions.foreign_currency_id',
\DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), \DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
] ]
) );
;
$currentBalance = $startBalance; $currentBalance = $startBalance;
/** @var Transaction $entry */ /** @var Transaction $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
// normal amount and foreign amount // normal amount and foreign amount
$modified = (string)(null === $entry->modified ? '0' : $entry->modified); $modified = (string) (null === $entry->modified ? '0' : $entry->modified);
$foreignModified = (string)(null === $entry->modified_foreign ? '0' : $entry->modified_foreign); $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
$amount = '0'; $amount = '0';
if ($currencyId === (int)$entry->transaction_currency_id || 0 === $currencyId) { if ($currencyId === (int) $entry->transaction_currency_id || 0 === $currencyId) {
// use normal amount: // use normal amount:
$amount = $modified; $amount = $modified;
} }
if ($currencyId === (int)$entry->foreign_currency_id) { if ($currencyId === (int) $entry->foreign_currency_id) {
// use foreign amount: // use foreign amount:
$amount = $foreignModified; $amount = $foreignModified;
} }
@ -167,6 +163,45 @@ class Steam
return $balances; return $balances;
} }
public function balanceByTransactions(Account $account, Carbon $date, ?TransactionCurrency $currency): array
{
$cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('balance-by-transactions');
$cache->addProperty($date);
$cache->addProperty(null !== $currency ? $currency->id : 0);
if ($cache->has()) {
return $cache->get();
}
$query = $account->transactions()
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->orderBy('transaction_journals.date', 'desc')
->orderBy('transaction_journals.order', 'asc')
->orderBy('transaction_journals.description', 'desc')
->orderBy('transactions.amount', 'desc');
if (null !== $currency) {
$query->where('transactions.transaction_currency_id', $currency->id);
$query->limit(1);
$result = $query->get(['transactions.transaction_currency_id', 'transactions.balance_after'])->first();
$key = (int) $result->transaction_currency_id;
$return = [$key => $result->balance_after];
$cache->store($return);
return $return;
}
$return = [];
$result = $query->get(['transactions.transaction_currency_id', 'transactions.balance_after']);
foreach ($result as $entry) {
$key = (int) $entry->transaction_currency_id;
if (array_key_exists($key, $return)) {
continue;
}
$return[$key] = $entry->balance_after;
}
return $return;
}
/** /**
* Gets balance at the end of current month by default * Gets balance at the end of current month by default
* *
@ -174,6 +209,8 @@ class Steam
*/ */
public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string
{ {
//throw new FireflyException('This method is obsolete.');
Log::warning('This method is obsolete.');
// abuse chart properties: // abuse chart properties:
$cache = new CacheProperties(); $cache = new CacheProperties();
$cache->addProperty($account->id); $cache->addProperty($account->id);
@ -194,8 +231,7 @@ class Steam
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.transaction_currency_id', $currency->id) ->where('transactions.transaction_currency_id', $currency->id)
->get(['transactions.amount'])->toArray() ->get(['transactions.amount'])->toArray();
;
$nativeBalance = $this->sumTransactions($transactions, 'amount'); $nativeBalance = $this->sumTransactions($transactions, 'amount');
// get all balances in foreign currency: // get all balances in foreign currency:
$transactions = $account->transactions() $transactions = $account->transactions()
@ -203,8 +239,7 @@ class Steam
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.foreign_currency_id', $currency->id) ->where('transactions.foreign_currency_id', $currency->id)
->where('transactions.transaction_currency_id', '!=', $currency->id) ->where('transactions.transaction_currency_id', '!=', $currency->id)
->get(['transactions.foreign_amount'])->toArray() ->get(['transactions.foreign_amount'])->toArray();
;
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount'); $foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
$balance = bcadd($nativeBalance, $foreignBalance); $balance = bcadd($nativeBalance, $foreignBalance);
$virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance; $virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance;
@ -262,8 +297,7 @@ class Steam
'transactions.foreign_currency_id', 'transactions.foreign_currency_id',
'transactions.foreign_amount', 'transactions.foreign_amount',
] ]
)->toArray() )->toArray();
;
// loop the set and convert if necessary: // loop the set and convert if necessary:
$currentBalance = $startBalance; $currentBalance = $startBalance;
@ -282,7 +316,7 @@ class Steam
} }
$format = $day->format('Y-m-d'); $format = $day->format('Y-m-d');
// if the transaction is in the expected currency, change nothing. // if the transaction is in the expected currency, change nothing.
if ((int)$transaction['transaction_currency_id'] === $native->id) { if ((int) $transaction['transaction_currency_id'] === $native->id) {
// change the current balance, set it to today, continue the loop. // change the current balance, set it to today, continue the loop.
$currentBalance = bcadd($currentBalance, $transaction['amount']); $currentBalance = bcadd($currentBalance, $transaction['amount']);
$balances[$format] = $currentBalance; $balances[$format] = $currentBalance;
@ -291,7 +325,7 @@ class Steam
continue; continue;
} }
// if foreign currency is in the expected currency, do nothing: // if foreign currency is in the expected currency, do nothing:
if ((int)$transaction['foreign_currency_id'] === $native->id) { if ((int) $transaction['foreign_currency_id'] === $native->id) {
$currentBalance = bcadd($currentBalance, $transaction['foreign_amount']); $currentBalance = bcadd($currentBalance, $transaction['foreign_amount']);
$balances[$format] = $currentBalance; $balances[$format] = $currentBalance;
Log::debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance)); Log::debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance));
@ -299,7 +333,7 @@ class Steam
continue; continue;
} }
// otherwise, convert 'amount' to the necessary currency: // otherwise, convert 'amount' to the necessary currency:
$currencyId = (int)$transaction['transaction_currency_id']; $currencyId = (int) $transaction['transaction_currency_id'];
$currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId); $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
$currencies[$currencyId] = $currency; $currencies[$currencyId] = $currency;
@ -376,16 +410,14 @@ class Steam
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.transaction_currency_id', $currency->id) ->where('transactions.transaction_currency_id', $currency->id)
->whereNull('transactions.foreign_currency_id') ->whereNull('transactions.foreign_currency_id')
->get(['transaction_journals.date', 'transactions.amount'])->toArray() ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
;
Log::debug(sprintf('%d transaction(s) in set #1', count($new[0]))); Log::debug(sprintf('%d transaction(s) in set #1', count($new[0])));
$existing[] = $account->transactions() // 2 $existing[] = $account->transactions() // 2
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.transaction_currency_id', $native->id) ->where('transactions.transaction_currency_id', $native->id)
->whereNull('transactions.foreign_currency_id') ->whereNull('transactions.foreign_currency_id')
->get(['transactions.amount'])->toArray() ->get(['transactions.amount'])->toArray();
;
Log::debug(sprintf('%d transaction(s) in set #2', count($existing[0]))); Log::debug(sprintf('%d transaction(s) in set #2', count($existing[0])));
$new[] = $account->transactions() // 3 $new[] = $account->transactions() // 3
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
@ -393,16 +425,14 @@ class Steam
->where('transactions.transaction_currency_id', '!=', $currency->id) ->where('transactions.transaction_currency_id', '!=', $currency->id)
->where('transactions.transaction_currency_id', '!=', $native->id) ->where('transactions.transaction_currency_id', '!=', $native->id)
->whereNull('transactions.foreign_currency_id') ->whereNull('transactions.foreign_currency_id')
->get(['transaction_journals.date', 'transactions.amount'])->toArray() ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
;
Log::debug(sprintf('%d transactions in set #3', count($new[1]))); Log::debug(sprintf('%d transactions in set #3', count($new[1])));
$existing[] = $account->transactions() // 4 $existing[] = $account->transactions() // 4
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->where('transactions.foreign_currency_id', $native->id) ->where('transactions.foreign_currency_id', $native->id)
->whereNotNull('transactions.foreign_amount') ->whereNotNull('transactions.foreign_amount')
->get(['transactions.foreign_amount'])->toArray() ->get(['transactions.foreign_amount'])->toArray();
;
Log::debug(sprintf('%d transactions in set #4', count($existing[1]))); Log::debug(sprintf('%d transactions in set #4', count($existing[1])));
$new[] = $account->transactions()// 5 $new[] = $account->transactions()// 5
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
@ -410,8 +440,7 @@ class Steam
->where('transactions.transaction_currency_id', $currency->id) ->where('transactions.transaction_currency_id', $currency->id)
->where('transactions.foreign_currency_id', '!=', $native->id) ->where('transactions.foreign_currency_id', '!=', $native->id)
->whereNotNull('transactions.foreign_amount') ->whereNotNull('transactions.foreign_amount')
->get(['transaction_journals.date', 'transactions.amount'])->toArray() ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
;
Log::debug(sprintf('%d transactions in set #5', count($new[2]))); Log::debug(sprintf('%d transactions in set #5', count($new[2])));
$new[] = $account->transactions()// 6 $new[] = $account->transactions()// 6
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
@ -419,8 +448,7 @@ class Steam
->where('transactions.transaction_currency_id', '!=', $currency->id) ->where('transactions.transaction_currency_id', '!=', $currency->id)
->where('transactions.foreign_currency_id', '!=', $native->id) ->where('transactions.foreign_currency_id', '!=', $native->id)
->whereNotNull('transactions.foreign_amount') ->whereNotNull('transactions.foreign_amount')
->get(['transaction_journals.date', 'transactions.amount'])->toArray() ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
;
Log::debug(sprintf('%d transactions in set #6', count($new[3]))); Log::debug(sprintf('%d transactions in set #6', count($new[3])));
// process both sets of transactions. Of course, no need to convert set "existing". // process both sets of transactions. Of course, no need to convert set "existing".
@ -591,14 +619,13 @@ class Steam
$query = $account->transactions() $query = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
->groupBy('transactions.transaction_currency_id') ->groupBy('transactions.transaction_currency_id');
;
$balances = $query->get(['transactions.transaction_currency_id', \DB::raw('SUM(transactions.amount) as sum_for_currency')]); // @phpstan-ignore-line $balances = $query->get(['transactions.transaction_currency_id', \DB::raw('SUM(transactions.amount) as sum_for_currency')]); // @phpstan-ignore-line
$return = []; $return = [];
/** @var \stdClass $entry */ /** @var \stdClass $entry */
foreach ($balances as $entry) { foreach ($balances as $entry) {
$return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency; $return[(int) $entry->transaction_currency_id] = (string) $entry->sum_for_currency;
} }
$cache->store($return); $cache->store($return);
@ -624,10 +651,10 @@ class Steam
// Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision));
if (str_contains($number, '.')) { if (str_contains($number, '.')) {
if ('-' !== $number[0]) { if ('-' !== $number[0]) {
return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
} }
return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
} }
return $number; return $number;
@ -703,7 +730,7 @@ class Steam
throw new FireflyException($e->getMessage(), 0, $e); throw new FireflyException($e->getMessage(), 0, $e);
} }
return (string)$hostName; return (string) $hostName;
} }
public function getLastActivities(array $accounts): array public function getLastActivities(array $accounts): array
@ -738,7 +765,7 @@ class Steam
if ('equal' === $locale) { if ('equal' === $locale) {
$locale = $this->getLanguage(); $locale = $this->getLanguage();
} }
$locale = (string)$locale; $locale = (string) $locale;
// Check for Windows to replace the locale correctly. // Check for Windows to replace the locale correctly.
if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) { if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
@ -838,20 +865,20 @@ class Steam
} }
Log::debug(sprintf('Floatalizing %s', $value)); Log::debug(sprintf('Floatalizing %s', $value));
$number = substr($value, 0, (int)strpos($value, 'E')); $number = substr($value, 0, (int) strpos($value, 'E'));
if (str_contains($number, '.')) { if (str_contains($number, '.')) {
$post = strlen(substr($number, (int)strpos($number, '.') + 1)); $post = strlen(substr($number, (int) strpos($number, '.') + 1));
$mantis = substr($value, (int)strpos($value, 'E') + 1); $mantis = substr($value, (int) strpos($value, 'E') + 1);
if ($mantis < 0) { if ($mantis < 0) {
$post += abs((int)$mantis); $post += abs((int) $mantis);
} }
// TODO careless float could break financial math. // TODO careless float could break financial math.
return number_format((float)$value, $post, '.', ''); return number_format((float) $value, $post, '.', '');
} }
// TODO careless float could break financial math. // TODO careless float could break financial math.
return number_format((float)$value, 0, '.', ''); return number_format((float) $value, 0, '.', '');
} }
public function opposite(?string $amount = null): ?string public function opposite(?string $amount = null): ?string
@ -871,24 +898,24 @@ class Steam
// has a K in it, remove the K and multiply by 1024. // has a K in it, remove the K and multiply by 1024.
$bytes = bcmul(rtrim($string, 'k'), '1024'); $bytes = bcmul(rtrim($string, 'k'), '1024');
return (int)$bytes; return (int) $bytes;
} }
if (false !== stripos($string, 'm')) { if (false !== stripos($string, 'm')) {
// has a M in it, remove the M and multiply by 1048576. // has a M in it, remove the M and multiply by 1048576.
$bytes = bcmul(rtrim($string, 'm'), '1048576'); $bytes = bcmul(rtrim($string, 'm'), '1048576');
return (int)$bytes; return (int) $bytes;
} }
if (false !== stripos($string, 'g')) { if (false !== stripos($string, 'g')) {
// has a G in it, remove the G and multiply by (1024)^3. // has a G in it, remove the G and multiply by (1024)^3.
$bytes = bcmul(rtrim($string, 'g'), '1073741824'); $bytes = bcmul(rtrim($string, 'g'), '1073741824');
return (int)$bytes; return (int) $bytes;
} }
return (int)$string; return (int) $string;
} }
public function positive(string $amount): string public function positive(string $amount): string

View File

@ -64,8 +64,14 @@ class General extends AbstractExtension
/** @var Carbon $date */ /** @var Carbon $date */
$date = session('end', today(config('app.timezone'))->endOfMonth()); $date = session('end', today(config('app.timezone'))->endOfMonth());
$info = app('steam')->balanceByTransactions($account, $date, null);
return app('steam')->balance($account, $date); $strings = [];
foreach($info as $currencyId => $balance) {
$strings[] = app('amount')->formatByCurrencyId($currencyId, $balance, false);
}
return implode(', ', $strings);
//return app('steam')->balance($account, $date);
} }
); );
} }

View File

@ -105,7 +105,7 @@
<div class="btn-group"> <div class="btn-group">
<a type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" <a type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" aria-haspopup="true" aria-expanded="false"
href="{{ route('accounts.show', [data.account.id]) }}">{{ formatAmountByAccount(data.account, data.account|balance, false) }} href="{{ route('accounts.show', [data.account.id]) }}">{{ data.account|balance }}
<span class="caret"></span> <span class="caret"></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">