Compare commits

...

3 Commits

Author SHA1 Message Date
github-actions[bot]
3c904c9017 Merge pull request #11286 from firefly-iii/release-1764136451
🤖 Automatically merge the PR into the develop branch.
2025-11-26 06:54:20 +01:00
JC5
d8bdbf2842 🤖 Auto commit for release 'develop' on 2025-11-26 2025-11-26 06:54:11 +01:00
James Cole
d08966d141 Add new correction command. 2025-11-26 06:50:29 +01:00
11 changed files with 281 additions and 195 deletions

View File

@@ -74,6 +74,7 @@ class CorrectsDatabase extends Command
'correction:group-accounts', 'correction:group-accounts',
'correction:recalculates-liabilities', 'correction:recalculates-liabilities',
'correction:preferences', 'correction:preferences',
'correction:corrects-inverted-budget-limits',
// 'correction:transaction-types', // resource heavy, disabled. // 'correction:transaction-types', // resource heavy, disabled.
'correction:recalculate-pc-amounts', 'correction:recalculate-pc-amounts',
'correction:remove-links-to-deleted-objects', 'correction:remove-links-to-deleted-objects',

View File

@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
/*
* CorrectsInversedBudgetLimits.php
* Copyright (c) 2025 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class CorrectsInvertedBudgetLimits extends Command
{
use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'correction:corrects-inverted-budget-limits';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Reverse budget limits where the dates are inverted.';
/**
* Execute the console command.
*/
public function handle(): int
{
$set = BudgetLimit::where('start_date', '>', DB::raw('end_date'))->get();
if (0 === $set->count()) {
Log::debug('No inverted budget limits found.');
return Command::SUCCESS;
}
/** @var BudgetLimit $budgetLimit */
foreach ($set as $budgetLimit) {
$start = $budgetLimit->start_date->copy();
$end = $budgetLimit->end_date->copy();
$budgetLimit->start_date = $end;
$budgetLimit->end_date = $start;
$budgetLimit->saveQuietly();
}
if (1 === $set->count()) {
$this->friendlyInfo('Corrected one budget limit to have the right start/end dates.');
return Command::SUCCESS;
}
$this->friendlyInfo(sprintf('Corrected %d budget limits to have the right start/end dates.', count($set)));
return Command::SUCCESS;
}
}

View File

