From 0a235ec523d2f1d0ad22534a2bf16e83296983d3 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 16 Aug 2025 06:34:28 +0200 Subject: [PATCH] Optimize category chart. --- .../Category/FrontpageChartGenerator.php | 79 +++++++++---------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/app/Support/Chart/Category/FrontpageChartGenerator.php b/app/Support/Chart/Category/FrontpageChartGenerator.php index dd10fd018e..14157c72d1 100644 --- a/app/Support/Chart/Category/FrontpageChartGenerator.php +++ b/app/Support/Chart/Category/FrontpageChartGenerator.php @@ -65,55 +65,27 @@ class FrontpageChartGenerator public function generate(): array { - Log::debug('Now in generate()'); - $categories = $this->repository->getCategories(); - $accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]); - - // get expenses + income per category: - $collection = []; - - /** @var Category $category */ - foreach ($categories as $category) { - // get expenses - $collection[] = $this->collectExpenses($category, $accounts); - } + Log::debug(sprintf('Now in %s', __METHOD__)); + $categories = $this->repository->getCategories(); + $accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]); + $collection = $this->collectExpensesAll($categories, $accounts); // collect for no-category: - $collection[] = $this->collectNoCatExpenses($accounts); - - $tempData = array_merge(...$collection); + $noCategory = $this->collectNoCatExpenses($accounts); + $collection = array_merge($collection, $noCategory); // sort temp array by amount. - $amounts = array_column($tempData, 'sum_float'); - array_multisort($amounts, SORT_ASC, $tempData); + $amounts = array_column($collection, 'sum_float'); + array_multisort($amounts, SORT_ASC, $collection); - $currencyData = $this->createCurrencyGroups($tempData); + $currencyData = $this->createCurrencyGroups($collection); - return $this->insertValues($currencyData, $tempData); - } - - private function collectExpenses(Category $category, Collection $accounts): array - { - Log::debug(sprintf('Collect expenses for category #%d ("%s")', $category->id, $category->name)); - $spent = $this->opsRepos->sumExpenses($this->start, $this->end, $accounts, new Collection([$category])); - $tempData = []; - foreach ($spent as $currency) { - Log::debug(sprintf('Spent %s %s', $currency['currency_code'], $currency['sum'])); - $this->addCurrency($currency); - $tempData[] = [ - 'name' => $category->name, - 'sum' => $currency['sum'], - 'sum_float' => round((float) $currency['sum'], $currency['currency_decimal_places']), - 'currency_id' => (int) $currency['currency_id'], - ]; - } - - return $tempData; + return $this->insertValues($currencyData, $collection); } private function addCurrency(array $currency): void { - $currencyId = (int) $currency['currency_id']; + $currencyId = (int)$currency['currency_id']; $this->currencies[$currencyId] ??= [ 'currency_id' => $currencyId, @@ -133,8 +105,8 @@ class FrontpageChartGenerator $tempData[] = [ 'name' => trans('firefly.no_category'), 'sum' => $currency['sum'], - 'sum_float' => round((float) $currency['sum'], $currency['currency_decimal_places'] ?? 2), // intentional float - 'currency_id' => (int) $currency['currency_id'], + 'sum_float' => round((float)$currency['sum'], $currency['currency_decimal_places'] ?? 2), // intentional float + 'currency_id' => (int)$currency['currency_id'], ]; } @@ -152,7 +124,7 @@ class FrontpageChartGenerator foreach ($this->currencies as $currencyId => $currency) { $key = sprintf('spent-%d', $currencyId); $return[$key] = [ - 'label' => sprintf('%s (%s)', (string) trans('firefly.spent'), $currency['currency_name']), + 'label' => sprintf('%s (%s)', (string)trans('firefly.spent'), $currency['currency_name']), 'type' => 'bar', 'currency_symbol' => $currency['currency_symbol'], 'entries' => $names, @@ -175,4 +147,27 @@ class FrontpageChartGenerator return $currencyData; } + + private function collectExpensesAll(Collection $categories, Collection $accounts): array + { + Log::debug(sprintf('Collect expenses for %d category(ies).', count($categories))); + $spent = $this->opsRepos->collectExpenses($this->start, $this->end, $accounts, $categories); + $tempData = []; + foreach ($categories as $category) { + $sums = $this->opsRepos->sumCollectedTransactionsByCategory($spent, $category, 'negative', $this->convertToPrimary); + if (0 === count($sums)) { + continue; + } + foreach ($sums as $currency) { + $this->addCurrency($currency); + $tempData[] = [ + 'name' => $category->name, + 'sum' => $currency['sum'], + 'sum_float' => round((float)$currency['sum'], $currency['currency_decimal_places']), + 'currency_id' => (int)$currency['currency_id'], + ]; + } + } + return $tempData; + } }