From 738829792a27323636c10e960eb62d3be9129f87 Mon Sep 17 00:00:00 2001 From: JC5 Date: Tue, 30 Jun 2026 14:51:31 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20release=20?= =?UTF-8?q?'develop'=20on=202026-06-30?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Insight/Income/TagController.php | 5 +- .../Insight/Transfer/TagController.php | 5 +- .../Commands/Correction/CorrectsAmounts.php | 201 +++++++++--------- app/Http/Controllers/Bill/IndexController.php | 5 +- .../Budget/BudgetLimitController.php | 8 +- .../Controllers/Budget/IndexController.php | 5 +- .../Controllers/Chart/BudgetController.php | 8 +- .../Controllers/System/InstallController.php | 44 ++-- app/Http/Middleware/Installer.php | 4 - app/Jobs/CreateAutoBudgetLimits.php | 16 +- app/Support/Http/Controllers/AugumentData.php | 9 +- .../Enrichments/RecurringEnrichment.php | 6 +- .../Models/AccountBalanceCalculator.php | 9 +- app/Support/System/IsOldVersion.php | 89 ++++---- composer.lock | 26 +-- config/firefly.php | 4 +- package-lock.json | 38 ++-- 17 files changed, 219 insertions(+), 263 deletions(-) diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php index 94be2ae461..df99eef909 100644 --- a/app/Api/V1/Controllers/Insight/Income/TagController.php +++ b/app/Api/V1/Controllers/Insight/Income/TagController.php @@ -158,10 +158,7 @@ final class TagController extends Controller 'currency_id' => (string) $foreignCurrencyId, 'currency_code' => $journal['foreign_currency_code'], ]; - $response[$foreignKey]['difference'] = bcadd( - (string) $response[$foreignKey]['difference'], - Steam::positive($journal['foreign_amount']) - ); + $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount'])); $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; } } diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php index b7b85fd376..f92a7aa9f0 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php @@ -155,10 +155,7 @@ final class TagController extends Controller 'currency_id' => (string) $foreignCurrencyId, 'currency_code' => $journal['foreign_currency_code'], ]; - $response[$foreignKey]['difference'] = bcadd( - (string) $response[$foreignKey]['difference'], - Steam::positive($journal['foreign_amount']) - ); + $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount'])); $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float } } diff --git a/app/Console/Commands/Correction/CorrectsAmounts.php b/app/Console/Commands/Correction/CorrectsAmounts.php index 16842dfafe..c67a1cfcea 100644 --- a/app/Console/Commands/Correction/CorrectsAmounts.php +++ b/app/Console/Commands/Correction/CorrectsAmounts.php @@ -85,6 +85,106 @@ class CorrectsAmounts extends Command return 0; } + private function correctDeposits(): void + { + Log::debug('Will now correct deposits.'); + + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + $type = TransactionType::query()->where('type', TransactionTypeEnum::DEPOSIT->value)->first(); + $journals = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->whereNotNull('transactions.foreign_amount') + ->where('transaction_journals.transaction_type_id', $type->id) + ->distinct() + ->get(['transaction_journals.*']) + ; + + /** @var TransactionJournal $journal */ + foreach ($journals as $journal) { + $repository->setUser($journal->user); + $primary = Amount::getPrimaryCurrencyByUserGroup($journal->userGroup); + + $valid = $this->validateJournal($journal); + if (false === $valid) { + // Log::debug(sprintf('Journal #%d does not need to be fixed or is invalid (see previous messages)', $journal->id)); + + continue; + } + Log::debug(sprintf('Journal #%d is ready to be corrected (if necessary).', $journal->id)); + $source = $journal->transactions()->where('amount', '<', '0')->first(); + $destination = $journal->transactions()->where('amount', '>', '0')->first(); + $sourceAccount = $source->account; + $destAccount = $destination->account; + $sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $primary; + $destCurrency = $repository->getAccountCurrency($destAccount) ?? $primary; + Log::debug(sprintf('Currency of source account #%d "%s" is %s', $sourceAccount->id, $sourceAccount->name, $sourceCurrency->code)); + Log::debug(sprintf('Currency of destination account #%d "%s" is %s', $destAccount->id, $destAccount->name, $destCurrency->code)); + if ($sourceCurrency->id === $destCurrency->id) { + Log::debug('Both accounts have the same currency. Removing foreign currency info.'); + $source->foreign_currency_id = null; + $source->foreign_amount = null; + $source->save(); + $destination->foreign_currency_id = null; + $destination->foreign_amount = null; + // also make sure that both transactions use the same amounts and currencies, since the currency is the same anyway. + $destination->amount = bcmul($source->amount, '-1'); + $destination->save(); + + continue; + } + + // validate source transaction + if ($destCurrency->id !== $source->foreign_currency_id) { + Log::debug(sprintf( + '[a] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".', + $journal->id, + $source->id, + $source->foreignCurrency->code, + $destCurrency->code + )); + $source->foreign_currency_id = $destCurrency->id; + $source->save(); + } + if ($sourceCurrency->id !== $source->transaction_currency_id) { + Log::debug(sprintf( + '[b] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".', + $journal->id, + $source->id, + $source->transactionCurrency->code, + $sourceCurrency->code + )); + $source->transaction_currency_id = $sourceCurrency->id; + $source->save(); + } + + // validate destination: + if ($sourceCurrency->id !== $destination->foreign_currency_id) { + Log::debug(sprintf( + '[c] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".', + $journal->id, + $destination->id, + $destination->foreignCurrency->code, + $sourceCurrency->code + )); + $destination->foreign_currency_id = $sourceCurrency->id; + $destination->save(); + } + + if ($destCurrency->id !== $destination->transaction_currency_id) { + Log::debug(sprintf( + '[d] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".', + $journal->id, + $destination->id, + $destination->transactionCurrency->code, + $destCurrency->code + )); + $destination->transaction_currency_id = $destCurrency->id; + $destination->save(); + } + Log::debug(sprintf('Done with journal #%d.', $journal->id)); + } + } + private function correctTransfers(): void { Log::debug('Will now correct transfers.'); @@ -184,107 +284,6 @@ class CorrectsAmounts extends Command } } - private function correctDeposits(): void - { - Log::debug('Will now correct deposits.'); - - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - $type = TransactionType::query()->where('type', TransactionTypeEnum::DEPOSIT->value)->first(); - $journals = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->whereNotNull('transactions.foreign_amount') - ->where('transaction_journals.transaction_type_id', $type->id) - ->distinct() - ->get(['transaction_journals.*']) - ; - - /** @var TransactionJournal $journal */ - foreach ($journals as $journal) { - $repository->setUser($journal->user); - $primary = Amount::getPrimaryCurrencyByUserGroup($journal->userGroup); - - $valid = $this->validateJournal($journal); - if (false === $valid) { - // Log::debug(sprintf('Journal #%d does not need to be fixed or is invalid (see previous messages)', $journal->id)); - - continue; - } - Log::debug(sprintf('Journal #%d is ready to be corrected (if necessary).', $journal->id)); - $source = $journal->transactions()->where('amount', '<', '0')->first(); - $destination = $journal->transactions()->where('amount', '>', '0')->first(); - $sourceAccount = $source->account; - $destAccount = $destination->account; - $sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $primary; - $destCurrency = $repository->getAccountCurrency($destAccount) ?? $primary; - Log::debug(sprintf('Currency of source account #%d "%s" is %s', $sourceAccount->id, $sourceAccount->name, $sourceCurrency->code)); - Log::debug(sprintf('Currency of destination account #%d "%s" is %s', $destAccount->id, $destAccount->name, $destCurrency->code)); - if ($sourceCurrency->id === $destCurrency->id) { - Log::debug('Both accounts have the same currency. Removing foreign currency info.'); - $source->foreign_currency_id = null; - $source->foreign_amount = null; - $source->save(); - $destination->foreign_currency_id = null; - $destination->foreign_amount = null; - // also make sure that both transactions use the same amounts and currencies, since the currency is the same anyway. - $destination->amount = bcmul($source->amount ,'-1'); - $destination->save(); - - - continue; - } - - // validate source transaction - if ($destCurrency->id !== $source->foreign_currency_id) { - Log::debug(sprintf( - '[a] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".', - $journal->id, - $source->id, - $source->foreignCurrency->code, - $destCurrency->code - )); - $source->foreign_currency_id = $destCurrency->id; - $source->save(); - } - if ($sourceCurrency->id !== $source->transaction_currency_id) { - Log::debug(sprintf( - '[b] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".', - $journal->id, - $source->id, - $source->transactionCurrency->code, - $sourceCurrency->code - )); - $source->transaction_currency_id = $sourceCurrency->id; - $source->save(); - } - - // validate destination: - if ($sourceCurrency->id !== $destination->foreign_currency_id) { - Log::debug(sprintf( - '[c] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".', - $journal->id, - $destination->id, - $destination->foreignCurrency->code, - $sourceCurrency->code - )); - $destination->foreign_currency_id = $sourceCurrency->id; - $destination->save(); - } - - if ($destCurrency->id !== $destination->transaction_currency_id) { - Log::debug(sprintf( - '[d] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".', - $journal->id, - $destination->id, - $destination->transactionCurrency->code, - $destCurrency->code - )); - $destination->transaction_currency_id = $destCurrency->id; - $destination->save(); - } - Log::debug(sprintf('Done with journal #%d.', $journal->id)); - } - } - private function deleteJournal(TransactionJournal $journal): void { $this->service->destroy($journal); diff --git a/app/Http/Controllers/Bill/IndexController.php b/app/Http/Controllers/Bill/IndexController.php index 07947c2c85..2009369ae0 100644 --- a/app/Http/Controllers/Bill/IndexController.php +++ b/app/Http/Controllers/Bill/IndexController.php @@ -255,10 +255,7 @@ final class IndexController extends Controller if (count($bill['paid_dates']) < count($bill['pay_dates'])) { $count = count($bill['pay_dates']) - count($bill['paid_dates']); if ($count > 0) { - $avg = bcdiv( - bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), - '2' - ); + $avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2'); $avg = bcmul($avg, (string) $count); $sums[$groupOrder][$currencyId]['total_left_to_pay'] = bcadd($sums[$groupOrder][$currencyId]['total_left_to_pay'], $avg); Log::debug( diff --git a/app/Http/Controllers/Budget/BudgetLimitController.php b/app/Http/Controllers/Budget/BudgetLimitController.php index b263d702a2..9632996690 100644 --- a/app/Http/Controllers/Budget/BudgetLimitController.php +++ b/app/Http/Controllers/Budget/BudgetLimitController.php @@ -198,13 +198,7 @@ final class BudgetLimitController extends Controller if ($request->expectsJson()) { $array = $limit->toArray(); // add some extra metadata: - $spentArr = $this->opsRepository->sumExpenses( - $limit->start_date, - $limit->end_date, - null, - new Collection()->push($budget), - $currency - ); + $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection()->push($budget), $currency); $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0'; $array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount'])); $array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']); diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index 750a88e633..674f77fbee 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -284,10 +284,7 @@ final class IndexController extends Controller if (array_key_exists($currency->id, $spentArr) && array_key_exists('sum', $spentArr[$currency->id])) { $array['spent'][$currency->id]['spent'] = $spentArr[$currency->id]['sum']; - $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub( - $spentInLimits[$currency->id], - $spentArr[$currency->id]['sum'] - )); + $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub($spentInLimits[$currency->id], $spentArr[$currency->id]['sum'])); $array['spent'][$currency->id]['currency_id'] = $currency->id; $array['spent'][$currency->id]['currency_symbol'] = $currency->symbol; $array['spent'][$currency->id]['currency_decimal_places'] = $currency->decimal_places; diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index f4b32fe5c5..ad724137dc 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -539,13 +539,7 @@ final class BudgetController extends Controller } // get spent amount in this period for this currency. - $sum = $this->opsRepository->sumExpenses( - $currentStart, - $currentEnd, - $accounts, - new Collection()->push($budget), - $currency - ); + $sum = $this->opsRepository->sumExpenses($currentStart, $currentEnd, $accounts, new Collection()->push($budget), $currency); $amount = Steam::positive($sum[$currency->id]['sum'] ?? '0'); $chartData[0]['entries'][$title] = Steam::bcround($amount, $currency->decimal_places); diff --git a/app/Http/Controllers/System/InstallController.php b/app/Http/Controllers/System/InstallController.php index 807a1f3a62..d80e452291 100644 --- a/app/Http/Controllers/System/InstallController.php +++ b/app/Http/Controllers/System/InstallController.php @@ -41,6 +41,7 @@ use Illuminate\Support\Facades\Log; use Illuminate\View\View; use Laravel\Passport\Passport; use phpseclib3\Crypt\RSA; + use function Safe\file_put_contents; /** @@ -55,36 +56,36 @@ final class InstallController extends Controller public const string FORBIDDEN_ERROR = 'Internal PHP function "proc_close" is disabled for your installation. Auto-migration is not possible.'; public const string OTHER_ERROR = 'An unknown error prevented Firefly III from executing the upgrade commands. Sorry.'; - private string $lastError = ''; + private string $lastError = ''; // empty on purpose. - private array $upgradeCommands - = [ - // there are 5 initial commands - // Check 4 places: InstallController, Docker image, UpgradeDatabase, composer.json - 'firefly-iii:create-database' => [], - 'migrate' => ['--seed' => true, '--force' => true], - 'generate-keys' => [], // an exception :( - 'firefly-iii:upgrade-database' => [], - 'firefly-iii:set-latest-version' => ['--james-is-cool' => true], - 'firefly-iii:verify-security-alerts' => [], - ]; + private array $upgradeCommands = [ + // there are 5 initial commands + // Check 4 places: InstallController, Docker image, UpgradeDatabase, composer.json + 'firefly-iii:create-database' => [], + 'migrate' => ['--seed' => true, '--force' => true], + 'generate-keys' => [], // an exception :( + 'firefly-iii:upgrade-database' => [], + 'firefly-iii:set-latest-version' => ['--james-is-cool' => true], + 'firefly-iii:verify-security-alerts' => [], + ]; /** * Show index. * * @return Factory|View */ - public function index(): Factory | \Illuminate\Contracts\View\View + public function index(): Factory|\Illuminate\Contracts\View\View { if ($this->hasNoTables() || $this->isOldVersionInstalled()) { app('view')->share('FF_VERSION', config('firefly.version')); // index will set FF3 version. - AppConfiguration::set('ff3_version', (string)config('firefly.version')); - AppConfiguration::set('ff3_build_time', (int)config('firefly.build_time')); + AppConfiguration::set('ff3_version', (string) config('firefly.version')); + AppConfiguration::set('ff3_build_time', (int) config('firefly.build_time')); return view('install.index'); } + throw new AuthorizationException('No access to this page.'); } @@ -94,7 +95,7 @@ final class InstallController extends Controller public function keys(): void { if (!$this->hasNoTables() && !$this->isOldVersionInstalled()) { - $key = RSA::createKey(4096); + $key = RSA::createKey(4096); [$publicKey, $privateKey] = [Passport::keyPath('oauth-public.key'), Passport::keyPath('oauth-private.key')]; @@ -102,7 +103,7 @@ final class InstallController extends Controller return; } - file_put_contents($publicKey, (string)$key->getPublicKey()); + file_put_contents($publicKey, (string) $key->getPublicKey()); file_put_contents($privateKey, $key->toString('PKCS1')); } } @@ -110,14 +111,14 @@ final class InstallController extends Controller public function runCommand(Request $request): JsonResponse { if (!$this->hasNoTables() && !$this->isOldVersionInstalled()) { - $requestIndex = (int)$request->input('index'); + $requestIndex = (int) $request->input('index'); $response = ['hasNextCommand' => false, 'done' => true, 'previous' => null, 'error' => false, 'errorMessage' => null]; Log::debug(sprintf('Will now run commands. Request index is %d', $requestIndex)); - $indexes = array_keys($this->upgradeCommands); + $indexes = array_keys($this->upgradeCommands); if (array_key_exists($requestIndex, $indexes)) { - $command = $indexes[$requestIndex]; - $parameters = $this->upgradeCommands[$command]; + $command = $indexes[$requestIndex]; + $parameters = $this->upgradeCommands[$command]; Log::debug(sprintf('Will now execute command "%s" with parameters', $command), $parameters); try { @@ -143,6 +144,7 @@ final class InstallController extends Controller return response()->json($response); } + return response()->json([], 403); } diff --git a/app/Http/Middleware/Installer.php b/app/Http/Middleware/Installer.php index eccb605758..f188484be1 100644 --- a/app/Http/Middleware/Installer.php +++ b/app/Http/Middleware/Installer.php @@ -28,9 +28,7 @@ use Closure; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Support\System\IsOldVersion; use FireflyIII\Support\System\OAuthKeys; -use Illuminate\Database\QueryException; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; /** @@ -85,6 +83,4 @@ class Installer { return false !== stripos($message, 'Access denied'); } - - } diff --git a/app/Jobs/CreateAutoBudgetLimits.php b/app/Jobs/CreateAutoBudgetLimits.php index d61661dd50..93cf5e9364 100644 --- a/app/Jobs/CreateAutoBudgetLimits.php +++ b/app/Jobs/CreateAutoBudgetLimits.php @@ -122,13 +122,7 @@ class CreateAutoBudgetLimits implements ShouldQueue // if has one, calculate expenses and use that as a base. $repository = app(OperationsRepositoryInterface::class); $repository->setUser($autoBudget->budget->user); - $spent = $repository->sumExpenses( - $previousStart, - $previousEnd, - null, - new Collection()->push($autoBudget->budget), - $autoBudget->transactionCurrency - ); + $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency); $currencyId = $autoBudget->transaction_currency_id; $spentAmount = $spent[$currencyId]['sum'] ?? '0'; Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); @@ -218,13 +212,7 @@ class CreateAutoBudgetLimits implements ShouldQueue // if has one, calculate expenses and use that as a base. $repository = app(OperationsRepositoryInterface::class); $repository->setUser($autoBudget->budget->user); - $spent = $repository->sumExpenses( - $previousStart, - $previousEnd, - null, - new Collection()->push($autoBudget->budget), - $autoBudget->transactionCurrency - ); + $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency); $currencyId = $autoBudget->transaction_currency_id; $spentAmount = $spent[$currencyId]['sum'] ?? '0'; Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); diff --git a/app/Support/Http/Controllers/AugumentData.php b/app/Support/Http/Controllers/AugumentData.php index a507156873..a3a940b1ba 100644 --- a/app/Support/Http/Controllers/AugumentData.php +++ b/app/Support/Http/Controllers/AugumentData.php @@ -222,14 +222,7 @@ trait AugumentData $currentEnd->addMonth(); } // primary currency amount. - $expenses = $opsRepository->sumExpenses( - $currentStart, - $currentEnd, - null, - $budgetCollection, - $entry->transactionCurrency, - $this->convertToPrimary - ); + $expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, $this->convertToPrimary); $spent = $expenses[$currency->id]['sum'] ?? '0'; $entry->pc_spent = $spent; diff --git a/app/Support/JsonApi/Enrichments/RecurringEnrichment.php b/app/Support/JsonApi/Enrichments/RecurringEnrichment.php index 2428353cb0..d0c09bf027 100644 --- a/app/Support/JsonApi/Enrichments/RecurringEnrichment.php +++ b/app/Support/JsonApi/Enrichments/RecurringEnrichment.php @@ -354,11 +354,7 @@ class RecurringEnrichment implements EnrichmentInterface /** @var RecurrenceRepetition $repetition */ foreach ($set as $repetition) { - $recurrence = $this->collection->filter( - static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id - ) - ->first() - ; + $recurrence = $this->collection->filter(static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id)->first(); $fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date); $recurrenceId = (int) $repetition->recurrence_id; $repId = (int) $repetition->id; diff --git a/app/Support/Models/AccountBalanceCalculator.php b/app/Support/Models/AccountBalanceCalculator.php index e3d13d0e35..9aafad0e99 100644 --- a/app/Support/Models/AccountBalanceCalculator.php +++ b/app/Support/Models/AccountBalanceCalculator.php @@ -139,7 +139,14 @@ class AccountBalanceCalculator /** @var Transaction $entry */ foreach ($set as $entry) { - Log::debug(sprintf('[%s] Processing transaction #%d on acount #%d with currency #%d and amount %s',$entry->date, $entry->id, $entry->account_id, $entry->transaction_currency_id, Steam::bcround($entry->amount, 2))); + Log::debug(sprintf( + '[%s] Processing transaction #%d on acount #%d with currency #%d and amount %s', + $entry->date, + $entry->id, + $entry->account_id, + $entry->transaction_currency_id, + Steam::bcround($entry->amount, 2) + )); // start with empty array: $entry->account_id = (int) $entry->account_id; $entry->transaction_currency_id = (int) $entry->transaction_currency_id; diff --git a/app/Support/System/IsOldVersion.php b/app/Support/System/IsOldVersion.php index 4e913c59f0..388e5473a8 100644 --- a/app/Support/System/IsOldVersion.php +++ b/app/Support/System/IsOldVersion.php @@ -33,51 +33,6 @@ use Illuminate\Support\Facades\Log; trait IsOldVersion { - - /** - * Check if the tables are created and accounted for. - * - * @throws FireflyException - */ - private function hasNoTables(): bool - { - // Log::debug('Now in routine hasNoTables()'); - - try { - DB::table('users')->count(); - } catch (QueryException $e) { - $message = $e->getMessage(); - Log::error(sprintf('Error message trying to access users-table: %s', $message)); - if ($this->isAccessDenied($message)) { - throw new FireflyException( - 'It seems your database configuration is not correct. Please verify the username and password in your .env file.', - 0, - $e - ); - } - if ($this->noTablesExist($message)) { - // redirect to UpdateController - Log::warning('There are no Firefly III tables present. Redirect to migrate routine.'); - - return true; - } - - throw new FireflyException(sprintf('Could not access the database: %s', $message), 0, $e); - } - - // Log::debug('Everything seems OK with the tables.'); - - return false; - } - /** - * Is no tables exist error. - */ - protected function noTablesExist(string $message): bool - { - return false !== stripos($message, 'Base table or view not found'); - } - - /** * By default, version_compare() returns -1 if the first version is lower than the second, 0 if they are equal, and * 1 if the second is lower. @@ -133,4 +88,48 @@ trait IsOldVersion return false; } + + /** + * Is no tables exist error. + */ + protected function noTablesExist(string $message): bool + { + return false !== stripos($message, 'Base table or view not found'); + } + + /** + * Check if the tables are created and accounted for. + * + * @throws FireflyException + */ + private function hasNoTables(): bool + { + // Log::debug('Now in routine hasNoTables()'); + + try { + DB::table('users')->count(); + } catch (QueryException $e) { + $message = $e->getMessage(); + Log::error(sprintf('Error message trying to access users-table: %s', $message)); + if ($this->isAccessDenied($message)) { + throw new FireflyException( + 'It seems your database configuration is not correct. Please verify the username and password in your .env file.', + 0, + $e + ); + } + if ($this->noTablesExist($message)) { + // redirect to UpdateController + Log::warning('There are no Firefly III tables present. Redirect to migrate routine.'); + + return true; + } + + throw new FireflyException(sprintf('Could not access the database: %s', $message), 0, $e); + } + + // Log::debug('Everything seems OK with the tables.'); + + return false; + } } diff --git a/composer.lock b/composer.lock index 1e9bd71174..92d110fd99 100644 --- a/composer.lock +++ b/composer.lock @@ -1246,16 +1246,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.12.3", + "version": "7.13.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3" + "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9aa17bcdd777ee31df9fc83c337ca4ca2340def3", - "reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/55901a76dfd2006a0cc012b9e3c5b487f796478d", + "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d", "shasum": "" }, "require": { @@ -1274,7 +1274,7 @@ "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.5.1", + "guzzlehttp/test-server": "^0.6", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -1354,7 +1354,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.12.3" + "source": "https://github.com/guzzle/guzzle/tree/7.13.1" }, "funding": [ { @@ -1370,7 +1370,7 @@ "type": "tidelift" } ], - "time": "2026-06-23T15:29:02+00:00" + "time": "2026-06-29T20:14:18+00:00" }, { "name": "guzzlehttp/promises", @@ -12109,16 +12109,16 @@ }, { "name": "phpunit/phpunit", - "version": "13.2.1", + "version": "13.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba" + "reference": "492c067e618de7b3c76105082c90f9d2833401b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/60da0ff1e10a0f72ee18a24117ec3b613a346bba", - "reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/492c067e618de7b3c76105082c90f9d2833401b7", + "reference": "492c067e618de7b3c76105082c90f9d2833401b7", "shasum": "" }, "require": { @@ -12189,7 +12189,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/13.2.1" + "source": "https://github.com/sebastianbergmann/phpunit/tree/13.2.2" }, "funding": [ { @@ -12197,7 +12197,7 @@ "type": "other" } ], - "time": "2026-06-15T13:14:22+00:00" + "time": "2026-06-29T13:36:29+00:00" }, { "name": "rector/rector", diff --git a/config/firefly.php b/config/firefly.php index 7a998cde99..a0c92942a5 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => (bool)env_default_when_empty(env('USE_RUNNING_BALANCE'), true), // this is only the default value, is not used. // see cer.php for exchange rates feature flag. ], -'version' => 'develop/2026-06-29', -'build_time' => 1782709367, +'version' => 'develop/2026-06-30', +'build_time' => 1782823890, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index 414189411f..e4903feb1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4149,9 +4149,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001799", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", - "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "version": "1.0.30001800", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001800.tgz", + "integrity": "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==", "dev": true, "funding": [ { @@ -5344,9 +5344,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.380", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.380.tgz", - "integrity": "sha512-W6d5AbuEoRayO447cqrg6lKJIlscgRnnxOZl/08kfV71BQDoEBC7Wwis68z87LjyK6f4kWyTaubuDbhHKrZkbA==", + "version": "1.5.382", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.382.tgz", + "integrity": "sha512-8ETaWbV6SZOrno+G93Ffd9ENsMtetqdnqj4nlfxFW90Sm5GgnuV28Kf62hqQVD6VUgzm7qFQKsTsAPmeUiU3Ug==", "dev": true, "license": "ISC" }, @@ -5469,9 +5469,9 @@ } }, "node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.2.0.tgz", + "integrity": "sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==", "dev": true, "license": "MIT" }, @@ -5742,9 +5742,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", + "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", "dev": true, "funding": [ { @@ -6651,9 +6651,9 @@ } }, "node_modules/i18next": { - "version": "26.3.3", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.3.tgz", - "integrity": "sha512-aYVegyBdXSO93CMMihvr47jI7GHSOcIahMpJX+qzUXDzW4xDJf2uenIA+45vDU+YhiVdcfsql70AC9RVdMNrHg==", + "version": "26.3.4", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.4.tgz", + "integrity": "sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==", "funding": [ { "type": "individual", @@ -6826,9 +6826,9 @@ } }, "node_modules/immutable": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.8.tgz", - "integrity": "sha512-TM5YqrGeTsVIPPpILzeqZ8D2Zc2TvNgSDi88zPF2a4cyqQdWV/wVWBDRDbNzzrLeRWScrFcOX9lW2iX6GOtUDw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", + "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==", "dev": true, "license": "MIT" }, @@ -12254,7 +12254,7 @@ "laravel-vite-plugin": "^3", "patch-package": "^8", "sass": "^1", - "vite": "^8.1.0", + "vite": "=8.1.0", "vite-plugin-manifest-sri": "^0.2.0" } }