Compare commits

...

29 Commits

Author SHA1 Message Date
github-actions[bot]
d96c7931d6 Merge pull request #11494 from firefly-iii/release-1768053858
🤖 Automatically merge the PR into the develop branch.
2026-01-10 15:04:28 +01:00
JC5
2ab105a902 🤖 Auto commit for release 'develop' on 2026-01-10 2026-01-10 15:04:18 +01:00
James Cole
7ced1f8cf3 Add debug logging for https://github.com/orgs/firefly-iii/discussions/11431 2026-01-10 14:35:14 +01:00
James Cole
03364d9530 More strict check on transaction journal type. 2026-01-10 08:19:10 +01:00
James Cole
1f75612741 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2026-01-10 08:16:47 +01:00
James Cole
a141cf6e67 Remove bills from transfers in more places. 2026-01-10 08:16:41 +01:00
James Cole
c97fb07e8d Group tags by date. 2026-01-10 07:37:22 +01:00
James Cole
9833dd49a9 Merge pull request #11483 from pilipovicn/add-rsd-currency 2026-01-09 11:59:26 +01:00
embedded
b76f4fe7b9 Add Serbian Dinar to Currency Seeder 2026-01-09 11:32:04 +01:00
James Cole
6c114e2ffc Throw better error 2026-01-09 06:07:50 +01:00
James Cole
bd396673ed Fix bad header exception. 2026-01-09 05:58:05 +01:00
James Cole
ad72bc1722 Fix #11479 2026-01-09 05:57:55 +01:00
James Cole
466b42200d Fix #11473 2026-01-07 20:53:44 +01:00
github-actions[bot]
067112904e Merge pull request #11467 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2026-01-06 21:05:43 +01:00
github-actions[bot]
fc371e27b7 Merge pull request #11466 from firefly-iii/release-1767729927
🤖 Automatically merge the PR into the develop branch.
2026-01-06 21:05:36 +01:00
JC5
52b14b46a2 🤖 Auto commit for release 'v6.4.15' on 2026-01-06 2026-01-06 21:05:27 +01:00
James Cole
5260b770bb Clean up changelog. 2026-01-06 21:01:07 +01:00
github-actions[bot]
226c4c8f8e Merge pull request #11464 from firefly-iii/release-1767729551
🤖 Automatically merge the PR into the develop branch.
2026-01-06 20:59:17 +01:00
JC5
9ebafe64f1 🤖 Auto commit for release 'develop' on 2026-01-06 2026-01-06 20:59:11 +01:00
James Cole
ffa618101d Update changelog. 2026-01-06 20:55:08 +01:00
James Cole
280e531a76 Fix #11396 2026-01-06 20:43:11 +01:00
James Cole
f542a3fd88 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2026-01-06 20:38:46 +01:00
James Cole
581d67a92c Fix #11399 2026-01-06 20:38:41 +01:00
github-actions[bot]
a00e8b976c Merge pull request #11458 from firefly-iii/release-1767598313
🤖 Automatically merge the PR into the develop branch.
2026-01-05 08:32:02 +01:00
JC5
e5b3c3e6bd 🤖 Auto commit for release 'develop' on 2026-01-05 2026-01-05 08:31:53 +01:00
James Cole
4d7f63273e Fix #11449 2026-01-04 20:21:41 +01:00
James Cole
04553f6fc5 Fix #11443 2026-01-03 14:46:39 +01:00
James Cole
54676715c0 Create new request for search. 2026-01-02 16:38:46 +01:00
github-actions[bot]
637d8e050a Merge pull request #11376 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2025-12-16 06:42:25 +01:00
32 changed files with 481 additions and 202 deletions

View File

