Optimize query for collecting transactions.

This commit is contained in:
James Cole
2025-09-26 20:46:23 +02:00
parent b1d86c3a37
commit 33dcce7525

View File

@@ -73,7 +73,8 @@ trait PeriodOverview
protected AccountRepositoryInterface $accountRepository; protected AccountRepositoryInterface $accountRepository;
protected JournalRepositoryInterface $journalRepos; protected JournalRepositoryInterface $journalRepos;
protected PeriodStatisticRepositoryInterface $periodStatisticRepo; protected PeriodStatisticRepositoryInterface $periodStatisticRepo;
private Collection $statistics; private Collection $statistics; // temp data holder
private array $transactions; // temp data holder
/** /**
* This method returns "period entries", so nov-2015, dec-2015, etc. (this depends on the users session range) * This method returns "period entries", so nov-2015, dec-2015, etc. (this depends on the users session range)
@@ -332,6 +333,7 @@ trait PeriodOverview
'route' => route('accounts.show', [$account->id, $start->format('Y-m-d'), $start->format('Y-m-d')]), 'route' => route('accounts.show', [$account->id, $start->format('Y-m-d'), $start->format('Y-m-d')]),
'total_transactions' => 0, 'total_transactions' => 0,
]; ];
$this->transactions = [];
foreach ($types as $type) { foreach ($types as $type) {
$set = $this->getSingleAccountPeriodByType($account, $start, $end, $type); $set = $this->getSingleAccountPeriodByType($account, $start, $end, $type);
$return['total_transactions'] += $set['count']; $return['total_transactions'] += $set['count'];
@@ -371,29 +373,31 @@ trait PeriodOverview
// nothing found, regenerate them. // nothing found, regenerate them.
if (0 === $statistics->count()) { if (0 === $statistics->count()) {
Log::debug(sprintf('Found nothing in this period for type "%s"', $type)); Log::debug(sprintf('Found nothing in this period for type "%s"', $type));
$transactions = $this->accountRepository->periodCollection($account, $start, $end); if (0 === count($this->transactions)) {
$this->transactions = $this->accountRepository->periodCollection($account, $start, $end);
}
switch ($type) { switch ($type) {
default: default:
throw new FireflyException(sprintf('Cannot deal with account period type %s', $type)); throw new FireflyException(sprintf('Cannot deal with account period type %s', $type));
case 'spent': case 'spent':
$result = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $transactions, $start, $end); $result = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $start, $end);
break; break;
case 'earned': case 'earned':
$result = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $transactions, $start, $end); $result = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $start, $end);
break; break;
case 'transferred_in': case 'transferred_in':
$result = $this->filterTransfers('in', $transactions, $start, $end); $result = $this->filterTransfers('in', $start, $end);
break; break;
case 'transferred_away': case 'transferred_away':
$result = $this->filterTransfers('away', $transactions, $start, $end); $result = $this->filterTransfers('away', $start, $end);
break; break;
} }
@@ -616,7 +620,7 @@ trait PeriodOverview
return $return; return $return;
} }
private function filterTransactionsByType(TransactionTypeEnum $type, array $transactions, Carbon $start, Carbon $end): array private function filterTransactionsByType(TransactionTypeEnum $type, Carbon $start, Carbon $end): array
{ {
$result = []; $result = [];
@@ -624,12 +628,11 @@ trait PeriodOverview
* @var int $index * @var int $index
* @var array $item * @var array $item
*/ */
foreach ($transactions as $index => $item) { foreach ($this->transactions as $item) {
$date = Carbon::parse($item['date']); $date = Carbon::parse($item['date']);
$fits = $item['type'] === $type->value && $date >= $start && $date <= $end; $fits = $item['type'] === $type->value && $date >= $start && $date <= $end;
if ($fits) { if ($fits) {
$result[] = $item; $result[] = $item;
unset($transactions[$index]);
} }
} }
@@ -670,7 +673,7 @@ trait PeriodOverview
return $return; return $return;
} }
private function filterTransfers(string $direction, array $transactions, Carbon $start, Carbon $end): array private function filterTransfers(string $direction, Carbon $start, Carbon $end): array
{ {
$result = []; $result = [];
@@ -678,7 +681,7 @@ trait PeriodOverview
* @var int $index * @var int $index
* @var array $item * @var array $item
*/ */
foreach ($transactions as $index => $item) { foreach ($this->transactions as $item) {
$date = Carbon::parse($item['date']); $date = Carbon::parse($item['date']);
if ($date >= $start && $date <= $end) { if ($date >= $start && $date <= $end) {
if ('Transfer' === $item['type'] && 'away' === $direction && -1 === bccomp((string)$item['amount'], '0')) { if ('Transfer' === $item['type'] && 'away' === $direction && -1 === bccomp((string)$item['amount'], '0')) {
@@ -688,8 +691,6 @@ trait PeriodOverview
} }
if ('Transfer' === $item['type'] && 'in' === $direction && 1 === bccomp((string)$item['amount'], '0')) { if ('Transfer' === $item['type'] && 'in' === $direction && 1 === bccomp((string)$item['amount'], '0')) {
$result[] = $item; $result[] = $item;
continue;
} }
} }
} }