Improved chart for #2938

This commit is contained in:
James Cole
2020-03-20 04:37:45 +01:00
parent 6dba44ba71
commit 7eb2451e3d
5 changed files with 96 additions and 45 deletions

View File

@@ -433,40 +433,15 @@ class AccountController extends Controller
$cache->addProperty($end); $cache->addProperty($end);
$cache->addProperty($account->id); $cache->addProperty($account->id);
if ($cache->has()) { 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); $data = $this->generator->multiSet($chartData);
$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);
$cache->store($data); $cache->store($data);
return response()->json($data); return response()->json($data);
@@ -580,4 +555,55 @@ class AccountController extends Controller
return response()->json($data); 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;
}
} }

View File

@@ -653,4 +653,20 @@ class AccountRepository implements AccountRepositoryInterface
{ {
return $account->attachments()->get(); 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();
}
} }

View File

@@ -47,6 +47,13 @@ interface AccountRepositoryInterface
*/ */
public function count(array $types): int; public function count(array $types): int;
/**
* @param Account $account
*
* @return Collection
*/
public function getUsedCurrencies(Account $account): Collection;
/** /**
* @param Account $account * @param Account $account
* *

View File

@@ -58,7 +58,7 @@ trait ChartGeneration
$cache->addProperty('chart.account.account-balance-chart'); $cache->addProperty('chart.account.account-balance-chart');
$cache->addProperty($accounts); $cache->addProperty($accounts);
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore //return $cache->get(); // @codeCoverageIgnore
} }
Log::debug('Regenerate chart.account.account-balance-chart from scratch.'); Log::debug('Regenerate chart.account.account-balance-chart from scratch.');
/** @var GeneratorInterface $generator */ /** @var GeneratorInterface $generator */
@@ -97,6 +97,7 @@ trait ChartGeneration
} }
$chartData[] = $currentSet; $chartData[] = $currentSet;
} }
var_dump($chartData);exit;
$data = $generator->multiSet($chartData); $data = $generator->multiSet($chartData);
$cache->store($data); $cache->store($data);

View File

@@ -26,6 +26,7 @@ use Carbon\Carbon;
use DB; use DB;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
@@ -44,7 +45,7 @@ class Steam
* *
* @return string * @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')) { if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__)); Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
@@ -59,8 +60,9 @@ class Steam
} }
/** @var AccountRepositoryInterface $repository */ /** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class); $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: // first part: get all balances in own currency:
$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')
@@ -168,10 +170,11 @@ class Steam
* @param \FireflyIII\Models\Account $account * @param \FireflyIII\Models\Account $account
* @param \Carbon\Carbon $start * @param \Carbon\Carbon $start
* @param \Carbon\Carbon $end * @param \Carbon\Carbon $end
* @param TransactionCurrency|null $currency
* *
* @return array * @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')) { if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__)); Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
@@ -180,6 +183,7 @@ class Steam
$cache = new CacheProperties; $cache = new CacheProperties;
$cache->addProperty($account->id); $cache->addProperty($account->id);
$cache->addProperty('balance-in-range'); $cache->addProperty('balance-in-range');
$cache->addProperty($currency ? $currency->id : 0);
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
if ($cache->has()) { if ($cache->has()) {
@@ -193,17 +197,14 @@ class Steam
$startBalance = $this->balance($account, $start); $startBalance = $this->balance($account, $start);
/** @var AccountRepositoryInterface $repository */ /** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
$balances[$formatted] = $startBalance; $balances[$formatted] = $startBalance;
$currencyId = (int)$repository->getMetaValue($account, 'currency_id'); if (null === $currency) {
$repository = app(AccountRepositoryInterface::class);
// use system default currency: $repository->setUser($account->user);
if (0 === $currencyId) { $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
$currency = app('amount')->getDefaultCurrencyByUser($account->user);
$currencyId = $currency->id;
} }
$currencyId = $currency->id;
$start->addDay(); $start->addDay();