Improved chart for #2938

This commit is contained in:
James Cole 2020-03-20 04:37:45 +01:00
parent 6dba44ba71
commit 7eb2451e3d
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
5 changed files with 96 additions and 45 deletions

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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
*

View File

@ -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);

View File

@ -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();