Compare commits

...

28 Commits

Author SHA1 Message Date
James Cole
babf9fe96f Add file permissions checks. #11323 2025-12-06 14:55:15 +01:00
James Cole
ca3922d00a Fix #11313 2025-12-06 13:50:51 +01:00
James Cole
aadb685b57 Add YTD fix. 2025-12-06 08:12:18 +01:00
github-actions[bot]
bee62b2115 Merge pull request #11335 from firefly-iii/release-1765004138
🤖 Automatically merge the PR into the develop branch.
2025-12-06 07:55:46 +01:00
JC5
205169a8ad 🤖 Auto commit for release 'develop' on 2025-12-06 2025-12-06 07:55:38 +01:00
James Cole
5f36bb84a4 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-12-06 07:51:19 +01:00
James Cole
5b395d870b Fix #11333 2025-12-06 07:32:43 +01:00
github-actions[bot]
bceb526cb3 Merge pull request #11334 from firefly-iii/release-1765002701
🤖 Automatically merge the PR into the develop branch.
2025-12-06 07:31:52 +01:00
JC5
1f89dddb08 🤖 Auto commit for release 'develop' on 2025-12-06 2025-12-06 07:31:41 +01:00
James Cole
a93f2d66af Fix #11329 2025-12-06 07:27:41 +01:00
James Cole
551909ea60 Merge branch 'main' into develop 2025-12-05 08:21:34 +01:00
Sander Dorigo
5667044349 Fix #11328 2025-12-04 17:27:20 +01:00
James Cole
6f73e4f2c9 Merge pull request #11316 from firefly-iii/dependabot/composer/develop/symfony/mailgun-mailer-8.0.0
Bump symfony/mailgun-mailer from 7.4.0 to 8.0.0
2025-12-01 14:32:55 +01:00
dependabot[bot]
1f19f20734 Bump symfony/mailgun-mailer from 7.4.0 to 8.0.0
Bumps [symfony/mailgun-mailer](https://github.com/symfony/mailgun-mailer) from 7.4.0 to 8.0.0.
- [Release notes](https://github.com/symfony/mailgun-mailer/releases)
- [Changelog](https://github.com/symfony/mailgun-mailer/blob/7.3/CHANGELOG.md)
- [Commits](https://github.com/symfony/mailgun-mailer/compare/v7.4.0...v8.0.0)

---
updated-dependencies:
- dependency-name: symfony/mailgun-mailer
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 10:45:09 +00:00
James Cole
91c8f0db80 Merge pull request #11317 from firefly-iii/dependabot/composer/develop/symfony/expression-language-8.0.0
Bump symfony/expression-language from 7.4.0 to 8.0.0
2025-12-01 11:41:22 +01:00
dependabot[bot]
2cdd1aa147 Bump symfony/expression-language from 7.4.0 to 8.0.0
Bumps [symfony/expression-language](https://github.com/symfony/expression-language) from 7.4.0 to 8.0.0.
- [Release notes](https://github.com/symfony/expression-language/releases)
- [Changelog](https://github.com/symfony/expression-language/blob/7.3/CHANGELOG.md)
- [Commits](https://github.com/symfony/expression-language/compare/v7.4.0...v8.0.0)

---
updated-dependencies:
- dependency-name: symfony/expression-language
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 08:17:15 +00:00
James Cole
5ac51218aa Merge pull request #11319 from firefly-iii/dependabot/github_actions/github/command-2.0.3 2025-12-01 05:15:37 +01:00
James Cole
80abd277a0 Merge pull request #11315 from firefly-iii/dependabot/composer/develop/symfony/http-client-8.0.0 2025-12-01 05:14:44 +01:00
mergify[bot]
b644f28882 Merge branch 'develop' into dependabot/composer/develop/symfony/http-client-8.0.0 2025-12-01 03:40:11 +00:00
github-actions[bot]
35a81fd2de Merge pull request #11321 from firefly-iii/release-1764560258
🤖 Automatically merge the PR into the develop branch.
2025-12-01 04:37:44 +01:00
JC5
51e8a1dbe2 🤖 Auto commit for release 'develop' on 2025-12-01 2025-12-01 04:37:38 +01:00
dependabot[bot]
b799379a0a Bump github/command from 2.0.2 to 2.0.3
Bumps [github/command](https://github.com/github/command) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/github/command/releases)
- [Commits](https://github.com/github/command/compare/v2.0.2...v2.0.3)

---
updated-dependencies:
- dependency-name: github/command
  dependency-version: 2.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 03:10:25 +00:00
dependabot[bot]
c8edaee848 Bump symfony/http-client from 7.4.0 to 8.0.0
Bumps [symfony/http-client](https://github.com/symfony/http-client) from 7.4.0 to 8.0.0.
- [Release notes](https://github.com/symfony/http-client/releases)
- [Changelog](https://github.com/symfony/http-client/blob/7.3/CHANGELOG.md)
- [Commits](https://github.com/symfony/http-client/compare/v7.4.0...v8.0.0)

---
updated-dependencies:
- dependency-name: symfony/http-client
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 03:03:40 +00:00
github-actions[bot]
bbe47635d3 Merge pull request #11304 from firefly-iii/release-1764397418
🤖 Automatically merge the PR into the develop branch.
2025-11-29 07:23:46 +01:00
JC5
5c73d238a0 🤖 Auto commit for release 'develop' on 2025-11-29 2025-11-29 07:23:38 +01:00
github-actions[bot]
2bee3d2728 Merge pull request #11301 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2025-11-28 21:36:11 +01:00
github-actions[bot]
73126786b0 Merge pull request #11300 from firefly-iii/release-1764362158
🤖 Automatically merge the PR into the develop branch.
2025-11-28 21:36:05 +01:00
JC5
962a729025 🤖 Auto commit for release 'v6.4.9' on 2025-11-28 2025-11-28 21:35:58 +01:00
18 changed files with 643 additions and 457 deletions

View File

@@ -402,16 +402,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.90.0",
"version": "v3.91.3",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155"
"reference": "9f10aa6390cea91da175ea608880e942d7c0226e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ad732c2e9299c9743f9c55ae53cc0e7642ab1155",
"reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/9f10aa6390cea91da175ea608880e942d7c0226e",
"reference": "9f10aa6390cea91da175ea608880e942d7c0226e",
"shasum": ""
},
"require": {
@@ -467,7 +467,7 @@
"PhpCsFixer\\": "src/"
},
"exclude-from-classmap": [
"src/Fixer/Internal/*"
"src/**/Internal/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -493,7 +493,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.90.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.91.3"
},
"funding": [
{
@@ -501,7 +501,7 @@
"type": "github"
}
],
"time": "2025-11-20T15:15:16+00:00"
"time": "2025-12-05T19:45:37+00:00"
},
{
"name": "psr/container",

View File

@@ -13,7 +13,7 @@ jobs:
close_duplicates:
runs-on: ubuntu-latest
steps:
- uses: github/command@v2.0.2
- uses: github/command@v2.0.3
id: command
with:
allowed_contexts: "issue"

View File

@@ -86,17 +86,27 @@ class RemovesLinksToDeletedObjects extends Command
private function cleanupJournals(array $journals): void
{
$count = DB::table('tag_transaction_journal')->whereIn('transaction_journal_id', $journals)->delete();
if ($count > 0) {
$this->friendlyInfo(sprintf('Removed %d old relationship(s) between tags and transactions.', $count));
$countTags = 0;
$countBudgets = 0;
$countCategories = 0;
// #11333
foreach (array_chunk($journals, 1337) as $set) {
$countTags += DB::table('tag_transaction_journal')->whereIn('transaction_journal_id', $set)->delete();
$countBudgets += DB::table('budget_transaction_journal')->whereIn('transaction_journal_id', $set)->delete();
$countCategories += DB::table('category_transaction_journal')->whereIn('transaction_journal_id', $set)->delete();
}
$count = DB::table('budget_transaction_journal')->whereIn('transaction_journal_id', $journals)->delete();
if ($count > 0) {
$this->friendlyInfo(sprintf('Removed %d old relationship(s) between budgets and transactions.', $count));
if ($countTags > 0) {
$this->friendlyInfo(sprintf('Removed %d old relationship(s) between tags and transactions.', $countTags));
}
$count = DB::table('category_transaction_journal')->whereIn('transaction_journal_id', $journals)->delete();
if ($count > 0) {
$this->friendlyInfo(sprintf('Removed %d old relationship(s) categories and transactions.', $count));
if ($countBudgets > 0) {
$this->friendlyInfo(sprintf('Removed %d old relationship(s) between budgets and transactions.', $countBudgets));
}
if ($countCategories > 0) {
$this->friendlyInfo(sprintf('Removed %d old relationship(s) categories and transactions.', $countCategories));
}
}

View File

@@ -1,26 +0,0 @@
<?php
namespace FireflyIII\Console\Commands\Integrity;
use Illuminate\Console\Command;
class ReportSkeleton extends Command
{
protected $description = 'DESCRIPTION HERE';
protected $signature = 'firefly-iii:INT_COMMAND';
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
//
$this->warn('Congrats, you found the skeleton command. Boo!');
return 0;
}
}

View File

@@ -48,6 +48,7 @@ class ReportsIntegrity extends Command
$commands = [
'integrity:empty-objects',
'integrity:total-sums',
'integrity:file-permissions',
];
foreach ($commands as $command) {
$this->friendlyLine(sprintf('Now executing %s', $command));

View File

@@ -0,0 +1,70 @@
<?php
/*
* ValidatesFilePermissions.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\Integrity;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
class ValidatesFilePermissions extends Command
{
use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'integrity:file-permissions';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle(): int
{
$directories = [storage_path('upload')];
$errors = false;
/** @var string $directory */
foreach ($directories as $directory) {
if (!is_dir($directory)) {
$this->friendlyError(sprintf('Directory "%s" cannot found. It is necessary to allow files to be uploaded.', $uploadDir));
$errors = true;
continue;
}
if (!is_writable($directory)) {
$this->friendlyError(sprintf('Directory "%s" is not writeable. Uploading attachments may fail silently.', $uploadDir));
$errors = true;
}
}
if(false === $errors) {
$this->friendlyInfo('All necessary file paths seem to exist, and are writeable.');
}
return self::SUCCESS;
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* TriggeredStoredTransactionGroup.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\Events\Model\TransactionGroup;
use FireflyIII\Events\Event;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Queue\SerializesModels;
class TriggeredStoredTransactionGroup extends Event
{
use SerializesModels;
/**
* Create a new event instance.
*/
public function __construct(public TransactionGroup $transactionGroup) {}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Enums\WebhookTrigger;
use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
@@ -51,6 +52,12 @@ class StoredGroupEventHandler
$this->removePeriodStatistics($event);
}
public function triggerRulesManually(TriggeredStoredTransactionGroup $event): void
{
$newEvent = new StoredTransactionGroup($event->transactionGroup, true, false);
$this->processRules($newEvent);
}
/**
* This method grabs all the users rules and processes them.
*/
@@ -63,14 +70,14 @@ class StoredGroupEventHandler
}
Log::debug('Now in StoredGroupEventHandler::processRules()');
$journals = $storedGroupEvent->transactionGroup->transactionJournals;
$array = [];
$journals = $storedGroupEvent->transactionGroup->transactionJournals;
$array = [];
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$array[] = $journal->id;
}
$journalIds = implode(',', $array);
$journalIds = implode(',', $array);
Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
// collect rules:
@@ -79,10 +86,10 @@ class StoredGroupEventHandler
// add the groups to the rule engine.
// it should run the rules in the group and cancel the group if necessary.
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
// create and fire rule engine.
$newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($storedGroupEvent->transactionGroup->user);
$newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
$newRuleEngine->setRuleGroups($groups);
@@ -91,7 +98,7 @@ class StoredGroupEventHandler
private function recalculateCredit(StoredTransactionGroup $event): void
{
$group = $event->transactionGroup;
$group = $event->transactionGroup;
/** @var CreditRecalculateService $object */
$object = app(CreditRecalculateService::class);
@@ -107,10 +114,10 @@ class StoredGroupEventHandler
/** @var TransactionJournal $journal */
foreach ($event->transactionGroup->transactionJournals as $journal) {
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', '0')->first();
$source = $journal->transactions()->where('amount', '<', '0')->first();
/** @var null|Transaction $dest */
$dest = $journal->transactions()->where('amount', '>', '0')->first();
$dest = $journal->transactions()->where('amount', '>', '0')->first();
if (null !== $source) {
$repository->deleteStatisticsForModel($source->account, $journal->date);
@@ -145,14 +152,14 @@ class StoredGroupEventHandler
private function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void
{
Log::debug(__METHOD__);
$group = $storedGroupEvent->transactionGroup;
$group = $storedGroupEvent->transactionGroup;
if (false === $storedGroupEvent->fireWebhooks) {
Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
return;
}
$user = $group->user;
$user = $group->user;
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);

View File

@@ -122,6 +122,9 @@ class IndexController extends Controller
$availableBudgets = $this->getAllAvailableBudgets($start, $end);
// get all active budgets:
$budgets = $this->getAllBudgets($start, $end, $currencies, $this->primaryCurrency);
// echo '<pre>';
// var_dump($budgets[0]);exit;
$sums = $this->getSums($budgets);
// get budgeted for default currency:

View File

@@ -26,14 +26,16 @@ namespace FireflyIII\Http\Controllers\RuleGroup;
use Carbon\Carbon;
use Exception;
use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\SelectTransactionsRequest;
use FireflyIII\Models\RuleGroup;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use FireflyIII\User;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -41,18 +43,20 @@ use Illuminate\View\View;
*/
class ExecutionController extends Controller
{
private AccountRepositoryInterface $repository;
/**
* ExecutionController constructor.
*/
public function __construct()
{
parent::__construct();
$this->repository = app(AccountRepositoryInterface::class);
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.rules'));
app('view')->share('title', (string)trans('firefly.rules'));
app('view')->share('mainTitleIcon', 'fa-random');
$this->repository->setUser(auth()->user());
return $next($request);
}
@@ -67,34 +71,35 @@ class ExecutionController extends Controller
public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
{
// Get parameters specified by the user
/** @var User $user */
$user = auth()->user();
$accounts = implode(',', $request->get('accounts'));
// create new rule engine:
$newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($user);
$accounts = $request->get('accounts');
$set = $this->repository->getAccountsById($accounts);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($set);
// add date operators.
if (null !== $request->get('start')) {
$startDate = new Carbon($request->get('start'));
$newRuleEngine->addOperator(['type' => 'date_after', 'value' => $startDate->format('Y-m-d')]);
$collector->setStart($startDate);
}
if (null !== $request->get('end')) {
$endDate = new Carbon($request->get('end'));
$newRuleEngine->addOperator(['type' => 'date_before', 'value' => $endDate->format('Y-m-d')]);
$collector->setEnd($endDate);
}
$final = $collector->getGroups();
$ids = $final->pluck('id')->toArray();
Log::debug(sprintf('Found %d groups collected from %d account(s)', $final->count(), $set->count()));
foreach (array_chunk($ids, 1337) as $setOfIds) {
Log::debug(sprintf('Now processing %d groups', count($setOfIds)));
$groups = TransactionGroup::whereIn('id', $setOfIds)->get();
/** @var TransactionGroup $group */
foreach ($groups as $group) {
Log::debug(sprintf('Processing group #%d.', $group->id));
event(new TriggeredStoredTransactionGroup($group));
}
}
// add extra operators:
$newRuleEngine->addOperator(['type' => 'account_id', 'value' => $accounts]);
// set rules:
// #10427, file rule group and not the set of rules.
$collection = new Collection()->push($ruleGroup);
$newRuleEngine->setRuleGroups($collection);
$newRuleEngine->fire();
// Tell the user that the job is queued
session()->flash('success', (string) trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
session()->flash('success', (string)trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
return redirect()->route('rules.index');
}
@@ -104,9 +109,9 @@ class ExecutionController extends Controller
*
* @return Factory|View
*/
public function selectTransactions(RuleGroup $ruleGroup): Factory|\Illuminate\Contracts\View\View
public function selectTransactions(RuleGroup $ruleGroup): Factory | \Illuminate\Contracts\View\View
{
$subTitle = (string) trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
$subTitle = (string)trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
return view('rules.rule-group.select-transactions', ['ruleGroup' => $ruleGroup, 'subTitle' => $subTitle]);
}

View File

@@ -33,6 +33,7 @@ use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
use FireflyIII\Events\Model\PiggyBank\ChangedName;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject;
use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
use FireflyIII\Events\NewVersionAvailable;
use FireflyIII\Events\Preferences\UserGroupChangedPrimaryCurrency;
use FireflyIII\Events\RegisteredUser;
@@ -131,6 +132,9 @@ class EventServiceProvider extends ServiceProvider
StoredTransactionGroup::class => [
'FireflyIII\Handlers\Events\StoredGroupEventHandler@runAllHandlers',
],
TriggeredStoredTransactionGroup::class => [
'FireflyIII\Handlers\Events\StoredGroupEventHandler@triggerRulesManually',
],
// is a Transaction Journal related event.
UpdatedTransactionGroup::class => [
'FireflyIII\Handlers\Events\UpdatedGroupEventHandler@runAllHandlers',

View File

@@ -151,13 +151,7 @@ class Navigation
public function diffInPeriods(string $period, int $skip, Carbon $beginning, Carbon $end): int
{
Log::debug(sprintf(
'diffInPeriods: %s (skip: %d), between %s and %s.',
$period,
$skip,
$beginning->format('Y-m-d'),
$end->format('Y-m-d')
));
Log::debug(sprintf('diffInPeriods: %s (skip: %d), between %s and %s.', $period, $skip, $beginning->format('Y-m-d'), $end->format('Y-m-d')));
$map = [
'daily' => 'diffInDays',
'weekly' => 'diffInWeeks',
@@ -211,9 +205,14 @@ class Navigation
// Log::debug(sprintf('Now in endOfPeriod("%s", "%s").', $currentEnd->toIso8601String(), $repeatFreq));
if ('MTD' === $repeatFreq && $end->isFuture()) {
// fall back to a monthly schedule if the requested period is MTD.
Log::debug('endOfPeriod() requests "MTD", set it to "1M" instead.');
Log::debug('endOfPeriod() requests "MTD" + future, set it to "1M" instead.');
$repeatFreq = '1M';
}
if ('YTD' === $repeatFreq && $end->isFuture()) {
// fall back to a yearly schedule if the requested period is YTD.
Log::debug('endOfPeriod() requests "YTD" + future, set it to "1Y" instead.');
$repeatFreq = '1Y';
}
$functionMap = [
'1D' => 'endOfDay',

View File

@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use Illuminate\Support\Facades\Log;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject;
@@ -33,10 +32,13 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
* Class ConvertToTransfer
@@ -77,10 +79,8 @@ class ConvertToTransfer implements ActionInterface
$user = $object->user;
$journalId = $object->id;
if (TransactionTypeEnum::TRANSFER->value === $type) {
Log::error(
sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer')));
Log::error(sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id));
// event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer')));
return false;
}
@@ -106,15 +106,7 @@ class ConvertToTransfer implements ActionInterface
$opposing = $repository->findByName($accountName, [$expectedType]);
if (null === $opposing) {
Log::error(
sprintf(
'Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).',
$expectedType,
$journalId,
$accountName,
$this->action->rule_id
)
);
Log::error(sprintf('Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).', $expectedType, $journalId, $accountName, $this->action->rule_id));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_valid_opposing', ['name' => $accountName])));
return false;
@@ -167,7 +159,7 @@ class ConvertToTransfer implements ActionInterface
return '';
}
return (string) $journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type;
return (string)$journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type;
}
private function getDestinationType(int $journalId): string
@@ -180,7 +172,7 @@ class ConvertToTransfer implements ActionInterface
return '';
}
return (string) $journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type;
return (string)$journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type;
}
/**
@@ -192,33 +184,57 @@ class ConvertToTransfer implements ActionInterface
*/
private function convertWithdrawalArray(TransactionJournal $journal, Account $opposing): bool
{
$sourceAccount = $this->getSourceAccount($journal);
$repository = app(AccountRepositoryInterface::class);
$sourceAccount = $this->getSourceAccount($journal);
$repository->setUser($sourceAccount->user);
if ($sourceAccount->id === $opposing->id) {
Log::error(
vsprintf(
'Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).',
[$journal->id, $opposing->name, $this->action->rule_id]
)
);
Log::error(vsprintf('Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).', [$journal->id, $opposing->name, $this->action->rule_id]));
event(new RuleActionFailedOnObject($this->action, $journal, trans('rules.already_has_source_asset', ['name' => $opposing->name])));
return false;
}
/** @var Transaction $sourceTransaction */
$sourceTransaction = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '<', 0)->first();
/** @var Transaction $destTransaction */
$destTransaction = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '>', 0)->first();
// update destination transaction:
DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '>', 0)
->update(['account_id' => $opposing->id])
;
$destTransaction->account_id = $opposing->id;
$destTransaction->save();
// check if the currencies are a match.
/** @var TransactionCurrency $sourceCurrency */
$sourceCurrency = $repository->getAccountCurrency($sourceAccount);
/** @var TransactionCurrency $destCurrency */
$destCurrency = $repository->getAccountCurrency($opposing);
// if the currencies do not match, need to be smart about the involved amounts:
if ($sourceCurrency->id !== $destCurrency->id) {
Log::debug(sprintf('Accounts have different currencies. Source has %s, dest has %s', $sourceCurrency->code, $destCurrency->code));
$foreignAmount = '' === (string)$sourceTransaction->foreign_amount ? $sourceTransaction->amount : $sourceTransaction->foreign_amount;
Log::debug(sprintf('Foreign amount: %s', $foreignAmount));
// source transaction: set the foreign currency ID and leave as is.
$sourceTransaction->foreign_currency_id = $destCurrency->id;
$sourceTransaction->foreign_amount = Steam::negative($foreignAmount);
$sourceTransaction->save();
Log::debug(sprintf('Set source transaction #%d foreign currency ID to #%d (amount: %s)', $sourceTransaction->id, $destCurrency->id, $foreignAmount));
// dest transaction: set reverse amounts and currency IDs from source transaction.
$destTransaction->foreign_currency_id = $sourceCurrency->transaction_currency_id;
$destTransaction->transaction_currency_id = $sourceTransaction->foreign_currency_id;
$destTransaction->amount = Steam::positive($foreignAmount);
$destTransaction->foreign_amount = Steam::positive($sourceTransaction->amount);
$destTransaction->save();
Log::debug(sprintf('Set dest transaction #%d to #%d %s and foreign #%d %s', $destTransaction->id, $destTransaction->transaction_currency_id, $destTransaction->amount, $destTransaction->foreign_currency_id, $destTransaction->foreign_amount));
}
// change transaction type of journal:
$newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first();
$newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first();
DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id, 'bill_id' => null])
;
DB::table('transaction_journals')->where('id', '=', $journal->id)->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
Log::debug('Converted withdrawal to transfer.');

View File

@@ -107,9 +107,9 @@
"spatie/laravel-html": "^3.2",
"spatie/laravel-ignition": "^2",
"spatie/period": "^2.4",
"symfony/expression-language": "^7.0",
"symfony/http-client": "^7.1",
"symfony/mailgun-mailer": "^7.1",
"symfony/expression-language": "^8.0",
"symfony/http-client": "^8.0",
"symfony/mailgun-mailer": "^8.0",
"thecodingmachine/safe": "^3.1"
},
"require-dev": {

368
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "946638fa99da77780e75953c338d9a55",
"content-hash": "8317b89f4d014debebcd301fde669321",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -1072,31 +1072,31 @@
},
{
"name": "fruitcake/php-cors",
"version": "v1.3.0",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/fruitcake/php-cors.git",
"reference": "3d158f36e7875e2f040f37bc0573956240a5a38b"
"reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b",
"reference": "3d158f36e7875e2f040f37bc0573956240a5a38b",
"url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379",
"reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379",
"shasum": ""
},
"require": {
"php": "^7.4|^8.0",
"symfony/http-foundation": "^4.4|^5.4|^6|^7"
"php": "^8.1",
"symfony/http-foundation": "^5.4|^6.4|^7.3|^8"
},
"require-dev": {
"phpstan/phpstan": "^1.4",
"phpstan/phpstan": "^2",
"phpunit/phpunit": "^9",
"squizlabs/php_codesniffer": "^3.5"
"squizlabs/php_codesniffer": "^4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
"dev-master": "1.3-dev"
}
},
"autoload": {
@@ -1127,7 +1127,7 @@
],
"support": {
"issues": "https://github.com/fruitcake/php-cors/issues",
"source": "https://github.com/fruitcake/php-cors/tree/v1.3.0"
"source": "https://github.com/fruitcake/php-cors/tree/v1.4.0"
},
"funding": [
{
@@ -1139,7 +1139,7 @@
"type": "github"
}
],
"time": "2023-10-12T05:21:21+00:00"
"time": "2025-12-03T09:33:47+00:00"
},
{
"name": "gdbots/query-parser",
@@ -1938,16 +1938,16 @@
},
{
"name": "laravel/framework",
"version": "v12.40.2",
"version": "v12.41.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "1ccd99220b474500e672b373f32bd709ec38de50"
"reference": "3e229b05935fd0300c632fb1f718c73046d664fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/1ccd99220b474500e672b373f32bd709ec38de50",
"reference": "1ccd99220b474500e672b373f32bd709ec38de50",
"url": "https://api.github.com/repos/laravel/framework/zipball/3e229b05935fd0300c632fb1f718c73046d664fc",
"reference": "3e229b05935fd0300c632fb1f718c73046d664fc",
"shasum": ""
},
"require": {
@@ -2153,7 +2153,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-11-26T19:24:25+00:00"
"time": "2025-12-03T01:02:13+00:00"
},
{
"name": "laravel/passport",
@@ -3543,22 +3543,22 @@
},
{
"name": "mailersend/laravel-driver",
"version": "v2.12.0",
"version": "v2.9.1",
"source": {
"type": "git",
"url": "https://github.com/mailersend/mailersend-laravel-driver.git",
"reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
"reference": "87fd5ab76808bbaac9221be0d306baef13e98725"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
"reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
"url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725",
"reference": "87fd5ab76808bbaac9221be0d306baef13e98725",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0",
"mailersend/mailersend": "^0.35.0",
"mailersend/mailersend": "^0.31.0",
"nyholm/psr7": "^1.5",
"php": ">=8.0",
"php-http/guzzle7-adapter": "^1.0",
@@ -3606,28 +3606,29 @@
],
"support": {
"issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
"source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
"source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1"
},
"time": "2025-10-28T14:59:16+00:00"
"time": "2025-04-09T09:33:07+00:00"
},
{
"name": "mailersend/mailersend",
"version": "v0.35.0",
"version": "v0.31.0",
"source": {
"type": "git",
"url": "https://github.com/mailersend/mailersend-php.git",
"reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
"reference": "513ff83ee768526055ad52987cde401ea7218c67"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
"reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
"url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67",
"reference": "513ff83ee768526055ad52987cde401ea7218c67",
"shasum": ""
},
"require": {
"beberlei/assert": "^3.2",
"ext-json": "*",
"php": "^7.4 || ^8.0 <8.5",
"illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
"php": "^7.4|^8.0",
"php-http/client-common": "^2.2",
"php-http/discovery": "^1.9",
"php-http/httplug": "^2.1",
@@ -3672,9 +3673,9 @@
],
"support": {
"issues": "https://github.com/mailersend/mailersend-php/issues",
"source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
"source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0"
},
"time": "2025-10-28T13:11:43+00:00"
"time": "2025-04-03T12:16:11+00:00"
},
{
"name": "monolog/monolog",
@@ -3781,16 +3782,16 @@
},
{
"name": "nesbot/carbon",
"version": "3.10.3",
"version": "3.11.0",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon.git",
"reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f"
"reference": "bdb375400dcd162624531666db4799b36b64e4a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f",
"reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1",
"reference": "bdb375400dcd162624531666db4799b36b64e4a1",
"shasum": ""
},
"require": {
@@ -3798,9 +3799,9 @@
"ext-json": "*",
"php": "^8.1",
"psr/clock": "^1.0",
"symfony/clock": "^6.3.12 || ^7.0",
"symfony/clock": "^6.3.12 || ^7.0 || ^8.0",
"symfony/polyfill-mbstring": "^1.0",
"symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0"
"symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0"
},
"provide": {
"psr/clock-implementation": "1.0"
@@ -3882,7 +3883,7 @@
"type": "tidelift"
}
],
"time": "2025-09-06T13:39:36+00:00"
"time": "2025-12-02T21:04:28+00:00"
},
{
"name": "nette/schema",
@@ -3951,20 +3952,20 @@
},
{
"name": "nette/utils",
"version": "v4.0.9",
"version": "v4.1.0",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "505a30ad386daa5211f08a318e47015b501cad30"
"reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/505a30ad386daa5211f08a318e47015b501cad30",
"reference": "505a30ad386daa5211f08a318e47015b501cad30",
"url": "https://api.github.com/repos/nette/utils/zipball/fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
"reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
"shasum": ""
},
"require": {
"php": "8.0 - 8.5"
"php": "8.2 - 8.5"
},
"conflict": {
"nette/finder": "<3",
@@ -3987,7 +3988,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
"dev-master": "4.1-dev"
}
},
"autoload": {
@@ -4034,9 +4035,9 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.9"
"source": "https://github.com/nette/utils/tree/v4.1.0"
},
"time": "2025-10-31T00:45:47+00:00"
"time": "2025-12-01T17:49:23+00:00"
},
{
"name": "nunomaduro/collision",
@@ -4423,16 +4424,16 @@
},
{
"name": "php-http/client-common",
"version": "2.7.2",
"version": "2.7.3",
"source": {
"type": "git",
"url": "https://github.com/php-http/client-common.git",
"reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46"
"reference": "dcc6de29c90dd74faab55f71b79d89409c4bf0c1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-http/client-common/zipball/0cfe9858ab9d3b213041b947c881d5b19ceeca46",
"reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46",
"url": "https://api.github.com/repos/php-http/client-common/zipball/dcc6de29c90dd74faab55f71b79d89409c4bf0c1",
"reference": "dcc6de29c90dd74faab55f71b79d89409c4bf0c1",
"shasum": ""
},
"require": {
@@ -4442,15 +4443,13 @@
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0 || ^2.0",
"symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0",
"symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0 || ^8.0",
"symfony/polyfill-php80": "^1.17"
},
"require-dev": {
"doctrine/instantiator": "^1.1",
"guzzlehttp/psr7": "^1.4",
"nyholm/psr7": "^1.2",
"phpspec/phpspec": "^5.1 || ^6.3 || ^7.1",
"phpspec/prophecy": "^1.10.2",
"phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7"
},
"suggest": {
@@ -4486,9 +4485,9 @@
],
"support": {
"issues": "https://github.com/php-http/client-common/issues",
"source": "https://github.com/php-http/client-common/tree/2.7.2"
"source": "https://github.com/php-http/client-common/tree/2.7.3"
},
"time": "2024-09-24T06:21:48+00:00"
"time": "2025-11-29T19:12:34+00:00"
},
{
"name": "php-http/discovery",
@@ -5973,16 +5972,16 @@
},
{
"name": "sentry/sentry",
"version": "4.19.0",
"version": "4.19.1",
"source": {
"type": "git",
"url": "https://github.com/getsentry/sentry-php.git",
"reference": "1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053"
"reference": "1c21d60bebe67c0122335bd3fe977990435af0a3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053",
"reference": "1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053",
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/1c21d60bebe67c0122335bd3fe977990435af0a3",
"reference": "1c21d60bebe67c0122335bd3fe977990435af0a3",
"shasum": ""
},
"require": {
@@ -6045,7 +6044,7 @@
],
"support": {
"issues": "https://github.com/getsentry/sentry-php/issues",
"source": "https://github.com/getsentry/sentry-php/tree/4.19.0"
"source": "https://github.com/getsentry/sentry-php/tree/4.19.1"
},
"funding": [
{
@@ -6057,27 +6056,27 @@
"type": "custom"
}
],
"time": "2025-11-27T14:53:55+00:00"
"time": "2025-12-02T15:57:41+00:00"
},
{
"name": "sentry/sentry-laravel",
"version": "4.19.0",
"version": "4.20.0",
"source": {
"type": "git",
"url": "https://github.com/getsentry/sentry-laravel.git",
"reference": "7fdffd57e8fff0a6f9a18d9a83f32e960af63e3f"
"reference": "95f2542ee1ebc993529b63f5c8543184abd00650"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/7fdffd57e8fff0a6f9a18d9a83f32e960af63e3f",
"reference": "7fdffd57e8fff0a6f9a18d9a83f32e960af63e3f",
"url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/95f2542ee1ebc993529b63f5c8543184abd00650",
"reference": "95f2542ee1ebc993529b63f5c8543184abd00650",
"shasum": ""
},
"require": {
"illuminate/support": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 | ^12.0",
"nyholm/psr7": "^1.0",
"php": "^7.2 | ^8.0",
"sentry/sentry": "^4.18.0",
"sentry/sentry": "^4.19.0",
"symfony/psr-http-message-bridge": "^1.0 | ^2.0 | ^6.0 | ^7.0"
},
"require-dev": {
@@ -6135,7 +6134,7 @@
],
"support": {
"issues": "https://github.com/getsentry/sentry-laravel/issues",
"source": "https://github.com/getsentry/sentry-laravel/tree/4.19.0"
"source": "https://github.com/getsentry/sentry-laravel/tree/4.20.0"
},
"funding": [
{
@@ -6147,7 +6146,7 @@
"type": "custom"
}
],
"time": "2025-11-11T09:01:14+00:00"
"time": "2025-12-02T10:37:40+00:00"
},
{
"name": "spatie/backtrace",
@@ -6840,22 +6839,21 @@
},
{
"name": "symfony/clock",
"version": "v7.4.0",
"version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/clock.git",
"reference": "9169f24776edde469914c1e7a1442a50f7a4e110"
"reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/clock/zipball/9169f24776edde469914c1e7a1442a50f7a4e110",
"reference": "9169f24776edde469914c1e7a1442a50f7a4e110",
"url": "https://api.github.com/repos/symfony/clock/zipball/832119f9b8dbc6c8e6f65f30c5969eca1e88764f",
"reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f",
"shasum": ""
},
"require": {
"php": ">=8.2",
"psr/clock": "^1.0",
"symfony/polyfill-php83": "^1.28"
"php": ">=8.4",
"psr/clock": "^1.0"
},
"provide": {
"psr/clock-implementation": "1.0"
@@ -6894,7 +6892,7 @@
"time"
],
"support": {
"source": "https://github.com/symfony/clock/tree/v7.4.0"
"source": "https://github.com/symfony/clock/tree/v8.0.0"
},
"funding": [
{
@@ -6914,7 +6912,7 @@
"type": "tidelift"
}
],
"time": "2025-11-12T15:39:26+00:00"
"time": "2025-11-12T15:46:48+00:00"
},
{
"name": "symfony/console",
@@ -7395,22 +7393,21 @@
},
{
"name": "symfony/expression-language",
"version": "v7.4.0",
"version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/expression-language.git",
"reference": "8b9bbbb8c71f79a09638f6ea77c531e511139efa"
"reference": "43f520aef59d2fd089662d721b39e0101bb69232"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/expression-language/zipball/8b9bbbb8c71f79a09638f6ea77c531e511139efa",
"reference": "8b9bbbb8c71f79a09638f6ea77c531e511139efa",
"url": "https://api.github.com/repos/symfony/expression-language/zipball/43f520aef59d2fd089662d721b39e0101bb69232",
"reference": "43f520aef59d2fd089662d721b39e0101bb69232",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/cache": "^6.4|^7.0|^8.0",
"symfony/deprecation-contracts": "^2.5|^3",
"php": ">=8.4",
"symfony/cache": "^7.4|^8.0",
"symfony/service-contracts": "^2.5|^3"
},
"type": "library",
@@ -7439,7 +7436,7 @@
"description": "Provides an engine that can compile and evaluate expressions",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/expression-language/tree/v7.4.0"
"source": "https://github.com/symfony/expression-language/tree/v8.0.0"
},
"funding": [
{
@@ -7459,7 +7456,7 @@
"type": "tidelift"
}
],
"time": "2025-11-12T15:39:26+00:00"
"time": "2025-11-12T15:46:48+00:00"
},
{
"name": "symfony/finder",
@@ -7531,31 +7528,27 @@
},
{
"name": "symfony/http-client",
"version": "v7.4.0",
"version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "ee5e0e0139ab506f6063a230e631bed677c650a4"
"reference": "b4be9eb608f5c7544e448908fb30472da77a975f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/ee5e0e0139ab506f6063a230e631bed677c650a4",
"reference": "ee5e0e0139ab506f6063a230e631bed677c650a4",
"url": "https://api.github.com/repos/symfony/http-client/zipball/b4be9eb608f5c7544e448908fb30472da77a975f",
"reference": "b4be9eb608f5c7544e448908fb30472da77a975f",
"shasum": ""
},
"require": {
"php": ">=8.2",
"php": ">=8.4",
"psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/http-client-contracts": "~3.4.4|^3.5.2",
"symfony/polyfill-php83": "^1.29",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
"amphp/amp": "<2.5",
"amphp/socket": "<1.1",
"php-http/discovery": "<1.15",
"symfony/http-foundation": "<6.4"
"amphp/amp": "<3",
"php-http/discovery": "<1.15"
},
"provide": {
"php-http/async-client-implementation": "*",
@@ -7564,20 +7557,19 @@
"symfony/http-client-implementation": "3.0"
},
"require-dev": {
"amphp/http-client": "^4.2.1|^5.0",
"amphp/http-tunnel": "^1.0|^2.0",
"amphp/http-client": "^5.3.2",
"amphp/http-tunnel": "^2.0",
"guzzlehttp/promises": "^1.4|^2.0",
"nyholm/psr7": "^1.0",
"php-http/httplug": "^1.0|^2.0",
"psr/http-client": "^1.0",
"symfony/amphp-http-client-meta": "^1.0|^2.0",
"symfony/cache": "^6.4|^7.0|^8.0",
"symfony/dependency-injection": "^6.4|^7.0|^8.0",
"symfony/http-kernel": "^6.4|^7.0|^8.0",
"symfony/messenger": "^6.4|^7.0|^8.0",
"symfony/process": "^6.4|^7.0|^8.0",
"symfony/rate-limiter": "^6.4|^7.0|^8.0",
"symfony/stopwatch": "^6.4|^7.0|^8.0"
"symfony/cache": "^7.4|^8.0",
"symfony/dependency-injection": "^7.4|^8.0",
"symfony/http-kernel": "^7.4|^8.0",
"symfony/messenger": "^7.4|^8.0",
"symfony/process": "^7.4|^8.0",
"symfony/rate-limiter": "^7.4|^8.0",
"symfony/stopwatch": "^7.4|^8.0"
},
"type": "library",
"autoload": {
@@ -7608,7 +7600,7 @@
"http"
],
"support": {
"source": "https://github.com/symfony/http-client/tree/v7.4.0"
"source": "https://github.com/symfony/http-client/tree/v8.0.0"
},
"funding": [
{
@@ -7628,7 +7620,7 @@
"type": "tidelift"
}
],
"time": "2025-11-20T12:32:50+00:00"
"time": "2025-11-20T12:42:53+00:00"
},
{
"name": "symfony/http-client-contracts",
@@ -7995,28 +7987,25 @@
},
{
"name": "symfony/mailgun-mailer",
"version": "v7.4.0",
"version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailgun-mailer.git",
"reference": "ffbcdbf93ed0700f083a6307acfb8f78dd3f091b"
"reference": "c8567e2b9a64db3aebd701838402a3726061c36a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/ffbcdbf93ed0700f083a6307acfb8f78dd3f091b",
"reference": "ffbcdbf93ed0700f083a6307acfb8f78dd3f091b",
"url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/c8567e2b9a64db3aebd701838402a3726061c36a",
"reference": "c8567e2b9a64db3aebd701838402a3726061c36a",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/mailer": "^7.2|^8.0"
},
"conflict": {
"symfony/http-foundation": "<6.4"
"php": ">=8.4",
"symfony/mailer": "^7.4|^8.0"
},
"require-dev": {
"symfony/http-client": "^6.4|^7.0|^8.0",
"symfony/webhook": "^6.4|^7.0|^8.0"
"symfony/http-client": "^7.4|^8.0",
"symfony/webhook": "^7.4|^8.0"
},
"type": "symfony-mailer-bridge",
"autoload": {
@@ -8044,7 +8033,7 @@
"description": "Symfony Mailgun Mailer Bridge",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailgun-mailer/tree/v7.4.0"
"source": "https://github.com/symfony/mailgun-mailer/tree/v8.0.0"
},
"funding": [
{
@@ -8064,7 +8053,7 @@
"type": "tidelift"
}
],
"time": "2025-08-04T07:05:15+00:00"
"time": "2025-08-04T07:36:47+00:00"
},
{
"name": "symfony/mime",
@@ -9472,34 +9461,27 @@
},
{
"name": "symfony/translation",
"version": "v7.4.0",
"version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68"
"reference": "82ab368a6fca6358d995b6dd5c41590fb42c03e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/2d01ca0da3f092f91eeedb46f24aa30d2fca8f68",
"reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68",
"url": "https://api.github.com/repos/symfony/translation/zipball/82ab368a6fca6358d995b6dd5c41590fb42c03e6",
"reference": "82ab368a6fca6358d995b6dd5c41590fb42c03e6",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/translation-contracts": "^2.5.3|^3.3"
"php": ">=8.4",
"symfony/polyfill-mbstring": "^1.0",
"symfony/translation-contracts": "^3.6.1"
},
"conflict": {
"nikic/php-parser": "<5.0",
"symfony/config": "<6.4",
"symfony/console": "<6.4",
"symfony/dependency-injection": "<6.4",
"symfony/http-client-contracts": "<2.5",
"symfony/http-kernel": "<6.4",
"symfony/service-contracts": "<2.5",
"symfony/twig-bundle": "<6.4",
"symfony/yaml": "<6.4"
"symfony/service-contracts": "<2.5"
},
"provide": {
"symfony/translation-implementation": "2.3|3.0"
@@ -9507,17 +9489,17 @@
"require-dev": {
"nikic/php-parser": "^5.0",
"psr/log": "^1|^2|^3",
"symfony/config": "^6.4|^7.0|^8.0",
"symfony/console": "^6.4|^7.0|^8.0",
"symfony/dependency-injection": "^6.4|^7.0|^8.0",
"symfony/finder": "^6.4|^7.0|^8.0",
"symfony/config": "^7.4|^8.0",
"symfony/console": "^7.4|^8.0",
"symfony/dependency-injection": "^7.4|^8.0",
"symfony/finder": "^7.4|^8.0",
"symfony/http-client-contracts": "^2.5|^3.0",
"symfony/http-kernel": "^6.4|^7.0|^8.0",
"symfony/intl": "^6.4|^7.0|^8.0",
"symfony/http-kernel": "^7.4|^8.0",
"symfony/intl": "^7.4|^8.0",
"symfony/polyfill-intl-icu": "^1.21",
"symfony/routing": "^6.4|^7.0|^8.0",
"symfony/routing": "^7.4|^8.0",
"symfony/service-contracts": "^2.5|^3",
"symfony/yaml": "^6.4|^7.0|^8.0"
"symfony/yaml": "^7.4|^8.0"
},
"type": "library",
"autoload": {
@@ -9548,7 +9530,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/translation/tree/v7.4.0"
"source": "https://github.com/symfony/translation/tree/v8.0.0"
},
"funding": [
{
@@ -9568,7 +9550,7 @@
"type": "tidelift"
}
],
"time": "2025-11-27T13:27:24+00:00"
"time": "2025-11-27T08:09:45+00:00"
},
{
"name": "symfony/translation-contracts",
@@ -10093,16 +10075,16 @@
},
{
"name": "twig/twig",
"version": "v3.22.0",
"version": "v3.22.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "4509984193026de413baf4ba80f68590a7f2c51d"
"reference": "1de2ec1fc43ab58a4b7e80b214b96bfc895750f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/4509984193026de413baf4ba80f68590a7f2c51d",
"reference": "4509984193026de413baf4ba80f68590a7f2c51d",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/1de2ec1fc43ab58a4b7e80b214b96bfc895750f3",
"reference": "1de2ec1fc43ab58a4b7e80b214b96bfc895750f3",
"shasum": ""
},
"require": {
@@ -10156,7 +10138,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.22.0"
"source": "https://github.com/twigphp/Twig/tree/v3.22.1"
},
"funding": [
{
@@ -10168,7 +10150,7 @@
"type": "tidelift"
}
],
"time": "2025-10-29T15:56:47+00:00"
"time": "2025-11-16T16:01:12+00:00"
},
{
"name": "vlucas/phpdotenv",
@@ -10769,16 +10751,16 @@
},
{
"name": "driftingly/rector-laravel",
"version": "2.1.3",
"version": "2.1.6",
"source": {
"type": "git",
"url": "https://github.com/driftingly/rector-laravel.git",
"reference": "2f1e9c3997bf45592d58916f0cedd775e844b9c6"
"reference": "682d1e73ac79aced7e645141fd61a9ac468a0c44"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/2f1e9c3997bf45592d58916f0cedd775e844b9c6",
"reference": "2f1e9c3997bf45592d58916f0cedd775e844b9c6",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/682d1e73ac79aced7e645141fd61a9ac468a0c44",
"reference": "682d1e73ac79aced7e645141fd61a9ac468a0c44",
"shasum": ""
},
"require": {
@@ -10799,9 +10781,9 @@
"description": "Rector upgrades rules for Laravel Framework",
"support": {
"issues": "https://github.com/driftingly/rector-laravel/issues",
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.3"
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.6"
},
"time": "2025-11-04T18:32:57+00:00"
"time": "2025-12-04T13:37:33+00:00"
},
{
"name": "fakerphp/faker",
@@ -11258,16 +11240,16 @@
},
{
"name": "nikic/php-parser",
"version": "v5.6.2",
"version": "v5.7.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "3a454ca033b9e06b63282ce19562e892747449bb"
"reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
"reference": "3a454ca033b9e06b63282ce19562e892747449bb",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
"reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
"shasum": ""
},
"require": {
@@ -11310,9 +11292,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
},
"time": "2025-10-21T19:32:17+00:00"
"time": "2025-12-06T11:56:16+00:00"
},
{
"name": "phar-io/manifest",
@@ -11555,11 +11537,11 @@
},
{
"name": "phpstan/phpstan",
"version": "2.1.32",
"version": "2.1.33",
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227",
"reference": "e126cad1e30a99b137b8ed75a85a676450ebb227",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f",
"reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f",
"shasum": ""
},
"require": {
@@ -11604,7 +11586,7 @@
"type": "github"
}
],
"time": "2025-11-11T15:18:17+00:00"
"time": "2025-12-05T10:24:31+00:00"
},
{
"name": "phpstan/phpstan-deprecation-rules",
@@ -11703,23 +11685,23 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "12.4.0",
"version": "12.5.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c"
"reference": "bca180c050dd3ae15f87c26d25cabb34fe1a0a5a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c",
"reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bca180c050dd3ae15f87c26d25cabb34fe1a0a5a",
"reference": "bca180c050dd3ae15f87c26d25cabb34fe1a0a5a",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
"nikic/php-parser": "^5.6.1",
"nikic/php-parser": "^5.6.2",
"php": ">=8.3",
"phpunit/php-file-iterator": "^6.0",
"phpunit/php-text-template": "^5.0",
@@ -11727,10 +11709,10 @@
"sebastian/environment": "^8.0.3",
"sebastian/lines-of-code": "^4.0",
"sebastian/version": "^6.0",
"theseer/tokenizer": "^1.2.3"
"theseer/tokenizer": "^1.3.1"
},
"require-dev": {
"phpunit/phpunit": "^12.3.7"
"phpunit/phpunit": "^12.4.4"
},
"suggest": {
"ext-pcov": "PHP extension that provides line coverage",
@@ -11739,7 +11721,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "12.4.x-dev"
"dev-main": "12.5.x-dev"
}
},
"autoload": {
@@ -11768,7 +11750,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.4.0"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.0"
},
"funding": [
{
@@ -11788,7 +11770,7 @@
"type": "tidelift"
}
],
"time": "2025-09-24T13:44:41+00:00"
"time": "2025-11-29T07:15:54+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -12037,16 +12019,16 @@
},
{
"name": "phpunit/phpunit",
"version": "12.4.4",
"version": "12.5.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7"
"reference": "e33a5132ea24119400f6ce5bce6665922e968bad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9253ec75a672e39fcc9d85bdb61448215b8162c7",
"reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e33a5132ea24119400f6ce5bce6665922e968bad",
"reference": "e33a5132ea24119400f6ce5bce6665922e968bad",
"shasum": ""
},
"require": {
@@ -12060,7 +12042,7 @@
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=8.3",
"phpunit/php-code-coverage": "^12.4.0",
"phpunit/php-code-coverage": "^12.5.0",
"phpunit/php-file-iterator": "^6.0.0",
"phpunit/php-invoker": "^6.0.0",
"phpunit/php-text-template": "^5.0.0",
@@ -12082,7 +12064,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "12.4-dev"
"dev-main": "12.5-dev"
}
},
"autoload": {
@@ -12114,7 +12096,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.4.4"
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.1"
},
"funding": [
{
@@ -12138,20 +12120,20 @@
"type": "tidelift"
}
],
"time": "2025-11-21T07:39:11+00:00"
"time": "2025-12-06T12:19:17+00:00"
},
{
"name": "rector/rector",
"version": "2.2.9",
"version": "2.2.11",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
"reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05"
"reference": "7bd21a40b0332b93d4bfee284093d7400696902d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/0b8e49ec234877b83244d2ecd0df7a4c16471f05",
"reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/7bd21a40b0332b93d4bfee284093d7400696902d",
"reference": "7bd21a40b0332b93d4bfee284093d7400696902d",
"shasum": ""
},
"require": {
@@ -12190,7 +12172,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/2.2.9"
"source": "https://github.com/rectorphp/rector/tree/2.2.11"
},
"funding": [
{
@@ -12198,7 +12180,7 @@
"type": "github"
}
],
"time": "2025-11-28T14:21:22+00:00"
"time": "2025-12-02T11:23:46+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2025-11-28',
'build_time' => 1764353187,
'version' => 'develop/2025-12-06',
'build_time' => 1765004025,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

