From 7eb2451e3dbcd57daf93f1d376baea428caf5332 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 20 Mar 2020 04:37:45 +0100 Subject: [PATCH] Improved chart for #2938 --- .../Controllers/Chart/AccountController.php | 90 ++++++++++++------- .../Account/AccountRepository.php | 16 ++++ .../Account/AccountRepositoryInterface.php | 7 ++ .../Http/Controllers/ChartGeneration.php | 3 +- app/Support/Steam.php | 25 +++--- 5 files changed, 96 insertions(+), 45 deletions(-) diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index 825d017c00..108075bc63 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -433,40 +433,15 @@ class AccountController extends Controller $cache->addProperty($end); $cache->addProperty($account->id); if ($cache->has()) { - return response()->json($cache->get()); // @codeCoverageIgnore + return response()->json($cache->get()); // @codeCoverageIgnore + } + $currencies = $this->accountRepository->getUsedCurrencies($account); + /** @var TransactionCurrency $currency */ + foreach ($currencies as $currency) { + $chartData[] = $this->periodByCurrency($start, $end, $account, $currency); } - $step = $this->calculateStep($start, $end); - $chartData = []; - $current = clone $start; - switch ($step) { - case '1D': - $format = (string) trans('config.month_and_day'); - $range = app('steam')->balanceInRange($account, $start, $end); - $previous = array_values($range)[0]; - while ($end >= $current) { - $theDate = $current->format('Y-m-d'); - $balance = $range[$theDate] ?? $previous; - $label = $current->formatLocalized($format); - $chartData[$label] = (float) $balance; - $previous = $balance; - $current->addDay(); - } - break; - // @codeCoverageIgnoreStart - case '1W': - case '1M': - case '1Y': - while ($end >= $current) { - $balance = (float) app('steam')->balance($account, $current); - $label = app('navigation')->periodShow($current, $step); - $chartData[$label] = $balance; - $current = app('navigation')->addPeriod($current, $step, 0); - } - break; - // @codeCoverageIgnoreEnd - } - $data = $this->generator->singleSet($account->name, $chartData); + $data = $this->generator->multiSet($chartData); $cache->store($data); return response()->json($data); @@ -580,4 +555,55 @@ class AccountController extends Controller return response()->json($data); } + + /** + * @param Carbon $start + * @param Carbon $end + * @param Account $account + * @param TransactionCurrency $currency + * + * @return array + */ + private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array + { + $step = $this->calculateStep($start, $end); + $result = [ + 'label' => sprintf('%s (%s)', $account->name, $currency->symbol), + 'currency_symbol' => $currency->symbol, + 'entries' => [], + ]; + $entries = []; + $current = clone $start; + switch ($step) { + case '1D': + // per day the entire period, balance for every day. + $format = (string) trans('config.month_and_day'); + $range = app('steam')->balanceInRange($account, $start, $end, $currency); + $previous = array_values($range)[0]; + while ($end >= $current) { + $theDate = $current->format('Y-m-d'); + $balance = $range[$theDate] ?? $previous; + $label = $current->formatLocalized($format); + $entries[$label] = (float) $balance; + $previous = $balance; + $current->addDay(); + } + break; + // @codeCoverageIgnoreStart + case '1W': + case '1M': + case '1Y': + while ($end >= $current) { + $balance = (float) app('steam')->balance($account, $current, $currency); + $label = app('navigation')->periodShow($current, $step); + $entries[$label] = $balance; + $current = app('navigation')->addPeriod($current, $step, 0); + } + break; + // @codeCoverageIgnoreEnd + } + $result['entries'] = $entries; + + return $result; + } } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index fa9662c1c3..16dce54039 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -653,4 +653,20 @@ class AccountRepository implements AccountRepositoryInterface { return $account->attachments()->get(); } + + /** + * @inheritDoc + */ + public function getUsedCurrencies(Account $account): Collection + { + $info = $account->transactions()->get(['transaction_currency_id', 'foreign_currency_id'])->toArray(); + $currencyIds = []; + foreach ($info as $entry) { + $currencyIds[] = (int) $entry['transaction_currency_id']; + $currencyIds[] = (int) $entry['foreign_currency_id']; + } + $currencyIds = array_unique($currencyIds); + + return TransactionCurrency::whereIn('id', $currencyIds)->get(); + } } diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 3c8e5847ad..176df182fc 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -47,6 +47,13 @@ interface AccountRepositoryInterface */ public function count(array $types): int; + /** + * @param Account $account + * + * @return Collection + */ + public function getUsedCurrencies(Account $account): Collection; + /** * @param Account $account * diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php index f19b9370fd..85bd88b347 100644 --- a/app/Support/Http/Controllers/ChartGeneration.php +++ b/app/Support/Http/Controllers/ChartGeneration.php @@ -58,7 +58,7 @@ trait ChartGeneration $cache->addProperty('chart.account.account-balance-chart'); $cache->addProperty($accounts); if ($cache->has()) { - return $cache->get(); // @codeCoverageIgnore + //return $cache->get(); // @codeCoverageIgnore } Log::debug('Regenerate chart.account.account-balance-chart from scratch.'); /** @var GeneratorInterface $generator */ @@ -97,6 +97,7 @@ trait ChartGeneration } $chartData[] = $currentSet; } + var_dump($chartData);exit; $data = $generator->multiSet($chartData); $cache->store($data); diff --git a/app/Support/Steam.php b/app/Support/Steam.php index da70a85388..be4e10579f 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -26,6 +26,7 @@ use Carbon\Carbon; use DB; use FireflyIII\Models\Account; use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use Illuminate\Support\Collection; use Log; @@ -44,7 +45,7 @@ class Steam * * @return string */ - public function balance(Account $account, Carbon $date): string + public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string { if ('testing' === config('app.env')) { Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__)); @@ -59,8 +60,9 @@ class Steam } /** @var AccountRepositoryInterface $repository */ $repository = app(AccountRepositoryInterface::class); - $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); - + if (null === $currency) { + $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); + } // first part: get all balances in own currency: $transactions = $account->transactions() ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') @@ -168,10 +170,11 @@ class Steam * @param \FireflyIII\Models\Account $account * @param \Carbon\Carbon $start * @param \Carbon\Carbon $end + * @param TransactionCurrency|null $currency * * @return array */ - public function balanceInRange(Account $account, Carbon $start, Carbon $end): array + public function balanceInRange(Account $account, Carbon $start, Carbon $end, ?TransactionCurrency $currency = null): array { if ('testing' === config('app.env')) { Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__)); @@ -180,6 +183,7 @@ class Steam $cache = new CacheProperties; $cache->addProperty($account->id); $cache->addProperty('balance-in-range'); + $cache->addProperty($currency ? $currency->id : 0); $cache->addProperty($start); $cache->addProperty($end); if ($cache->has()) { @@ -193,17 +197,14 @@ class Steam $startBalance = $this->balance($account, $start); /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - $repository->setUser($account->user); $balances[$formatted] = $startBalance; - $currencyId = (int)$repository->getMetaValue($account, 'currency_id'); - - // use system default currency: - if (0 === $currencyId) { - $currency = app('amount')->getDefaultCurrencyByUser($account->user); - $currencyId = $currency->id; + if (null === $currency) { + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($account->user); + $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user); } + $currencyId = $currency->id; $start->addDay();