🤖 Auto commit for release 'develop' on 2026-06-30

This commit is contained in:
JC5
2026-06-30 14:51:31 +02:00
parent 727297ac80
commit 738829792a
17 changed files with 219 additions and 263 deletions
@@ -158,10 +158,7 @@ final class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
(string) $response[$foreignKey]['difference'],
Steam::positive($journal['foreign_amount'])
);
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
} }
} }
@@ -155,10 +155,7 @@ final class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
(string) $response[$foreignKey]['difference'],
Steam::positive($journal['foreign_amount'])
);
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
} }
} }
@@ -85,6 +85,106 @@ class CorrectsAmounts extends Command
return 0; 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 private function correctTransfers(): void
{ {
Log::debug('Will now correct transfers.'); 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 private function deleteJournal(TransactionJournal $journal): void
{ {
$this->service->destroy($journal); $this->service->destroy($journal);
@@ -255,10 +255,7 @@ final class IndexController extends Controller
if (count($bill['paid_dates']) < count($bill['pay_dates'])) { if (count($bill['paid_dates']) < count($bill['pay_dates'])) {
$count = count($bill['pay_dates']) - count($bill['paid_dates']); $count = count($bill['pay_dates']) - count($bill['paid_dates']);
if ($count > 0) { if ($count > 0) {
$avg = bcdiv( $avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2');
bcadd((string) $bill['amount_min'], (string) $bill['amount_max']),
'2'
);
$avg = bcmul($avg, (string) $count); $avg = bcmul($avg, (string) $count);
$sums[$groupOrder][$currencyId]['total_left_to_pay'] = bcadd($sums[$groupOrder][$currencyId]['total_left_to_pay'], $avg); $sums[$groupOrder][$currencyId]['total_left_to_pay'] = bcadd($sums[$groupOrder][$currencyId]['total_left_to_pay'], $avg);
Log::debug( Log::debug(
@@ -198,13 +198,7 @@ final class BudgetLimitController extends Controller
if ($request->expectsJson()) { if ($request->expectsJson()) {
$array = $limit->toArray(); $array = $limit->toArray();
// add some extra metadata: // add some extra metadata:
$spentArr = $this->opsRepository->sumExpenses( $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection()->push($budget), $currency);
$limit->start_date,
$limit->end_date,
null,
new Collection()->push($budget),
$currency
);
$array['spent'] = $spentArr[$currency->id]['sum'] ?? '0'; $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
$array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount'])); $array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
$array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']); $array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']);
@@ -284,10 +284,7 @@ final class IndexController extends Controller
if (array_key_exists($currency->id, $spentArr) && array_key_exists('sum', $spentArr[$currency->id])) { 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'] = $spentArr[$currency->id]['sum'];
$array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub( $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub($spentInLimits[$currency->id], $spentArr[$currency->id]['sum']));
$spentInLimits[$currency->id],
$spentArr[$currency->id]['sum']
));
$array['spent'][$currency->id]['currency_id'] = $currency->id; $array['spent'][$currency->id]['currency_id'] = $currency->id;
$array['spent'][$currency->id]['currency_symbol'] = $currency->symbol; $array['spent'][$currency->id]['currency_symbol'] = $currency->symbol;
$array['spent'][$currency->id]['currency_decimal_places'] = $currency->decimal_places; $array['spent'][$currency->id]['currency_decimal_places'] = $currency->decimal_places;
@@ -539,13 +539,7 @@ final class BudgetController extends Controller
} }
// get spent amount in this period for this currency. // get spent amount in this period for this currency.
$sum = $this->opsRepository->sumExpenses( $sum = $this->opsRepository->sumExpenses($currentStart, $currentEnd, $accounts, new Collection()->push($budget), $currency);
$currentStart,
$currentEnd,
$accounts,
new Collection()->push($budget),
$currency
);
$amount = Steam::positive($sum[$currency->id]['sum'] ?? '0'); $amount = Steam::positive($sum[$currency->id]['sum'] ?? '0');
$chartData[0]['entries'][$title] = Steam::bcround($amount, $currency->decimal_places); $chartData[0]['entries'][$title] = Steam::bcround($amount, $currency->decimal_places);
@@ -41,6 +41,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
use Laravel\Passport\Passport; use Laravel\Passport\Passport;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use function Safe\file_put_contents; 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 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.'; 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. // empty on purpose.
private array $upgradeCommands private array $upgradeCommands = [
= [ // there are 5 initial commands
// there are 5 initial commands // Check 4 places: InstallController, Docker image, UpgradeDatabase, composer.json
// Check 4 places: InstallController, Docker image, UpgradeDatabase, composer.json 'firefly-iii:create-database' => [],
'firefly-iii:create-database' => [], 'migrate' => ['--seed' => true, '--force' => true],
'migrate' => ['--seed' => true, '--force' => true], 'generate-keys' => [], // an exception :(
'generate-keys' => [], // an exception :( 'firefly-iii:upgrade-database' => [],
'firefly-iii:upgrade-database' => [], 'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
'firefly-iii:set-latest-version' => ['--james-is-cool' => true], 'firefly-iii:verify-security-alerts' => [],
'firefly-iii:verify-security-alerts' => [], ];
];
/** /**
* Show index. * Show index.
* *
* @return Factory|View * @return Factory|View
*/ */
public function index(): Factory | \Illuminate\Contracts\View\View public function index(): Factory|\Illuminate\Contracts\View\View
{ {
if ($this->hasNoTables() || $this->isOldVersionInstalled()) { if ($this->hasNoTables() || $this->isOldVersionInstalled()) {
app('view')->share('FF_VERSION', config('firefly.version')); app('view')->share('FF_VERSION', config('firefly.version'));
// index will set FF3 version. // index will set FF3 version.
AppConfiguration::set('ff3_version', (string)config('firefly.version')); AppConfiguration::set('ff3_version', (string) config('firefly.version'));
AppConfiguration::set('ff3_build_time', (int)config('firefly.build_time')); AppConfiguration::set('ff3_build_time', (int) config('firefly.build_time'));
return view('install.index'); return view('install.index');
} }
throw new AuthorizationException('No access to this page.'); throw new AuthorizationException('No access to this page.');
} }
@@ -94,7 +95,7 @@ final class InstallController extends Controller
public function keys(): void public function keys(): void
{ {
if (!$this->hasNoTables() && !$this->isOldVersionInstalled()) { 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')]; [$publicKey, $privateKey] = [Passport::keyPath('oauth-public.key'), Passport::keyPath('oauth-private.key')];
@@ -102,7 +103,7 @@ final class InstallController extends Controller
return; return;
} }
file_put_contents($publicKey, (string)$key->getPublicKey()); file_put_contents($publicKey, (string) $key->getPublicKey());
file_put_contents($privateKey, $key->toString('PKCS1')); file_put_contents($privateKey, $key->toString('PKCS1'));
} }
} }
@@ -110,14 +111,14 @@ final class InstallController extends Controller
public function runCommand(Request $request): JsonResponse public function runCommand(Request $request): JsonResponse
{ {
if (!$this->hasNoTables() && !$this->isOldVersionInstalled()) { 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]; $response = ['hasNextCommand' => false, 'done' => true, 'previous' => null, 'error' => false, 'errorMessage' => null];
Log::debug(sprintf('Will now run commands. Request index is %d', $requestIndex)); 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)) { if (array_key_exists($requestIndex, $indexes)) {
$command = $indexes[$requestIndex]; $command = $indexes[$requestIndex];
$parameters = $this->upgradeCommands[$command]; $parameters = $this->upgradeCommands[$command];
Log::debug(sprintf('Will now execute command "%s" with parameters', $command), $parameters); Log::debug(sprintf('Will now execute command "%s" with parameters', $command), $parameters);
try { try {
@@ -143,6 +144,7 @@ final class InstallController extends Controller
return response()->json($response); return response()->json($response);
} }
return response()->json([], 403); return response()->json([], 403);
} }
-4
View File
@@ -28,9 +28,7 @@ use Closure;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\System\IsOldVersion; use FireflyIII\Support\System\IsOldVersion;
use FireflyIII\Support\System\OAuthKeys; use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
/** /**
@@ -85,6 +83,4 @@ class Installer
{ {
return false !== stripos($message, 'Access denied'); return false !== stripos($message, 'Access denied');
} }
} }
+2 -14
View File
@@ -122,13 +122,7 @@ class CreateAutoBudgetLimits implements ShouldQueue
// if has one, calculate expenses and use that as a base. // if has one, calculate expenses and use that as a base.
$repository = app(OperationsRepositoryInterface::class); $repository = app(OperationsRepositoryInterface::class);
$repository->setUser($autoBudget->budget->user); $repository->setUser($autoBudget->budget->user);
$spent = $repository->sumExpenses( $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency);
$previousStart,
$previousEnd,
null,
new Collection()->push($autoBudget->budget),
$autoBudget->transactionCurrency
);
$currencyId = $autoBudget->transaction_currency_id; $currencyId = $autoBudget->transaction_currency_id;
$spentAmount = $spent[$currencyId]['sum'] ?? '0'; $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)); 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. // if has one, calculate expenses and use that as a base.
$repository = app(OperationsRepositoryInterface::class); $repository = app(OperationsRepositoryInterface::class);
$repository->setUser($autoBudget->budget->user); $repository->setUser($autoBudget->budget->user);
$spent = $repository->sumExpenses( $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency);
$previousStart,
$previousEnd,
null,
new Collection()->push($autoBudget->budget),
$autoBudget->transactionCurrency
);
$currencyId = $autoBudget->transaction_currency_id; $currencyId = $autoBudget->transaction_currency_id;
$spentAmount = $spent[$currencyId]['sum'] ?? '0'; $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)); Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
@@ -222,14 +222,7 @@ trait AugumentData
$currentEnd->addMonth(); $currentEnd->addMonth();
} }
// primary currency amount. // primary currency amount.
$expenses = $opsRepository->sumExpenses( $expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, $this->convertToPrimary);
$currentStart,
$currentEnd,
null,
$budgetCollection,
$entry->transactionCurrency,
$this->convertToPrimary
);
$spent = $expenses[$currency->id]['sum'] ?? '0'; $spent = $expenses[$currency->id]['sum'] ?? '0';
$entry->pc_spent = $spent; $entry->pc_spent = $spent;
@@ -354,11 +354,7 @@ class RecurringEnrichment implements EnrichmentInterface
/** @var RecurrenceRepetition $repetition */ /** @var RecurrenceRepetition $repetition */
foreach ($set as $repetition) { foreach ($set as $repetition) {
$recurrence = $this->collection->filter( $recurrence = $this->collection->filter(static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id)->first();
static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id
)
->first()
;
$fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date); $fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
$recurrenceId = (int) $repetition->recurrence_id; $recurrenceId = (int) $repetition->recurrence_id;
$repId = (int) $repetition->id; $repId = (int) $repetition->id;
@@ -139,7 +139,14 @@ class AccountBalanceCalculator
/** @var Transaction $entry */ /** @var Transaction $entry */
foreach ($set as $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: // start with empty array:
$entry->account_id = (int) $entry->account_id; $entry->account_id = (int) $entry->account_id;
$entry->transaction_currency_id = (int) $entry->transaction_currency_id; $entry->transaction_currency_id = (int) $entry->transaction_currency_id;
+44 -45
View File
@@ -33,51 +33,6 @@ use Illuminate\Support\Facades\Log;
trait IsOldVersion 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 * 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. * 1 if the second is lower.
@@ -133,4 +88,48 @@ trait IsOldVersion
return false; 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;
}
} }
Generated
+13 -13
View File
@@ -1246,16 +1246,16 @@
}, },
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "7.12.3", "version": "7.13.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/guzzle.git", "url": "https://github.com/guzzle/guzzle.git",
"reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3" "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/9aa17bcdd777ee31df9fc83c337ca4ca2340def3", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/55901a76dfd2006a0cc012b9e3c5b487f796478d",
"reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3", "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1274,7 +1274,7 @@
"bamarni/composer-bin-plugin": "^1.8.2", "bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*", "ext-curl": "*",
"guzzle/client-integration-tests": "3.0.2", "guzzle/client-integration-tests": "3.0.2",
"guzzlehttp/test-server": "^0.5.1", "guzzlehttp/test-server": "^0.6",
"php-http/message-factory": "^1.1", "php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.52 || ^9.6.34", "phpunit/phpunit": "^8.5.52 || ^9.6.34",
"psr/log": "^1.1 || ^2.0 || ^3.0" "psr/log": "^1.1 || ^2.0 || ^3.0"
@@ -1354,7 +1354,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/guzzle/issues", "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": [ "funding": [
{ {
@@ -1370,7 +1370,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-23T15:29:02+00:00" "time": "2026-06-29T20:14:18+00:00"
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
@@ -12109,16 +12109,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "13.2.1", "version": "13.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba" "reference": "492c067e618de7b3c76105082c90f9d2833401b7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/60da0ff1e10a0f72ee18a24117ec3b613a346bba", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/492c067e618de7b3c76105082c90f9d2833401b7",
"reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba", "reference": "492c067e618de7b3c76105082c90f9d2833401b7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12189,7 +12189,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "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": [ "funding": [
{ {
@@ -12197,7 +12197,7 @@
"type": "other" "type": "other"
} }
], ],
"time": "2026-06-15T13:14:22+00:00" "time": "2026-06-29T13:36:29+00:00"
}, },
{ {
"name": "rector/rector", "name": "rector/rector",
+2 -2
View File
@@ -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. '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. // see cer.php for exchange rates feature flag.
], ],
'version' => 'develop/2026-06-29', 'version' => 'develop/2026-06-30',
'build_time' => 1782709367, 'build_time' => 1782823890,
'api_version' => '2.1.0', // field is no longer used. 'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used. 'db_version' => 28, // field is no longer used.
+19 -19
View File
@@ -4149,9 +4149,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001799", "version": "1.0.30001800",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001800.tgz",
"integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", "integrity": "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -5344,9 +5344,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.380", "version": "1.5.382",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.380.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.382.tgz",
"integrity": "sha512-W6d5AbuEoRayO447cqrg6lKJIlscgRnnxOZl/08kfV71BQDoEBC7Wwis68z87LjyK6f4kWyTaubuDbhHKrZkbA==", "integrity": "sha512-8ETaWbV6SZOrno+G93Ffd9ENsMtetqdnqj4nlfxFW90Sm5GgnuV28Kf62hqQVD6VUgzm7qFQKsTsAPmeUiU3Ug==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@@ -5469,9 +5469,9 @@
} }
}, },
"node_modules/es-module-lexer": { "node_modules/es-module-lexer": {
"version": "2.1.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.2.0.tgz",
"integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", "integrity": "sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@@ -5742,9 +5742,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-uri": { "node_modules/fast-uri": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz",
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -6651,9 +6651,9 @@
} }
}, },
"node_modules/i18next": { "node_modules/i18next": {
"version": "26.3.3", "version": "26.3.4",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.3.tgz", "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.4.tgz",
"integrity": "sha512-aYVegyBdXSO93CMMihvr47jI7GHSOcIahMpJX+qzUXDzW4xDJf2uenIA+45vDU+YhiVdcfsql70AC9RVdMNrHg==", "integrity": "sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@@ -6826,9 +6826,9 @@
} }
}, },
"node_modules/immutable": { "node_modules/immutable": {
"version": "5.1.8", "version": "5.1.9",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.8.tgz", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
"integrity": "sha512-TM5YqrGeTsVIPPpILzeqZ8D2Zc2TvNgSDi88zPF2a4cyqQdWV/wVWBDRDbNzzrLeRWScrFcOX9lW2iX6GOtUDw==", "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@@ -12254,7 +12254,7 @@
"laravel-vite-plugin": "^3", "laravel-vite-plugin": "^3",
"patch-package": "^8", "patch-package": "^8",
"sass": "^1", "sass": "^1",
"vite": "^8.1.0", "vite": "=8.1.0",
"vite-plugin-manifest-sri": "^0.2.0" "vite-plugin-manifest-sri": "^0.2.0"
} }
} }