@@ -402,16 +402,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.92.3",
"version": "v3.92.5",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8"
"reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8",
"reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58",
"reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58",
"shasum": ""
},
"require": {
@@ -443,17 +443,17 @@
},
"require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7",
"infection/infection": "^0.31.0",
"justinrainbow/json-schema": "^6.5",
"keradus/cli-executor": "^2.2",
"infection/infection": "^0.31",
"justinrainbow/json-schema": "^6.6",
"keradus/cli-executor": "^2.3",
"mikey179/vfsstream": "^1.6.12",
"php-coveralls/php-coveralls": "^2.9",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
"phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34",
"phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.46",
"symfony/polyfill-php85": "^1.33",
"symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2 || ^8.0",
"symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2 || ^8.0"
"symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0",
"symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -494,7 +494,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.92.3"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.5"
},
"funding": [
{
@@ -502,7 +502,7 @@
"type": "github"
}
],
"time": "2025-12-18T10:45:02+00:00"
"time": "2026-01-08T21:57:37+00:00"
},
{
"name": "psr/container",

View File

@@ -3,6 +3,9 @@
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
## 2026
- embedded
## 2025
- Diego Algorta
- Jihad

View File

@@ -25,11 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Search\TransactionSearchRequest;
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
use FireflyIII\Support\Search\SearchInterface;
use FireflyIII\Transformers\TransactionGroupTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection;
@@ -42,12 +42,12 @@ class TransactionController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchTransactions
*/
public function search(Request $request, SearchInterface $searcher): JsonResponse
public function search(TransactionSearchRequest $request, SearchInterface $searcher): JsonResponse
{
$manager = $this->getManager();
$fullQuery = (string) $request->get('query');
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
$pageSize = $this->parameters->get('limit');
$fullQuery = (string) $request->attributes->get('query');
$page = $request->attributes->get('page');
$pageSize = $request->attributes->get('limit');
$searcher->parseQuery($fullQuery);
$searcher->setPage($page);
$searcher->setLimit($pageSize);

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* SearchQueryRequest.php
* Copyright (c) 2026 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\Api\V1\Requests\Search;
use FireflyIII\Api\V1\Requests\ApiRequest;
use Illuminate\Contracts\Validation\Validator;
class SearchQueryRequest extends ApiRequest
{
public function rules(): array
{
return [
'query' => sprintf('min:0|max:500|%s', $this->required),
];
}
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator): void {
if ($validator->failed()) {
return;
}
$query = $this->convertString('query');
$this->attributes->set('query', $query);
}
);
}
}

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/*
* SearchRequest.php
* Copyright (c) 2026 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\Api\V1\Requests\Search;
use FireflyIII\Api\V1\Requests\AggregateFormRequest;
use FireflyIII\Api\V1\Requests\PaginationRequest;
use FireflyIII\Models\TransactionJournal;
use Override;
class TransactionSearchRequest extends AggregateFormRequest
{
#[Override]
protected function getRequests(): array
{
return [
[PaginationRequest::class, 'sort_class' => TransactionJournal::class],
SearchQueryRequest::class,
// [ObjectTypeApiRequest::class, 'object_type' => Account::class],
];
}
}

View File

@@ -34,7 +34,7 @@ class RemovesBills extends Command
{
use ShowsFriendlyMessages;
protected $description = 'Remove bills from transactions that shouldn\'t have one.';
protected $description = 'Remove subscriptions from transactions that shouldn\'t have one.';
protected $signature = 'correction:bills';
/**

View File

@@ -24,15 +24,20 @@ declare(strict_types=1);
namespace FireflyIII\Events\Model\TransactionGroup;
use FireflyIII\Events\Event;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Queue\SerializesModels;
class TriggeredStoredTransactionGroup extends Event
{
use SerializesModels;
public ?RuleGroup $ruleGroup = null;
/**
* Create a new event instance.
*/
public function __construct(public TransactionGroup $transactionGroup) {}
public function __construct(public TransactionGroup $transactionGroup, ?RuleGroup $ruleGroup = null)
{
$this->ruleGroup = $ruleGroup;
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\PeriodStatistic\PeriodStatisticRepositoryInterface;
@@ -46,7 +47,7 @@ class StoredGroupEventHandler
{
public function runAllHandlers(StoredTransactionGroup $event): void
{
$this->processRules($event);
$this->processRules($event, null);
$this->recalculateCredit($event);
$this->triggerWebhooks($event);
$this->removePeriodStatistics($event);
@@ -55,13 +56,13 @@ class StoredGroupEventHandler
public function triggerRulesManually(TriggeredStoredTransactionGroup $event): void
{
$newEvent = new StoredTransactionGroup($event->transactionGroup, true, false);
$this->processRules($newEvent);
$this->processRules($newEvent, $event->ruleGroup);
}
/**
* This method grabs all the users rules and processes them.
*/
private function processRules(StoredTransactionGroup $storedGroupEvent): void
private function processRules(StoredTransactionGroup $storedGroupEvent, ?RuleGroup $ruleGroup): void
{
if (false === $storedGroupEvent->applyRules) {
Log::info(sprintf('Will not run rules on group #%d', $storedGroupEvent->transactionGroup->id));
@@ -86,7 +87,14 @@ 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');
if (null === $ruleGroup) {
Log::debug('Fire processRules with ALL store-journal rule groups.');
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
}
if (null !== $ruleGroup) {
Log::debug(sprintf('Fire processRules with rule group #%d.', $ruleGroup->id));
$groups = new Collection([$ruleGroup]);
}
// create and fire rule engine.
$newRuleEngine = app(RuleEngineInterface::class);

View File

@@ -784,14 +784,23 @@ trait MetaCollection
$filter = static function (array $object) use ($list): bool {
Log::debug(sprintf('Now in setTags(%s) filter', implode(', ', $list)));
foreach ($object['transactions'] as $transaction) {
$total = count($transaction['tags']);
$matched = 0;
foreach ($transaction['tags'] as $tag) {
Log::debug(sprintf('"%s" versus', strtolower((string) $tag['name'])), $list);
if (in_array(strtolower((string) $tag['name']), $list, true)) {
Log::debug(sprintf('Transaction has tag "%s" so return true.', $tag['name']));
return true;
++$matched;
if (1 === count($list)) {
return true;
}
}
}
if (count($list) > 1 && $total === $matched && $matched === count($list)) {
Log::debug(sprintf('All %d searched tags are present.', $total));
return true;
}
}
Log::debug('Transaction has no tags from the list, so return false.');

View File

@@ -74,6 +74,7 @@ class IndexController extends Controller
{
$this->cleanupObjectGroups();
$this->repository->correctOrder();
$this->repository->correctTransfers();
$start = session('start');
$end = session('end');
$collection = $this->repository->getBills();

View File

@@ -122,6 +122,7 @@ class ShowController extends Controller
*/
public function show(Request $request, Bill $bill): Factory|\Illuminate\Contracts\View\View
{
$this->repository->correctTransfers();
// add info about rules:
$rules = $this->repository->getRulesForBill($bill);
$subTitle = $bill->name;

View File

@@ -212,6 +212,13 @@ class ReconcileController extends Controller
$startBalance = Steam::accountsBalancesOptimized(new Collection()->push($account), $startDate)[$account->id];
$endBalance = Steam::accountsBalancesOptimized(new Collection()->push($account), $end)[$account->id];
// round balances.
foreach ($startBalance as $key => $value) {
$startBalance[$key] = Steam::bcround($value, $currency->decimal_places);
}
foreach ($endBalance as $key => $value) {
$endBalance[$key] = Steam::bcround($value, $currency->decimal_places);
}
// get the transactions

View File

@@ -198,12 +198,14 @@ class PreferencesController extends Controller
*/
public function postIndex(PreferencesRequest $request): Redirector|RedirectResponse
{
Log::debug('postIndex for preferences.');
// front page accounts
$frontpageAccounts = [];
if (is_array($request->get('frontpageAccounts')) && count($request->get('frontpageAccounts')) > 0) {
foreach ($request->get('frontpageAccounts') as $id) {
$frontpageAccounts[] = (int)$id;
}
Log::debug('Update frontpageAccounts', $frontpageAccounts);
Preferences::set('frontpageAccounts', $frontpageAccounts);
}
@@ -212,14 +214,17 @@ class PreferencesController extends Controller
foreach (config('notifications.notifications.user') as $key => $info) {
$key = sprintf('notification_%s', $key);
if (array_key_exists($key, $all)) {
Log::debug(sprintf('update notification to true: %s', $key));
Preferences::set($key, true);
}
if (!array_key_exists($key, $all)) {
Log::debug(sprintf('update notification to false: %s', $key));
Preferences::set($key, false);
}
}
// view range:
Log::debug(sprintf('Let viewRange to "%s"', $request->get('viewRange')));
Preferences::set('viewRange', $request->get('viewRange'));
// forget session values:
session()->forget('start');
@@ -319,6 +324,7 @@ class PreferencesController extends Controller
// save and continue
session()->flash('success', (string)trans('firefly.saved_preferences'));
Preferences::mark();
Log::debug('Done saving settings.');
return redirect(route('preferences.index'));
}

View File

@@ -35,6 +35,7 @@ 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;
@@ -70,13 +71,20 @@ class ExecutionController extends Controller
*/
public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
{
Log::debug(sprintf('You have selected rule group #%d', $ruleGroup->id));
// Get parameters specified by the user
$accounts = $request->get('accounts');
$set = $this->repository->getAccountsById($accounts);
$set = new Collection();
if (is_array($accounts)) {
$set = $this->repository->getAccountsById($accounts);
}
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($set);
if (count($set) > 0) {
$collector->setAccounts($set);
}
// add date operators.
if (null !== $request->get('start')) {
$startDate = new Carbon($request->get('start'));
@@ -96,7 +104,7 @@ class ExecutionController extends Controller
/** @var TransactionGroup $group */
foreach ($groups as $group) {
Log::debug(sprintf('Processing group #%d.', $group->id));
event(new TriggeredStoredTransactionGroup($group));
event(new TriggeredStoredTransactionGroup($group, $ruleGroup));
}
}

View File

@@ -58,6 +58,7 @@ class AcceptHeaders
// some routes are exempt from this.
$exempt = [
'api.v1.data.bulk.transactions',
'api.v1.attachments.upload',
];
if (('POST' === $method || 'PUT' === $method) && !$request->hasHeader('Content-Type') && !in_array($request->route()->getName(), $exempt, true)) {

View File

@@ -23,8 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Bill;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\BillFactory;
use FireflyIII\Models\Attachment;
@@ -34,12 +34,14 @@ use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\Rule;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use FireflyIII\Services\Internal\Destroy\BillDestroyService;
use FireflyIII\Services\Internal\Update\BillUpdateService;
use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Navigation;
use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use Illuminate\Database\Query\JoinClause;
@@ -48,6 +50,7 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Override;
/**
* Class BillRepository.
@@ -244,7 +247,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
/** @var null|Note $note */
$note = $bill->notes()->first();
return (string) $note?->text;
return (string)$note?->text;
}
public function getOverallAverage(Bill $bill): array
@@ -261,7 +264,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
foreach ($journals as $journal) {
/** @var Transaction $transaction */
$transaction = $journal->transactions()->where('amount', '<', 0)->first();
$currencyId = (int) $journal->transaction_currency_id;
$currencyId = (int)$journal->transaction_currency_id;
$currency = $journal->transactionCurrency;
$result[$currencyId] ??= [
'sum' => '0',
@@ -274,10 +277,10 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
];
$result[$currencyId]['sum'] = bcadd($result[$currencyId]['sum'], (string) $transaction->amount);
$result[$currencyId]['sum'] = bcadd($result[$currencyId]['sum'], (string)$transaction->amount);
$result[$currencyId]['pc_sum'] = bcadd($result[$currencyId]['pc_sum'], $transaction->native_amount ?? '0');
if ($journal->foreign_currency_id === Amount::getPrimaryCurrency()->id) {
$result[$currencyId]['pc_sum'] = bcadd($result[$currencyId]['pc_sum'], (string) $transaction->amount);
$result[$currencyId]['pc_sum'] = bcadd($result[$currencyId]['pc_sum'], (string)$transaction->amount);
}
++$result[$currencyId]['count'];
}
@@ -288,8 +291,8 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
* @var array $arr
*/
foreach ($result as $currencyId => $arr) {
$result[$currencyId]['avg'] = bcdiv((string) $arr['sum'], (string) $arr['count']);
$result[$currencyId]['pc_avg'] = bcdiv((string) $arr['pc_sum'], (string) $arr['count']);
$result[$currencyId]['avg'] = bcdiv((string)$arr['sum'], (string)$arr['count']);
$result[$currencyId]['pc_avg'] = bcdiv((string)$arr['pc_sum'], (string)$arr['count']);
}
return $result;
@@ -398,7 +401,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
if (null === $transaction) {
continue;
}
$currencyId = (int) $journal->transaction_currency_id;
$currencyId = (int)$journal->transaction_currency_id;
$currency = $journal->transactionCurrency;
$result[$currencyId] ??= [
'sum' => '0',
@@ -410,10 +413,10 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
];
$result[$currencyId]['sum'] = bcadd($result[$currencyId]['sum'], (string) $transaction->amount);
$result[$currencyId]['sum'] = bcadd($result[$currencyId]['sum'], (string)$transaction->amount);
$result[$currencyId]['pc_sum'] = bcadd($result[$currencyId]['pc_sum'], $transaction->native_amount ?? '0');
if ($journal->foreign_currency_id === Amount::getPrimaryCurrency()->id) {
$result[$currencyId]['pc_sum'] = bcadd($result[$currencyId]['pc_sum'], (string) $transaction->amount);
$result[$currencyId]['pc_sum'] = bcadd($result[$currencyId]['pc_sum'], (string)$transaction->amount);
}
++$result[$currencyId]['count'];
}
@@ -424,8 +427,8 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
* @var array $arr
*/
foreach ($result as $currencyId => $arr) {
$result[$currencyId]['avg'] = bcdiv((string) $arr['sum'], (string) $arr['count']);
$result[$currencyId]['pc_avg'] = bcdiv((string) $arr['pc_sum'], (string) $arr['count']);
$result[$currencyId]['avg'] = bcdiv((string)$arr['sum'], (string)$arr['count']);
$result[$currencyId]['pc_avg'] = bcdiv((string)$arr['pc_sum'], (string)$arr['count']);
}
return $result;
@@ -438,7 +441,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
{
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$journal = $bill->user->transactionJournals()->find((int) $transaction['transaction_journal_id']);
$journal = $bill->user->transactionJournals()->find((int)$transaction['transaction_journal_id']);
$journal->bill_id = $bill->id;
$journal->save();
Log::debug(sprintf('Linked journal #%d to bill #%d', $journal->id, $bill->id));
@@ -544,8 +547,8 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
/** @var Collection $set */
$set = $bill->transactionJournals()->after($start)->before($end)->get(['transaction_journals.*']);
$currency = $convertToPrimary && $bill->transactionCurrency->id !== $primary->id ? $primary : $bill->transactionCurrency;
$return[(int) $currency->id] ??= [
'id' => (string) $currency->id,
$return[(int)$currency->id] ??= [
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
'code' => $currency->code,
@@ -557,9 +560,9 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
/** @var TransactionJournal $transactionJournal */
foreach ($set as $transactionJournal) {
// grab currency from transaction.
$transactionCurrency = $transactionJournal->transactionCurrency;
$return[(int) $transactionCurrency->id] ??= [
'id' => (string) $transactionCurrency->id,
$transactionCurrency = $transactionJournal->transactionCurrency;
$return[(int)$transactionCurrency->id] ??= [
'id' => (string)$transactionCurrency->id,
'name' => $transactionCurrency->name,
'symbol' => $transactionCurrency->symbol,
'code' => $transactionCurrency->code,
@@ -568,7 +571,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
];
// get currency from transaction as well.
$return[(int) $transactionCurrency->id]['sum'] = bcadd($return[(int) $transactionCurrency->id]['sum'], Amount::getAmountFromJournalObject($transactionJournal));
$return[(int)$transactionCurrency->id]['sum'] = bcadd($return[(int)$transactionCurrency->id]['sum'], Amount::getAmountFromJournalObject($transactionJournal));
// $setAmount = bcadd($setAmount, Amount::getAmountFromJournalObject($transactionJournal));
}
// Log::debug(sprintf('Bill #%d ("%s") with %d transaction(s) and sum %s %s', $bill->id, $bill->name, $set->count(), $currency->code, $setAmount));
@@ -622,14 +625,14 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
$average = bcdiv(bcadd($bill->{$maxField} ?? '0', $bill->{$minField} ?? '0'), '2');
Log::debug(sprintf('Amount to pay is %s %s (%d times)', $currency->code, $average, $total));
$return[$currency->id] ??= [
'id' => (string) $currency->id,
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
'code' => $currency->code,
'decimal_places' => $currency->decimal_places,
'sum' => '0',
];
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], bcmul($average, (string) $total));
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], bcmul($average, (string)$total));
}
}
@@ -704,4 +707,19 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
return $service->update($bill, $data);
}
#[Override]
public function correctTransfers(): void
{
/** @var null|TransactionType $withdrawal */
$withdrawal = TransactionType::where('type', TransactionTypeEnum::WITHDRAWAL->value)->first();
if (null === $withdrawal) {
return;
}
$this->user
->transactionJournals()
->whereNotNull('bill_id')
->where('transaction_type_id', '!=', $withdrawal->id)
->update(['bill_id' => null]);
}
}

View File

@@ -54,6 +54,8 @@ interface BillRepositoryInterface
*/
public function correctOrder(): void;
public function correctTransfers(): void;
public function destroy(Bill $bill): bool;
public function destroyAll(): void;

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Http\Controllers;
use FireflyIII\Models\Tag;
use Illuminate\Support\Facades\Log;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Exceptions\FireflyException;
@@ -416,8 +417,21 @@ trait RenderPartialViews
$repository = app(TagRepositoryInterface::class);
$tags = $repository->get();
$grouped = [];
/** @var Tag $tag */
foreach ($tags as $tag) {
$year = (int) $tag->date?->year;
$grouped[$year] ??= [
'tags' => [],
'year' => 0 === $year ? trans('firefly.no_date') : $year,
];
$grouped[$year]['tags'][] = $tag;
}
ksort($grouped);
try {
$result = view('reports.options.tag', ['tags' => $tags])->render();
$result = view('reports.options.tag', ['tags' => $grouped])->render();
} catch (Throwable $e) {
Log::error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';

View File

@@ -321,7 +321,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
$array['foreign_currency_code'] = $entry->foreign_currency_code;
$array['foreign_currency_symbol'] = $entry->foreign_currency_symbol;
$array['foreign_currency_decimal_places'] = $entry->foreign_currency_decimal_places;
$array['foreign_amount'] = Steam::bcround($entry->foreign_amount, $entry->foreign_currency_decimal_places);
$array['foreign_amount'] = Steam::bcround((string) $entry->foreign_amount, $entry->foreign_currency_decimal_places);
}
// convert to primary, but is already primary.
if ($this->convertToPrimary && (int)$entry->transaction_currency_id === $this->primaryCurrency->id) {
@@ -329,7 +329,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
}
// convert to primary, but is NOT already primary.
if ($this->convertToPrimary && (int)$entry->transaction_currency_id !== $this->primaryCurrency->id) {
$array['pc_amount'] = $converter->convert($entry->transactionCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
$array['pc_amount'] = $converter->convert($entry->transactionCurrency, $this->primaryCurrency, $entry->date, (string) $entry->amount);
}
// convert to primary, but foreign is already primary.
if ($this->convertToPrimary && (int)$entry->foreign_currency_id === $this->primaryCurrency->id) {
@@ -340,7 +340,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
// TODO this is very database intensive.
/** @var TransactionCurrency $foreignCurrency */
$foreignCurrency = Amount::getTransactionCurrencyById($entry->foreign_currency_id);
$array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
$array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, (string) $entry->amount);
}
$result[] = $array;
}

View File

@@ -202,7 +202,6 @@ class Navigation
public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon
{
$currentEnd = clone $end;
// 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.
@@ -325,6 +324,7 @@ class Navigation
}
unset($result);
if (!array_key_exists($repeatFreq, $functionMap)) {
Log::error(sprintf('Cannot do endOfPeriod for $repeat_freq "%s"', $repeatFreq));

View File

@@ -54,7 +54,11 @@ class LinkToBill implements ActionInterface
$billName = $this->action->getValue($journal);
$bill = $repository->findByName($billName);
if (null !== $bill && TransactionTypeEnum::WITHDRAWAL->value === $journal['transaction_type_type']) {
/** @var TransactionJournal $object */
$object = TransactionJournal::with('transactionType')->find($journal['transaction_journal_id']);
$type = $object->transactionType->type;
if (null !== $bill && TransactionTypeEnum::WITHDRAWAL->value === $type) {
$count = DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])->where('bill_id', $bill->id)->count();
if (0 !== $count) {
Log::error(sprintf('RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": already set.', $journal['transaction_journal_id'], $billName));

View File

@@ -24,6 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Expressions;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Support\Facades\Log;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\SyntaxError;
@@ -141,6 +143,11 @@ class ActionExpression
private function evaluateExpression(string $expr, array $journal): string
{
$result = $this->expressionLanguage->evaluate($expr, $journal);
if (is_array($result)) {
Log::error('Result of evaluating the expression is an array, please investigate', $result);
throw new FireflyException('Result of evaluating the expression is an array, please open a GitHub issue about this and include the error logs.');
}
return (string) $result;
}

View File

@@ -457,8 +457,9 @@ class FireflyValidator extends Validator
*
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
*/
public function validateSecurePassword($attribute, string $value): bool
public function validateSecurePassword($attribute, ?string $value): bool
{
$value = (string)$value;
$verify = false;
if (array_key_exists('verify_password', $this->data)) {
$verify = 1 === (int) $this->data['verify_password'];

View File

@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## v6.4.15 - 2026-01-07
### Added
- [Issue 11264](https://github.com/firefly-iii/firefly-iii/issues/11264) (Add GUI for some settings, replacing environment variables) reported by @jacobburrell
- [Discussion 11433](https://github.com/orgs/firefly-iii/discussions/11433) (Updates to Date Range selection) started by @fett327
### Changed
- Moved some settings to your system settings
### Removed
- The following environment variables are removed and will no longer work. They are now in your settings.
- `ENABLE_EXTERNAL_MAP`
- `ENABLE_EXCHANGE_RATES`
- `ENABLE_EXTERNAL_RATES`
- `VALID_URL_PROTOCOLS`
- `ALLOW_WEBHOOKS`
- `USE_RUNNING_BALANCE`
- Removed sentry.io code
### Fixed
- [Issue 11378](https://github.com/firefly-iii/firefly-iii/issues/11378) (Wrong account balance with initial transfer from different currency) reported by @bozho
- [Issue 11383](https://github.com/firefly-iii/firefly-iii/issues/11383) (Login flow could redirect to javascript path) reported by @stefvonb
- [Issue 11388](https://github.com/firefly-iii/firefly-iii/issues/11388) (TypeError bugs during upgrade to 6.4.14 + account_balances corruption) reported by @jaconde2
- [Issue 11396](https://github.com/firefly-iii/firefly-iii/issues/11396) (Reconciliation adds extra digits) reported by @niklas2810
- [Issue 11399](https://github.com/firefly-iii/firefly-iii/issues/11399) (Unusual behavior in audit logs (multi-currency)) reported by @jgmm81
- [Issue 11403](https://github.com/firefly-iii/firefly-iii/issues/11403) (Error 404 when trying to view the details (Piggy banks section)) reported by @jgmm81
- [Issue 11410](https://github.com/firefly-iii/firefly-iii/issues/11410) (nitpick: Bulk edit tags should keep the option chosen instead of always changing back to "replace") reported by @jxtxzzw
- [Issue 11443](https://github.com/firefly-iii/firefly-iii/issues/11443) (Exception thrown, when subscription is in foreign currency) reported by @ajgon
- [Issue 11445](https://github.com/firefly-iii/firefly-iii/issues/11445) (“Reconcile” screen breaks when Preferences → Layout is set to “Year to date”) reported by @semonsir
- [Issue 11449](https://github.com/firefly-iii/firefly-iii/issues/11449) (Non-strict rules break with "Apply rule" and "Apply rule group") reported by @Bytenka
## v6.4.14 - 2025-12-17
### Fixed

View File

@@ -34,6 +34,9 @@
"transfers",
"management"
],
"platform": {
"php": "8.4"
},
"license": "AGPL-3.0-or-later",
"homepage": "https://github.com/firefly-iii/firefly-iii",
"type": "project",

34
composer.lock generated
View File

@@ -1878,16 +1878,16 @@
},
{
"name": "laravel/framework",
"version": "v12.44.0",
"version": "v12.46.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "592bbf1c036042958332eb98e3e8131b29102f33"
"reference": "9dcff48d25a632c1fadb713024c952fec489c4ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/592bbf1c036042958332eb98e3e8131b29102f33",
"reference": "592bbf1c036042958332eb98e3e8131b29102f33",
"url": "https://api.github.com/repos/laravel/framework/zipball/9dcff48d25a632c1fadb713024c952fec489c4ae",
"reference": "9dcff48d25a632c1fadb713024c952fec489c4ae",
"shasum": ""
},
"require": {
@@ -2096,7 +2096,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-12-23T15:29:43+00:00"
"time": "2026-01-07T23:26:53+00:00"
},
{
"name": "laravel/passport",
@@ -2235,16 +2235,16 @@
},
{
"name": "laravel/sanctum",
"version": "v4.2.1",
"version": "v4.2.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664"
"reference": "fd447754d2d3f56950d53b930128af2e3b617de9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/fd447754d2d3f56950d53b930128af2e3b617de9",
"reference": "fd447754d2d3f56950d53b930128af2e3b617de9",
"shasum": ""
},
"require": {
@@ -2294,7 +2294,7 @@
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
"time": "2025-11-21T13:59:03+00:00"
"time": "2026-01-06T23:11:51+00:00"
},
{
"name": "laravel/serializable-closure",
@@ -3621,16 +3621,16 @@
},
{
"name": "monolog/monolog",
"version": "3.9.0",
"version": "3.10.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
"reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0",
"reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
"shasum": ""
},
"require": {
@@ -3648,7 +3648,7 @@
"graylog2/gelf-php": "^1.4.2 || ^2.0",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"mongodb/mongodb": "^1.8 || ^2.0",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"php-console/php-console": "^3.1.8",
"phpstan/phpstan": "^2",
@@ -3708,7 +3708,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/3.9.0"
"source": "https://github.com/Seldaek/monolog/tree/3.10.0"
},
"funding": [
{
@@ -3720,7 +3720,7 @@
"type": "tidelift"
}
],
"time": "2025-03-24T10:02:05+00:00"
"time": "2026-01-02T08:56:05+00:00"
},
{
"name": "nesbot/carbon",

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => (bool)envNonEmpty('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2026-01-02',
'build_time' => 1767337875,
'version' => 'develop/2026-01-10',
'build_time' => 1768053746,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

View File

@@ -87,6 +87,7 @@ class TransactionCurrencySeeder extends Seeder
$currencies[] = ['code' => 'CZK', 'name' => 'Czech koruna', 'symbol' => 'Kč', 'decimal_places' => 2];
$currencies[] = ['code' => 'KZT', 'name' => 'Kazakhstani tenge', 'symbol' => '₸', 'decimal_places' => 2];
$currencies[] = ['code' => 'SAR', 'name' => 'Saudi Riyal', 'symbol' => 'SAR', 'decimal_places' => 2];
$currencies[] = ['code' => 'RSD', 'name' => 'Serbian Dinar', 'symbol' => 'RSD', 'decimal_places' => 2];
foreach ($currencies as $currency) {
if (null === TransactionCurrency::where('code', $currency['code'])->first()) {

281
package-lock.json generated
View File

@@ -2592,9 +2592,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz",
"integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz",
"integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==",
"cpu": [
"arm"
],
@@ -2606,9 +2606,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz",
"integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz",
"integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==",
"cpu": [
"arm64"
],
@@ -2620,9 +2620,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz",
"integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz",
"integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==",
"cpu": [
"arm64"
],
@@ -2634,9 +2634,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz",
"integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz",
"integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==",
"cpu": [
"x64"
],
@@ -2648,9 +2648,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz",
"integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz",
"integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==",
"cpu": [
"arm64"
],
@@ -2662,9 +2662,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz",
"integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz",
"integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==",
"cpu": [
"x64"
],
@@ -2676,9 +2676,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz",
"integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz",
"integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==",
"cpu": [
"arm"
],
@@ -2690,9 +2690,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz",
"integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz",
"integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==",
"cpu": [
"arm"
],
@@ -2704,9 +2704,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz",
"integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz",
"integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==",
"cpu": [
"arm64"
],
@@ -2718,9 +2718,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz",
"integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz",
"integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==",
"cpu": [
"arm64"
],
@@ -2732,9 +2732,23 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz",
"integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz",
"integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz",
"integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==",
"cpu": [
"loong64"
],
@@ -2746,9 +2760,23 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz",
"integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz",
"integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz",
"integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==",
"cpu": [
"ppc64"
],
@@ -2760,9 +2788,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz",
"integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz",
"integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==",
"cpu": [
"riscv64"
],
@@ -2774,9 +2802,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz",
"integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz",
"integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==",
"cpu": [
"riscv64"
],
@@ -2788,9 +2816,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz",
"integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz",
"integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==",
"cpu": [
"s390x"
],
@@ -2802,9 +2830,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz",
"integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz",
"integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==",
"cpu": [
"x64"
],
@@ -2816,9 +2844,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz",
"integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz",
"integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==",
"cpu": [
"x64"
],
@@ -2829,10 +2857,24 @@
"linux"
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz",
"integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz",
"integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz",
"integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==",
"cpu": [
"arm64"
],
@@ -2844,9 +2886,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz",
"integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz",
"integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==",
"cpu": [
"arm64"
],
@@ -2858,9 +2900,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz",
"integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz",
"integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==",
"cpu": [
"ia32"
],
@@ -2872,9 +2914,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz",
"integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz",
"integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==",
"cpu": [
"x64"
],
@@ -2886,9 +2928,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz",
"integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz",
"integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==",
"cpu": [
"x64"
],
@@ -3050,9 +3092,9 @@
}
},
"node_modules/@types/express-serve-static-core": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz",
"integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz",
"integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3063,9 +3105,9 @@
}
},
"node_modules/@types/express/node_modules/@types/express-serve-static-core": {
"version": "4.19.7",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz",
"integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==",
"version": "4.19.8",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz",
"integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3176,9 +3218,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.0.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
"integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
"version": "25.0.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.5.tgz",
"integrity": "sha512-FuLxeLuSVOqHPxSN1fkcD8DLU21gAP7nCKqGRJ/FglbCUBs0NYN6TpHcdmyLeh8C0KwGIaZQJSv+OYG+KZz+Gw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4075,9 +4117,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.9.11",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
"integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
"version": "2.9.14",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz",
"integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -4508,9 +4550,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001762",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
"integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
"version": "1.0.30001763",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001763.tgz",
"integrity": "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==",
"dev": true,
"funding": [
{
@@ -7051,9 +7093,9 @@
}
},
"node_modules/i18next": {
"version": "25.7.3",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.3.tgz",
"integrity": "sha512-2XaT+HpYGuc2uTExq9TVRhLsso+Dxym6PWaKpn36wfBmTI779OQ7iP/XaZHzrnGyzU4SHpFrTYLKfVyBfAhVNA==",
"version": "25.7.4",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.4.tgz",
"integrity": "sha512-hRkpEblXXcXSNbw8mBNq9042OEetgyB/ahc/X17uV/khPwzV+uB8RHceHh3qavyrkPJvmXFKXME2Sy1E0KjAfw==",
"funding": [
{
"type": "individual",
@@ -10036,9 +10078,9 @@
}
},
"node_modules/rollup": {
"version": "4.54.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz",
"integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10052,28 +10094,31 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.54.0",
"@rollup/rollup-android-arm64": "4.54.0",
"@rollup/rollup-darwin-arm64": "4.54.0",
"@rollup/rollup-darwin-x64": "4.54.0",
"@rollup/rollup-freebsd-arm64": "4.54.0",
"@rollup/rollup-freebsd-x64": "4.54.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.54.0",
"@rollup/rollup-linux-arm-musleabihf": "4.54.0",
"@rollup/rollup-linux-arm64-gnu": "4.54.0",
"@rollup/rollup-linux-arm64-musl": "4.54.0",
"@rollup/rollup-linux-loong64-gnu": "4.54.0",
"@rollup/rollup-linux-ppc64-gnu": "4.54.0",
"@rollup/rollup-linux-riscv64-gnu": "4.54.0",
"@rollup/rollup-linux-riscv64-musl": "4.54.0",
"@rollup/rollup-linux-s390x-gnu": "4.54.0",
"@rollup/rollup-linux-x64-gnu": "4.54.0",
"@rollup/rollup-linux-x64-musl": "4.54.0",
"@rollup/rollup-openharmony-arm64": "4.54.0",
"@rollup/rollup-win32-arm64-msvc": "4.54.0",
"@rollup/rollup-win32-ia32-msvc": "4.54.0",
"@rollup/rollup-win32-x64-gnu": "4.54.0",
"@rollup/rollup-win32-x64-msvc": "4.54.0",
"@rollup/rollup-android-arm-eabi": "4.55.1",
"@rollup/rollup-android-arm64": "4.55.1",
"@rollup/rollup-darwin-arm64": "4.55.1",
"@rollup/rollup-darwin-x64": "4.55.1",
"@rollup/rollup-freebsd-arm64": "4.55.1",
"@rollup/rollup-freebsd-x64": "4.55.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.55.1",
"@rollup/rollup-linux-arm-musleabihf": "4.55.1",
"@rollup/rollup-linux-arm64-gnu": "4.55.1",
"@rollup/rollup-linux-arm64-musl": "4.55.1",
"@rollup/rollup-linux-loong64-gnu": "4.55.1",
"@rollup/rollup-linux-loong64-musl": "4.55.1",
"@rollup/rollup-linux-ppc64-gnu": "4.55.1",
"@rollup/rollup-linux-ppc64-musl": "4.55.1",
"@rollup/rollup-linux-riscv64-gnu": "4.55.1",
"@rollup/rollup-linux-riscv64-musl": "4.55.1",
"@rollup/rollup-linux-s390x-gnu": "4.55.1",
"@rollup/rollup-linux-x64-gnu": "4.55.1",
"@rollup/rollup-linux-x64-musl": "4.55.1",
"@rollup/rollup-openbsd-x64": "4.55.1",
"@rollup/rollup-openharmony-arm64": "4.55.1",
"@rollup/rollup-win32-arm64-msvc": "4.55.1",
"@rollup/rollup-win32-ia32-msvc": "4.55.1",
"@rollup/rollup-win32-x64-gnu": "4.55.1",
"@rollup/rollup-win32-x64-msvc": "4.55.1",
"fsevents": "~2.3.2"
}
},
@@ -10129,9 +10174,9 @@
"license": "MIT"
},
"node_modules/sass": {
"version": "1.97.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.1.tgz",
"integrity": "sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==",
"version": "1.97.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.2.tgz",
"integrity": "sha512-y5LWb0IlbO4e97Zr7c3mlpabcbBtS+ieiZ9iwDooShpFKWXf62zz5pEPdwrLYm+Bxn1fnbwFGzHuCLSA9tBmrw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11417,9 +11462,9 @@
}
},
"node_modules/vite": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12288,9 +12333,9 @@
"license": "ISC"
},
"node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"dev": true,
"license": "MIT",
"engines": {

View File

@@ -68,8 +68,8 @@ export default {
props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title',],
mounted() {
this.liability = false;
// console.log('I am mounted with a ' + this.transactionType + ' transaction type and currency id!');
// console.log(this.value);
console.log('ForeignAmountSelect is mounted with a ' + this.transactionType + ' transaction type and currency id!');
console.log(this.value);
this.loadCurrencies();
},
data() {
@@ -124,23 +124,25 @@ export default {
let sourceIsLiability = liabilities.indexOf(srcType) !== -1;
let destIsLiability = liabilities.indexOf(destType) !== -1;
// console.log(srcType + ' (source) is a liability: ' + sourceIsLiability);
// console.log(destType + ' (dest) is a liability: ' + destIsLiability);
// console.log('tType: ' + tType);
if (tType === 'transfer' || destIsLiability || sourceIsLiability) {
// console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
console.log('Source or dest is a liability.')
console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
// console.log('Length of currencies is ' + this.currencies.length);
// console.log(this.currencies);
this.liability = true;
// lock dropdown list on currencyID of destination.
// lock dropdown list on currencyID of destination UNLESS dest is not liab
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id)
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id) || !destIsLiability
) {
// console.log('Enable currency!!');
console.log('Enable currency!!');
console.log(this.currencies[key]);
// console.log(this.destination);
// console.log(this.currencies[key]);
this.enabledCurrencies.push(this.currencies[key]);
}
}
@@ -151,6 +153,7 @@ export default {
// if type is withdrawal, list all but skip the source account ID.
if (tType === 'withdrawal' && this.source && false === sourceIsLiability) {
console.log('Type is withdrawal, there is a source, it is not a liability.')
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (this.source.currency_id !== this.currencies[key].id) {

View File

@@ -2480,6 +2480,7 @@ return [
'balanceFor' => 'Balance for :name',
'no_tags' => '(no tags)',
'nothing_found' => '(nothing found)',
'no_date' => '(no date)',
// page settings and wizard dialogs

View File

@@ -2,9 +2,13 @@
<label for="inputTags" class="col-sm-3 control-label">{{ 'select_tag'|_ }}</label>
<div class="col-sm-9">
<select id="inputTags" name="tag[]" multiple="multiple" class="form-control">
{% for tag in tags %}
<option value="{{ tag.id }}" label="{{ tag.tag|e('html') }}">{{ tag.tag|e('html') }}</option>
{% for year in tags %}
<optgroup label="{{ year.year }}">
{% for tag in year.tags %}
<option value="{{ tag.id }}" label="{{ tag.tag|e('html') }}">{{ tag.tag|e('html') }}</option>
{% endfor %}
{% endfor %}
</select>
</div>
</div>