@@ -42,6 +42,7 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use function Safe\json_encode; use function Safe\json_encode;
use function Safe\mb_regex_encoding; use function Safe\mb_regex_encoding;
@@ -54,11 +55,11 @@ class ForcesDecimalSize extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).'; protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
protected $signature = 'firefly-iii:force-decimal-size {--force}'; protected $signature = 'firefly-iii:force-decimal-size {--force}';
private string $cast; private string $cast;
private array $classes private array $classes
= [ = [
'accounts' => Account::class, 'accounts' => Account::class,
'auto_budgets' => AutoBudget::class, 'auto_budgets' => AutoBudget::class,
'available_budgets' => AvailableBudget::class, 'available_budgets' => AvailableBudget::class,
@@ -74,7 +75,7 @@ class ForcesDecimalSize extends Command
private string $operator; private string $operator;
private string $regularExpression; private string $regularExpression;
private array $tables private array $tables
= [ = [
'accounts' => ['virtual_balance'], 'accounts' => ['virtual_balance'],
'auto_budgets' => ['amount'], 'auto_budgets' => ['amount'],
'available_budgets' => ['amount'], 'available_budgets' => ['amount'],
@@ -238,9 +239,10 @@ class ForcesDecimalSize extends Command
$regularExpression = $this->regularExpression; $regularExpression = $this->regularExpression;
/** @var Builder $query */ /** @var Builder $query */
$query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') $query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id') ->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id)); ->where('account_meta.data', json_encode((string)$currency->id))
;
$query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { $query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) { foreach ($fields as $field) {
$q->orWhere( $q->orWhere(
@@ -250,7 +252,7 @@ class ForcesDecimalSize extends Command
); );
} }
}); });
$result = $query->get(['accounts.*']); $result = $query->get(['accounts.*']);
if (0 === $result->count()) { if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All accounts in %s are OK', $currency->code)); $this->friendlyPositive(sprintf('All accounts in %s are OK', $currency->code));
@@ -261,13 +263,13 @@ class ForcesDecimalSize extends Command
foreach ($result as $account) { foreach ($result as $account) {
/** @var string $field */ /** @var string $field */
foreach ($fields as $field) { foreach ($fields as $field) {
$value = $account->{$field}; $value = $account->{$field};
if (null === $value) { if (null === $value) {
continue; continue;
} }
// fix $field by rounding it down correctly. // fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places; $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12); $correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct)); $this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
/** @var null|Account $updateAccount */ /** @var null|Account $updateAccount */
@@ -289,7 +291,7 @@ class ForcesDecimalSize extends Command
$regularExpression = $this->regularExpression; $regularExpression = $this->regularExpression;
/** @var Builder $query */ /** @var Builder $query */
$query = $class::where('transaction_currency_id', $currency->id)->where( $query = $class::where('transaction_currency_id', $currency->id)->where(
static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
/** @var string $field */ /** @var string $field */
foreach ($fields as $field) { foreach ($fields as $field) {
@@ -302,7 +304,7 @@ class ForcesDecimalSize extends Command
} }
); );
$result = $query->get(); $result = $query->get();
if (0 === $result->count()) { if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All %s in %s are OK', $table, $currency->code)); $this->friendlyPositive(sprintf('All %s in %s are OK', $table, $currency->code));
@@ -313,7 +315,7 @@ class ForcesDecimalSize extends Command
foreach ($result as $item) { foreach ($result as $item) {
/** @var string $field */ /** @var string $field */
foreach ($fields as $field) { foreach ($fields as $field) {
$value = $item->{$field}; $value = $item->{$field};
if (null === $value || '' === $value) { if (null === $value || '' === $value) {
continue; continue;
} }
@@ -323,7 +325,7 @@ class ForcesDecimalSize extends Command
$this->friendlyWarning(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct)); $this->friendlyWarning(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
/** @var null|Model $model */ /** @var null|Model $model */
$model = $class::find($item->id); $model = $class::find($item->id);
$model?->update([$field => $correct]); $model?->update([$field => $correct]);
} }
} }
@@ -339,22 +341,23 @@ class ForcesDecimalSize extends Command
$regularExpression = $this->regularExpression; $regularExpression = $this->regularExpression;
/** @var Builder $query */ /** @var Builder $query */
$query = PiggyBankEvent::leftJoin('piggy_banks', 'piggy_bank_events.piggy_bank_id', '=', 'piggy_banks.id') $query = PiggyBankEvent::leftJoin('piggy_banks', 'piggy_bank_events.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id') ->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id)) ->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression): void { ->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression): void {
foreach ($fields as $field) { foreach ($fields as $field) {
$q->orWhere( $q->orWhere(
DB::raw(sprintf('CAST(piggy_bank_events.%s AS %s)', $field, $cast)), DB::raw(sprintf('CAST(piggy_bank_events.%s AS %s)', $field, $cast)),
$operator, $operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places)) DB::raw(sprintf($regularExpression, $currency->decimal_places))
); );
} }
}); })
;
$result = $query->get(['piggy_bank_events.*']); $result = $query->get(['piggy_bank_events.*']);
if (0 === $result->count()) { if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All piggy bank events in %s are OK', $currency->code)); $this->friendlyPositive(sprintf('All piggy bank events in %s are OK', $currency->code));
@@ -365,7 +368,7 @@ class ForcesDecimalSize extends Command
foreach ($result as $item) { foreach ($result as $item) {
/** @var string $field */ /** @var string $field */
foreach ($fields as $field) { foreach ($fields as $field) {
$value = $item->{$field}; $value = $item->{$field};
if (null === $value) { if (null === $value) {
continue; continue;
} }
@@ -377,7 +380,7 @@ class ForcesDecimalSize extends Command
); );
/** @var null|PiggyBankEvent $event */ /** @var null|PiggyBankEvent $event */
$event = PiggyBankEvent::find($item->id); $event = PiggyBankEvent::find($item->id);
$event?->update([$field => $correct]); $event?->update([$field => $correct]);
} }
} }
@@ -394,22 +397,23 @@ class ForcesDecimalSize extends Command
// select all piggy bank repetitions with this currency and issue. // select all piggy bank repetitions with this currency and issue.
/** @var Builder $query */ /** @var Builder $query */
$query = PiggyBankRepetition::leftJoin('piggy_banks', 'piggy_bank_repetitions.piggy_bank_id', '=', 'piggy_banks.id') $query = PiggyBankRepetition::leftJoin('piggy_banks', 'piggy_bank_repetitions.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id') ->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id)) ->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) { foreach ($fields as $field) {
$q->orWhere( $q->orWhere(
DB::raw(sprintf('CAST(piggy_bank_repetitions.%s AS %s)', $field, $cast)), DB::raw(sprintf('CAST(piggy_bank_repetitions.%s AS %s)', $field, $cast)),
$operator, $operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places)) DB::raw(sprintf($regularExpression, $currency->decimal_places))
); );
} }
}); })
;
$result = $query->get(['piggy_bank_repetitions.*']); $result = $query->get(['piggy_bank_repetitions.*']);
if (0 === $result->count()) { if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All piggy bank repetitions in %s', $currency->code)); $this->friendlyPositive(sprintf('All piggy bank repetitions in %s', $currency->code));
@@ -420,13 +424,13 @@ class ForcesDecimalSize extends Command
foreach ($result as $item) { foreach ($result as $item) {
/** @var string $field */ /** @var string $field */
foreach ($fields as $field) { foreach ($fields as $field) {
$value = $item->{$field}; $value = $item->{$field};
if (null === $value) { if (null === $value) {
continue; continue;
} }
// fix $field by rounding it down correctly. // fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places; $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12); $correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning( $this->friendlyWarning(
sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct) sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
); );
@@ -448,21 +452,22 @@ class ForcesDecimalSize extends Command
$regularExpression = $this->regularExpression; $regularExpression = $this->regularExpression;
/** @var Builder $query */ /** @var Builder $query */
$query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') $query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id') ->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id)) ->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) { foreach ($fields as $field) {
$q->orWhere( $q->orWhere(
DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)), DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)),
$operator, $operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places)) DB::raw(sprintf($regularExpression, $currency->decimal_places))
); );
} }
}); })
;
$result = $query->get(['piggy_banks.*']); $result = $query->get(['piggy_banks.*']);
if (0 === $result->count()) { if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All piggy banks in %s are OK', $currency->code)); $this->friendlyPositive(sprintf('All piggy banks in %s are OK', $currency->code));
@@ -473,13 +478,13 @@ class ForcesDecimalSize extends Command
foreach ($result as $item) { foreach ($result as $item) {
/** @var string $field */ /** @var string $field */
foreach ($fields as $field) { foreach ($fields as $field) {
$value = $item->{$field}; $value = $item->{$field};
if (null === $value) { if (null === $value) {
continue; continue;
} }
// fix $field by rounding it down correctly. // fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places; $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12); $correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)); $this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
/** @var null|PiggyBank $piggyBank */ /** @var null|PiggyBank $piggyBank */
@@ -496,7 +501,7 @@ class ForcesDecimalSize extends Command
{ {
// select all transactions with this currency and issue. // select all transactions with this currency and issue.
/** @var Builder $query */ /** @var Builder $query */
$query = Transaction::where('transaction_currency_id', $currency->id)->where( $query = Transaction::where('transaction_currency_id', $currency->id)->where(
DB::raw(sprintf('CAST(amount as %s)', $this->cast)), DB::raw(sprintf('CAST(amount as %s)', $this->cast)),
$this->operator, $this->operator,
DB::raw(sprintf($this->regularExpression, $currency->decimal_places)) DB::raw(sprintf($this->regularExpression, $currency->decimal_places))
@@ -509,13 +514,13 @@ class ForcesDecimalSize extends Command
/** @var Transaction $item */ /** @var Transaction $item */
foreach ($result as $item) { foreach ($result as $item) {
$value = $item->amount; $value = $item->amount;
if ('' === $value) { if ('' === $value) {
continue; continue;
} }
// fix $field by rounding it down correctly. // fix $field by rounding it down correctly.
$pow = 10.0 ** $currency->decimal_places; $pow = 10.0 ** $currency->decimal_places;
$correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12); $correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct)); $this->friendlyWarning(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
/** @var null|Transaction $transaction */ /** @var null|Transaction $transaction */
@@ -525,7 +530,7 @@ class ForcesDecimalSize extends Command
// select all transactions with this FOREIGN currency and issue. // select all transactions with this FOREIGN currency and issue.
/** @var Builder $query */ /** @var Builder $query */
$query = Transaction::where('foreign_currency_id', $currency->id)->where( $query = Transaction::where('foreign_currency_id', $currency->id)->where(
DB::raw(sprintf('CAST(foreign_amount as %s)', $this->cast)), DB::raw(sprintf('CAST(foreign_amount as %s)', $this->cast)),
$this->operator, $this->operator,
DB::raw(sprintf($this->regularExpression, $currency->decimal_places)) DB::raw(sprintf($this->regularExpression, $currency->decimal_places))
@@ -540,13 +545,13 @@ class ForcesDecimalSize extends Command
/** @var Transaction $item */ /** @var Transaction $item */
foreach ($result as $item) { foreach ($result as $item) {
$value = $item->foreign_amount; $value = $item->foreign_amount;
if (null === $value) { if (null === $value) {
continue; continue;
} }
// fix $field by rounding it down correctly. // fix $field by rounding it down correctly.
$pow = 10.0 ** $currency->decimal_places; $pow = 10.0 ** $currency->decimal_places;
$correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12); $correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning( $this->friendlyWarning(
sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct) sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct)
); );

View File

@@ -167,7 +167,7 @@ class IndexController extends Controller
/** @var Carbon $end */ /** @var Carbon $end */
$end = clone session('end', today(config('app.timezone'))->endOfMonth()); $end = clone session('end', today(config('app.timezone'))->endOfMonth());
$now = now(); $now = now();
if ($now->gt($end) || $now->lt($start)) { if ($now->gt($end) || $now->lt($start)) {
$now = $end; $now = $end;
} }

View File

@@ -221,7 +221,7 @@ class ShowController extends Controller
// correct // correct
Log::debug(sprintf('showAll: Call accountsBalancesOptimized with date/time "%s"', $end->toIso8601String())); Log::debug(sprintf('showAll: Call accountsBalancesOptimized with date/time "%s"', $end->toIso8601String()));
$now = now(); $now = now();
if ($now->gt($end) || $now->lt($start)) { if ($now->gt($end) || $now->lt($start)) {
$now = $end; $now = $end;
} }

View File

@@ -121,8 +121,8 @@ class Navigation
if ($workEnd->gt($start)) { if ($workEnd->gt($start)) {
while ($workEnd->gt($start) && $loopCount < 20) { while ($workEnd->gt($start) && $loopCount < 20) {
// make range: // make range:
$workStart = \FireflyIII\Support\Facades\Navigation::startOfPeriod($workStart, '1Y'); $workStart = Facades\Navigation::startOfPeriod($workStart, '1Y');
$workEnd = \FireflyIII\Support\Facades\Navigation::endOfPeriod($workStart, '1Y'); $workEnd = Facades\Navigation::endOfPeriod($workStart, '1Y');
// make sure we don't go overboard // make sure we don't go overboard
if ($workEnd->gt($start)) { if ($workEnd->gt($start)) {

View File

@@ -43,10 +43,10 @@ trait RecalculatesAvailableBudgetsTrait
{ {
private function calculateAmount(AvailableBudget $availableBudget): void private function calculateAmount(AvailableBudget $availableBudget): void
{ {
$repository = app(BudgetLimitRepositoryInterface::class); $repository = app(BudgetLimitRepositoryInterface::class);
$repository->setUser($availableBudget->user); $repository->setUser($availableBudget->user);
$newAmount = '0'; $newAmount = '0';
$abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY()); $abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY());
Log::debug( Log::debug(
sprintf( sprintf(
'Now at AB #%d, ("%s" to "%s")', 'Now at AB #%d, ("%s" to "%s")',
@@ -56,7 +56,7 @@ trait RecalculatesAvailableBudgetsTrait
) )
); );
// have to recalculate everything just in case. // have to recalculate everything just in case.
$set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date); $set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date);
Log::debug(sprintf('Found %d interesting budget limit(s).', $set->count())); Log::debug(sprintf('Found %d interesting budget limit(s).', $set->count()));
/** @var BudgetLimit $budgetLimit */ /** @var BudgetLimit $budgetLimit */
@@ -71,8 +71,8 @@ trait RecalculatesAvailableBudgetsTrait
); );
// overlap in days: // overlap in days:
$limitPeriod = Period::make( $limitPeriod = Period::make(
$budgetLimit->start_date, $budgetLimit->start_date,
$budgetLimit->end_date, $budgetLimit->end_date,
precision : Precision::DAY(), precision : Precision::DAY(),
boundaries: Boundaries::EXCLUDE_NONE() boundaries: Boundaries::EXCLUDE_NONE()
); );
@@ -113,8 +113,8 @@ trait RecalculatesAvailableBudgetsTrait
return '0'; return '0';
} }
$limitPeriod = Period::make( $limitPeriod = Period::make(
$budgetLimit->start_date, $budgetLimit->start_date,
$budgetLimit->end_date, $budgetLimit->end_date,
precision : Precision::DAY(), precision : Precision::DAY(),
boundaries: Boundaries::EXCLUDE_NONE() boundaries: Boundaries::EXCLUDE_NONE()
); );
@@ -132,7 +132,7 @@ trait RecalculatesAvailableBudgetsTrait
Log::debug(sprintf('Now in updateAvailableBudget(limit #%d)', $budgetLimit->id)); Log::debug(sprintf('Now in updateAvailableBudget(limit #%d)', $budgetLimit->id));
/** @var null|Budget $budget */ /** @var null|Budget $budget */
$budget = Budget::find($budgetLimit->budget_id); $budget = Budget::find($budgetLimit->budget_id);
if (null === $budget) { if (null === $budget) {
Log::warning('Budget is null, probably deleted, find deleted version.'); Log::warning('Budget is null, probably deleted, find deleted version.');
@@ -147,7 +147,7 @@ trait RecalculatesAvailableBudgetsTrait
} }
/** @var null|User $user */ /** @var null|User $user */
$user = $budget->user; $user = $budget->user;
// sanity check. It happens when the budget has been deleted so the original user is unknown. // sanity check. It happens when the budget has been deleted so the original user is unknown.
if (null === $user) { if (null === $user) {
@@ -163,7 +163,7 @@ trait RecalculatesAvailableBudgetsTrait
// all have to be created or updated. // all have to be created or updated.
try { try {
$viewRange = app('preferences')->getForUser($user, 'viewRange', '1M')->data; $viewRange = app('preferences')->getForUser($user, 'viewRange', '1M')->data;
} catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) { } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
$viewRange = '1M'; $viewRange = '1M';
} }
@@ -171,13 +171,13 @@ trait RecalculatesAvailableBudgetsTrait
if (null === $viewRange || is_array($viewRange)) { if (null === $viewRange || is_array($viewRange)) {
$viewRange = '1M'; $viewRange = '1M';
} }
$viewRange = (string)$viewRange; $viewRange = (string)$viewRange;
$start = Navigation::startOfPeriod($budgetLimit->start_date, $viewRange); $start = Navigation::startOfPeriod($budgetLimit->start_date, $viewRange);
$end = Navigation::startOfPeriod($budgetLimit->end_date, $viewRange); $end = Navigation::startOfPeriod($budgetLimit->end_date, $viewRange);
$end = Navigation::endOfPeriod($end, $viewRange); $end = Navigation::endOfPeriod($end, $viewRange);
if ($end < $start) { if ($end < $start) {
[$start, $end] = [$end, $start]; [$start, $end] = [$end, $start];
$budgetLimit->start_date = $start; $budgetLimit->start_date = $start;
$budgetLimit->end_date = $end; $budgetLimit->end_date = $end;
$budgetLimit->saveQuietly(); $budgetLimit->saveQuietly();
@@ -189,9 +189,9 @@ trait RecalculatesAvailableBudgetsTrait
Log::debug(sprintf('Limit period is from %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d'))); Log::debug(sprintf('Limit period is from %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
// from the start until the end of the budget limit, need to loop! // from the start until the end of the budget limit, need to loop!
$current = clone $start; $current = clone $start;
while ($current <= $end) { while ($current <= $end) {
$currentEnd = Navigation::endOfPeriod($current, $viewRange); $currentEnd = Navigation::endOfPeriod($current, $viewRange);
// create or find AB for this particular period, and set the amount accordingly. // create or find AB for this particular period, and set the amount accordingly.
/** @var null|AvailableBudget $availableBudget */ /** @var null|AvailableBudget $availableBudget */
@@ -203,12 +203,14 @@ trait RecalculatesAvailableBudgetsTrait
} }
if (null === $availableBudget) { if (null === $availableBudget) {
Log::debug('No AB found, will create.'); Log::debug('No AB found, will create.');
// if not exists: // if not exists:
try { try {
$currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE()); $currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
} catch (InvalidPeriod $e) { } catch (InvalidPeriod $e) {
Log::error('Tried to make invalid period.'); Log::error('Tried to make invalid period.');
Log::error($e->getMessage()); Log::error($e->getMessage());
continue; continue;
} }
$daily = $this->getDailyAmount($budgetLimit); $daily = $this->getDailyAmount($budgetLimit);
@@ -242,7 +244,7 @@ trait RecalculatesAvailableBudgetsTrait
} }
// prep for next loop // prep for next loop
$current = Navigation::addPeriod($current, $viewRange); $current = Navigation::addPeriod($current, $viewRange);
} }
} }
} }

View File

@@ -55,8 +55,8 @@ class AddTag implements ActionInterface
$tagName = $this->action->getValue($journal); $tagName = $this->action->getValue($journal);
$tag = $factory->findOrCreate($tagName); $tag = $factory->findOrCreate($tagName);
$type = $journal['transaction_type_type']; $type = $journal['transaction_type_type'];
if(TransactionTypeEnum::OPENING_BALANCE->value === $type || TransactionTypeEnum::LIABILITY_CREDIT->value === $type || TransactionTypeEnum::INVALID->value === $type) { if (TransactionTypeEnum::OPENING_BALANCE->value === $type || TransactionTypeEnum::LIABILITY_CREDIT->value === $type || TransactionTypeEnum::INVALID->value === $type) {
// fail silently on invalid transaction types. // fail silently on invalid transaction types.
return false; return false;

118
composer.lock generated
View File

@@ -130,16 +130,16 @@
}, },
{ {
"name": "brick/math", "name": "brick/math",
"version": "0.14.0", "version": "0.14.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/brick/math.git", "url": "https://github.com/brick/math.git",
"reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" "reference": "f05858549e5f9d7bb45875a75583240a38a281d0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", "url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0",
"reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", "reference": "f05858549e5f9d7bb45875a75583240a38a281d0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -178,7 +178,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/brick/math/issues", "issues": "https://github.com/brick/math/issues",
"source": "https://github.com/brick/math/tree/0.14.0" "source": "https://github.com/brick/math/tree/0.14.1"
}, },
"funding": [ "funding": [
{ {
@@ -186,7 +186,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-08-29T12:40:03+00:00" "time": "2025-11-24T14:40:29+00:00"
}, },
{ {
"name": "carbonphp/carbon-doctrine-types", "name": "carbonphp/carbon-doctrine-types",
@@ -1938,16 +1938,16 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v12.39.0", "version": "v12.40.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "1a6176129ef28eaf42b6b4a6250025120c3d8dac" "reference": "2e986acbf9acf62cba13400bc23c4d639bf188b9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/1a6176129ef28eaf42b6b4a6250025120c3d8dac", "url": "https://api.github.com/repos/laravel/framework/zipball/2e986acbf9acf62cba13400bc23c4d639bf188b9",
"reference": "1a6176129ef28eaf42b6b4a6250025120c3d8dac", "reference": "2e986acbf9acf62cba13400bc23c4d639bf188b9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2059,7 +2059,7 @@
"league/flysystem-sftp-v3": "^3.25.1", "league/flysystem-sftp-v3": "^3.25.1",
"mockery/mockery": "^1.6.10", "mockery/mockery": "^1.6.10",
"opis/json-schema": "^2.4.1", "opis/json-schema": "^2.4.1",
"orchestra/testbench-core": "^10.7.0", "orchestra/testbench-core": "^10.8.0",
"pda/pheanstalk": "^5.0.6|^7.0.0", "pda/pheanstalk": "^5.0.6|^7.0.0",
"php-http/discovery": "^1.15", "php-http/discovery": "^1.15",
"phpstan/phpstan": "^2.0", "phpstan/phpstan": "^2.0",
@@ -2153,7 +2153,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2025-11-18T15:16:10+00:00" "time": "2025-11-25T16:16:33+00:00"
}, },
{ {
"name": "laravel/passport", "name": "laravel/passport",
@@ -2233,16 +2233,16 @@
}, },
{ {
"name": "laravel/prompts", "name": "laravel/prompts",
"version": "v0.3.7", "version": "v0.3.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/prompts.git", "url": "https://github.com/laravel/prompts.git",
"reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc" "reference": "096748cdfb81988f60090bbb839ce3205ace0d35"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/prompts/zipball/a1891d362714bc40c8d23b0b1d7090f022ea27cc", "url": "https://api.github.com/repos/laravel/prompts/zipball/096748cdfb81988f60090bbb839ce3205ace0d35",
"reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc", "reference": "096748cdfb81988f60090bbb839ce3205ace0d35",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2258,7 +2258,7 @@
"require-dev": { "require-dev": {
"illuminate/collections": "^10.0|^11.0|^12.0", "illuminate/collections": "^10.0|^11.0|^12.0",
"mockery/mockery": "^1.5", "mockery/mockery": "^1.5",
"pestphp/pest": "^2.3|^3.4", "pestphp/pest": "^2.3|^3.4|^4.0",
"phpstan/phpstan": "^1.12.28", "phpstan/phpstan": "^1.12.28",
"phpstan/phpstan-mockery": "^1.1.3" "phpstan/phpstan-mockery": "^1.1.3"
}, },
@@ -2286,22 +2286,22 @@
"description": "Add beautiful and user-friendly forms to your command-line applications.", "description": "Add beautiful and user-friendly forms to your command-line applications.",
"support": { "support": {
"issues": "https://github.com/laravel/prompts/issues", "issues": "https://github.com/laravel/prompts/issues",
"source": "https://github.com/laravel/prompts/tree/v0.3.7" "source": "https://github.com/laravel/prompts/tree/v0.3.8"
}, },
"time": "2025-09-19T13:47:56+00:00" "time": "2025-11-21T20:52:52+00:00"
}, },
{ {
"name": "laravel/sanctum", "name": "laravel/sanctum",
"version": "v4.2.0", "version": "v4.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/sanctum.git", "url": "https://github.com/laravel/sanctum.git",
"reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677" "reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677", "url": "https://api.github.com/repos/laravel/sanctum/zipball/f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677", "reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2315,9 +2315,8 @@
}, },
"require-dev": { "require-dev": {
"mockery/mockery": "^1.6", "mockery/mockery": "^1.6",
"orchestra/testbench": "^9.0|^10.0", "orchestra/testbench": "^9.15|^10.8",
"phpstan/phpstan": "^1.10", "phpstan/phpstan": "^1.10"
"phpunit/phpunit": "^11.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@@ -2352,20 +2351,20 @@
"issues": "https://github.com/laravel/sanctum/issues", "issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum" "source": "https://github.com/laravel/sanctum"
}, },
"time": "2025-07-09T19:45:24+00:00" "time": "2025-11-21T13:59:03+00:00"
}, },
{ {
"name": "laravel/serializable-closure", "name": "laravel/serializable-closure",
"version": "v2.0.6", "version": "v2.0.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/serializable-closure.git", "url": "https://github.com/laravel/serializable-closure.git",
"reference": "038ce42edee619599a1debb7e81d7b3759492819" "reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/038ce42edee619599a1debb7e81d7b3759492819", "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/cb291e4c998ac50637c7eeb58189c14f5de5b9dd",
"reference": "038ce42edee619599a1debb7e81d7b3759492819", "reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2374,7 +2373,7 @@
"require-dev": { "require-dev": {
"illuminate/support": "^10.0|^11.0|^12.0", "illuminate/support": "^10.0|^11.0|^12.0",
"nesbot/carbon": "^2.67|^3.0", "nesbot/carbon": "^2.67|^3.0",
"pestphp/pest": "^2.36|^3.0", "pestphp/pest": "^2.36|^3.0|^4.0",
"phpstan/phpstan": "^2.0", "phpstan/phpstan": "^2.0",
"symfony/var-dumper": "^6.2.0|^7.0.0" "symfony/var-dumper": "^6.2.0|^7.0.0"
}, },
@@ -2413,20 +2412,20 @@
"issues": "https://github.com/laravel/serializable-closure/issues", "issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure" "source": "https://github.com/laravel/serializable-closure"
}, },
"time": "2025-10-09T13:42:30+00:00" "time": "2025-11-21T20:52:36+00:00"
}, },
{ {
"name": "laravel/slack-notification-channel", "name": "laravel/slack-notification-channel",
"version": "v3.6.0", "version": "v3.7.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git", "url": "https://github.com/laravel/slack-notification-channel.git",
"reference": "642677a57490eebccb7e9fb666f5a5379c6e3459" "reference": "414aec57b487bfbac7f90fc30f50a2f0a2df4caa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/642677a57490eebccb7e9fb666f5a5379c6e3459", "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/414aec57b487bfbac7f90fc30f50a2f0a2df4caa",
"reference": "642677a57490eebccb7e9fb666f5a5379c6e3459", "reference": "414aec57b487bfbac7f90fc30f50a2f0a2df4caa",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2476,9 +2475,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/laravel/slack-notification-channel/issues", "issues": "https://github.com/laravel/slack-notification-channel/issues",
"source": "https://github.com/laravel/slack-notification-channel/tree/v3.6.0" "source": "https://github.com/laravel/slack-notification-channel/tree/v3.7.0"
}, },
"time": "2025-06-26T16:51:38+00:00" "time": "2025-11-20T17:26:07+00:00"
}, },
{ {
"name": "laravel/ui", "name": "laravel/ui",
@@ -3544,22 +3543,22 @@
}, },
{ {
"name": "mailersend/laravel-driver", "name": "mailersend/laravel-driver",
"version": "v2.9.1", "version": "v2.12.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/mailersend/mailersend-laravel-driver.git", "url": "https://github.com/mailersend/mailersend-laravel-driver.git",
"reference": "87fd5ab76808bbaac9221be0d306baef13e98725" "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725", "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
"reference": "87fd5ab76808bbaac9221be0d306baef13e98725", "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0", "illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0",
"mailersend/mailersend": "^0.31.0", "mailersend/mailersend": "^0.35.0",
"nyholm/psr7": "^1.5", "nyholm/psr7": "^1.5",
"php": ">=8.0", "php": ">=8.0",
"php-http/guzzle7-adapter": "^1.0", "php-http/guzzle7-adapter": "^1.0",
@@ -3607,29 +3606,28 @@
], ],
"support": { "support": {
"issues": "https://github.com/mailersend/mailersend-laravel-driver/issues", "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
"source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1" "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
}, },
"time": "2025-04-09T09:33:07+00:00" "time": "2025-10-28T14:59:16+00:00"
}, },
{ {
"name": "mailersend/mailersend", "name": "mailersend/mailersend",
"version": "v0.31.0", "version": "v0.35.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/mailersend/mailersend-php.git", "url": "https://github.com/mailersend/mailersend-php.git",
"reference": "513ff83ee768526055ad52987cde401ea7218c67" "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67", "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
"reference": "513ff83ee768526055ad52987cde401ea7218c67", "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"beberlei/assert": "^3.2", "beberlei/assert": "^3.2",
"ext-json": "*", "ext-json": "*",
"illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0", "php": "^7.4 || ^8.0 <8.5",
"php": "^7.4|^8.0",
"php-http/client-common": "^2.2", "php-http/client-common": "^2.2",
"php-http/discovery": "^1.9", "php-http/discovery": "^1.9",
"php-http/httplug": "^2.1", "php-http/httplug": "^2.1",
@@ -3674,9 +3672,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/mailersend/mailersend-php/issues", "issues": "https://github.com/mailersend/mailersend-php/issues",
"source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0" "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
}, },
"time": "2025-04-03T12:16:11+00:00" "time": "2025-10-28T13:11:43+00:00"
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
@@ -5181,16 +5179,16 @@
}, },
{ {
"name": "predis/predis", "name": "predis/predis",
"version": "v3.2.0", "version": "v3.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/predis/predis.git", "url": "https://github.com/predis/predis.git",
"reference": "9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8" "reference": "153097374b39a2f737fe700ebcd725642526cdec"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/predis/predis/zipball/9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8", "url": "https://api.github.com/repos/predis/predis/zipball/153097374b39a2f737fe700ebcd725642526cdec",
"reference": "9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8", "reference": "153097374b39a2f737fe700ebcd725642526cdec",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5232,7 +5230,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/predis/predis/issues", "issues": "https://github.com/predis/predis/issues",
"source": "https://github.com/predis/predis/tree/v3.2.0" "source": "https://github.com/predis/predis/tree/v3.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -5240,7 +5238,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-08-06T06:41:24+00:00" "time": "2025-11-24T17:48:50+00:00"
}, },
{ {
"name": "psr/cache", "name": "psr/cache",

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false), 'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag. // see cer.php for exchange rates feature flag.
], ],
'version' => 'develop/2025-11-24', 'version' => 'develop/2025-11-26',
'build_time' => 1763955176, 'build_time' => 1764136346,
'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.

