From 92f534bcb392f47df92dfd04094821bbabbdab99 Mon Sep 17 00:00:00 2001 From: JC5 Date: Fri, 8 Aug 2025 21:03:45 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20release=20?= =?UTF-8?q?'develop'=20on=202025-08-08?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Chart/BalanceController.php | 18 +- .../Controllers/Chart/AccountController.php | 175 ++++++------ .../Transaction/ShowController.php | 52 ++-- .../Account/AccountRepository.php | 4 +- .../AuditLogEntry/ALERepositoryInterface.php | 2 +- app/Support/Amount.php | 57 ++-- .../Http/Controllers/ChartGeneration.php | 2 +- .../Http/Controllers/PeriodOverview.php | 268 +++++++++--------- app/Support/Preferences.php | 9 +- .../Singleton/PreferencesSingleton.php | 14 +- composer.lock | 22 +- config/firefly.php | 2 +- package-lock.json | 12 +- routes/api.php | 4 - 14 files changed, 323 insertions(+), 318 deletions(-) diff --git a/app/Api/V1/Controllers/Chart/BalanceController.php b/app/Api/V1/Controllers/Chart/BalanceController.php index b9ed26cd35..9be3c42830 100644 --- a/app/Api/V1/Controllers/Chart/BalanceController.php +++ b/app/Api/V1/Controllers/Chart/BalanceController.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Chart; - use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Chart\ChartRequest; use FireflyIII\Enums\TransactionTypeEnum; @@ -43,7 +42,7 @@ class BalanceController extends Controller $userGroup = $this->validateUserGroup($request); $this->repository->setUserGroup($userGroup); $this->collector->setUserGroup($userGroup); - $this->chartData = new ChartData(); + $this->chartData = new ChartData(); // $this->default = app('amount')->getPrimaryCurrency(); return $next($request); @@ -69,17 +68,18 @@ class BalanceController extends Controller // prepare for currency conversion and data collection: /** @var TransactionCurrency $primary */ - $primary = Amount::getPrimaryCurrency(); + $primary = Amount::getPrimaryCurrency(); // get journals for entire period: $this->collector->setRange($queryParameters['start'], $queryParameters['end']) - ->withAccountInformation() - ->setXorAccounts($accounts) - ->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::RECONCILIATION->value, TransactionTypeEnum::TRANSFER->value]); - $journals = $this->collector->getExtractedJournals(); + ->withAccountInformation() + ->setXorAccounts($accounts) + ->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::RECONCILIATION->value, TransactionTypeEnum::TRANSFER->value]) + ; + $journals = $this->collector->getExtractedJournals(); - $object = new AccountBalanceGrouped(); + $object = new AccountBalanceGrouped(); $object->setPreferredRange($queryParameters['period']); $object->setPrimary($primary); $object->setAccounts($accounts); @@ -87,7 +87,7 @@ class BalanceController extends Controller $object->setStart($queryParameters['start']); $object->setEnd($queryParameters['end']); $object->groupByCurrencyAndPeriod(); - $data = $object->convertToChartData(); + $data = $object->convertToChartData(); foreach ($data as $entry) { $this->chartData->add($entry); } diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index 80bed9b677..63f80a2d92 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -43,6 +43,7 @@ use FireflyIII\Support\Http\Controllers\DateCalculation; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; + use function Safe\json_encode; /** @@ -87,14 +88,14 @@ class AccountController extends Controller Log::debug('ExpenseAccounts'); /** @var Carbon $start */ - $start = clone session('start', today(config('app.timezone'))->startOfMonth()); + $start = clone session('start', today(config('app.timezone'))->startOfMonth()); /** @var Carbon $end */ - $end = clone session('end', today(config('app.timezone'))->endOfMonth()); + $end = clone session('end', today(config('app.timezone'))->endOfMonth()); $start->startOfDay(); $end->endOfDay(); - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($this->convertToPrimary); @@ -104,13 +105,13 @@ class AccountController extends Controller } // prep some vars: - $currencies = []; - $chartData = []; - $tempData = []; + $currencies = []; + $chartData = []; + $tempData = []; // grab all accounts and names - $accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::EXPENSE->value]); - $accountNames = $this->extractNames($accounts); + $accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::EXPENSE->value]); + $accountNames = $this->extractNames($accounts); // grab all balances Log::debug(sprintf('expenseAccounts: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); @@ -144,14 +145,14 @@ class AccountController extends Controller continue; } // Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance)); - $searchCode = $this->convertToPrimary ? $this->primaryCurrency->code : $key; - $searchCode = 'balance' === $searchCode || 'pc_balance' === $searchCode ? $this->primaryCurrency->code : $searchCode; + $searchCode = $this->convertToPrimary ? $this->primaryCurrency->code : $key; + $searchCode = 'balance' === $searchCode || 'pc_balance' === $searchCode ? $this->primaryCurrency->code : $searchCode; // Log::debug(sprintf('Search code is %s', $searchCode)); // see if there is an accompanying start amount. // grab the difference and find the currency. $startBalance = ($startBalances[$account->id][$key] ?? '0'); // Log::debug(sprintf('Start balance is %s', $startBalance)); - $diff = bcsub($endBalance, $startBalance); + $diff = bcsub($endBalance, $startBalance); $currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode); if (0 !== bccomp($diff, '0')) { // store the values in a temporary array. @@ -169,26 +170,26 @@ class AccountController extends Controller foreach ($currencies as $currency) { $newCurrencies[$currency->id] = $currency; } - $currencies = $newCurrencies; + $currencies = $newCurrencies; // sort temp array by amount. - $amounts = array_column($tempData, 'diff_float'); + $amounts = array_column($tempData, 'diff_float'); array_multisort($amounts, SORT_DESC, $tempData); // loop all found currencies and build the data array for the chart. /** - * @var int $currencyId + * @var int $currencyId * @var TransactionCurrency $currency */ foreach ($currencies as $currencyId => $currency) { $dataSet = [ - 'label' => (string)trans('firefly.spent'), - 'type' => 'bar', - 'currency_symbol' => $currency->symbol, - 'currency_code' => $currency->code, - 'entries' => $this->expandNames($tempData), - ]; + 'label' => (string)trans('firefly.spent'), + 'type' => 'bar', + 'currency_symbol' => $currency->symbol, + 'currency_code' => $currency->code, + 'entries' => $this->expandNames($tempData), + ]; $chartData[$currencyId] = $dataSet; } @@ -199,7 +200,7 @@ class AccountController extends Controller $chartData[$currencyId]['entries'][$name] = (float)$entry['difference']; } - $data = $this->generator->multiSet($chartData); + $data = $this->generator->multiSet($chartData); $cache->store($data); return response()->json($data); @@ -207,7 +208,6 @@ class AccountController extends Controller /** * Expenses per budget for all time, as shown on account overview. - * */ public function expenseBudgetAll(AccountRepositoryInterface $repository, Account $account): JsonResponse { @@ -222,7 +222,7 @@ class AccountController extends Controller */ public function expenseBudget(Account $account, Carbon $start, Carbon $end): JsonResponse { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($start); $cache->addProperty($this->convertToPrimary); @@ -235,8 +235,9 @@ class AccountController extends Controller /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); $collector->setAccounts(new Collection([$account])) - ->setRange($start, $end) - ->withBudgetInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); + ->setRange($start, $end) + ->withBudgetInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]) + ; $journals = $collector->getExtractedJournals(); $chartData = []; $result = []; @@ -244,9 +245,9 @@ class AccountController extends Controller /** @var array $journal */ foreach ($journals as $journal) { - $budgetId = (int)$journal['budget_id']; - $key = sprintf('%d-%d', $budgetId, $journal['currency_id']); - $budgetIds[] = $budgetId; + $budgetId = (int)$journal['budget_id']; + $key = sprintf('%d-%d', $budgetId, $journal['currency_id']); + $budgetIds[] = $budgetId; // currency info: $currencyId = (int)$journal['currency_id']; @@ -277,7 +278,7 @@ class AccountController extends Controller $result[$key]['total'] = bcadd((string)$journal[$field], $result[$key]['total']); } - $names = $this->getBudgetNames($budgetIds); + $names = $this->getBudgetNames($budgetIds); foreach ($result as $row) { $budgetId = $row['budget_id']; @@ -286,7 +287,7 @@ class AccountController extends Controller $chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']]; } - $data = $this->generator->multiCurrencyPieChart($chartData); + $data = $this->generator->multiCurrencyPieChart($chartData); $cache->store($data); return response()->json($data); @@ -308,14 +309,14 @@ class AccountController extends Controller */ public function expenseCategory(Account $account, Carbon $start, Carbon $end): JsonResponse { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($this->convertToPrimary); $cache->addProperty('chart.account.expense-category'); if ($cache->has()) { - return response()->json($cache->get()); + return response()->json($cache->get()); } /** @var GroupCollectorInterface $collector */ @@ -327,7 +328,7 @@ class AccountController extends Controller /** @var array $journal */ foreach ($journals as $journal) { - $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); + $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); if (!array_key_exists($key, $result)) { // currency info: @@ -345,7 +346,7 @@ class AccountController extends Controller $currencyDecimalPlaces = $this->primaryCurrency->decimal_places; } - $result[$key] = [ + $result[$key] = [ 'total' => '0', 'category_id' => (int)$journal['category_id'], 'currency_name' => $currencyName, @@ -356,7 +357,7 @@ class AccountController extends Controller } $result[$key]['total'] = bcadd((string)$journal[$field], $result[$key]['total']); } - $names = $this->getCategoryNames(array_keys($result)); + $names = $this->getCategoryNames(array_keys($result)); foreach ($result as $row) { $categoryId = $row['category_id']; @@ -365,7 +366,7 @@ class AccountController extends Controller $chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']]; } - $data = $this->generator->multiCurrencyPieChart($chartData); + $data = $this->generator->multiCurrencyPieChart($chartData); $cache->store($data); return response()->json($data); @@ -378,9 +379,9 @@ class AccountController extends Controller * */ public function frontpage(AccountRepositoryInterface $repository): JsonResponse { - $start = clone session('start', today(config('app.timezone'))->startOfMonth()); - $end = clone session('end', today(config('app.timezone'))->endOfMonth()); - $defaultSet = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray(); + $start = clone session('start', today(config('app.timezone'))->startOfMonth()); + $end = clone session('end', today(config('app.timezone'))->endOfMonth()); + $defaultSet = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray(); // Log::debug('Default set is ', $defaultSet); $frontpage = Preferences::get('frontpageAccounts', $defaultSet); $frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data; @@ -389,7 +390,7 @@ class AccountController extends Controller Preferences::set('frontpageAccounts', $defaultSet); Log::debug('frontpage set is empty!'); } - $accounts = $repository->getAccountsById($frontpageArray); + $accounts = $repository->getAccountsById($frontpageArray); // move to end of day for $end. $end->endOfDay(); @@ -413,14 +414,14 @@ class AccountController extends Controller */ public function incomeCategory(Account $account, Carbon $start, Carbon $end): JsonResponse { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($start); $cache->addProperty($this->convertToPrimary); $cache->addProperty($end); $cache->addProperty('chart.account.income-category'); if ($cache->has()) { - return response()->json($cache->get()); + return response()->json($cache->get()); } // grab all journals: @@ -434,7 +435,7 @@ class AccountController extends Controller /** @var array $journal */ foreach ($journals as $journal) { - $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); + $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); if (!array_key_exists($key, $result)) { // currency info: @@ -452,26 +453,26 @@ class AccountController extends Controller $currencyDecimalPlaces = $this->primaryCurrency->decimal_places; } - $result[$key] = [ - 'total' => '0', - 'category_id' => $journal['category_id'], - 'currency_name' => $currencyName, - 'currency_code' => $currencyCode, - 'currency_symbol' => $currencySymbol, + $result[$key] = [ + 'total' => '0', + 'category_id' => $journal['category_id'], + 'currency_name' => $currencyName, + 'currency_code' => $currencyCode, + 'currency_symbol' => $currencySymbol, 'currency_decimal_places' => $currencyDecimalPlaces, ]; } $result[$key]['total'] = bcadd((string)$journal[$field], $result[$key]['total']); } - $names = $this->getCategoryNames(array_keys($result)); + $names = $this->getCategoryNames(array_keys($result)); foreach ($result as $row) { $categoryId = $row['category_id']; $name = $names[$categoryId] ?? '(unknown)'; $label = (string)trans('firefly.name_in_currency', ['name' => $name, 'currency' => $row['currency_name']]); $chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']]; } - $data = $this->generator->multiCurrencyPieChart($chartData); + $data = $this->generator->multiCurrencyPieChart($chartData); $cache->store($data); return response()->json($data); @@ -488,7 +489,7 @@ class AccountController extends Controller $end->endOfDay(); // TODO not sure if these date ranges will work as expected. Log::debug(sprintf('Now in period("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty('chart.account.period'); $cache->addProperty($start); $cache->addProperty($end); @@ -499,10 +500,10 @@ class AccountController extends Controller } // collect and filter balances for the entire period. - $step = $this->calculateStep($start, $end); + $step = $this->calculateStep($start, $end); Log::debug(sprintf('Step is %s', $step)); - $locale = Steam::getLocale(); - $return = []; + $locale = Steam::getLocale(); + $return = []; // fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041 // have to make sure this chart is always based on the balance at the END of the period. @@ -512,8 +513,8 @@ class AccountController extends Controller $format = (string)trans('config.month_and_day_js', [], $locale); $accountCurrency = $this->accountRepository->getAccountCurrency($account); - $range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToPrimary); - $range = Steam::filterAccountBalances($range, $account, $this->convertToPrimary, $accountCurrency); + $range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToPrimary); + $range = Steam::filterAccountBalances($range, $account, $this->convertToPrimary, $accountCurrency); // temp, get end balance. Log::debug(sprintf('period: Call finalAccountBalance with date/time "%s"', $end->toIso8601String())); @@ -524,14 +525,14 @@ class AccountController extends Controller $accountCurrency ??= $this->primaryCurrency; // do this AFTER getting the balances. Log::debug('Start chart loop.'); - $newRange = []; - $expectedIndex = 0; + $newRange = []; + $expectedIndex = 0; Log::debug('Balances exist at:'); foreach ($range as $key => $value) { $newRange[] = ['date' => $key, 'info' => $value]; Log::debug(sprintf('%d - %s (%s)', count($newRange) - 1, $key, json_encode($value))); } - $carbon = Carbon::createFromFormat('Y-m-d', $newRange[0]['date'])->endOfDay(); + $carbon = Carbon::createFromFormat('Y-m-d', $newRange[0]['date'])->endOfDay(); Log::debug(sprintf('Start of loop, $carbon is %s', $carbon->format('Y-m-d H:i:s'))); while ($end->gte($current)) { $momentBalance = $previous; @@ -552,21 +553,21 @@ class AccountController extends Controller } } Log::debug(sprintf('momentBalance is now %s', json_encode($momentBalance))); - $return = $this->updateChartKeys($return, $momentBalance); - $previous = $momentBalance; + $return = $this->updateChartKeys($return, $momentBalance); + $previous = $momentBalance; // process each balance thing. foreach ($momentBalance as $key => $amount) { $label = $current->isoFormat($format); $return[$key]['entries'][$label] = $amount; } - $current = app('navigation')->addPeriod($current, $step, 0); + $current = app('navigation')->addPeriod($current, $step, 0); // here too, to fix #8041, the data is corrected to the end of the period. - $current = app('navigation')->endOfX($current, $step, null); + $current = app('navigation')->endOfX($current, $step, null); } Log::debug('End of chart loop.'); // second loop (yes) to create nice array with info! Yay! - $chartData = []; + $chartData = []; foreach ($return as $key => $info) { if ('balance' !== $key && 'pc_balance' !== $key) { @@ -589,7 +590,7 @@ class AccountController extends Controller $chartData[] = $info; } - $data = $this->generator->multiSet($chartData); + $data = $this->generator->multiSet($chartData); $cache->store($data); return response()->json($data); @@ -626,15 +627,15 @@ class AccountController extends Controller public function revenueAccounts(): JsonResponse { /** @var Carbon $start */ - $start = clone session('start', today(config('app.timezone'))->startOfMonth()); + $start = clone session('start', today(config('app.timezone'))->startOfMonth()); /** @var Carbon $end */ - $end = clone session('end', today(config('app.timezone'))->endOfMonth()); + $end = clone session('end', today(config('app.timezone'))->endOfMonth()); $start->startOfDay(); $end->endOfDay(); - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($this->convertToPrimary); @@ -644,13 +645,13 @@ class AccountController extends Controller } // prep some vars: - $currencies = []; - $chartData = []; - $tempData = []; + $currencies = []; + $chartData = []; + $tempData = []; // grab all accounts and names - $accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::REVENUE->value]); - $accountNames = $this->extractNames($accounts); + $accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::REVENUE->value]); + $accountNames = $this->extractNames($accounts); // grab all balances Log::debug(sprintf('revAccounts: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); @@ -685,14 +686,14 @@ class AccountController extends Controller continue; } // Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance)); - $searchCode = $this->convertToPrimary ? $this->primaryCurrency->code : $key; - $searchCode = 'balance' === $searchCode || 'pc_balance' === $searchCode ? $this->primaryCurrency->code : $searchCode; + $searchCode = $this->convertToPrimary ? $this->primaryCurrency->code : $key; + $searchCode = 'balance' === $searchCode || 'pc_balance' === $searchCode ? $this->primaryCurrency->code : $searchCode; // Log::debug(sprintf('Search code is %s', $searchCode)); // see if there is an accompanying start amount. // grab the difference and find the currency. $startBalance = ($startBalances[$account->id][$key] ?? '0'); // Log::debug(sprintf('Start balance is %s', $startBalance)); - $diff = bcsub($endBalance, $startBalance); + $diff = bcsub($endBalance, $startBalance); $currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode); if (0 !== bccomp($diff, '0')) { // store the values in a temporary array. @@ -712,26 +713,26 @@ class AccountController extends Controller foreach ($currencies as $currency) { $newCurrencies[$currency->id] = $currency; } - $currencies = $newCurrencies; + $currencies = $newCurrencies; // sort temp array by amount. - $amounts = array_column($tempData, 'diff_float'); + $amounts = array_column($tempData, 'diff_float'); array_multisort($amounts, SORT_ASC, $tempData); // loop all found currencies and build the data array for the chart. /** - * @var int $currencyId + * @var int $currencyId * @var TransactionCurrency $currency */ foreach ($currencies as $currencyId => $currency) { $dataSet = [ - 'label' => (string)trans('firefly.earned'), - 'type' => 'bar', - 'currency_symbol' => $currency->symbol, - 'currency_code' => $currency->code, - 'entries' => $this->expandNames($tempData), - ]; + 'label' => (string)trans('firefly.earned'), + 'type' => 'bar', + 'currency_symbol' => $currency->symbol, + 'currency_code' => $currency->code, + 'entries' => $this->expandNames($tempData), + ]; $chartData[$currencyId] = $dataSet; } @@ -742,7 +743,7 @@ class AccountController extends Controller $chartData[$currencyId]['entries'][$name] = bcmul($entry['difference'], '-1'); } - $data = $this->generator->multiSet($chartData); + $data = $this->generator->multiSet($chartData); $cache->store($data); return response()->json($data); diff --git a/app/Http/Controllers/Transaction/ShowController.php b/app/Http/Controllers/Transaction/ShowController.php index bb6c60af1a..3df555292c 100644 --- a/app/Http/Controllers/Transaction/ShowController.php +++ b/app/Http/Controllers/Transaction/ShowController.php @@ -85,52 +85,52 @@ class ShowController extends Controller public function show(TransactionGroup $transactionGroup) { /** @var User $admin */ - $admin = auth()->user(); + $admin = auth()->user(); // use new group collector: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setUser($admin)->setTransactionGroup($transactionGroup)->withAPIInformation(); - $selectedGroup = $collector->getGroups()->first(); + $selectedGroup = $collector->getGroups()->first(); if (null === $selectedGroup) { throw new NotFoundHttpException(); } // enrich - $enrichment = new TransactionGroupEnrichment(); + $enrichment = new TransactionGroupEnrichment(); $enrichment->setUser($admin); - $selectedGroup = $enrichment->enrichSingle($selectedGroup); + $selectedGroup = $enrichment->enrichSingle($selectedGroup); /** @var null|TransactionJournal $first */ - $first = $transactionGroup->transactionJournals()->first(['transaction_journals.*']); - $splits = $transactionGroup->transactionJournals()->count(); - $splits = count($selectedGroup['transactions']); - $keys = array_keys($selectedGroup['transactions']); - $first = $selectedGroup['transactions'][array_shift($keys)]; + $first = $transactionGroup->transactionJournals()->first(['transaction_journals.*']); + $splits = $transactionGroup->transactionJournals()->count(); + $splits = count($selectedGroup['transactions']); + $keys = array_keys($selectedGroup['transactions']); + $first = $selectedGroup['transactions'][array_shift($keys)]; unset($keys); if (null === $first) { throw new FireflyException('This transaction is broken :(.'); } - $type = (string)trans(sprintf('firefly.%s', $first['transaction_type_type'])); - $title = 1 === $splits ? $first['description'] : $selectedGroup['title']; - $subTitle = sprintf('%s: "%s"', $type, $title); + $type = (string)trans(sprintf('firefly.%s', $first['transaction_type_type'])); + $title = 1 === $splits ? $first['description'] : $selectedGroup['title']; + $subTitle = sprintf('%s: "%s"', $type, $title); // enrich - $enrichment = new TransactionGroupEnrichment(); + $enrichment = new TransactionGroupEnrichment(); $enrichment->setUser($admin); - $selectedGroup = $enrichment->enrichSingle($selectedGroup); + $selectedGroup = $enrichment->enrichSingle($selectedGroup); /** @var TransactionGroupTransformer $transformer */ - $transformer = app(TransactionGroupTransformer::class); + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters(new ParameterBag()); - $groupArray = $transformer->transformObject($transactionGroup); + $groupArray = $transformer->transformObject($transactionGroup); // do some calculations: - $amounts = $this->getAmounts($selectedGroup); - $accounts = $this->getAccounts($selectedGroup); + $amounts = $this->getAmounts($selectedGroup); + $accounts = $this->getAccounts($selectedGroup); foreach (array_keys($selectedGroup['transactions']) as $index) { $selectedGroup['transactions'][$index]['tags'] = $this->repository->getTagObjects((int)$selectedGroup['transactions'][$index]['transaction_journal_id']); @@ -142,9 +142,9 @@ class ShowController extends Controller $logEntries[$journal['transaction_journal_id']] = $this->aleRepository->getForId(TransactionJournal::class, $journal['transaction_journal_id']); } - $events = $this->repository->getPiggyEvents($transactionGroup); - $attachments = $this->repository->getAttachments($transactionGroup); - $links = $this->repository->getLinks($transactionGroup); + $events = $this->repository->getPiggyEvents($transactionGroup); + $attachments = $this->repository->getAttachments($transactionGroup); + $links = $this->repository->getLinks($transactionGroup); return view( 'transactions.show', @@ -173,7 +173,7 @@ class ShowController extends Controller foreach ($group['transactions'] as $transaction) { // add normal amount: $symbol = $transaction['currency_symbol']; - $amounts[$symbol] ??= [ + $amounts[$symbol] ??= [ 'amount' => '0', 'symbol' => $symbol, 'decimal_places' => $transaction['currency_decimal_places'], @@ -184,7 +184,7 @@ class ShowController extends Controller if (null !== $transaction['foreign_amount'] && '' !== $transaction['foreign_amount'] && 0 !== bccomp('0', (string)$transaction['foreign_amount'])) { // same for foreign currency: $foreignSymbol = $transaction['foreign_currency_symbol']; - $amounts[$foreignSymbol] ??= [ + $amounts[$foreignSymbol] ??= [ 'amount' => '0', 'symbol' => $foreignSymbol, 'decimal_places' => $transaction['foreign_currency_decimal_places'], @@ -195,7 +195,7 @@ class ShowController extends Controller if (null !== $transaction['pc_amount'] && $transaction['currency_id'] !== $this->primaryCurrency->id) { // same for foreign currency: $primarySymbol = $this->primaryCurrency->symbol; - $amounts[$primarySymbol] ??= [ + $amounts[$primarySymbol] ??= [ 'amount' => '0', 'symbol' => $this->primaryCurrency->symbol, 'decimal_places' => $this->primaryCurrency->decimal_places, @@ -210,7 +210,7 @@ class ShowController extends Controller private function getAccounts(array $group): array { - $accounts = [ + $accounts = [ 'source' => [], 'destination' => [], ]; diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 13b32d0c02..70c4035df2 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -567,8 +567,8 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac 'transaction_journals.transaction_currency_id', 'transactions.amount', 'transactions.native_amount', - 'transactions.foreign_amount' - ]) + 'transactions.foreign_amount', + ]) ->toArray() ; diff --git a/app/Repositories/AuditLogEntry/ALERepositoryInterface.php b/app/Repositories/AuditLogEntry/ALERepositoryInterface.php index 389450e97a..3860b52b3b 100644 --- a/app/Repositories/AuditLogEntry/ALERepositoryInterface.php +++ b/app/Repositories/AuditLogEntry/ALERepositoryInterface.php @@ -45,8 +45,8 @@ use Illuminate\Support\Collection; interface ALERepositoryInterface { public function getForObject(Model $model): Collection; - public function getForId(string $model, int $modelId): Collection; + public function getForId(string $model, int $modelId): Collection; public function store(array $data): AuditLogEntry; } diff --git a/app/Support/Amount.php b/app/Support/Amount.php index ed834e8f54..c0c40ac390 100644 --- a/app/Support/Amount.php +++ b/app/Support/Amount.php @@ -58,15 +58,15 @@ class Amount */ public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string { - $locale = app('steam')->getLocale(); - $rounded = app('steam')->bcround($amount, $decimalPlaces); + $locale = app('steam')->getLocale(); + $rounded = app('steam')->bcround($amount, $decimalPlaces); $coloured ??= true; - $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY); + $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY); $fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, $symbol); $fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces); $fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces); - $result = (string)$fmt->format((float)$rounded); // intentional float + $result = (string)$fmt->format((float)$rounded); // intentional float if (true === $coloured) { if (1 === bccomp((string)$rounded, '0')) { @@ -122,15 +122,18 @@ class Amount if (null === $pref) { $res = true === Preferences::get('convert_to_primary', false)->data && true === config('cer.enabled'); $instance->setPreference('convert_to_primary_no_user', $res); + return $res; } + return $pref; } - $key = sprintf('convert_to_primary_%d', $user->id); - $pref = $instance->getPreference($key); - if(null === $pref) { + $key = sprintf('convert_to_primary_%d', $user->id); + $pref = $instance->getPreference($key); + if (null === $pref) { $res = true === Preferences::getForUser($user, 'convert_to_primary', false)->data && true === config('cer.enabled'); $instance->setPreference($key, $res); + return $res; } @@ -152,7 +155,7 @@ class Amount public function getPrimaryCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty('getPrimaryCurrencyByGroup'); $cache->addProperty($userGroup->id); if ($cache->has()) { @@ -182,16 +185,16 @@ class Amount */ public function getAmountFromJournalObject(TransactionJournal $journal): string { - $convertToPrimary = $this->convertToPrimary(); - $currency = $this->getPrimaryCurrency(); - $field = $convertToPrimary && $currency->id !== $journal->transaction_currency_id ? 'pc_amount' : 'amount'; + $convertToPrimary = $this->convertToPrimary(); + $currency = $this->getPrimaryCurrency(); + $field = $convertToPrimary && $currency->id !== $journal->transaction_currency_id ? 'pc_amount' : 'amount'; /** @var null|Transaction $sourceTransaction */ $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); if (null === $sourceTransaction) { return '0'; } - $amount = $sourceTransaction->{$field} ?? '0'; + $amount = $sourceTransaction->{$field} ?? '0'; if ((int)$sourceTransaction->foreign_currency_id === $currency->id) { // use foreign amount instead! $amount = (string)$sourceTransaction->foreign_amount; // hard coded to be foreign amount. @@ -239,20 +242,20 @@ class Amount private function getLocaleInfo(): array { // get config from preference, not from translation: - $locale = app('steam')->getLocale(); - $array = app('steam')->getLocaleArray($locale); + $locale = app('steam')->getLocale(); + $array = app('steam')->getLocaleArray($locale); setlocale(LC_MONETARY, $array); - $info = localeconv(); + $info = localeconv(); // correct variables - $info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes'); - $info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes'); + $info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes'); + $info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes'); - $info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space'); - $info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space'); + $info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space'); + $info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space'); - $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY); + $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY); $info['mon_decimal_point'] = $fmt->getSymbol(NumberFormatter::MONETARY_SEPARATOR_SYMBOL); $info['mon_thousands_sep'] = $fmt->getSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL); @@ -284,11 +287,11 @@ class Amount // there are five possible positions for the "+" or "-" sign (if it is even used) // pos_a and pos_e could be the ( and ) symbol. - $posA = ''; // before everything - $posB = ''; // before currency symbol - $posC = ''; // after currency symbol - $posD = ''; // before amount - $posE = ''; // after everything + $posA = ''; // before everything + $posB = ''; // before currency symbol + $posC = ''; // after currency symbol + $posD = ''; // before amount + $posE = ''; // after everything // format would be (currency before amount) // AB%sC_D%vE @@ -330,9 +333,9 @@ class Amount } if ($csPrecedes) { - return $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE; + return $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE; } - return $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE; + return $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE; } } diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php index 246e7ecc9a..47a85c5c83 100644 --- a/app/Support/Http/Controllers/ChartGeneration.php +++ b/app/Support/Http/Controllers/ChartGeneration.php @@ -56,7 +56,7 @@ trait ChartGeneration $cache->addProperty($accounts); $cache->addProperty($convertToPrimary); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } Log::debug('Regenerate chart.account.account-balance-chart from scratch.'); $locale = app('steam')->getLocale(); diff --git a/app/Support/Http/Controllers/PeriodOverview.php b/app/Support/Http/Controllers/PeriodOverview.php index 8f11f6b74e..d83f6501a4 100644 --- a/app/Support/Http/Controllers/PeriodOverview.php +++ b/app/Support/Http/Controllers/PeriodOverview.php @@ -83,10 +83,10 @@ trait PeriodOverview Timer::start('account-period-total'); $this->accountRepository = app(AccountRepositoryInterface::class); $range = Navigation::getViewRange(true); - [$start, $end] = $end < $start ? [$end, $start] : [$start, $end]; + [$start, $end] = $end < $start ? [$end, $start] : [$start, $end]; // properties for cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('account-show-period-entries'); @@ -96,35 +96,35 @@ trait PeriodOverview } /** @var array $dates */ - $dates = Navigation::blockPeriods($start, $end, $range); - $entries = []; - $spent = []; - $earned = []; - $transferredAway = []; - $transferredIn = []; + $dates = Navigation::blockPeriods($start, $end, $range); + $entries = []; + $spent = []; + $earned = []; + $transferredAway = []; + $transferredIn = []; // run a custom query because doing this with the collector is MEGA slow. - $transactions = $this->accountRepository->periodCollection($account, $start, $end); + $transactions = $this->accountRepository->periodCollection($account, $start, $end); // loop dates Log::debug(sprintf('Count of loops: %d', count($dates))); - $loops = 0; + $loops = 0; // stop after 10 loops for memory reasons. foreach ($dates as $currentDate) { - $title = Navigation::periodShow($currentDate['start'], $currentDate['period']); - [$transactions, $spent] = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $transactions, $currentDate['start'], $currentDate['end']); - [$transactions, $earned] = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $transactions, $currentDate['start'], $currentDate['end']); + $title = Navigation::periodShow($currentDate['start'], $currentDate['period']); + [$transactions, $spent] = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $transactions, $currentDate['start'], $currentDate['end']); + [$transactions, $earned] = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $transactions, $currentDate['start'], $currentDate['end']); [$transactions, $transferredAway] = $this->filterTransfers('away', $transactions, $currentDate['start'], $currentDate['end']); - [$transactions, $transferredIn] = $this->filterTransfers('in', $transactions, $currentDate['start'], $currentDate['end']); + [$transactions, $transferredIn] = $this->filterTransfers('in', $transactions, $currentDate['start'], $currentDate['end']); $entries[] - = [ - 'title' => $title, - 'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), - 'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn), - 'spent' => $this->groupByCurrency($spent), - 'earned' => $this->groupByCurrency($earned), - 'transferred_away' => $this->groupByCurrency($transferredAway), - 'transferred_in' => $this->groupByCurrency($transferredIn), - ]; + = [ + 'title' => $title, + 'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), + 'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn), + 'spent' => $this->groupByCurrency($spent), + 'earned' => $this->groupByCurrency($earned), + 'transferred_away' => $this->groupByCurrency($transferredAway), + 'transferred_in' => $this->groupByCurrency($transferredIn), + ]; ++$loops; } $cache->store($entries); @@ -136,11 +136,11 @@ trait PeriodOverview private function filterTransactionsByType(TransactionTypeEnum $type, array $transactions, Carbon $start, Carbon $end): array { - $result = []; + $result = []; $filtered = []; /** - * @var int $index + * @var int $index * @var array $item */ foreach ($transactions as $index => $item) { @@ -150,7 +150,7 @@ trait PeriodOverview $result[] = $item; unset($transactions[$index]); } - if(!$fits) { + if (!$fits) { $filtered[] = $item; } } @@ -160,11 +160,11 @@ trait PeriodOverview private function filterTransfers(string $direction, array $transactions, Carbon $start, Carbon $end): array { - $result = []; + $result = []; $filtered = []; /** - * @var int $index + * @var int $index * @var array $item */ foreach ($transactions as $index => $item) { @@ -172,10 +172,12 @@ trait PeriodOverview if ($date >= $start && $date <= $end) { if ('away' === $direction && -1 === bccomp((string)$item['amount'], '0')) { $result[] = $item; + continue; } if ('in' === $direction && 1 === bccomp((string)$item['amount'], '0')) { $result[] = $item; + continue; } $filtered[] = $item; @@ -191,13 +193,13 @@ trait PeriodOverview /** @var array $journal */ foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $currencyCode = $journal['currency_code']; - $currencyName = $journal['currency_name']; - $currencySymbol = $journal['currency_symbol']; - $currencyDecimalPlaces = $journal['currency_decimal_places']; - $foreignCurrencyId = $journal['foreign_currency_id']; - $amount = $journal['amount'] ?? '0'; + $currencyId = (int)$journal['currency_id']; + $currencyCode = $journal['currency_code']; + $currencyName = $journal['currency_name']; + $currencySymbol = $journal['currency_symbol']; + $currencyDecimalPlaces = $journal['currency_decimal_places']; + $foreignCurrencyId = $journal['foreign_currency_id']; + $amount = $journal['amount'] ?? '0'; if ($this->convertToPrimary && $currencyId !== $this->primaryCurrency->id && $foreignCurrencyId !== $this->primaryCurrency->id) { $amount = $journal['pc_amount'] ?? '0'; @@ -240,11 +242,11 @@ trait PeriodOverview */ protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array { - $range = Navigation::getViewRange(true); + $range = Navigation::getViewRange(true); [$start, $end] = $end < $start ? [$end, $start] : [$start, $end]; // properties for entries with their amounts. - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($range); @@ -256,32 +258,32 @@ trait PeriodOverview } /** @var array $dates */ - $dates = Navigation::blockPeriods($start, $end, $range); - $entries = []; + $dates = Navigation::blockPeriods($start, $end, $range); + $entries = []; // collect all expenses in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setCategory($category); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::DEPOSIT->value]); - $earnedSet = $collector->getExtractedJournals(); + $earnedSet = $collector->getExtractedJournals(); // collect all income in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setCategory($category); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); - $spentSet = $collector->getExtractedJournals(); + $spentSet = $collector->getExtractedJournals(); // collect all transfers in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setCategory($category); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::TRANSFER->value]); - $transferSet = $collector->getExtractedJournals(); + $transferSet = $collector->getExtractedJournals(); foreach ($dates as $currentDate) { $spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']); $earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']); @@ -289,17 +291,17 @@ trait PeriodOverview $title = Navigation::periodShow($currentDate['end'], $currentDate['period']); $entries[] = [ - 'transactions' => 0, - 'title' => $title, - 'route' => route( - 'categories.show', - [$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')] - ), - 'total_transactions' => count($spent) + count($earned) + count($transferred), - 'spent' => $this->groupByCurrency($spent), - 'earned' => $this->groupByCurrency($earned), - 'transferred' => $this->groupByCurrency($transferred), - ]; + 'transactions' => 0, + 'title' => $title, + 'route' => route( + 'categories.show', + [$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')] + ), + 'total_transactions' => count($spent) + count($earned) + count($transferred), + 'spent' => $this->groupByCurrency($spent), + 'earned' => $this->groupByCurrency($earned), + 'transferred' => $this->groupByCurrency($transferred), + ]; } $cache->store($entries); @@ -332,11 +334,11 @@ trait PeriodOverview */ protected function getNoBudgetPeriodOverview(Carbon $start, Carbon $end): array { - $range = Navigation::getViewRange(true); + $range = Navigation::getViewRange(true); [$start, $end] = $end < $start ? [$end, $start] : [$start, $end]; - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($this->convertToPrimary); @@ -347,28 +349,28 @@ trait PeriodOverview } /** @var array $dates */ - $dates = Navigation::blockPeriods($start, $end, $range); - $entries = []; + $dates = Navigation::blockPeriods($start, $end, $range); + $entries = []; // get all expenses without a budget. /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); - $journals = $collector->getExtractedJournals(); + $journals = $collector->getExtractedJournals(); foreach ($dates as $currentDate) { $set = $this->filterJournalsByDate($journals, $currentDate['start'], $currentDate['end']); $title = Navigation::periodShow($currentDate['end'], $currentDate['period']); $entries[] = [ - 'title' => $title, - 'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), - 'total_transactions' => count($set), - 'spent' => $this->groupByCurrency($set), - 'earned' => [], - 'transferred_away' => [], - 'transferred_in' => [], - ]; + 'title' => $title, + 'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), + 'total_transactions' => count($set), + 'spent' => $this->groupByCurrency($set), + 'earned' => [], + 'transferred_away' => [], + 'transferred_in' => [], + ]; } $cache->store($entries); @@ -385,38 +387,38 @@ trait PeriodOverview protected function getNoCategoryPeriodOverview(Carbon $theDate): array { app('log')->debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d'))); - $range = Navigation::getViewRange(true); - $first = $this->journalRepos->firstNull(); - $start = null === $first ? new Carbon() : $first->date; - $end = clone $theDate; - $end = Navigation::endOfPeriod($end, $range); + $range = Navigation::getViewRange(true); + $first = $this->journalRepos->firstNull(); + $start = null === $first ? new Carbon() : $first->date; + $end = clone $theDate; + $end = Navigation::endOfPeriod($end, $range); app('log')->debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d'))); app('log')->debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d'))); // properties for cache - $dates = Navigation::blockPeriods($start, $end, $range); - $entries = []; + $dates = Navigation::blockPeriods($start, $end, $range); + $entries = []; // collect all expenses in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->withoutCategory(); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::DEPOSIT->value]); - $earnedSet = $collector->getExtractedJournals(); + $earnedSet = $collector->getExtractedJournals(); // collect all income in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->withoutCategory(); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); - $spentSet = $collector->getExtractedJournals(); + $spentSet = $collector->getExtractedJournals(); // collect all transfers in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->withoutCategory(); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::TRANSFER->value]); @@ -430,13 +432,13 @@ trait PeriodOverview $title = Navigation::periodShow($currentDate['end'], $currentDate['period']); $entries[] = [ - 'title' => $title, - 'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), - 'total_transactions' => count($spent) + count($earned) + count($transferred), - 'spent' => $this->groupByCurrency($spent), - 'earned' => $this->groupByCurrency($earned), - 'transferred' => $this->groupByCurrency($transferred), - ]; + 'title' => $title, + 'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), + 'total_transactions' => count($spent) + count($earned) + count($transferred), + 'spent' => $this->groupByCurrency($spent), + 'earned' => $this->groupByCurrency($earned), + 'transferred' => $this->groupByCurrency($transferred), + ]; } app('log')->debug('End of loops'); @@ -450,11 +452,11 @@ trait PeriodOverview */ protected function getTagPeriodOverview(Tag $tag, Carbon $start, Carbon $end): array // period overview for tags. { - $range = Navigation::getViewRange(true); + $range = Navigation::getViewRange(true); [$start, $end] = $end < $start ? [$end, $start] : [$start, $end]; // properties for cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('tag-period-entries'); @@ -464,37 +466,37 @@ trait PeriodOverview } /** @var array $dates */ - $dates = Navigation::blockPeriods($start, $end, $range); - $entries = []; + $dates = Navigation::blockPeriods($start, $end, $range); + $entries = []; // collect all expenses in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTag($tag); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::DEPOSIT->value]); - $earnedSet = $collector->getExtractedJournals(); + $earnedSet = $collector->getExtractedJournals(); // collect all income in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTag($tag); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); - $spentSet = $collector->getExtractedJournals(); + $spentSet = $collector->getExtractedJournals(); // collect all transfers in this period: /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTag($tag); $collector->setRange($start, $end); $collector->setTypes([TransactionTypeEnum::TRANSFER->value]); - $transferSet = $collector->getExtractedJournals(); + $transferSet = $collector->getExtractedJournals(); // filer all of them: - $earnedSet = $this->filterJournalsByTag($earnedSet, $tag); - $spentSet = $this->filterJournalsByTag($spentSet, $tag); - $transferSet = $this->filterJournalsByTag($transferSet, $tag); + $earnedSet = $this->filterJournalsByTag($earnedSet, $tag); + $spentSet = $this->filterJournalsByTag($spentSet, $tag); + $transferSet = $this->filterJournalsByTag($transferSet, $tag); foreach ($dates as $currentDate) { $spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']); @@ -503,17 +505,17 @@ trait PeriodOverview $title = Navigation::periodShow($currentDate['end'], $currentDate['period']); $entries[] = [ - 'transactions' => 0, - 'title' => $title, - 'route' => route( - 'tags.show', - [$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')] - ), - 'total_transactions' => count($spent) + count($earned) + count($transferred), - 'spent' => $this->groupByCurrency($spent), - 'earned' => $this->groupByCurrency($earned), - 'transferred' => $this->groupByCurrency($transferred), - ]; + 'transactions' => 0, + 'title' => $title, + 'route' => route( + 'tags.show', + [$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')] + ), + 'total_transactions' => count($spent) + count($earned) + count($transferred), + 'spent' => $this->groupByCurrency($spent), + 'earned' => $this->groupByCurrency($earned), + 'transferred' => $this->groupByCurrency($transferred), + ]; } return $entries; @@ -523,7 +525,7 @@ trait PeriodOverview { $return = []; foreach ($set as $entry) { - $found = false; + $found = false; /** @var array $localTag */ foreach ($entry['tags'] as $localTag) { @@ -545,12 +547,12 @@ trait PeriodOverview */ protected function getTransactionPeriodOverview(string $transactionType, Carbon $start, Carbon $end): array { - $range = Navigation::getViewRange(true); - $types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType)); + $range = Navigation::getViewRange(true); + $types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType)); [$start, $end] = $end < $start ? [$end, $start] : [$start, $end]; // properties for cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('transactions-period-entries'); @@ -560,16 +562,16 @@ trait PeriodOverview } /** @var array $dates */ - $dates = Navigation::blockPeriods($start, $end, $range); - $entries = []; - $spent = []; - $earned = []; - $transferred = []; + $dates = Navigation::blockPeriods($start, $end, $range); + $entries = []; + $spent = []; + $earned = []; + $transferred = []; // collect all journals in this period (regardless of type) - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes($types)->setRange($start, $end); - $genericSet = $collector->getExtractedJournals(); - $loops = 0; + $genericSet = $collector->getExtractedJournals(); + $loops = 0; foreach ($dates as $currentDate) { $title = Navigation::periodShow($currentDate['end'], $currentDate['period']); @@ -587,14 +589,14 @@ trait PeriodOverview } } $entries[] - = [ - 'title' => $title, - 'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), - 'total_transactions' => count($spent) + count($earned) + count($transferred), - 'spent' => $this->groupByCurrency($spent), - 'earned' => $this->groupByCurrency($earned), - 'transferred' => $this->groupByCurrency($transferred), - ]; + = [ + 'title' => $title, + 'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]), + 'total_transactions' => count($spent) + count($earned) + count($transferred), + 'spent' => $this->groupByCurrency($spent), + 'earned' => $this->groupByCurrency($earned), + 'transferred' => $this->groupByCurrency($transferred), + ]; ++$loops; } diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php index 7332c69d20..41dbe8f9dd 100644 --- a/app/Support/Preferences.php +++ b/app/Support/Preferences.php @@ -284,9 +284,9 @@ class Preferences */ public function lastActivity(): string { - $instance = PreferencesSingleton::getInstance(); - $pref = $instance->getPreference('last_activity'); - if(null !== $pref) { + $instance = PreferencesSingleton::getInstance(); + $pref = $instance->getPreference('last_activity'); + if (null !== $pref) { // Log::debug(sprintf('Found last activity in singleton: %s', $pref)); return $pref; } @@ -299,8 +299,9 @@ class Preferences if (is_array($lastActivity)) { $lastActivity = implode(',', $lastActivity); } - $setting = hash('sha256', (string) $lastActivity); + $setting = hash('sha256', (string) $lastActivity); $instance->setPreference('last_activity', $setting); + return $setting; } diff --git a/app/Support/Singleton/PreferencesSingleton.php b/app/Support/Singleton/PreferencesSingleton.php index 21f81d1492..e955a0f5ec 100644 --- a/app/Support/Singleton/PreferencesSingleton.php +++ b/app/Support/Singleton/PreferencesSingleton.php @@ -1,28 +1,31 @@ preferences = []; } @@ -35,5 +38,4 @@ class PreferencesSingleton { return $this->preferences[$key] ?? null; } - } diff --git a/composer.lock b/composer.lock index d268d4e3ad..38e3231d2c 100644 --- a/composer.lock +++ b/composer.lock @@ -939,16 +939,16 @@ }, { "name": "filp/whoops", - "version": "2.18.3", + "version": "2.18.4", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "59a123a3d459c5a23055802237cb317f609867e5" + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", - "reference": "59a123a3d459c5a23055802237cb317f609867e5", + "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", "shasum": "" }, "require": { @@ -998,7 +998,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.3" + "source": "https://github.com/filp/whoops/tree/2.18.4" }, "funding": [ { @@ -1006,7 +1006,7 @@ "type": "github" } ], - "time": "2025-06-16T00:02:10+00:00" + "time": "2025-08-08T12:00:00+00:00" }, { "name": "firebase/php-jwt", @@ -1879,16 +1879,16 @@ }, { "name": "laravel/framework", - "version": "v12.22.0", + "version": "v12.22.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "6ab00c913ef6ec6fad0bd506f7452c0bb9e792c3" + "reference": "d33ee45184126f32f593d4b809a846ed88a1dc43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/6ab00c913ef6ec6fad0bd506f7452c0bb9e792c3", - "reference": "6ab00c913ef6ec6fad0bd506f7452c0bb9e792c3", + "url": "https://api.github.com/repos/laravel/framework/zipball/d33ee45184126f32f593d4b809a846ed88a1dc43", + "reference": "d33ee45184126f32f593d4b809a846ed88a1dc43", "shasum": "" }, "require": { @@ -2090,7 +2090,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-08-07T13:49:53+00:00" + "time": "2025-08-08T13:58:03+00:00" }, { "name": "laravel/passport", diff --git a/config/firefly.php b/config/firefly.php index 4517d36def..359cb64864 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -79,7 +79,7 @@ return [ // see cer.php for exchange rates feature flag. ], 'version' => 'develop/2025-08-08', - 'build_time' => 1754630161, + 'build_time' => 1754679717, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 26, diff --git a/package-lock.json b/package-lock.json index 21340e45aa..fbe613d13e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3148,9 +3148,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.0.tgz", - "integrity": "sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==", + "version": "24.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz", + "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4486,9 +4486,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001731", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", - "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", + "version": "1.0.30001733", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001733.tgz", + "integrity": "sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q==", "dev": true, "funding": [ { diff --git a/routes/api.php b/routes/api.php index c2074ecdc8..fc8ed57ab2 100644 --- a/routes/api.php +++ b/routes/api.php @@ -24,10 +24,6 @@ declare(strict_types=1); use Illuminate\Support\Facades\Route; - - - - /* * ____ ____ __ .______ ______ __ __ .___________. _______ _______. * \ \ / / /_ | | _ \ / __ \ | | | | | || ____| / |