345
package-lock.json generated
View File

@@ -4075,9 +4075,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.8.32",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz",
"integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==",
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.3.tgz",
"integrity": "sha512-8QdH6czo+G7uBsNo0GiUfouPN1lRzKdJTGnKXwe12gkFbnnOUaUKGN55dMkfy+mnxmvjwl9zcI4VncczcVXDhA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -4129,24 +4129,24 @@
"license": "MIT"
},
"node_modules/body-parser": {
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"version": "1.20.4",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
"integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
"dev": true,
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"bytes": "~3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.13.0",
"raw-body": "2.5.2",
"destroy": "~1.2.0",
"http-errors": "~2.0.1",
"iconv-lite": "~0.4.24",
"on-finished": "~2.4.1",
"qs": "~6.14.0",
"raw-body": "~2.5.3",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8",
@@ -4170,22 +4170,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/body-parser/node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/bonjour-service": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz",
@@ -4237,9 +4221,9 @@
"license": "MIT"
},
"node_modules/bootstrap5-tags": {
"version": "1.7.15",
"resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.7.15.tgz",
"integrity": "sha512-UnHmJC9p0ei5rZG1/5qOFBoKFJ+ZyXiVTi1+fJnN/+6d/htZZ9M4cALxsjxQR53K2PrOSApMBOR2QZDbIkdK+g==",
"version": "1.7.16",
"resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.7.16.tgz",
"integrity": "sha512-P5guDQc+DVFJFK0+udbBRgapRnU6dWWhi4FcuAoMOEX7JdhqW/WB0xUxZGOa338odYIi1HogYN/b24yvJpAxfw==",
"license": "MIT"
},
"node_modules/brace-expansion": {
@@ -4360,9 +4344,9 @@
}
},
"node_modules/browserslist": {
"version": "4.28.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
"integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==",
"version": "4.28.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
"dev": true,
"funding": [
{
@@ -4380,11 +4364,11 @@
],
"license": "MIT",
"dependencies": {
"baseline-browser-mapping": "^2.8.25",
"caniuse-lite": "^1.0.30001754",
"electron-to-chromium": "^1.5.249",
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
"electron-to-chromium": "^1.5.263",
"node-releases": "^2.0.27",
"update-browserslist-db": "^1.1.4"
"update-browserslist-db": "^1.2.0"
},
"bin": {
"browserslist": "cli.js"
@@ -4521,9 +4505,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001757",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
"integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==",
"version": "1.0.30001759",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz",
"integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==",
"dev": true,
"funding": [
{
@@ -4949,9 +4933,9 @@
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4959,9 +4943,9 @@
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
"dev": true,
"license": "MIT"
},
@@ -5736,9 +5720,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
"version": "1.5.262",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz",
"integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==",
"version": "1.5.266",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz",
"integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==",
"dev": true,
"license": "ISC"
},
@@ -6084,40 +6068,40 @@
}
},
"node_modules/express": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"version": "4.22.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
"dev": true,
"license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"body-parser": "~1.20.3",
"content-disposition": "~0.5.4",
"content-type": "~1.0.4",
"cookie": "0.7.1",
"cookie-signature": "1.0.6",
"cookie": "~0.7.1",
"cookie-signature": "~1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"finalhandler": "~1.3.1",
"fresh": "~0.5.2",
"http-errors": "~2.0.0",
"merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"on-finished": "~2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.12",
"path-to-regexp": "~0.1.12",
"proxy-addr": "~2.0.7",
"qs": "6.13.0",
"qs": "~6.14.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.19.0",
"serve-static": "1.16.2",
"send": "~0.19.0",
"serve-static": "~1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"statuses": "~2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
@@ -6147,22 +6131,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/express/node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -6308,18 +6276,18 @@
}
},
"node_modules/finalhandler": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
"integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"on-finished": "~2.4.1",
"parseurl": "~1.3.3",
"statuses": "2.0.1",
"statuses": "~2.0.2",
"unpipe": "~1.0.0"
},
"engines": {
@@ -7007,20 +6975,24 @@
"license": "MIT"
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
"depd": "~2.0.0",
"inherits": "~2.0.4",
"setprototypeof": "~1.2.0",
"statuses": "~2.0.2",
"toidentifier": "~1.0.1"
},
"engines": {
"node": ">= 0.8"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/http-parser-js": {
@@ -7088,9 +7060,9 @@
}
},
"node_modules/i18next": {
"version": "25.6.3",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.3.tgz",
"integrity": "sha512-AEQvoPDljhp67a1+NsnG/Wb1Nh6YoSvtrmeEd24sfGn3uujCtXCF3cXpr7ulhMywKNFF7p3TX1u2j7y+caLOJg==",
"version": "25.7.1",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.1.tgz",
"integrity": "sha512-XbTnkh1yCZWSAZGnA9xcQfHcYNgZs2cNxm+c6v1Ma9UAUGCeJPplRe1ILia6xnDvXBjk0uXU+Z8FYWhA19SKFw==",
"funding": [
{
"type": "individual",
@@ -7137,12 +7109,12 @@
}
},
"node_modules/i18next-localstorage-backend": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/i18next-localstorage-backend/-/i18next-localstorage-backend-4.2.0.tgz",
"integrity": "sha512-vglEQF0AnLriX7dLA2drHnqAYzHxnLwWQzBDw8YxcIDjOvYZz5rvpal59Dq4In+IHNmGNM32YgF0TDjBT0fHmA==",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/i18next-localstorage-backend/-/i18next-localstorage-backend-4.3.1.tgz",
"integrity": "sha512-ry8WNBanUs55rsRZs9+xaZWRxCoTEMMOf+2vNSfzzJqDPbHaf0eMFMrtYp/2ocxU6Xrxfwz17Fdz0rSs3Kw39Q==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.22.15"
"@babel/runtime": "^7.28.4"
}
},
"node_modules/iconv-lite": {
@@ -8400,9 +8372,9 @@
}
},
"node_modules/node-forge": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
"integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==",
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz",
"integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==",
"dev": true,
"license": "(BSD-3-Clause OR GPL-2.0)",
"engines": {
@@ -9808,16 +9780,16 @@
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
"integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
"bytes": "~3.1.2",
"http-errors": "~2.0.1",
"iconv-lite": "~0.4.24",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
@@ -10307,16 +10279,16 @@
}
},
"node_modules/send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.1.tgz",
"integrity": "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
@@ -10348,10 +10320,27 @@
"dev": true,
"license": "MIT"
},
"node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"node_modules/send/node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/send/node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10470,6 +10459,85 @@
"node": ">= 0.8.0"
}
},
"node_modules/serve-static/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/serve-static/node_modules/debug/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true,
"license": "MIT"
},
"node_modules/serve-static/node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/serve-static/node_modules/send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "2.4.1",
"range-parser": "~1.2.1",
"statuses": "2.0.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/serve-static/node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/serve-static/node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
@@ -10778,9 +10846,9 @@
"license": "MIT"
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -11027,9 +11095,9 @@
}
},
"node_modules/terser-webpack-plugin": {
"version": "5.3.14",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
"integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
"version": "5.3.15",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.15.tgz",
"integrity": "sha512-PGkOdpRFK+rb1TzVz+msVhw4YMRT9txLF4kRqvJhGhCM324xuR3REBSHALN+l+sAhKUmz0aotnjp5D+P83mLhQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11391,9 +11459,9 @@
}
},
"node_modules/update-browserslist-db": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
"integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
"integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==",
"dev": true,
"funding": [
{
@@ -11517,9 +11585,9 @@
}
},
"node_modules/vite": {
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz",
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz",
"integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12438,9 +12506,9 @@
"license": "ISC"
},
"node_modules/yaml": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
"dev": true,
"license": "ISC",
"bin": {
@@ -12448,6 +12516,9 @@
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/yargs": {

View File

@@ -366,13 +366,21 @@
</span>
<br/>
{% endif %}
{% if spentInfo.currency_id == budgetLimit.currency_id and not budgetLimit.in_range %}
{% if spentInfo.currency_id == budgetLimit.currency_id and not budgetLimit.in_range and 0.0 == budgetLimit.total_days %}
<span class="left_span" data-currency="{{ spentInfo.currency_id }}" data-limit="{{ budgetLimit.id }}"
data-value="{{ spentInfo.spent + budgetLimit.amount }}" class="amount_left">
{{ formatAmountBySymbol(spentInfo.spent + budgetLimit.amount, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }}
</span>
<span class="text-muted">({{ 'unknown'|_ }})</span>
{% endif %}
{% if spentInfo.currency_id == budgetLimit.currency_id and not budgetLimit.in_range and 0.0 != budgetLimit.total_days %}
<span class="left_span" data-currency="{{ spentInfo.currency_id }}" data-limit="{{ budgetLimit.id }}"
data-value="{{ spentInfo.spent + budgetLimit.amount }}" class="amount_left">
{{ formatAmountBySymbol(spentInfo.spent + budgetLimit.amount, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }}
</span>
({{ formatAmountBySymbol((spentInfo.spent + budgetLimit.amount) / budgetLimit.total_days, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }})
{% endif %}
{% endfor %}
{% if countLimit == 0 %}