66
package-lock.json generated
View File

@@ -3291,42 +3291,42 @@
} }
}, },
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.5.24", "version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
"integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==", "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.28.5", "@babel/parser": "^7.28.5",
"@vue/shared": "3.5.24", "@vue/shared": "3.5.25",
"entities": "^4.5.0", "entities": "^4.5.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.5.24", "version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
"integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==", "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.5.24", "@vue/compiler-core": "3.5.25",
"@vue/shared": "3.5.24" "@vue/shared": "3.5.25"
} }
}, },
"node_modules/@vue/compiler-sfc": { "node_modules/@vue/compiler-sfc": {
"version": "3.5.24", "version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz",
"integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==", "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.28.5", "@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.24", "@vue/compiler-core": "3.5.25",
"@vue/compiler-dom": "3.5.24", "@vue/compiler-dom": "3.5.25",
"@vue/compiler-ssr": "3.5.24", "@vue/compiler-ssr": "3.5.25",
"@vue/shared": "3.5.24", "@vue/shared": "3.5.25",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"magic-string": "^0.30.21", "magic-string": "^0.30.21",
"postcss": "^8.5.6", "postcss": "^8.5.6",
@@ -3334,14 +3334,14 @@
} }
}, },
"node_modules/@vue/compiler-ssr": { "node_modules/@vue/compiler-ssr": {
"version": "3.5.24", "version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
"integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==", "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.24", "@vue/compiler-dom": "3.5.25",
"@vue/shared": "3.5.24" "@vue/shared": "3.5.25"
} }
}, },
"node_modules/@vue/component-compiler-utils": { "node_modules/@vue/component-compiler-utils": {
@@ -3423,9 +3423,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.5.24", "version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz",
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==", "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@@ -4521,9 +4521,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001756", "version": "1.0.30001757",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001756.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
"integrity": "sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==", "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -5736,9 +5736,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.259", "version": "1.5.260",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.259.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.260.tgz",
"integrity": "sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==", "integrity": "sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@@ -8400,9 +8400,9 @@
} }
}, },
"node_modules/node-forge": { "node_modules/node-forge": {
"version": "1.3.1", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==",
"dev": true, "dev": true,
"license": "(BSD-3-Clause OR GPL-2.0)", "license": "(BSD-3-Clause OR GPL-2.0)",
"engines": { "engines": {