From a0e92b69690b54ef1f5e63e98846bceddd8e24b3 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 22 Dec 2024 19:42:06 +0100 Subject: [PATCH] Clean up variety of account balance methods. --- .../Autocomplete/AccountController.php | 5 +- .../Report/Audit/MonthReportGenerator.php | 7 +- .../Account/ReconcileController.php | 5 +- .../Controllers/Account/ShowController.php | 5 +- .../Controllers/Chart/AccountController.php | 3 +- app/Http/Controllers/HomeController.php | 3 +- .../Controllers/Json/ReconcileController.php | 5 +- .../Transaction/ConvertController.php | 5 +- .../PiggyBank/PiggyBankRepository.php | 4 +- app/Support/Steam.php | 765 +++++++++--------- app/Support/Twig/General.php | 64 +- app/Transformers/AccountTransformer.php | 3 +- 12 files changed, 448 insertions(+), 426 deletions(-) diff --git a/app/Api/V1/Controllers/Autocomplete/AccountController.php b/app/Api/V1/Controllers/Autocomplete/AccountController.php index 586646f804..82e62a0626 100644 --- a/app/Api/V1/Controllers/Autocomplete/AccountController.php +++ b/app/Api/V1/Controllers/Autocomplete/AccountController.php @@ -31,6 +31,7 @@ use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\Http\Api\AccountFilter; +use FireflyIII\Support\Steam; use FireflyIII\User; use Illuminate\Http\JsonResponse; @@ -89,11 +90,11 @@ class AccountController extends Controller $currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency; if (in_array($account->accountType->type, $this->balanceTypes, true)) { - $balance = app('steam')->balance($account, $date); + $balance = Steam::finalAccountBalance($account, $date); $nameWithBalance = sprintf( '%s (%s)', $account->name, - app('amount')->formatAnything($currency, $balance, false) + app('amount')->formatAnything($currency, $balance['balance'], false) ); } diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index c5f65261bd..2ae858c600 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -31,6 +31,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Account; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use Illuminate\Support\Collection; /** @@ -129,8 +130,8 @@ class MonthReportGenerator implements ReportGeneratorInterface ; $journals = $collector->getExtractedJournals(); $journals = array_reverse($journals, true); - $dayBeforeBalance = app('steam')->balance($account, $date); - $startBalance = $dayBeforeBalance; + $dayBeforeBalance = Steam::finalAccountBalance($account, $date); + $startBalance = $dayBeforeBalance['balance']; $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup); $currency = $accountRepository->getAccountCurrency($account) ?? $defaultCurrency; @@ -169,7 +170,7 @@ class MonthReportGenerator implements ReportGeneratorInterface 'currency' => $currency, 'exists' => 0 !== count($journals), 'end' => $this->end->isoFormat((string) trans('config.month_and_day_moment_js', [], $locale)), - 'endBalance' => app('steam')->balance($account, $this->end), + 'endBalance' => Steam::finalAccountBalance($account, $this->end)['balance'], 'dayBefore' => $date->isoFormat((string) trans('config.month_and_day_moment_js', [], $locale)), 'dayBeforeBalance' => $dayBeforeBalance, ]; diff --git a/app/Http/Controllers/Account/ReconcileController.php b/app/Http/Controllers/Account/ReconcileController.php index 7efe4bf057..6a76227a83 100644 --- a/app/Http/Controllers/Account/ReconcileController.php +++ b/app/Http/Controllers/Account/ReconcileController.php @@ -34,6 +34,7 @@ use FireflyIII\Models\AccountType; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use FireflyIII\User; use Illuminate\Contracts\View\Factory; use Illuminate\Http\RedirectResponse; @@ -110,8 +111,8 @@ class ReconcileController extends Controller $startDate = clone $start; $startDate->subDay(); - $startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places); - $endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places); + $startBalance = Steam::finalAccountBalance($account, $startDate)['balance']; + $endBalance = Steam::finalAccountBalance($account, $end)['balance']; $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type)); $subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]); diff --git a/app/Http/Controllers/Account/ShowController.php b/app/Http/Controllers/Account/ShowController.php index db17a8fec7..9defa7eb70 100644 --- a/app/Http/Controllers/Account/ShowController.php +++ b/app/Http/Controllers/Account/ShowController.php @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Account; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Http\Controllers\PeriodOverview; use Illuminate\Contracts\View\Factory; use Illuminate\Http\RedirectResponse; @@ -128,7 +129,7 @@ class ShowController extends Controller $groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')])); $showAll = false; - $balance = app('steam')->balance($account, $end); + $balance = Steam::finalAccountBalance($account, $end)['balance']; return view( 'accounts.show', @@ -190,7 +191,7 @@ class ShowController extends Controller $groups->setPath(route('accounts.show.all', [$account->id])); $chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]); $showAll = true; - $balance = app('steam')->balance($account, $end); + $balance = Steam::finalAccountBalance($account, $end)['balance']; return view( 'accounts.show', diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index bf9477db9d..6dfbbca78b 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -36,6 +36,7 @@ use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\ChartGeneration; use FireflyIII\Support\Http\Controllers\DateCalculation; @@ -450,7 +451,7 @@ class AccountController extends Controller if ('1W' === $step || '1M' === $step || '1Y' === $step) { while ($end >= $current) { Log::debug(sprintf('Current is: %s', $current->format('Y-m-d'))); - $balance = (float) app('steam')->balance($account, $current, $currency); + $balance = Steam::finalAccountBalance($account, $current)[$currency->code] ?? '0'; $label = app('navigation')->periodShow($current, $step); $entries[$label] = $balance; $current = app('navigation')->addPeriod($current, $step, 0); diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index d491b74ecf..75d927bcd8 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -29,9 +29,11 @@ use FireflyIII\Events\RequestedVersionCheckStatus; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Http\Middleware\Installer; +use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -120,7 +122,6 @@ class HomeController extends Controller */ public function index(AccountRepositoryInterface $repository): mixed { - $types = config('firefly.accountTypesByIdentifier.asset'); $count = $repository->count($types); Log::channel('audit')->info('User visits homepage.'); diff --git a/app/Http/Controllers/Json/ReconcileController.php b/app/Http/Controllers/Json/ReconcileController.php index 3f4c8b90ad..72fad4d610 100644 --- a/app/Http/Controllers/Json/ReconcileController.php +++ b/app/Http/Controllers/Json/ReconcileController.php @@ -32,6 +32,7 @@ use FireflyIII\Models\Account; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Collection; @@ -193,8 +194,8 @@ class ReconcileController extends Controller $end->endOfDay(); $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency(); - $startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places); - $endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places); + $startBalance = Steam::finalAccountBalance($account, $startDate)['balance']; + $endBalance = Steam::finalAccountBalance($account, $end)['balance']; // get the transactions $selectionStart = clone $start; diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php index 1b3c4287ec..ca3700b0eb 100644 --- a/app/Http/Controllers/Transaction/ConvertController.php +++ b/app/Http/Controllers/Transaction/ConvertController.php @@ -34,6 +34,7 @@ use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Services\Internal\Update\JournalUpdateService; +use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Http\Controllers\ModelInformation; use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\Validation\AccountValidator; @@ -222,7 +223,7 @@ class ConvertController extends Controller // group accounts: /** @var Account $account */ foreach ($accountList as $account) { - $balance = app('steam')->balance($account, today()); + $balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance']; $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; $role = 'l_'.$account->accountType->type; $key = (string) trans('firefly.opt_group_'.$role); @@ -245,7 +246,7 @@ class ConvertController extends Controller // group accounts: /** @var Account $account */ foreach ($accountList as $account) { - $balance = app('steam')->balance($account, today()); + $balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance']; $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; $role = (string) $this->accountRepository->getMetaValue($account, 'account_role'); if ('' === $role) { diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index e2775e1073..b7f500ca1e 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -35,6 +35,7 @@ use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use FireflyIII\User; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Support\Collection; @@ -334,7 +335,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface public function leftOnAccount(PiggyBank $piggyBank, Account $account, Carbon $date): string { Log::debug(sprintf('leftOnAccount("%s","%s","%s")', $piggyBank->name, $account->name, $date->format('Y-m-d H:i:s'))); - $balance = app('steam')->balanceConvertedIgnoreVirtual($account, $date, $piggyBank->transactionCurrency); + $balance = Steam::finalAccountBalance($account, $date)['balance']; + Log::debug(sprintf('Balance is: %s', $balance)); /** @var Collection $piggies */ diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 87d698592a..baffb810e6 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -25,6 +25,8 @@ namespace FireflyIII\Support; use Carbon\Carbon; use Carbon\Exceptions\InvalidFormatException; +use DB; +use Exception; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Models\Transaction; @@ -33,76 +35,126 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; +use stdClass; +use Str; +use ValueError; /** * Class Steam. */ class Steam { - 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; - } - /** + * @throws FireflyException + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @deprecated */ - public function balanceConvertedIgnoreVirtual(Account $account, Carbon $date, TransactionCurrency $currency): string + public function balanceInRangeConverted(Account $account, Carbon $start, Carbon $end, TransactionCurrency $native): array { - $balance = $this->balanceConverted($account, $date, $currency); - $virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance; + // Log::warning(sprintf('Deprecated method %s, do not use.', __METHOD__)); + $cache = new CacheProperties(); + $cache->addProperty($account->id); + $cache->addProperty('balance-in-range-converted'); + $cache->addProperty($native->id); + $cache->addProperty($start); + $cache->addProperty($end); + if ($cache->has()) { + //return $cache->get(); + } + Log::debug(sprintf('balanceInRangeConverted for account #%d to %s', $account->id, $native->code)); + $start->subDay(); + $end->addDay(); + $balances = []; + $formatted = $start->format('Y-m-d'); + $currencies = []; + $startBalance = $this->balanceConverted($account, $start, $native); // already converted to native amount + $balances[$formatted] = $startBalance; - // currency of account - $repository = app(AccountRepositoryInterface::class); - $repository->setUser($account->user); - $accountCurrency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup); - if ($accountCurrency->id !== $currency->id && 0 !== bccomp($virtual, '0')) { - // convert amount to given currency. - Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); - $converter = new ExchangeRateConverter(); - $virtual = $converter->convert($accountCurrency, $currency, $date, $virtual); + Log::debug(sprintf('Start balance on %s is %s', $formatted, $startBalance)); + Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); + $converter = new ExchangeRateConverter(); + + // not sure why this is happening: + $start->addDay(); + + // grab all transactions between start and end: + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59')) + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ + 'transaction_journals.date', + 'transactions.transaction_currency_id', + 'transactions.amount', + 'transactions.foreign_currency_id', + 'transactions.foreign_amount', + ] + )->toArray(); + + // loop the set and convert if necessary: + $currentBalance = $startBalance; + + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + $day = false; + + try { + $day = Carbon::parse($transaction['date'], config('app.timezone')); + } catch (InvalidFormatException $e) { + Log::error(sprintf('Could not parse date "%s" in %s: %s', $transaction['date'], __METHOD__, $e->getMessage())); + } + if (false === $day) { + $day = today(config('app.timezone')); + } + $format = $day->format('Y-m-d'); + // if the transaction is in the expected currency, change nothing. + if ((int) $transaction['transaction_currency_id'] === $native->id) { + // change the current balance, set it to today, continue the loop. + $currentBalance = bcadd($currentBalance, $transaction['amount']); + $balances[$format] = $currentBalance; + Log::debug(sprintf('%s: transaction in %s, new balance is %s.', $format, $native->code, $currentBalance)); + + continue; + } + // if foreign currency is in the expected currency, do nothing: + if ((int) $transaction['foreign_currency_id'] === $native->id) { + $currentBalance = bcadd($currentBalance, $transaction['foreign_amount']); + $balances[$format] = $currentBalance; + Log::debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance)); + + continue; + } + // otherwise, convert 'amount' to the necessary currency: + $currencyId = (int) $transaction['transaction_currency_id']; + $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId); + $currencies[$currencyId] = $currency; + + $rate = $converter->getCurrencyRate($currency, $native, $day); + $convertedAmount = bcmul($transaction['amount'], $rate); + $currentBalance = bcadd($currentBalance, $convertedAmount); + $balances[$format] = $currentBalance; + + Log::debug(sprintf( + '%s: transaction in %s(!). Conversion rate is %s. %s %s = %s %s', + $format, + $currency->code, + $rate, + $currency->code, + $transaction['amount'], + $native->code, + $convertedAmount + )); } - return bcsub($balance, $virtual); - } + $cache->store($balances); + $converter->summarize(); - // + return $balances; + } /** * @throws FireflyException @@ -124,7 +176,7 @@ class Steam * to the indicated currency ($native). * */ - public function balanceConverted(Account $account, Carbon $date, TransactionCurrency $native): string + private function balanceConverted(Account $account, Carbon $date, TransactionCurrency $native): string { Log::debug(sprintf('Now in balanceConverted (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code)); $cache = new CacheProperties(); @@ -257,84 +309,15 @@ class Steam return $balance; } - /** - * Balance of an (asset) account in the user's native currency. - * Is calculated by summing up three numbers. - * - * - Transactions in foreign amount that happen to be in the native currency. - * - The rest of the transactions in the native currency. - * - Where both are zero or NULL, the normal amount converted (and stored!) - * - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function balanceNative(Account $account, Carbon $date): string - { - $native = app('amount')->getDefaultCurrency(); - Log::debug(sprintf('Now in balanceNative (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code)); - $cache = new CacheProperties(); - $cache->addProperty($account->id); - $cache->addProperty('balance-native'); - $cache->addProperty($date); - $cache->addProperty($native->id); - if ($cache->has()) { - $value = $cache->get(); - Log::debug(sprintf('Return cached value %s', $value)); - return $value; - } - - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - $currency = $repository->getAccountCurrency($account); - $currency = null === $currency ? $native : $currency; - if ($native->id === $currency->id) { - Log::debug('No conversion necessary!'); - - return $this->balance($account, $date); - } - $balance = '0'; - // transactions in foreign amount that happen to be in the native currency: - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->where('transactions.foreign_currency_id', $native->id) - ->get(['transactions.foreign_amount'])->toArray(); - $balance = bcadd($this->sumTransactions($set, 'foreign_amount'), $balance); - Log::debug(sprintf('The balance is now %s', $balance)); - - // transactions in the native amount. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->whereNull('transactions.foreign_currency_id') - ->whereNotNull('transactions.native_amount') - ->get(['transactions.native_amount'])->toArray(); - $balance = bcadd($this->sumTransactions($set, 'native_amount'), $balance); - Log::debug(sprintf('The balance is now %s', $balance)); - - // transactions in the normal amount with no native amount set. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->whereNull('transactions.foreign_currency_id') - ->whereNull('transactions.native_amount') - ->get(['transactions.amount'])->toArray(); - $balance = bcadd($this->sumTransactions($set, 'amount'), $balance); - Log::debug(sprintf('The balance is now %s', $balance)); - - // add virtual balance (also needs conversion) - $virtualNative = null === $account->native_virtual_balance ? '0' : $account->native_virtual_balance; - $final = bcadd($virtualNative, $balance); - Log::debug(sprintf('Final balance is %s', $final)); - $cache->store($final); - return $final; - } + // /** * Gets balance at the end of current month by default * * @throws FireflyException + * @deprecated */ - public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string + private function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string { // Log::warning(sprintf('Deprecated method %s, do not use.', __METHOD__)); // abuse chart properties: @@ -377,250 +360,8 @@ class Steam } /** + * @throws FireflyException * @deprecated - */ - public function balanceIgnoreVirtual(Account $account, Carbon $date): string - { - throw new FireflyException('Deprecated method balanceIgnoreVirtual.'); - - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - $repository->setUser($account->user); - - $currencyId = (int) $repository->getMetaValue($account, 'currency_id'); - $transactions = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->where('transactions.transaction_currency_id', $currencyId) - ->get(['transactions.amount'])->toArray(); - $nativeBalance = $this->sumTransactions($transactions, 'amount'); - - // get all balances in foreign currency: - $transactions = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) - ->where('transactions.foreign_currency_id', $currencyId) - ->where('transactions.transaction_currency_id', '!=', $currencyId) - ->get(['transactions.foreign_amount'])->toArray(); - - $foreignBalance = $this->sumTransactions($transactions, 'foreign_amount'); - - return bcadd($nativeBalance, $foreignBalance); - } - - public function sumTransactions(array $transactions, string $key): string - { - $sum = '0'; - - /** @var array $transaction */ - foreach ($transactions as $transaction) { - $value = (string) ($transaction[$key] ?? '0'); - $value = '' === $value ? '0' : $value; - $sum = bcadd($sum, $value); - } - - return $sum; - } - - - /** - * Gets the balance for the given account during the whole range, using this format:. - * - * [yyyy-mm-dd] => 123,2 - * - * @throws FireflyException - */ - public function balanceInRange(Account $account, Carbon $start, Carbon $end, ?TransactionCurrency $currency = null): array - { - // Log::warning(sprintf('Deprecated method %s, do not use.', __METHOD__)); - $cache = new CacheProperties(); - $cache->addProperty($account->id); - $cache->addProperty('balance-in-range'); - $cache->addProperty(null !== $currency ? $currency->id : 0); - $cache->addProperty($start); - $cache->addProperty($end); - if ($cache->has()) { - return $cache->get(); - } - - $start->subDay(); - $end->addDay(); - $balances = []; - $formatted = $start->format('Y-m-d'); - $startBalance = $this->balance($account, $start, $currency); - - $balances[$formatted] = $startBalance; - if (null === $currency) { - $repository = app(AccountRepositoryInterface::class); - $repository->setUser($account->user); - $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup); - } - $currencyId = $currency->id; - - $start->addDay(); - - // query! - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59')) - ->groupBy('transaction_journals.date') - ->groupBy('transactions.transaction_currency_id') - ->groupBy('transactions.foreign_currency_id') - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ // @phpstan-ignore-line - 'transaction_journals.date', - 'transactions.transaction_currency_id', - \DB::raw('SUM(transactions.amount) AS modified'), - 'transactions.foreign_currency_id', - \DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), - ] - ); - - $currentBalance = $startBalance; - - /** @var Transaction $entry */ - foreach ($set as $entry) { - // normal amount and foreign amount - $modified = (string) (null === $entry->modified ? '0' : $entry->modified); - $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); - $amount = '0'; - if ($currencyId === (int) $entry->transaction_currency_id || 0 === $currencyId) { - // use normal amount: - $amount = $modified; - } - if ($currencyId === (int) $entry->foreign_currency_id) { - // use foreign amount: - $amount = $foreignModified; - } - // Log::debug(sprintf('Trying to add %s and %s.', var_export($currentBalance, true), var_export($amount, true))); - $currentBalance = bcadd($currentBalance, $amount); - $carbon = new Carbon($entry->date, config('app.timezone')); - $date = $carbon->format('Y-m-d'); - $balances[$date] = $currentBalance; - } - - $cache->store($balances); - - return $balances; - } - - /** - * @throws FireflyException - * - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function balanceInRangeConverted(Account $account, Carbon $start, Carbon $end, TransactionCurrency $native): array - { - // Log::warning(sprintf('Deprecated method %s, do not use.', __METHOD__)); - $cache = new CacheProperties(); - $cache->addProperty($account->id); - $cache->addProperty('balance-in-range-converted'); - $cache->addProperty($native->id); - $cache->addProperty($start); - $cache->addProperty($end); - if ($cache->has()) { - //return $cache->get(); - } - Log::debug(sprintf('balanceInRangeConverted for account #%d to %s', $account->id, $native->code)); - $start->subDay(); - $end->addDay(); - $balances = []; - $formatted = $start->format('Y-m-d'); - $currencies = []; - $startBalance = $this->balanceConverted($account, $start, $native); // already converted to native amount - $balances[$formatted] = $startBalance; - - Log::debug(sprintf('Start balance on %s is %s', $formatted, $startBalance)); - Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); - $converter = new ExchangeRateConverter(); - - // not sure why this is happening: - $start->addDay(); - - // grab all transactions between start and end: - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59')) - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ - 'transaction_journals.date', - 'transactions.transaction_currency_id', - 'transactions.amount', - 'transactions.foreign_currency_id', - 'transactions.foreign_amount', - ] - )->toArray(); - - // loop the set and convert if necessary: - $currentBalance = $startBalance; - - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $day = false; - - try { - $day = Carbon::parse($transaction['date'], config('app.timezone')); - } catch (InvalidFormatException $e) { - Log::error(sprintf('Could not parse date "%s" in %s: %s', $transaction['date'], __METHOD__, $e->getMessage())); - } - if (false === $day) { - $day = today(config('app.timezone')); - } - $format = $day->format('Y-m-d'); - // if the transaction is in the expected currency, change nothing. - if ((int) $transaction['transaction_currency_id'] === $native->id) { - // change the current balance, set it to today, continue the loop. - $currentBalance = bcadd($currentBalance, $transaction['amount']); - $balances[$format] = $currentBalance; - Log::debug(sprintf('%s: transaction in %s, new balance is %s.', $format, $native->code, $currentBalance)); - - continue; - } - // if foreign currency is in the expected currency, do nothing: - if ((int) $transaction['foreign_currency_id'] === $native->id) { - $currentBalance = bcadd($currentBalance, $transaction['foreign_amount']); - $balances[$format] = $currentBalance; - Log::debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance)); - - continue; - } - // otherwise, convert 'amount' to the necessary currency: - $currencyId = (int) $transaction['transaction_currency_id']; - $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId); - $currencies[$currencyId] = $currency; - - $rate = $converter->getCurrencyRate($currency, $native, $day); - $convertedAmount = bcmul($transaction['amount'], $rate); - $currentBalance = bcadd($currentBalance, $convertedAmount); - $balances[$format] = $currentBalance; - - Log::debug(sprintf( - '%s: transaction in %s(!). Conversion rate is %s. %s %s = %s %s', - $format, - $currency->code, - $rate, - $currency->code, - $transaction['amount'], - $native->code, - $convertedAmount - )); - } - - $cache->store($balances); - $converter->summarize(); - - return $balances; - } - - /** - * @throws FireflyException - * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function balanceInRangeNative(Account $account, Carbon $start, Carbon $end): array @@ -723,10 +464,169 @@ class Steam return $balances; } + /** + * Gets the balance for the given account during the whole range, using this format:. + * + * [yyyy-mm-dd] => 123,2 + * + * @throws FireflyException + * @deprecated + */ + public function balanceInRange(Account $account, Carbon $start, Carbon $end, ?TransactionCurrency $currency = null): array + { + // Log::warning(sprintf('Deprecated method %s, do not use.', __METHOD__)); + $cache = new CacheProperties(); + $cache->addProperty($account->id); + $cache->addProperty('balance-in-range'); + $cache->addProperty(null !== $currency ? $currency->id : 0); + $cache->addProperty($start); + $cache->addProperty($end); + if ($cache->has()) { + return $cache->get(); + } + + $start->subDay(); + $end->addDay(); + $balances = []; + $formatted = $start->format('Y-m-d'); + $startBalance = $this->balance($account, $start, $currency); + + $balances[$formatted] = $startBalance; + if (null === $currency) { + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($account->user); + $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup); + } + $currencyId = $currency->id; + + $start->addDay(); + + // query! + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59')) + ->groupBy('transaction_journals.date') + ->groupBy('transactions.transaction_currency_id') + ->groupBy('transactions.foreign_currency_id') + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ // @phpstan-ignore-line + 'transaction_journals.date', + 'transactions.transaction_currency_id', + DB::raw('SUM(transactions.amount) AS modified'), + 'transactions.foreign_currency_id', + DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), + ] + ); + + $currentBalance = $startBalance; + + /** @var Transaction $entry */ + foreach ($set as $entry) { + // normal amount and foreign amount + $modified = (string) (null === $entry->modified ? '0' : $entry->modified); + $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); + $amount = '0'; + if ($currencyId === (int) $entry->transaction_currency_id || 0 === $currencyId) { + // use normal amount: + $amount = $modified; + } + if ($currencyId === (int) $entry->foreign_currency_id) { + // use foreign amount: + $amount = $foreignModified; + } + // Log::debug(sprintf('Trying to add %s and %s.', var_export($currentBalance, true), var_export($amount, true))); + $currentBalance = bcadd($currentBalance, $amount); + $carbon = new Carbon($entry->date, config('app.timezone')); + $date = $carbon->format('Y-m-d'); + $balances[$date] = $currentBalance; + } + + $cache->store($balances); + + return $balances; + } + + /** + * Balance of an (asset) account in the user's native currency. + * Is calculated by summing up three numbers. + * + * - Transactions in foreign amount that happen to be in the native currency. + * - The rest of the transactions in the native currency. + * - Where both are zero or NULL, the normal amount converted (and stored!) + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @deprecated + */ + private function balanceNative(Account $account, Carbon $date): string + { + $native = app('amount')->getDefaultCurrency(); + Log::debug(sprintf('Now in balanceNative (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code)); + $cache = new CacheProperties(); + $cache->addProperty($account->id); + $cache->addProperty('balance-native'); + $cache->addProperty($date); + $cache->addProperty($native->id); + if ($cache->has()) { + $value = $cache->get(); + Log::debug(sprintf('Return cached value %s', $value)); + return $value; + } + + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + $currency = $repository->getAccountCurrency($account); + $currency = null === $currency ? $native : $currency; + if ($native->id === $currency->id) { + Log::debug('No conversion necessary!'); + + return $this->balance($account, $date); + } + $balance = '0'; + // transactions in foreign amount that happen to be in the native currency: + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) + ->where('transactions.foreign_currency_id', $native->id) + ->get(['transactions.foreign_amount'])->toArray(); + $balance = bcadd($this->sumTransactions($set, 'foreign_amount'), $balance); + Log::debug(sprintf('The balance is now %s', $balance)); + + // transactions in the native amount. + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) + ->whereNull('transactions.foreign_currency_id') + ->whereNotNull('transactions.native_amount') + ->get(['transactions.native_amount'])->toArray(); + $balance = bcadd($this->sumTransactions($set, 'native_amount'), $balance); + Log::debug(sprintf('The balance is now %s', $balance)); + + // transactions in the normal amount with no native amount set. + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) + ->whereNull('transactions.foreign_currency_id') + ->whereNull('transactions.native_amount') + ->get(['transactions.amount'])->toArray(); + $balance = bcadd($this->sumTransactions($set, 'amount'), $balance); + Log::debug(sprintf('The balance is now %s', $balance)); + + // add virtual balance (also needs conversion) + $virtualNative = null === $account->native_virtual_balance ? '0' : $account->native_virtual_balance; + $final = bcadd($virtualNative, $balance); + Log::debug(sprintf('Final balance is %s', $final)); + $cache->store($final); + return $final; + } + /** * This method always ignores the virtual balance. * * @throws FireflyException + * @deprecated */ public function balancesByAccounts(Collection $accounts, Carbon $date): array { @@ -758,6 +658,7 @@ class Steam * This method always ignores the virtual balance. * * @throws FireflyException + * @deprecated */ public function balancesByAccountsConverted(Collection $accounts, Carbon $date): array { @@ -792,6 +693,8 @@ class Steam /** * Same as above, but also groups per currency. + * + * @deprecated */ public function balancesPerCurrencyByAccounts(Collection $accounts, Carbon $date): array { @@ -819,7 +722,14 @@ class Steam return $result; } - public function balancePerCurrency(Account $account, Carbon $date): array + /** + * @param Account $account + * @param Carbon $date + * + * @return array + * @deprecated + */ + private function balancePerCurrency(Account $account, Carbon $date): array { // Log::warning(sprintf('Deprecated method %s, do not use.', __METHOD__)); // abuse chart properties: @@ -834,10 +744,10 @@ class Steam ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59')) ->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 = []; - /** @var \stdClass $entry */ + /** @var stdClass $entry */ foreach ($balances as $entry) { $return[(int) $entry->transaction_currency_id] = (string) $entry->sum_for_currency; } @@ -933,6 +843,103 @@ class Steam return str_replace($search, '', $string); } + /** + * Returns the balance of an account at exact moment given. Array with at least one value. + * + * "balance" the balance in whatever currency the account has, so the sum of all transaction that happen to have + * THAT currency. + * "native_balance" the balance according to the "native_amount" + "native_foreign_amount" fields. + * "ABC" the balance in this particular currency code (may repeat for each found currency). + * + * @param Account $account + * @param Carbon $date + * + * @return array + */ + public function finalAccountBalance(Account $account, Carbon $date): array + { + $native = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup); + $currency = $this->getAccountCurrency($account) ?? $native; + $return = [ + 'native_balance' => '0', + ]; + Log::debug(sprintf('Now in finalAccountBalance("%s", "%s")', $account->name, $date->format('Y-m-d H:i:s'))); + // first, the "balance", as described earlier. + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->where('transactions.transaction_currency_id', $currency->id) + ->get(['transactions.amount'])->toArray(); + $return['balance'] = $this->sumTransactions($array, 'amount'); + Log::debug(sprintf('balance is %s', $return['balance'])); + // add virtual balance: + $return['balance'] = bcadd('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance, $return['balance']); + Log::debug(sprintf('balance is %s (with virtual balance)', $return['balance'])); + + // then, native balance (if necessary( + if ($native->id !== $currency->id) { + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->get(['transactions.native_amount'])->toArray(); + $return['native_balance'] = $this->sumTransactions($array, 'native_amount'); + Log::debug(sprintf('native_balance is %s', $return['native_balance'])); + $return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['balance']); + Log::debug(sprintf('native_balance is %s (with virtual balance)', $return['native_balance'])); + } + + // balance(s) in other currencies. + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + Log::debug('All others are (joined)', $others); + return array_merge($return, $others); + } + + public function getAccountCurrency(Account $account): ?TransactionCurrency + { + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); + + // return null if not in this list. + if (!in_array($type, $list, true)) { + return null; + } + $result = $account->accountMeta->where('name', 'currency_id')->first(); + if (null === $result) { + return null; + } + return TransactionCurrency::find((int) $result->data); + } + + private function sumTransactions(array $transactions, string $key): string + { + $sum = '0'; + + /** @var array $transaction */ + foreach ($transactions as $transaction) { + $value = (string) ($transaction[$key] ?? '0'); + $value = '' === $value ? '0' : $value; + $sum = bcadd($sum, $value); + } + + return $sum; + } + + private function groupAndSumTransactions(array $array, string $group, string $field): array + { + $return = []; + + foreach ($array as $item) { + $groupKey = $item[$group] ?? 'unknown'; + $return[$groupKey] = bcadd($return[$groupKey] ?? '0', $item[$field]); + } + return $return; + } + /** * @throws FireflyException */ @@ -942,7 +949,7 @@ class Steam try { $hostName = gethostbyaddr($ipAddress); - } catch (\Exception $e) { + } catch (Exception $e) { app('log')->error($e->getMessage()); $hostName = $ipAddress; } @@ -961,7 +968,7 @@ class Steam $set = auth()->user()->transactions() ->whereIn('transactions.account_id', $accounts) ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) - ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line + ->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line ; /** @var Transaction $entry */ @@ -1051,7 +1058,7 @@ class Steam // URL must not lead to weird pages $forbiddenWords = ['jscript', 'json', 'debug', 'serviceworker', 'offline', 'delete', '/login', '/attachments/view']; - if (\Str::contains($returnUrl, $forbiddenWords)) { + if (Str::contains($returnUrl, $forbiddenWords)) { $returnUrl = $safeUrl; } @@ -1149,7 +1156,7 @@ class Steam if (-1 === bccomp($amount, '0')) { $amount = bcmul($amount, '-1'); } - } catch (\ValueError $e) { + } catch (ValueError $e) { Log::error(sprintf('ValueError in Steam::positive("%s"): %s', $amount, $e->getMessage())); Log::error($e->getTraceAsString()); diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php index 0a30779bb0..a587c28cd3 100644 --- a/app/Support/Twig/General.php +++ b/app/Support/Twig/General.php @@ -25,8 +25,11 @@ namespace FireflyIII\Support\Twig; use Carbon\Carbon; use FireflyIII\Models\Account; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; +use FireflyIII\Support\Facades\Amount; +use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Search\OperatorQuerySearch; use League\CommonMark\GithubFlavoredMarkdownConverter; use Route; @@ -63,28 +66,29 @@ class General extends AbstractExtension } /** @var Carbon $date */ - $date = session('end', today(config('app.timezone'))->endOfMonth()); - $runningBalance = config('firefly.feature_flags.running_balance_column'); - $info = []; - if (true === $runningBalance) { - $info = app('steam')->balanceByTransactions($account, $date, null); - } - if (false === $runningBalance) { - $info[] = app('steam')->balance($account, $date); - } - - $strings = []; - foreach ($info as $currencyId => $balance) { - $balance = (string) $balance; - if (0 === $currencyId) { - // not good code but OK - /** @var AccountRepositoryInterface $accountRepos */ - $accountRepos = app(AccountRepositoryInterface::class); - $currency = $accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency(); - $strings[] = app('amount')->formatAnything($currency, $balance, false); + $date = session('end', today(config('app.timezone'))->endOfMonth()); + $info = Steam::finalAccountBalance($account, $date); + $currency = Steam::getAccountCurrency($account); + $native = Amount::getDefaultCurrency(); + $convertToNative = app('preferences')->get('convert_to_native', false)->data; + $strings = []; + foreach ($info as $key => $balance) { + if ('balance' === $key) { + // balance in account currency. + if (!$convertToNative || $currency->code === $native->code) { + $strings[] = app('amount')->formatAnything($currency, $balance, false); + } + continue; } - if (0 !== $currencyId) { - $strings[] = app('amount')->formatByCurrencyId($currencyId, $balance, false); + if ('native_balance' === $key) { + // balance in native currency. + if($convertToNative) { + $strings[] = app('amount')->formatAnything($native, $balance, false); + } + continue; + } + if ($key !== $currency->code) { + $strings[] = app('amount')->formatAnything(TransactionCurrency::where('code', $key)->first(), $balance, false); } } @@ -104,15 +108,15 @@ class General extends AbstractExtension static function (int $size): string { // less than one GB, more than one MB if ($size < (1024 * 1024 * 2014) && $size >= (1024 * 1024)) { - return round($size / (1024 * 1024), 2).' MB'; + return round($size / (1024 * 1024), 2) . ' MB'; } // less than one MB if ($size < (1024 * 1024)) { - return round($size / 1024, 2).' KB'; + return round($size / 1024, 2) . ' KB'; } - return $size.' bytes'; + return $size . ' bytes'; } ); } @@ -134,7 +138,7 @@ class General extends AbstractExtension case 'application/pdf': return 'fa-file-pdf-o'; - // image + // image case 'image/png': case 'image/jpeg': case 'image/svg+xml': @@ -143,7 +147,7 @@ class General extends AbstractExtension case 'application/vnd.oasis.opendocument.image': return 'fa-file-image-o'; - // MS word + // MS word case 'application/msword': case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': case 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': @@ -159,7 +163,7 @@ class General extends AbstractExtension case 'application/vnd.oasis.opendocument.text-master': return 'fa-file-word-o'; - // MS excel + // MS excel case 'application/vnd.ms-excel': case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': case 'application/vnd.openxmlformats-officedocument.spreadsheetml.template': @@ -170,7 +174,7 @@ class General extends AbstractExtension case 'application/vnd.oasis.opendocument.spreadsheet-template': return 'fa-file-excel-o'; - // MS powerpoint + // MS powerpoint case 'application/vnd.ms-powerpoint': case 'application/vnd.openxmlformats-officedocument.presentationml.presentation': case 'application/vnd.openxmlformats-officedocument.presentationml.template': @@ -182,7 +186,7 @@ class General extends AbstractExtension case 'application/vnd.oasis.opendocument.presentation-template': return 'fa-file-powerpoint-o'; - // calc + // calc case 'application/vnd.sun.xml.draw': case 'application/vnd.sun.xml.draw.template': case 'application/vnd.stardivision.draw': @@ -318,7 +322,7 @@ class General extends AbstractExtension 'activeRoutePartialObjectType', static function ($context): string { [, $route, $objectType] = func_get_args(); - $activeObjectType = $context['objectType'] ?? false; + $activeObjectType = $context['objectType'] ?? false; if ($objectType === $activeObjectType && false !== stripos( diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php index a411953edf..08f257ccfa 100644 --- a/app/Transformers/AccountTransformer.php +++ b/app/Transformers/AccountTransformer.php @@ -28,6 +28,7 @@ use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use Symfony\Component\HttpFoundation\ParameterBag; /** @@ -103,7 +104,7 @@ class AccountTransformer extends AbstractTransformer 'currency_code' => $currencyCode, 'currency_symbol' => $currencySymbol, 'currency_decimal_places' => $decimalPlaces, - 'current_balance' => app('steam')->bcround(app('steam')->balance($account, $date), $decimalPlaces), + 'current_balance' => app('steam')->bcround(Steam::finalAccountBalance($account, $date)['balance'], $decimalPlaces), 'current_balance_date' => $date->toAtomString(), 'notes' => $this->repository->getNoteText($account), 'monthly_payment_date' => $monthlyPaymentDate,