Compare commits

...

29 Commits

Author SHA1 Message Date
github-actions[bot]
3c904c9017 Merge pull request #11286 from firefly-iii/release-1764136451
🤖 Automatically merge the PR into the develop branch.
2025-11-26 06:54:20 +01:00
JC5
d8bdbf2842 🤖 Auto commit for release 'develop' on 2025-11-26 2025-11-26 06:54:11 +01:00
James Cole
d08966d141 Add new correction command. 2025-11-26 06:50:29 +01:00
James Cole
bd71095e40 Merge branch 'main' into develop 2025-11-25 20:13:04 +01:00
James Cole
d7967a81e3 Fix https://github.com/firefly-iii/firefly-iii/issues/11284 2025-11-25 20:12:35 +01:00
James Cole
fa018e80c0 Replace classes 2025-11-25 20:12:23 +01:00
James Cole
eb4b9659cf Merge pull request #11278 from firefly-iii/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 5 to 6
2025-11-24 08:49:23 +01:00
github-actions[bot]
7b7b9118cd Merge pull request #11279 from firefly-iii/release-1763955257
🤖 Automatically merge the PR into the develop branch.
2025-11-24 04:34:26 +01:00
JC5
373e5c3733 🤖 Auto commit for release 'develop' on 2025-11-24 2025-11-24 04:34:17 +01:00
dependabot[bot]
4e0b1bf65d Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 03:17:24 +00:00
James Cole
521a496c17 Fix #11267 2025-11-23 21:03:53 +01:00
James Cole
5fea35d5b1 Allow command to be forced. 2025-11-23 08:44:01 +01:00
James Cole
21a6892601 Fix #11265 2025-11-23 06:55:54 +01:00
James Cole
3f386b9003 Fix #11191 2025-11-19 06:26:40 +01:00
github-actions[bot]
72fb534eb4 Merge pull request #11249 from firefly-iii/release-1763402892
🤖 Automatically merge the PR into the develop branch.
2025-11-17 19:08:20 +01:00
JC5
69b46af245 🤖 Auto commit for release 'develop' on 2025-11-17 2025-11-17 19:08:12 +01:00
James Cole
4a901a1b42 Add a bunch of debug #11247 2025-11-17 19:01:38 +01:00
James Cole
a8fffc25c0 Merge pull request #11241 from firefly-iii/dependabot/composer/develop/bacon/bacon-qr-code-3.0.2
Bump bacon/bacon-qr-code from 3.0.1 to 3.0.2
2025-11-17 06:48:36 +01:00
mergify[bot]
d0dab136b1 Merge branch 'develop' into dependabot/composer/develop/bacon/bacon-qr-code-3.0.2 2025-11-17 05:47:38 +00:00
James Cole
91184489da Merge pull request #11242 from firefly-iii/dependabot/npm_and_yarn/develop/alpinejs-3.15.2
Bump alpinejs from 3.15.1 to 3.15.2
2025-11-17 06:46:55 +01:00
mergify[bot]
e4e6cc71c3 Merge branch 'develop' into dependabot/composer/develop/bacon/bacon-qr-code-3.0.2 2025-11-17 03:30:51 +00:00
mergify[bot]
33d637e618 Merge branch 'develop' into dependabot/npm_and_yarn/develop/alpinejs-3.15.2 2025-11-17 03:30:49 +00:00
github-actions[bot]
42eb4410f8 Merge pull request #11243 from firefly-iii/release-1763350179
🤖 Automatically merge the PR into the develop branch.
2025-11-17 04:29:45 +01:00
JC5
5f6b345c79 🤖 Auto commit for release 'develop' on 2025-11-17 2025-11-17 04:29:39 +01:00
dependabot[bot]
30b48a479c Bump alpinejs from 3.15.1 to 3.15.2
Bumps [alpinejs](https://github.com/alpinejs/alpine/tree/HEAD/packages/alpinejs) from 3.15.1 to 3.15.2.
- [Release notes](https://github.com/alpinejs/alpine/releases)
- [Commits](https://github.com/alpinejs/alpine/commits/v3.15.2/packages/alpinejs)

---
updated-dependencies:
- dependency-name: alpinejs
  dependency-version: 3.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 03:01:12 +00:00
dependabot[bot]
55d23af802 Bump bacon/bacon-qr-code from 3.0.1 to 3.0.2
Bumps [bacon/bacon-qr-code](https://github.com/Bacon/BaconQrCode) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/Bacon/BaconQrCode/releases)
- [Changelog](https://github.com/Bacon/BaconQrCode/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Bacon/BaconQrCode/compare/v3.0.1...v3.0.2)

---
updated-dependencies:
- dependency-name: bacon/bacon-qr-code
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 03:00:53 +00:00
James Cole
34bfeba63a Fix #11211 2025-11-13 20:32:02 +01:00
github-actions[bot]
761c20b670 Merge pull request #11234 from firefly-iii/release-1763009724
🤖 Automatically merge the PR into the develop branch.
2025-11-13 05:55:30 +01:00
JC5
d756977ee0 🤖 Auto commit for release 'develop' on 2025-11-13 2025-11-13 05:55:24 +01:00
47 changed files with 679 additions and 519 deletions

View File

@@ -402,16 +402,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.89.2",
"version": "v3.90.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "7569658f91e475ec93b99bd5964b059ad1336dcf"
"reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7569658f91e475ec93b99bd5964b059ad1336dcf",
"reference": "7569658f91e475ec93b99bd5964b059ad1336dcf",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ad732c2e9299c9743f9c55ae53cc0e7642ab1155",
"reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155",
"shasum": ""
},
"require": {
@@ -429,17 +429,17 @@
"react/socket": "^1.16",
"react/stream": "^1.4",
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
"symfony/console": "^5.4.47 || ^6.4.24 || ^7.0",
"symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/polyfill-mbstring": "^1.33",
"symfony/polyfill-php80": "^1.33",
"symfony/polyfill-php81": "^1.33",
"symfony/polyfill-php84": "^1.33",
"symfony/process": "^5.4.47 || ^6.4.24 || ^7.2",
"symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0"
"symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0",
"symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0"
},
"require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7",
@@ -451,8 +451,8 @@
"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",
"symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2",
"symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2"
"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"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -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.89.2"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.90.0"
},
"funding": [
{
@@ -501,7 +501,7 @@
"type": "github"
}
],
"time": "2025-11-06T21:12:50+00:00"
"time": "2025-11-20T15:15:16+00:00"
},
{
"name": "psr/container",
@@ -805,16 +805,16 @@
},
{
"name": "react/dns",
"version": "v1.13.0",
"version": "v1.14.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/dns.git",
"reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5"
"reference": "7562c05391f42701c1fccf189c8225fece1cd7c3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
"reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
"url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3",
"reference": "7562c05391f42701c1fccf189c8225fece1cd7c3",
"shasum": ""
},
"require": {
@@ -869,7 +869,7 @@
],
"support": {
"issues": "https://github.com/reactphp/dns/issues",
"source": "https://github.com/reactphp/dns/tree/v1.13.0"
"source": "https://github.com/reactphp/dns/tree/v1.14.0"
},
"funding": [
{
@@ -877,20 +877,20 @@
"type": "open_collective"
}
],
"time": "2024-06-13T14:18:03+00:00"
"time": "2025-11-18T19:34:28+00:00"
},
{
"name": "react/event-loop",
"version": "v1.5.0",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/event-loop.git",
"reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354"
"reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354",
"reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354",
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a",
"reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a",
"shasum": ""
},
"require": {
@@ -941,7 +941,7 @@
],
"support": {
"issues": "https://github.com/reactphp/event-loop/issues",
"source": "https://github.com/reactphp/event-loop/tree/v1.5.0"
"source": "https://github.com/reactphp/event-loop/tree/v1.6.0"
},
"funding": [
{
@@ -949,7 +949,7 @@
"type": "open_collective"
}
],
"time": "2023-11-13T13:48:05+00:00"
"time": "2025-11-17T20:46:25+00:00"
},
{
"name": "react/promise",
@@ -1026,16 +1026,16 @@
},
{
"name": "react/socket",
"version": "v1.16.0",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
"reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1"
"reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
"reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
"url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08",
"reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08",
"shasum": ""
},
"require": {
@@ -1094,7 +1094,7 @@
],
"support": {
"issues": "https://github.com/reactphp/socket/issues",
"source": "https://github.com/reactphp/socket/tree/v1.16.0"
"source": "https://github.com/reactphp/socket/tree/v1.17.0"
},
"funding": [
{
@@ -1102,7 +1102,7 @@
"type": "open_collective"
}
],
"time": "2024-07-26T10:38:09+00:00"
"time": "2025-11-19T20:47:34+00:00"
},
{
"name": "react/stream",
@@ -2675,5 +2675,5 @@
"prefer-lowest": false,
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.9.0"
}

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout repository'
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: 'Dependency review'

View File

@@ -29,7 +29,7 @@ jobs:
env:
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Import GPG key

View File

@@ -40,7 +40,7 @@ class IndexController extends Controller
{
use ValidatesUserGroupTrait;
public const string RESOURCE_KEY = 'currency_exchange_rates';
public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository;

View File

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

View File

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

View File

@@ -56,7 +56,7 @@ class ForcesDecimalSize extends Command
use ShowsFriendlyMessages;
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
protected $signature = 'firefly-iii:force-decimal-size';
protected $signature = 'firefly-iii:force-decimal-size {--force}';
private string $cast;
private array $classes
= [
@@ -98,9 +98,14 @@ class ForcesDecimalSize extends Command
Log::debug('Now in ForceDecimalSize::handle()');
$this->determineDatabaseType();
$this->friendlyError('Running this command is dangerous and can cause data loss.');
$this->friendlyError('Please do not continue.');
$question = $this->confirm('Do you want to continue?');
$force = $this->option('force');
$question = true;
if (false === $force) {
$this->friendlyError('Running this command is dangerous and can cause data loss.');
$this->friendlyError('Please make sure you have a backup.');
$question = $this->confirm('Do you want to continue?');
}
if (true === $question) {
$this->correctAmounts();
$this->updateDecimals();
@@ -131,17 +136,17 @@ class ForcesDecimalSize extends Command
private function correctAmounts(): void
{
// if sqlite, add function?
if ('sqlite' === (string) config('database.default')) {
if ('sqlite' === (string)config('database.default')) {
DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', static function ($pattern, $value): int {
mb_regex_encoding('UTF-8');
$pattern = trim($pattern, '"');
return (mb_ereg($pattern, (string) $value)) ? 1 : 0;
return (mb_ereg($pattern, (string)$value)) ? 1 : 0;
});
}
if (!in_array((string) config('database.default'), ['mysql', 'pgsql', 'sqlite'], true)) {
$this->friendlyWarning(sprintf('Skip correcting amounts, does not support "%s"...', (string) config('database.default')));
if (!in_array((string)config('database.default'), ['mysql', 'pgsql', 'sqlite'], true)) {
$this->friendlyWarning(sprintf('Skip correcting amounts, does not support "%s"...', (string)config('database.default')));
return;
}
@@ -236,7 +241,7 @@ class ForcesDecimalSize extends Command
/** @var Builder $query */
$query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
;
$query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
@@ -264,7 +269,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
/** @var null|Account $updateAccount */
@@ -316,7 +321,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
/** @var null|Model $model */
@@ -340,7 +345,7 @@ class ForcesDecimalSize extends Command
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -369,7 +374,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Piggy bank event #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
);
@@ -396,7 +401,7 @@ class ForcesDecimalSize extends Command
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -425,7 +430,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
);
@@ -450,7 +455,7 @@ class ForcesDecimalSize extends Command
$query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -479,7 +484,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
/** @var null|PiggyBank $piggyBank */
@@ -515,7 +520,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10.0 ** $currency->decimal_places;
$correct = bcdiv((string) round((float) $value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
/** @var null|Transaction $transaction */
@@ -546,7 +551,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10.0 ** $currency->decimal_places;
$correct = bcdiv((string) round((float) $value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct)
);
@@ -560,7 +565,7 @@ class ForcesDecimalSize extends Command
private function updateDecimals(): void
{
$this->friendlyInfo('Going to force the size of DECIMAL columns. Please hold.');
$type = (string) config('database.default');
$type = (string)config('database.default');
/**
* @var string $name

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Report;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
@@ -81,7 +82,7 @@ class ReportHelper implements ReportHelperInterface
/** @var Carbon $expectedStart */
foreach ($expectedDates as $expectedStart) {
$expectedEnd = app('navigation')->endOfX($expectedStart, $bill->repeat_freq, null);
$expectedEnd = Navigation::endOfX($expectedStart, $bill->repeat_freq, null);
// is paid in this period maybe?
/** @var GroupCollectorInterface $collector */

View File

@@ -167,12 +167,17 @@ class IndexController extends Controller
/** @var Carbon $end */
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
$now = now();
if ($now->gt($end) || $now->lt($start)) {
$now = $end;
}
$ids = $accounts->pluck('id')->toArray();
Log::debug(sprintf('index: accountsBalancesInRange("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
[
$startBalances,
$endBalances,
] = Steam::accountsBalancesInRange($accounts, $start, $end, $this->primaryCurrency, $this->convertToPrimary);
] = Steam::accountsBalancesInRange($accounts, $start, $now, $this->primaryCurrency, $this->convertToPrimary);
$activities = Steam::getLastActivities($ids);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Account;
use FireflyIII\Support\Facades\Navigation;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use FireflyIII\Enums\AccountTypeEnum;
@@ -91,20 +92,20 @@ class ReconcileController extends Controller
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->primaryCurrency;
// no start or end:
$range = app('navigation')->getViewRange(false);
$range = Navigation::getViewRange(false);
// get start and end
if (!$start instanceof Carbon && !$end instanceof Carbon) {
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon(), $range));
$start = clone session('start', Navigation::startOfPeriod(new Carbon(), $range));
/** @var Carbon $end */
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon(), $range));
$end = clone session('end', Navigation::endOfPeriod(new Carbon(), $range));
}
if (null === $end) {
/** @var Carbon $end */
$end = app('navigation')->endOfPeriod($start, $range);
$end = Navigation::endOfPeriod($start, $range);
}
if ($end->lt($start)) {

View File

@@ -164,7 +164,7 @@ class ShowController extends Controller
$timer->stop('collection');
$groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
$showAll = false;
$now = today()->endOfDay();
$now = now();
if ($now->gt($end) || $now->lt($start)) {
$now = $end;
}
@@ -173,10 +173,7 @@ class ShowController extends Controller
$balances = Steam::accountsBalancesOptimized(new Collection()->push($account), $now)[$account->id];
// $balances = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $now), $account, $this->convertToPrimary, $accountCurrency);
return view(
'accounts.show',
['account' => $account, 'showAll' => $showAll, 'objectType' => $objectType, 'currency' => $currency, 'today' => $today, 'periods' => $periods, 'subTitleIcon' => $subTitleIcon, 'groups' => $groups, 'attachments' => $attachments, 'subTitle' => $subTitle, 'start' => $start, 'end' => $end, 'chartUrl' => $chartUrl, 'location' => $location, 'balances' => $balances]
);
return view('accounts.show', ['account' => $account, 'showAll' => $showAll, 'objectType' => $objectType, 'currency' => $currency, 'today' => $today, 'periods' => $periods, 'subTitleIcon' => $subTitleIcon, 'groups' => $groups, 'attachments' => $attachments, 'subTitle' => $subTitle, 'start' => $start, 'end' => $end, 'chartUrl' => $chartUrl, 'location' => $location, 'balances' => $balances]);
}
/**
@@ -224,14 +221,16 @@ class ShowController extends Controller
// correct
Log::debug(sprintf('showAll: Call accountsBalancesOptimized with date/time "%s"', $end->toIso8601String()));
$now = now();
if ($now->gt($end) || $now->lt($start)) {
$now = $end;
}
// 2025-10-08 replace finalAccountBalance with accountsBalancesOptimized.
// $balances = Steam::finalAccountBalance($account, $end);
// $balances = Steam::filterAccountBalance($balances, $account, $this->convertToPrimary, $accountCurrency);
$balances = Steam::accountsBalancesOptimized(new Collection()->push($account), $end)[$account->id];
$balances = Steam::accountsBalancesOptimized(new Collection()->push($account), $now)[$account->id];
return view(
'accounts.show',
['account' => $account, 'showAll' => $showAll, 'location' => $location, 'objectType' => $objectType, 'isLiability' => $isLiability, 'attachments' => $attachments, 'currency' => $currency, 'today' => $today, 'chartUrl' => $chartUrl, 'periods' => $periods, 'subTitleIcon' => $subTitleIcon, 'groups' => $groups, 'subTitle' => $subTitle, 'start' => $start, 'end' => $end, 'balances' => $balances]
);
return view('accounts.show', ['account' => $account, 'showAll' => $showAll, 'location' => $location, 'objectType' => $objectType, 'isLiability' => $isLiability, 'attachments' => $attachments, 'currency' => $currency, 'today' => $today, 'chartUrl' => $chartUrl, 'periods' => $periods, 'subTitleIcon' => $subTitleIcon, 'groups' => $groups, 'subTitle' => $subTitle, 'start' => $start, 'end' => $end, 'balances' => $balances]);
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Bill;
use FireflyIII\Support\Facades\Navigation;
use Illuminate\Support\Facades\Log;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Bill;
@@ -151,7 +152,7 @@ class IndexController extends Controller
private function getSums(array $bills): array
{
$sums = [];
$range = app('navigation')->getViewRange(true);
$range = Navigation::getViewRange(true);
/** @var array $group */
foreach ($bills as $groupOrder => $group) {

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Bill;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -139,8 +140,8 @@ class ShowController extends Controller
$manager->parseIncludes(['attachments', 'notes']);
// add another period to end, could fix 8163
$range = app('navigation')->getViewRange(true);
$end = app('navigation')->addPeriod($end, $range);
$range = Navigation::getViewRange(true);
$end = Navigation::addPeriod($end, $range);
// Make a resource out of the data and
$parameters = new ParameterBag();

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Budget;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
@@ -94,11 +95,11 @@ class IndexController extends Controller
Log::debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
// collect some basic vars:
$range = app('navigation')->getViewRange(true);
$range = Navigation::getViewRange(true);
$isCustomRange = session('is_custom_range', false);
if (false === $isCustomRange) {
$start ??= session('start', today(config('app.timezone'))->startOfMonth());
$end ??= app('navigation')->endOfPeriod($start, $range);
$end ??= Navigation::endOfPeriod($start, $range);
}
// overrule start and end if necessary:
@@ -112,7 +113,7 @@ class IndexController extends Controller
$spent = '0';
// new period stuff:
$periodTitle = app('navigation')->periodShow($start, $range);
$periodTitle = Navigation::periodShow($start, $range);
$prevLoop = $this->getPreviousPeriods($start, $range);
$nextLoop = $this->getNextPeriods($start, $range);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Enums\TransactionTypeEnum;
@@ -514,7 +515,7 @@ class AccountController extends Controller
// have to make sure this chart is always based on the balance at the END of the period.
// This period depends on the size of the chart
$current = clone $start;
$current = app('navigation')->endOfX($current, $step, null);
$current = Navigation::endOfX($current, $step, null);
$format = (string)trans('config.month_and_day_js', [], $locale);
$accountCurrency = $this->accountRepository->getAccountCurrency($account);
Log::debug('Get and filter balance for entire range start');
@@ -574,9 +575,9 @@ class AccountController extends Controller
$label = $current->isoFormat($format);
$return[$key]['entries'][$label] = $amount;
}
$current = app('navigation')->addPeriod($current, $step);
$current = Navigation::addPeriod($current, $step);
// here too, to fix #8041, the data is corrected to the end of the period.
$current = app('navigation')->endOfX($current, $step, null);
$current = Navigation::endOfX($current, $step, null);
}
Log::debug('End of chart loop.');
// second loop (yes) to create nice array with info! Yay!

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -81,8 +82,8 @@ class CategoryController extends Controller
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class);
$start = $repository->firstUseDate($category) ?? $this->getDate();
$range = app('navigation')->getViewRange(false);
$start = app('navigation')->startOfPeriod($start, $range);
$range = Navigation::getViewRange(false);
$start = Navigation::startOfPeriod($start, $range);
$end = $this->getDate();
/** @var WholePeriodChartGenerator $chartGenerator */
@@ -178,8 +179,8 @@ class CategoryController extends Controller
$income = $opsRepository->listIncome($start, $end, $accounts, $collection);
}
$currencies = array_unique(array_merge(array_keys($income), array_keys($expenses)));
$periods = app('navigation')->listOfPeriods($start, $end);
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$periods = Navigation::listOfPeriods($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$chartData = [];
// make empty data array:
// double foreach (bad) to make empty array:
@@ -260,8 +261,8 @@ class CategoryController extends Controller
*/
public function specificPeriod(Category $category, Carbon $date): JsonResponse
{
$range = app('navigation')->getViewRange(false);
$start = app('navigation')->startOfPeriod($date, $range);
$range = Navigation::getViewRange(false);
$start = Navigation::startOfPeriod($date, $range);
$end = session()->get('end');
if ($end < $start) {
[$end, $start] = [$start, $end];

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -210,7 +211,7 @@ class CategoryReportController extends Controller
$chartData = [];
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, new Collection()->push($category));
$earned = $this->opsRepository->listIncome($start, $end, $accounts, new Collection()->push($category));
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
// loop expenses.
foreach ($spent as $currency) {
// add things to chart Data for each currency:
@@ -276,11 +277,11 @@ class CategoryReportController extends Controller
private function makeEntries(Carbon $start, Carbon $end): array
{
$return = [];
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$preferredRange = Navigation::preferredRangeFormat($start, $end);
$currentStart = clone $start;
while ($currentStart <= $end) {
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange);
$currentEnd = Navigation::endOfPeriod($currentStart, $preferredRange);
$key = $currentStart->isoFormat($format);
$return[$key] = '0';
$currentStart = clone $currentEnd;

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -154,7 +155,7 @@ class DoubleReportController extends Controller
$accounts = $accounts->merge($opposing);
$spent = $this->opsRepository->listExpenses($start, $end, $accounts);
$earned = $this->opsRepository->listIncome($start, $end, $accounts);
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
// loop expenses.
foreach ($spent as $currency) {
@@ -238,11 +239,11 @@ class DoubleReportController extends Controller
private function makeEntries(Carbon $start, Carbon $end): array
{
$return = [];
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$preferredRange = Navigation::preferredRangeFormat($start, $end);
$currentStart = clone $start;
while ($currentStart <= $end) {
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange);
$currentEnd = Navigation::endOfPeriod($currentStart, $preferredRange);
$key = $currentStart->isoFormat($format);
$return[$key] = '0';
$currentStart = clone $currentEnd;

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -83,8 +84,8 @@ class ExpenseReportController extends Controller
return response()->json($cache->get());
}
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$function = app('navigation')->preferredEndOfPeriod($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$function = Navigation::preferredEndOfPeriod($start, $end);
$chartData = [];
$currentStart = clone $start;
$combined = $this->combineAccounts($expense);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -92,7 +93,7 @@ class PiggyBankController extends Controller
$currentSum = $filtered->sum('amount');
$label = $oldest->isoFormat((string) trans('config.month_and_day_js', [], $locale));
$chartData[$label] = $currentSum;
$oldest = app('navigation')->addPeriod($oldest, $step);
$oldest = Navigation::addPeriod($oldest, $step);
}
$finalFiltered = $set->filter(
static fn (PiggyBankEvent $event) => $event->date->lte($today)

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
@@ -154,9 +155,9 @@ class ReportController extends Controller
Log::debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
Log::debug(sprintf('Period: %s to %s', $start->toW3cString(), $end->toW3cString()));
$format = app('navigation')->preferredCarbonFormat($start, $end);
$titleFormat = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end);
$format = Navigation::preferredCarbonFormat($start, $end);
$titleFormat = Navigation::preferredCarbonLocalizedFormat($start, $end);
$preferredRange = Navigation::preferredRangeFormat($start, $end);
$ids = $accounts->pluck('id')->toArray();
$data = [];
$chartData = [];
@@ -242,7 +243,7 @@ class ReportController extends Controller
// #8374. Sloppy fix for yearly charts. Not really interested in a better fix with v2 layout and all.
if ('1Y' === $preferredRange) {
$currentEnd = app('navigation')->endOfPeriod($currentEnd, $preferredRange);
$currentEnd = Navigation::endOfPeriod($currentEnd, $preferredRange);
}
Log::debug('Start of sub-loop');
while ($currentStart <= $currentEnd) {
@@ -260,7 +261,7 @@ class ReportController extends Controller
$expense['entries'][$title] = '0';
}
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange);
$currentStart = Navigation::addPeriod($currentStart, $preferredRange);
}
Log::debug('End of sub-loop');

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
@@ -214,7 +215,7 @@ class TagReportController extends Controller
$chartData = [];
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, new Collection()->push($tag));
$earned = $this->opsRepository->listIncome($start, $end, $accounts, new Collection()->push($tag));
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
// loop expenses.
foreach ($spent as $currency) {
@@ -281,11 +282,11 @@ class TagReportController extends Controller
private function makeEntries(Carbon $start, Carbon $end): array
{
$return = [];
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end);
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$preferredRange = Navigation::preferredRangeFormat($start, $end);
$currentStart = clone $start;
while ($currentStart <= $end) {
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange);
$currentEnd = Navigation::endOfPeriod($currentStart, $preferredRange);
$key = $currentStart->isoFormat($format);
$return[$key] = '0';
$currentStart = clone $currentEnd;

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Events\Preferences\UserGroupChangedPrimaryCurrency;
@@ -101,7 +102,7 @@ class PreferencesController extends Controller
/** @var array<int, int> $accountIds */
$accountIds = $accounts->pluck('id')->toArray();
$viewRange = app('navigation')->getViewRange(false);
$viewRange = Navigation::getViewRange(false);
$frontpageAccountsPref = Preferences::get('frontpageAccounts', $accountIds);
$frontpageAccounts = $frontpageAccountsPref->data;
if (!is_array($frontpageAccounts)) {

View File

@@ -173,15 +173,15 @@ class EditController extends Controller
*/
public function update(RecurrenceFormRequest $request, Recurrence $recurrence)
{
$data = $request->getAll();
$this->repository->update($recurrence, $data);
$data = $request->getAll();
$recurrence = $this->repository->update($recurrence, $data);
$request->session()->flash('success', (string) trans('firefly.updated_recurrence', ['title' => $recurrence->title]));
Log::channel('audit')->info(sprintf('Updated recurrence #%d.', $recurrence->id), $data);
// store new attachment(s):
/** @var null|array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($recurrence, $files);
}
@@ -194,7 +194,7 @@ class EditController extends Controller
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments'));
}
app('preferences')->mark();
$redirect = redirect($this->getPreviousUrl('recurrences.edit.url'));
$redirect = redirect($this->getPreviousUrl('recurrences.edit.url'));
if (1 === (int) $request->get('return_to_edit')) {
// set value so edit routine will not overwrite URL:
$request->session()->put('recurrences.edit.fromUpdate', true);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Report;
use FireflyIII\Support\Facades\Navigation;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
@@ -485,7 +486,7 @@ class CategoryController extends Controller
// depending on the carbon format (a reliable way to determine the general date difference)
// change the "listOfPeriods" call so the entire period gets included correctly.
$format = app('navigation')->preferredCarbonFormat($start, $end);
$format = Navigation::preferredCarbonFormat($start, $end);
if ('Y' === $format) {
$start->startOfYear();
@@ -494,7 +495,7 @@ class CategoryController extends Controller
$start->startOfMonth();
}
$periods = app('navigation')->listOfPeriods($start, $end);
$periods = Navigation::listOfPeriods($start, $end);
$data = [];
$with = $this->opsRepository->listExpenses($start, $end, $accounts);
$without = $this->noCatRepository->listExpenses($start, $end, $accounts);
@@ -559,7 +560,7 @@ class CategoryController extends Controller
// depending on the carbon format (a reliable way to determine the general date difference)
// change the "listOfPeriods" call so the entire period gets included correctly.
$format = app('navigation')->preferredCarbonFormat($start, $end);
$format = Navigation::preferredCarbonFormat($start, $end);
if ('Y' === $format) {
$start->startOfYear();
@@ -568,7 +569,7 @@ class CategoryController extends Controller
$start->startOfMonth();
}
$periods = app('navigation')->listOfPeriods($start, $end);
$periods = Navigation::listOfPeriods($start, $end);
$data = [];
$with = $this->opsRepository->listIncome($start, $end, $accounts);
$without = $this->noCatRepository->listIncome($start, $end, $accounts);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use Closure;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
@@ -75,8 +76,8 @@ class Range
}
$today = today(config('app.timezone'));
$start = app('navigation')->updateStartDate((string) $viewRange, $today);
$end = app('navigation')->updateEndDate((string) $viewRange, $start);
$start = Navigation::updateStartDate((string) $viewRange, $today);
$end = Navigation::updateEndDate((string) $viewRange, $start);
app('session')->put('start', $start);
app('session')->put('end', $end);

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Jobs;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\AutoBudgetType;
use FireflyIII\Exceptions\FireflyException;
@@ -122,8 +123,8 @@ class CreateAutoBudgetLimits implements ShouldQueue
);
// get date range for budget limit, based on range in auto-budget
$start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
$end = app('navigation')->endOfPeriod($start, $autoBudget->period);
$start = Navigation::startOfPeriod($this->date, $autoBudget->period);
$end = Navigation::endOfPeriod($start, $autoBudget->period);
// find budget limit:
$budgetLimit = $this->findBudgetLimit($autoBudget->budget, $start, $end);
@@ -237,12 +238,12 @@ class CreateAutoBudgetLimits implements ShouldQueue
{
Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id));
// current period:
$start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
$end = app('navigation')->endOfPeriod($start, $autoBudget->period);
$start = Navigation::startOfPeriod($this->date, $autoBudget->period);
$end = Navigation::endOfPeriod($start, $autoBudget->period);
// which means previous period:
$previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period);
$previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period);
$previousStart = Navigation::subtractPeriod($start, $autoBudget->period);
$previousEnd = Navigation::endOfPeriod($previousStart, $autoBudget->period);
Log::debug(
sprintf(
@@ -297,12 +298,12 @@ class CreateAutoBudgetLimits implements ShouldQueue
{
Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id));
// current period:
$start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
$end = app('navigation')->endOfPeriod($start, $autoBudget->period);
$start = Navigation::startOfPeriod($this->date, $autoBudget->period);
$end = Navigation::endOfPeriod($start, $autoBudget->period);
// which means previous period:
$previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period);
$previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period);
$previousStart = Navigation::subtractPeriod($start, $autoBudget->period);
$previousEnd = Navigation::endOfPeriod($previousStart, $autoBudget->period);
Log::debug(
sprintf(

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Bill;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\BillFactory;
@@ -463,11 +464,11 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
while ($start < $date) {
Log::debug(sprintf('$start (%s) < $date (%s)', $start->format('Y-m-d H:i:s'), $date->format('Y-m-d H:i:s')));
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
$start = Navigation::addPeriod($start, $bill->repeat_freq, $bill->skip);
Log::debug('Start is now '.$start->format('Y-m-d H:i:s'));
}
$end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
$end = Navigation::addPeriod($start, $bill->repeat_freq, $bill->skip);
$end->endOfDay();
// see if the bill was paid in this period.
@@ -477,7 +478,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
// this period had in fact a bill. The new start is the current end, and we create a new end.
Log::debug(sprintf('Journal count is %d, so start becomes %s', $journalCount, $end->format('Y-m-d')));
$start = clone $end;
$end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
$end = Navigation::addPeriod($start, $bill->repeat_freq, $bill->skip);
}
Log::debug('nextExpectedMatch: Final start is '.$start->format('Y-m-d'));
Log::debug('nextExpectedMatch: Matching end is '.$end->format('Y-m-d'));
@@ -681,7 +682,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
$start = clone $bill->date;
while ($start < $date) {
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
$start = Navigation::addPeriod($start, $bill->repeat_freq, $bill->skip);
}
$cache->store($start);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Budget;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\AutoBudgetType;
use FireflyIII\Enums\TransactionTypeEnum;
@@ -790,8 +791,8 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface
// create initial budget limit.
$today = today(config('app.timezone'));
$start = app('navigation')->startOfPeriod($today, $autoBudget->period);
$end = app('navigation')->endOfPeriod($start, $autoBudget->period);
$start = Navigation::startOfPeriod($today, $autoBudget->period);
$end = Navigation::endOfPeriod($start, $autoBudget->period);
$limitRepos = app(BudgetLimitRepositoryInterface::class);
$limitRepos->setUser($this->user);

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Budget;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
@@ -45,7 +46,7 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface, UserGroupInterf
#[Deprecated]
public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array
{
$carbonFormat = app('navigation')->preferredCarbonFormat($start, $end);
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Budget;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use Deprecated;
use FireflyIII\Enums\TransactionTypeEnum;
@@ -82,7 +83,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
#[Deprecated]
public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array
{
$carbonFormat = app('navigation')->preferredCarbonFormat($start, $end);
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
$data = [];
// get all transactions:

View File

@@ -76,7 +76,6 @@ class JournalRepository implements JournalRepositoryInterface, UserGroupInterfac
*/
public function firstNull(): ?TransactionJournal
{
/** @var null|TransactionJournal $entry */
return $this->user->transactionJournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']);
}
@@ -113,7 +112,6 @@ class JournalRepository implements JournalRepositoryInterface, UserGroupInterfac
public function getLast(): ?TransactionJournal
{
/** @var null|TransactionJournal $entry */
return $this->user->transactionJournals()->orderBy('date', 'DESC')->first(['transaction_journals.*']);
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Chart\Category;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Models\Category;
@@ -59,10 +60,10 @@ class WholePeriodChartGenerator
while ($current <= $end) {
$key = $current->format('Y-m-d');
$currentEnd = app('navigation')->endOfPeriod($current, $step);
$currentEnd = Navigation::endOfPeriod($current, $step);
$spent[$key] = $opsRepository->sumExpenses($current, $currentEnd, $accounts, $collection);
$earned[$key] = $opsRepository->sumIncome($current, $currentEnd, $accounts, $collection);
$current = app('navigation')->addPeriod($current, $step);
$current = Navigation::addPeriod($current, $step);
}
$currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned);
@@ -91,7 +92,7 @@ class WholePeriodChartGenerator
while ($current <= $end) {
$key = $current->format('Y-m-d');
$label = app('navigation')->periodShow($current, $step);
$label = Navigation::periodShow($current, $step);
/** @var array $currency */
foreach ($currencies as $currency) {
@@ -104,7 +105,7 @@ class WholePeriodChartGenerator
$chartData[$spentInfoKey]['entries'][$label] = app('steam')->bcround($spentAmount, $currency['currency_decimal_places']);
$chartData[$earnedInfoKey]['entries'][$label] = app('steam')->bcround($earnedAmount, $currency['currency_decimal_places']);
}
$current = app('navigation')->addPeriod($current, $step);
$current = Navigation::addPeriod($current, $step);
}
return $chartData;

View File

@@ -107,7 +107,7 @@ trait AccountFilter
}
if (0 === count($return)) {
$return = $this->types['normal'];
return $this->types['normal'];
}
return $return;

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Http\Controllers;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
/**
@@ -93,18 +94,18 @@ trait DateCalculation
$loop = [];
/** @var Carbon $current */
$current = app('navigation')->startOfPeriod($date, $range);
$current = app('navigation')->endOfPeriod($current, $range);
$current = Navigation::startOfPeriod($date, $range);
$current = Navigation::endOfPeriod($current, $range);
$current->addDay();
$count = 0;
while ($count < 12) {
$current = app('navigation')->endOfPeriod($current, $range);
$currentStart = app('navigation')->startOfPeriod($current, $range);
$current = Navigation::endOfPeriod($current, $range);
$currentStart = Navigation::startOfPeriod($current, $range);
$loop[] = [
'label' => $current->format('Y-m-d'),
'title' => app('navigation')->periodShow($current, $range),
'title' => Navigation::periodShow($current, $range),
'start' => clone $currentStart,
'end' => clone $current,
];
@@ -125,15 +126,15 @@ trait DateCalculation
$loop = [];
/** @var Carbon $current */
$current = app('navigation')->startOfPeriod($date, $range);
$current = Navigation::startOfPeriod($date, $range);
$count = 0;
while ($count < 12) {
$current->subDay();
$current = app('navigation')->startOfPeriod($current, $range);
$currentEnd = app('navigation')->endOfPeriod($current, $range);
$current = Navigation::startOfPeriod($current, $range);
$currentEnd = Navigation::endOfPeriod($current, $range);
$loop[] = [
'label' => $current->format('Y-m-d'),
'title' => app('navigation')->periodShow($current, $range),
'title' => Navigation::periodShow($current, $range),
'start' => clone $current,
'end' => clone $currentEnd,
];

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Http\Controllers;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Facades\FireflyConfig;
@@ -82,7 +83,7 @@ trait GetConfigurationData
*/
protected function getDateRangeConfig(): array // get configuration + get preferences.
{
$viewRange = app('navigation')->getViewRange(false);
$viewRange = Navigation::getViewRange(false);
Log::debug(sprintf('dateRange: the view range is "%s"', $viewRange));
@@ -105,32 +106,32 @@ trait GetConfigurationData
// when current range is a custom range, add the current period as the next range.
if ($isCustom) {
$index = app('navigation')->periodShow($start, $viewRange);
$customPeriodStart = app('navigation')->startOfPeriod($start, $viewRange);
$customPeriodEnd = app('navigation')->endOfPeriod($customPeriodStart, $viewRange);
$index = Navigation::periodShow($start, $viewRange);
$customPeriodStart = Navigation::startOfPeriod($start, $viewRange);
$customPeriodEnd = Navigation::endOfPeriod($customPeriodStart, $viewRange);
$ranges[$index] = [$customPeriodStart, $customPeriodEnd];
}
// then add previous range and next range, but skip this for the lastX and YTD stuff.
if (!in_array($viewRange, config('firefly.dynamic_date_ranges', []), true)) {
$previousDate = app('navigation')->subtractPeriod($start, $viewRange);
$index = app('navigation')->periodShow($previousDate, $viewRange);
$previousStart = app('navigation')->startOfPeriod($previousDate, $viewRange);
$previousEnd = app('navigation')->endOfPeriod($previousStart, $viewRange);
$previousDate = Navigation::subtractPeriod($start, $viewRange);
$index = Navigation::periodShow($previousDate, $viewRange);
$previousStart = Navigation::startOfPeriod($previousDate, $viewRange);
$previousEnd = Navigation::endOfPeriod($previousStart, $viewRange);
$ranges[$index] = [$previousStart, $previousEnd];
$nextDate = app('navigation')->addPeriod($start, $viewRange);
$index = app('navigation')->periodShow($nextDate, $viewRange);
$nextStart = app('navigation')->startOfPeriod($nextDate, $viewRange);
$nextEnd = app('navigation')->endOfPeriod($nextStart, $viewRange);
$nextDate = Navigation::addPeriod($start, $viewRange);
$index = Navigation::periodShow($nextDate, $viewRange);
$nextStart = Navigation::startOfPeriod($nextDate, $viewRange);
$nextEnd = Navigation::endOfPeriod($nextStart, $viewRange);
$ranges[$index] = [$nextStart, $nextEnd];
}
// today:
/** @var Carbon $todayStart */
$todayStart = app('navigation')->startOfPeriod($today, $viewRange);
$todayStart = Navigation::startOfPeriod($today, $viewRange);
/** @var Carbon $todayEnd */
$todayEnd = app('navigation')->endOfPeriod($todayStart, $viewRange);
$todayEnd = Navigation::endOfPeriod($todayStart, $viewRange);
if ($todayStart->ne($start) || $todayEnd->ne($end)) {
$ranges[ucfirst((string)trans('firefly.today'))] = [$todayStart, $todayEnd];

View File

@@ -56,23 +56,23 @@ use function Safe\json_decode;
class RecurringEnrichment implements EnrichmentInterface
{
private array $accounts = [];
private array $accounts = [];
private Collection $collection;
// private array $transactionTypeIds = [];
// private array $transactionTypes = [];
private readonly bool $convertToPrimary;
private array $currencies = [];
private array $currencyIds = [];
private array $destinationAccountIds = [];
private array $foreignCurrencyIds = [];
private array $ids = [];
private string $language = 'en_US';
private array $notes = [];
private readonly bool $convertToPrimary;
private array $currencies = [];
private array $currencyIds = [];
private array $destinationAccountIds = [];
private array $foreignCurrencyIds = [];
private array $ids = [];
private string $language = 'en_US';
private array $notes = [];
private readonly TransactionCurrency $primaryCurrency;
private array $recurrenceIds = [];
private array $repetitions = [];
private array $sourceAccountIds = [];
private array $transactions = [];
private array $recurrenceByTransaction = [];
private array $repetitions = [];
private array $sourceAccountIds = [];
private array $transactions = [];
private User $user;
private UserGroup $userGroup;
@@ -84,6 +84,7 @@ class RecurringEnrichment implements EnrichmentInterface
public function enrich(Collection $collection): Collection
{
Log::debug(__METHOD__);
$this->collection = $collection;
$this->collectIds();
$this->collectRepetitions();
@@ -194,6 +195,7 @@ class RecurringEnrichment implements EnrichmentInterface
foreach ($accounts as $account) {
$id = (int)$account->id;
$this->accounts[$id] = $account;
Log::debug(sprintf('Collected account #%d', $id));
}
}
@@ -279,6 +281,7 @@ class RecurringEnrichment implements EnrichmentInterface
foreach ($currencies as $currency) {
$id = (int)$currency->id;
$this->currencies[$id] = $currency;
Log::debug(sprintf('Collected currency #%d', $id));
}
}
@@ -287,18 +290,11 @@ class RecurringEnrichment implements EnrichmentInterface
/** @var Recurrence $recurrence */
foreach ($this->collection as $recurrence) {
$id = (int)$recurrence->id;
// $typeId = (int)$recurrence->transaction_type_id;
$this->ids[] = $id;
// $this->transactionTypeIds[$id] = $typeId;
Log::debug(sprintf('Collected recurrence id #%d', $id));
}
$this->ids = array_unique($this->ids);
// collect transaction types.
// $transactionTypes = TransactionType::whereIn('id', array_unique($this->transactionTypeIds))->get();
// foreach ($transactionTypes as $transactionType) {
// $id = (int)$transactionType->id;
// $this->transactionTypes[$id] = TransactionTypeEnum::from($transactionType->type);
// }
Log::debug('Final array:', $this->ids);
}
private function collectNotes(): void
@@ -306,10 +302,12 @@ class RecurringEnrichment implements EnrichmentInterface
$notes = Note::query()->whereIn('noteable_id', $this->ids)
->whereNotNull('notes.text')
->where('notes.text', '!=', '')
->where('noteable_type', Recurrence::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
->where('noteable_type', Recurrence::class)->get(['notes.id', 'notes.noteable_id', 'notes.text'])->toArray()
;
foreach ($notes as $note) {
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
$notableId = (int)$note['noteable_id'];
$this->notes[$notableId] = (string)$note['text'];
Log::debug(sprintf('Collected note #%d for recurrence #%d', $note['id'], $notableId));
}
Log::debug(sprintf('Enrich with %d note(s)', count($this->notes)));
}
@@ -341,22 +339,23 @@ class RecurringEnrichment implements EnrichmentInterface
/** @var RecurrenceRepetition $repetition */
foreach ($set as $repetition) {
$recurrence = $this->collection->filter(fn (Recurrence $item): bool => (int)$item->id === (int)$repetition->recurrence_id)->first();
$fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
$id = (int)$repetition->recurrence_id;
$repId = (int)$repetition->id;
$this->repetitions[$id] ??= [];
$recurrence = $this->collection->filter(fn (Recurrence $item): bool => (int)$item->id === (int)$repetition->recurrence_id)->first();
$fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
$recurrenceId = (int)$repetition->recurrence_id;
$repId = (int)$repetition->id;
$this->repetitions[$recurrenceId] ??= [];
Log::debug(sprintf('Collected repetition #%d of recurrence #%d.', $repId, $recurrenceId));
// get the (future) occurrences for this specific type of repetition:
$amount = 'daily' === $repetition->repetition_type ? 9 : 5;
$set = $repository->getXOccurrencesSince($repetition, $fromDate, now(config('app.timezone')), $amount);
$occurrences = [];
$amount = 'daily' === $repetition->repetition_type ? 9 : 5;
$set = $repository->getXOccurrencesSince($repetition, $fromDate, now(config('app.timezone')), $amount);
$occurrences = [];
/** @var Carbon $carbon */
foreach ($set as $carbon) {
$occurrences[] = $carbon->toAtomString();
}
$this->repetitions[$id][$repId] = [
$this->repetitions[$recurrenceId][$repId] = [
'id' => (string)$repId,
'created_at' => $repetition->created_at->toAtomString(),
'updated_at' => $repetition->updated_at->toAtomString(),
@@ -373,8 +372,11 @@ class RecurringEnrichment implements EnrichmentInterface
private function collectTransactionMetaData(): void
{
$ids = array_keys($this->transactions);
$meta = RecurrenceTransactionMeta::whereNull('deleted_at')->whereIn('rt_id', $ids)->get();
$rtIds = [];
foreach ($this->ids as $recurrenceId) {
$rtIds = array_merge($rtIds, array_keys($this->transactions[$recurrenceId]));
}
$meta = RecurrenceTransactionMeta::whereNull('deleted_at')->whereIn('rt_id', $rtIds)->get();
// other meta-data to be collected:
$billIds = [];
$piggyBankIds = [];
@@ -386,10 +388,11 @@ class RecurringEnrichment implements EnrichmentInterface
$transactionId = (int)$entry->rt_id;
// this should refer to another array, were rtIds can be used to find the recurrence.
$recurrenceId = $this->recurrenceIds[$transactionId] ?? 0;
$recurrenceId = $this->recurrenceByTransaction[$transactionId] ?? 0;
Log::debug(sprintf('Collecting meta data entry #%d for recurrence transaction #%d, for recurrence #%d ', $id, $transactionId, $recurrenceId));
$name = (string)($entry->name ?? '');
if (0 === $recurrenceId) {
Log::error(sprintf('Could not find recurrence ID for recurrence transaction ID %d', $transactionId));
Log::error(sprintf('Could not find recurrence ID for recurrence transaction ID #%d', $transactionId));
continue;
}
@@ -487,16 +490,16 @@ class RecurringEnrichment implements EnrichmentInterface
/** @var RecurrenceTransaction $transaction */
foreach ($set as $transaction) {
$id = (int)$transaction->recurrence_id;
$transactionId = (int)$transaction->id;
$this->recurrenceIds[$transactionId] = $id;
$this->transactions[$id] ??= [];
$amount = $transaction->amount;
$foreignAmount = $transaction->foreign_amount;
$recurrenceId = (int)$transaction->recurrence_id;
$transactionId = (int)$transaction->id;
$this->recurrenceByTransaction[$transactionId] = $recurrenceId;
$this->transactions[$recurrenceId] ??= [];
$amount = $transaction->amount;
$foreignAmount = $transaction->foreign_amount;
Log::debug(sprintf('Collected transaction #%d of recurrence #%d', $transactionId, $recurrenceId));
$this->transactions[$id][$transactionId] = [
$this->transactions[$recurrenceId][$transactionId] = [
'id' => (string)$transactionId,
// 'recurrence_id' => $id,
'transaction_currency_id' => (int)$transaction->transaction_currency_id,
'foreign_currency_id' => null === $transaction->foreign_currency_id ? null : (int)$transaction->foreign_currency_id,
'source_id' => (int)$transaction->source_id,
@@ -518,10 +521,10 @@ class RecurringEnrichment implements EnrichmentInterface
'subscription_name' => null,
];
// collect all kinds of meta data to be collected later.
$this->currencyIds[$transactionId] = (int)$transaction->transaction_currency_id;
$this->sourceAccountIds[$transactionId] = (int)$transaction->source_id;
$this->destinationAccountIds[$transactionId] = (int)$transaction->destination_id;
// collect all kinds of meta-data to be collected later.
$this->currencyIds[$transactionId] = (int)$transaction->transaction_currency_id;
$this->sourceAccountIds[$transactionId] = (int)$transaction->source_id;
$this->destinationAccountIds[$transactionId] = (int)$transaction->destination_id;
if (null !== $transaction->foreign_currency_id) {
$this->foreignCurrencyIds[$transactionId] = (int)$transaction->foreign_currency_id;
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Models;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
@@ -49,7 +50,7 @@ class BillDateCalculator
Log::debug(sprintf('Dates must be between %s and %s.', $earliest->format('Y-m-d'), $latest->format('Y-m-d')));
Log::debug(sprintf('Bill started on %s, period is "%s", skip is %d, last paid = "%s".', $billStart->format('Y-m-d'), $period, $skip, $lastPaid?->format('Y-m-d')));
$daysUntilEOM = app('navigation')->daysUntilEndOfMonth($billStart);
$daysUntilEOM = Navigation::daysUntilEndOfMonth($billStart);
Log::debug(sprintf('For bill start, days until end of month is %d', $daysUntilEOM));
$set = new Collection();
@@ -94,7 +95,7 @@ class BillDateCalculator
// the next expected month because that month has only 28 days (i.e. february).
// this applies to leap years as well.
if ($daysUntilEOM < 4) {
$nextUntilEOM = app('navigation')->daysUntilEndOfMonth($nextExpectedMatch);
$nextUntilEOM = Navigation::daysUntilEndOfMonth($nextExpectedMatch);
$diffEOM = $daysUntilEOM - $nextUntilEOM;
if ($diffEOM > 0) {
Log::debug(sprintf('Bill start is %d days from the end of the month. nextExceptedMatch is %d days from the end of the month.', $daysUntilEOM, $nextUntilEOM));
@@ -140,7 +141,7 @@ class BillDateCalculator
return $billStartDate;
}
$steps = app('navigation')->diffInPeriods($period, $skip, $earliest, $billStartDate);
$steps = Navigation::diffInPeriods($period, $skip, $earliest, $billStartDate);
if ($steps === $this->diffInMonths) {
Log::debug(sprintf('Steps is %d, which is the same as diffInMonths (%d), so we add another 1.', $steps, $this->diffInMonths));
++$steps;
@@ -150,7 +151,7 @@ class BillDateCalculator
if ($steps > 0) {
--$steps;
Log::debug(sprintf('Steps is %d, because addPeriod already adds 1.', $steps));
$result = app('navigation')->addPeriod($billStartDate, $period, $steps);
$result = Navigation::addPeriod($billStartDate, $period, $steps);
}
Log::debug(sprintf('Number of steps is %d, added to %s, result is %s', $steps, $billStartDate->format('Y-m-d'), $result->format('Y-m-d')));

View File

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

View File

@@ -29,11 +29,13 @@ use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Support\Facades\Navigation;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Spatie\Period\Boundaries;
use Spatie\Period\Exceptions\InvalidPeriod;
use Spatie\Period\Period;
use Spatie\Period\Precision;
@@ -171,9 +173,16 @@ trait RecalculatesAvailableBudgetsTrait
}
$viewRange = (string)$viewRange;
$start = app('navigation')->startOfPeriod($budgetLimit->start_date, $viewRange);
$end = app('navigation')->startOfPeriod($budgetLimit->end_date, $viewRange);
$end = app('navigation')->endOfPeriod($end, $viewRange);
$start = Navigation::startOfPeriod($budgetLimit->start_date, $viewRange);
$end = Navigation::startOfPeriod($budgetLimit->end_date, $viewRange);
$end = Navigation::endOfPeriod($end, $viewRange);
if ($end < $start) {
[$start, $end] = [$end, $start];
$budgetLimit->start_date = $start;
$budgetLimit->end_date = $end;
$budgetLimit->saveQuietly();
}
// limit period in total is:
$limitPeriod = Period::make($start, $end, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
@@ -182,7 +191,7 @@ trait RecalculatesAvailableBudgetsTrait
// from the start until the end of the budget limit, need to loop!
$current = clone $start;
while ($current <= $end) {
$currentEnd = app('navigation')->endOfPeriod($current, $viewRange);
$currentEnd = Navigation::endOfPeriod($current, $viewRange);
// create or find AB for this particular period, and set the amount accordingly.
/** @var null|AvailableBudget $availableBudget */
@@ -194,10 +203,18 @@ trait RecalculatesAvailableBudgetsTrait
}
if (null === $availableBudget) {
Log::debug('No AB found, will create.');
// if not exists:
$currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
$daily = $this->getDailyAmount($budgetLimit);
$amount = bcmul((string) $daily, (string)$currentPeriod->length(), 12);
try {
$currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
} catch (InvalidPeriod $e) {
Log::error('Tried to make invalid period.');
Log::error($e->getMessage());
continue;
}
$daily = $this->getDailyAmount($budgetLimit);
$amount = bcmul((string)$daily, (string)$currentPeriod->length(), 12);
// no need to calculate if period is equal.
if ($currentPeriod->equals($limitPeriod)) {
@@ -227,7 +244,7 @@ trait RecalculatesAvailableBudgetsTrait
}
// prep for next loop
$current = app('navigation')->addPeriod($current, $viewRange);
$current = Navigation::addPeriod($current, $viewRange);
}
}
}

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use FireflyIII\Enums\TransactionTypeEnum;
use Illuminate\Support\Facades\Log;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
@@ -54,6 +55,13 @@ class AddTag implements ActionInterface
$tagName = $this->action->getValue($journal);
$tag = $factory->findOrCreate($tagName);
$type = $journal['transaction_type_type'];
if (TransactionTypeEnum::OPENING_BALANCE->value === $type || TransactionTypeEnum::LIABILITY_CREDIT->value === $type || TransactionTypeEnum::INVALID->value === $type) {
// fail silently on invalid transaction types.
return false;
}
if (null === $tag) {
// could not find, could not create tag.
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.find_or_create_tag_failed', ['tag' => $tagName])));
@@ -61,11 +69,7 @@ class AddTag implements ActionInterface
return false;
}
$count = DB::table('tag_transaction_journal')
->where('tag_id', $tag->id)
->where('transaction_journal_id', $journal['transaction_journal_id'])
->count()
;
$count = DB::table('tag_transaction_journal')->where('tag_id', $tag->id)->where('transaction_journal_id', $journal['transaction_journal_id'])->count();
if (0 === $count) {
// add to journal:
DB::table('tag_transaction_journal')->insert(['tag_id' => $tag->id, 'transaction_journal_id' => $journal['transaction_journal_id']]);

View File

@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 6.4.9 - 2025-11-xx
### Fixed
- [Discussion 11211](https://github.com/orgs/firefly-iii/discussions/11211) (question about Transaction journal ID) started by @zhiiwg
- [Issue 11267](https://github.com/firefly-iii/firefly-iii/issues/11267) (Tags can be added to elements that can't be removed) reported by @Fmstrat
### API
- [Issue 11265](https://github.com/firefly-iii/firefly-iii/issues/11265) (Inconsistent object type in exchange rates API) reported by @jfpedroza
## 6.4.8 - 2025-11-14
### Fixed

260
composer.lock generated
View File

@@ -8,16 +8,16 @@
"packages": [
{
"name": "bacon/bacon-qr-code",
"version": "v3.0.1",
"version": "v3.0.3",
"source": {
"type": "git",
"url": "https://github.com/Bacon/BaconQrCode.git",
"reference": "f9cc1f52b5a463062251d666761178dbdb6b544f"
"reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/f9cc1f52b5a463062251d666761178dbdb6b544f",
"reference": "f9cc1f52b5a463062251d666761178dbdb6b544f",
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/36a1cb2b81493fa5b82e50bf8068bf84d1542563",
"reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563",
"shasum": ""
},
"require": {
@@ -27,8 +27,9 @@
},
"require-dev": {
"phly/keep-a-changelog": "^2.12",
"phpunit/phpunit": "^10.5.11 || 11.0.4",
"phpunit/phpunit": "^10.5.11 || ^11.0.4",
"spatie/phpunit-snapshot-assertions": "^5.1.5",
"spatie/pixelmatch-php": "^1.2.0",
"squizlabs/php_codesniffer": "^3.9"
},
"suggest": {
@@ -56,9 +57,9 @@
"homepage": "https://github.com/Bacon/BaconQrCode",
"support": {
"issues": "https://github.com/Bacon/BaconQrCode/issues",
"source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.1"
"source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.3"
},
"time": "2024-10-01T13:55:55+00:00"
"time": "2025-11-19T17:15:36+00:00"
},
{
"name": "beberlei/assert",
@@ -129,16 +130,16 @@
},
{
"name": "brick/math",
"version": "0.14.0",
"version": "0.14.1",
"source": {
"type": "git",
"url": "https://github.com/brick/math.git",
"reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2"
"reference": "f05858549e5f9d7bb45875a75583240a38a281d0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2",
"reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2",
"url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0",
"reference": "f05858549e5f9d7bb45875a75583240a38a281d0",
"shasum": ""
},
"require": {
@@ -177,7 +178,7 @@
],
"support": {
"issues": "https://github.com/brick/math/issues",
"source": "https://github.com/brick/math/tree/0.14.0"
"source": "https://github.com/brick/math/tree/0.14.1"
},
"funding": [
{
@@ -185,7 +186,7 @@
"type": "github"
}
],
"time": "2025-08-29T12:40:03+00:00"
"time": "2025-11-24T14:40:29+00:00"
},
{
"name": "carbonphp/carbon-doctrine-types",
@@ -1937,16 +1938,16 @@
},
{
"name": "laravel/framework",
"version": "v12.38.1",
"version": "v12.40.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "7f3012af6059f5f64a12930701cd8caed6cf7c17"
"reference": "2e986acbf9acf62cba13400bc23c4d639bf188b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/7f3012af6059f5f64a12930701cd8caed6cf7c17",
"reference": "7f3012af6059f5f64a12930701cd8caed6cf7c17",
"url": "https://api.github.com/repos/laravel/framework/zipball/2e986acbf9acf62cba13400bc23c4d639bf188b9",
"reference": "2e986acbf9acf62cba13400bc23c4d639bf188b9",
"shasum": ""
},
"require": {
@@ -2058,7 +2059,7 @@
"league/flysystem-sftp-v3": "^3.25.1",
"mockery/mockery": "^1.6.10",
"opis/json-schema": "^2.4.1",
"orchestra/testbench-core": "^10.7.0",
"orchestra/testbench-core": "^10.8.0",
"pda/pheanstalk": "^5.0.6|^7.0.0",
"php-http/discovery": "^1.15",
"phpstan/phpstan": "^2.0",
@@ -2152,7 +2153,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-11-13T02:12:47+00:00"
"time": "2025-11-25T16:16:33+00:00"
},
{
"name": "laravel/passport",
@@ -2232,16 +2233,16 @@
},
{
"name": "laravel/prompts",
"version": "v0.3.7",
"version": "v0.3.8",
"source": {
"type": "git",
"url": "https://github.com/laravel/prompts.git",
"reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc"
"reference": "096748cdfb81988f60090bbb839ce3205ace0d35"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/prompts/zipball/a1891d362714bc40c8d23b0b1d7090f022ea27cc",
"reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc",
"url": "https://api.github.com/repos/laravel/prompts/zipball/096748cdfb81988f60090bbb839ce3205ace0d35",
"reference": "096748cdfb81988f60090bbb839ce3205ace0d35",
"shasum": ""
},
"require": {
@@ -2257,7 +2258,7 @@
"require-dev": {
"illuminate/collections": "^10.0|^11.0|^12.0",
"mockery/mockery": "^1.5",
"pestphp/pest": "^2.3|^3.4",
"pestphp/pest": "^2.3|^3.4|^4.0",
"phpstan/phpstan": "^1.12.28",
"phpstan/phpstan-mockery": "^1.1.3"
},
@@ -2285,22 +2286,22 @@
"description": "Add beautiful and user-friendly forms to your command-line applications.",
"support": {
"issues": "https://github.com/laravel/prompts/issues",
"source": "https://github.com/laravel/prompts/tree/v0.3.7"
"source": "https://github.com/laravel/prompts/tree/v0.3.8"
},
"time": "2025-09-19T13:47:56+00:00"
"time": "2025-11-21T20:52:52+00:00"
},
{
"name": "laravel/sanctum",
"version": "v4.2.0",
"version": "v4.2.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
"reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677"
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677",
"reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664",
"shasum": ""
},
"require": {
@@ -2314,9 +2315,8 @@
},
"require-dev": {
"mockery/mockery": "^1.6",
"orchestra/testbench": "^9.0|^10.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^11.3"
"orchestra/testbench": "^9.15|^10.8",
"phpstan/phpstan": "^1.10"
},
"type": "library",
"extra": {
@@ -2351,20 +2351,20 @@
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
"time": "2025-07-09T19:45:24+00:00"
"time": "2025-11-21T13:59:03+00:00"
},
{
"name": "laravel/serializable-closure",
"version": "v2.0.6",
"version": "v2.0.7",
"source": {
"type": "git",
"url": "https://github.com/laravel/serializable-closure.git",
"reference": "038ce42edee619599a1debb7e81d7b3759492819"
"reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/038ce42edee619599a1debb7e81d7b3759492819",
"reference": "038ce42edee619599a1debb7e81d7b3759492819",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/cb291e4c998ac50637c7eeb58189c14f5de5b9dd",
"reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd",
"shasum": ""
},
"require": {
@@ -2373,7 +2373,7 @@
"require-dev": {
"illuminate/support": "^10.0|^11.0|^12.0",
"nesbot/carbon": "^2.67|^3.0",
"pestphp/pest": "^2.36|^3.0",
"pestphp/pest": "^2.36|^3.0|^4.0",
"phpstan/phpstan": "^2.0",
"symfony/var-dumper": "^6.2.0|^7.0.0"
},
@@ -2412,20 +2412,20 @@
"issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure"
},
"time": "2025-10-09T13:42:30+00:00"
"time": "2025-11-21T20:52:36+00:00"
},
{
"name": "laravel/slack-notification-channel",
"version": "v3.6.0",
"version": "v3.7.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git",
"reference": "642677a57490eebccb7e9fb666f5a5379c6e3459"
"reference": "414aec57b487bfbac7f90fc30f50a2f0a2df4caa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/642677a57490eebccb7e9fb666f5a5379c6e3459",
"reference": "642677a57490eebccb7e9fb666f5a5379c6e3459",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/414aec57b487bfbac7f90fc30f50a2f0a2df4caa",
"reference": "414aec57b487bfbac7f90fc30f50a2f0a2df4caa",
"shasum": ""
},
"require": {
@@ -2475,9 +2475,9 @@
],
"support": {
"issues": "https://github.com/laravel/slack-notification-channel/issues",
"source": "https://github.com/laravel/slack-notification-channel/tree/v3.6.0"
"source": "https://github.com/laravel/slack-notification-channel/tree/v3.7.0"
},
"time": "2025-06-26T16:51:38+00:00"
"time": "2025-11-20T17:26:07+00:00"
},
{
"name": "laravel/ui",
@@ -3361,33 +3361,38 @@
},
{
"name": "league/uri",
"version": "7.5.1",
"version": "7.6.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri.git",
"reference": "81fb5145d2644324614cc532b28efd0215bda430"
"reference": "f625804987a0a9112d954f9209d91fec52182344"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430",
"reference": "81fb5145d2644324614cc532b28efd0215bda430",
"url": "https://api.github.com/repos/thephpleague/uri/zipball/f625804987a0a9112d954f9209d91fec52182344",
"reference": "f625804987a0a9112d954f9209d91fec52182344",
"shasum": ""
},
"require": {
"league/uri-interfaces": "^7.5",
"php": "^8.1"
"league/uri-interfaces": "^7.6",
"php": "^8.1",
"psr/http-factory": "^1"
},
"conflict": {
"league/uri-schemes": "^1.0"
},
"suggest": {
"ext-bcmath": "to improve IPV4 host parsing",
"ext-dom": "to convert the URI into an HTML anchor tag",
"ext-fileinfo": "to create Data URI from file contennts",
"ext-gmp": "to improve IPV4 host parsing",
"ext-intl": "to handle IDN host with the best performance",
"ext-uri": "to use the PHP native URI class",
"jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain",
"league/uri-components": "Needed to easily manipulate URI objects components",
"league/uri-polyfill": "Needed to backport the PHP URI extension for older versions of PHP",
"php-64bit": "to improve IPV4 host parsing",
"rowbot/url": "to handle WHATWG URL",
"symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
},
"type": "library",
@@ -3415,6 +3420,7 @@
"description": "URI manipulation library",
"homepage": "https://uri.thephpleague.com",
"keywords": [
"URN",
"data-uri",
"file-uri",
"ftp",
@@ -3427,9 +3433,11 @@
"psr-7",
"query-string",
"querystring",
"rfc2141",
"rfc3986",
"rfc3987",
"rfc6570",
"rfc8141",
"uri",
"uri-template",
"url",
@@ -3439,7 +3447,7 @@
"docs": "https://uri.thephpleague.com",
"forum": "https://thephpleague.slack.com",
"issues": "https://github.com/thephpleague/uri-src/issues",
"source": "https://github.com/thephpleague/uri/tree/7.5.1"
"source": "https://github.com/thephpleague/uri/tree/7.6.0"
},
"funding": [
{
@@ -3447,26 +3455,25 @@
"type": "github"
}
],
"time": "2024-12-08T08:40:02+00:00"
"time": "2025-11-18T12:17:23+00:00"
},
{
"name": "league/uri-interfaces",
"version": "7.5.0",
"version": "7.6.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri-interfaces.git",
"reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742"
"reference": "ccbfb51c0445298e7e0b7f4481b942f589665368"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742",
"reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742",
"url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/ccbfb51c0445298e7e0b7f4481b942f589665368",
"reference": "ccbfb51c0445298e7e0b7f4481b942f589665368",
"shasum": ""
},
"require": {
"ext-filter": "*",
"php": "^8.1",
"psr/http-factory": "^1",
"psr/http-message": "^1.1 || ^2.0"
},
"suggest": {
@@ -3474,6 +3481,7 @@
"ext-gmp": "to improve IPV4 host parsing",
"ext-intl": "to handle IDN host with the best performance",
"php-64bit": "to improve IPV4 host parsing",
"rowbot/url": "to handle WHATWG URL",
"symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
},
"type": "library",
@@ -3498,7 +3506,7 @@
"homepage": "https://nyamsprod.com"
}
],
"description": "Common interfaces and classes for URI representation and interaction",
"description": "Common tools for parsing and resolving RFC3987/RFC3986 URI",
"homepage": "https://uri.thephpleague.com",
"keywords": [
"data-uri",
@@ -3523,7 +3531,7 @@
"docs": "https://uri.thephpleague.com",
"forum": "https://thephpleague.slack.com",
"issues": "https://github.com/thephpleague/uri-src/issues",
"source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0"
"source": "https://github.com/thephpleague/uri-interfaces/tree/7.6.0"
},
"funding": [
{
@@ -3531,7 +3539,7 @@
"type": "github"
}
],
"time": "2024-12-08T08:18:47+00:00"
"time": "2025-11-18T12:17:23+00:00"
},
{
"name": "mailersend/laravel-driver",
@@ -3943,16 +3951,16 @@
},
{
"name": "nette/utils",
"version": "v4.0.8",
"version": "v4.0.9",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede"
"reference": "505a30ad386daa5211f08a318e47015b501cad30"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede",
"reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede",
"url": "https://api.github.com/repos/nette/utils/zipball/505a30ad386daa5211f08a318e47015b501cad30",
"reference": "505a30ad386daa5211f08a318e47015b501cad30",
"shasum": ""
},
"require": {
@@ -4026,22 +4034,22 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.8"
"source": "https://github.com/nette/utils/tree/v4.0.9"
},
"time": "2025-08-06T21:43:34+00:00"
"time": "2025-10-31T00:45:47+00:00"
},
{
"name": "nunomaduro/collision",
"version": "v8.8.2",
"version": "v8.8.3",
"source": {
"type": "git",
"url": "https://github.com/nunomaduro/collision.git",
"reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb"
"reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/60207965f9b7b7a4ce15a0f75d57f9dadb105bdb",
"reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/1dc9e88d105699d0fee8bb18890f41b274f6b4c4",
"reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4",
"shasum": ""
},
"require": {
@@ -4063,7 +4071,7 @@
"laravel/sanctum": "^4.1.1",
"laravel/tinker": "^2.10.1",
"orchestra/testbench-core": "^9.12.0 || ^10.4",
"pestphp/pest": "^3.8.2",
"pestphp/pest": "^3.8.2 || ^4.0.0",
"sebastian/environment": "^7.2.1 || ^8.0"
},
"type": "library",
@@ -4127,35 +4135,35 @@
"type": "patreon"
}
],
"time": "2025-06-25T02:12:12+00:00"
"time": "2025-11-20T02:55:25+00:00"
},
{
"name": "nunomaduro/termwind",
"version": "v2.3.2",
"version": "v2.3.3",
"source": {
"type": "git",
"url": "https://github.com/nunomaduro/termwind.git",
"reference": "eb61920a53057a7debd718a5b89c2178032b52c0"
"reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nunomaduro/termwind/zipball/eb61920a53057a7debd718a5b89c2178032b52c0",
"reference": "eb61920a53057a7debd718a5b89c2178032b52c0",
"url": "https://api.github.com/repos/nunomaduro/termwind/zipball/6fb2a640ff502caace8e05fd7be3b503a7e1c017",
"reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "^8.2",
"symfony/console": "^7.3.4"
"symfony/console": "^7.3.6"
},
"require-dev": {
"illuminate/console": "^11.46.1",
"laravel/pint": "^1.25.1",
"mockery/mockery": "^1.6.12",
"pestphp/pest": "^2.36.0 || ^3.8.4",
"pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.1.3",
"phpstan/phpstan": "^1.12.32",
"phpstan/phpstan-strict-rules": "^1.6.2",
"symfony/var-dumper": "^7.3.4",
"symfony/var-dumper": "^7.3.5",
"thecodingmachine/phpstan-strict-rules": "^1.0.0"
},
"type": "library",
@@ -4198,7 +4206,7 @@
],
"support": {
"issues": "https://github.com/nunomaduro/termwind/issues",
"source": "https://github.com/nunomaduro/termwind/tree/v2.3.2"
"source": "https://github.com/nunomaduro/termwind/tree/v2.3.3"
},
"funding": [
{
@@ -4214,7 +4222,7 @@
"type": "github"
}
],
"time": "2025-10-18T11:10:27+00:00"
"time": "2025-11-20T02:34:59+00:00"
},
{
"name": "nyholm/psr7",
@@ -5171,16 +5179,16 @@
},
{
"name": "predis/predis",
"version": "v3.2.0",
"version": "v3.3.0",
"source": {
"type": "git",
"url": "https://github.com/predis/predis.git",
"reference": "9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8"
"reference": "153097374b39a2f737fe700ebcd725642526cdec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/predis/predis/zipball/9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8",
"reference": "9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8",
"url": "https://api.github.com/repos/predis/predis/zipball/153097374b39a2f737fe700ebcd725642526cdec",
"reference": "153097374b39a2f737fe700ebcd725642526cdec",
"shasum": ""
},
"require": {
@@ -5222,7 +5230,7 @@
],
"support": {
"issues": "https://github.com/predis/predis/issues",
"source": "https://github.com/predis/predis/tree/v3.2.0"
"source": "https://github.com/predis/predis/tree/v3.3.0"
},
"funding": [
{
@@ -5230,7 +5238,7 @@
"type": "github"
}
],
"time": "2025-08-06T06:41:24+00:00"
"time": "2025-11-24T17:48:50+00:00"
},
{
"name": "psr/cache",
@@ -10306,24 +10314,24 @@
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.16.0",
"version": "v3.16.1",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "f265cf5e38577d42311f1a90d619bcd3740bea23"
"reference": "21b2c6fce05453efd4bceb34f9fddaa1cdb44090"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/f265cf5e38577d42311f1a90d619bcd3740bea23",
"reference": "f265cf5e38577d42311f1a90d619bcd3740bea23",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/21b2c6fce05453efd4bceb34f9fddaa1cdb44090",
"reference": "21b2c6fce05453efd4bceb34f9fddaa1cdb44090",
"shasum": ""
},
"require": {
"illuminate/routing": "^9|^10|^11|^12",
"illuminate/session": "^9|^10|^11|^12",
"illuminate/support": "^9|^10|^11|^12",
"illuminate/routing": "^10|^11|^12",
"illuminate/session": "^10|^11|^12",
"illuminate/support": "^10|^11|^12",
"php": "^8.1",
"php-debugbar/php-debugbar": "~2.2.0",
"php-debugbar/php-debugbar": "^2.2.4",
"symfony/finder": "^6|^7"
},
"require-dev": {
@@ -10375,7 +10383,7 @@
],
"support": {
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.16.0"
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.16.1"
},
"funding": [
{
@@ -10387,7 +10395,7 @@
"type": "github"
}
],
"time": "2025-07-14T11:56:43+00:00"
"time": "2025-11-19T08:31:25+00:00"
},
{
"name": "barryvdh/laravel-ide-helper",
@@ -10595,22 +10603,22 @@
},
{
"name": "composer/class-map-generator",
"version": "1.6.2",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/composer/class-map-generator.git",
"reference": "ba9f089655d4cdd64e762a6044f411ccdaec0076"
"reference": "2373419b7709815ed323ebf18c3c72d03ff4a8a6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/class-map-generator/zipball/ba9f089655d4cdd64e762a6044f411ccdaec0076",
"reference": "ba9f089655d4cdd64e762a6044f411ccdaec0076",
"url": "https://api.github.com/repos/composer/class-map-generator/zipball/2373419b7709815ed323ebf18c3c72d03ff4a8a6",
"reference": "2373419b7709815ed323ebf18c3c72d03ff4a8a6",
"shasum": ""
},
"require": {
"composer/pcre": "^2.1 || ^3.1",
"php": "^7.2 || ^8.0",
"symfony/finder": "^4.4 || ^5.3 || ^6 || ^7"
"symfony/finder": "^4.4 || ^5.3 || ^6 || ^7 || ^8"
},
"require-dev": {
"phpstan/phpstan": "^1.12 || ^2",
@@ -10618,7 +10626,7 @@
"phpstan/phpstan-phpunit": "^1 || ^2",
"phpstan/phpstan-strict-rules": "^1.1 || ^2",
"phpunit/phpunit": "^8",
"symfony/filesystem": "^5.4 || ^6"
"symfony/filesystem": "^5.4 || ^6 || ^7 || ^8"
},
"type": "library",
"extra": {
@@ -10648,7 +10656,7 @@
],
"support": {
"issues": "https://github.com/composer/class-map-generator/issues",
"source": "https://github.com/composer/class-map-generator/tree/1.6.2"
"source": "https://github.com/composer/class-map-generator/tree/1.7.0"
},
"funding": [
{
@@ -10660,7 +10668,7 @@
"type": "github"
}
],
"time": "2025-08-20T18:52:43+00:00"
"time": "2025-11-19T10:41:15+00:00"
},
{
"name": "composer/pcre",
@@ -12011,16 +12019,16 @@
},
{
"name": "phpunit/phpunit",
"version": "12.4.2",
"version": "12.4.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "a94ea4d26d865875803b23aaf78c3c2c670ea2ea"
"reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a94ea4d26d865875803b23aaf78c3c2c670ea2ea",
"reference": "a94ea4d26d865875803b23aaf78c3c2c670ea2ea",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9253ec75a672e39fcc9d85bdb61448215b8162c7",
"reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7",
"shasum": ""
},
"require": {
@@ -12088,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.2"
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.4.4"
},
"funding": [
{
@@ -12112,7 +12120,7 @@
"type": "tidelift"
}
],
"time": "2025-10-30T08:41:39+00:00"
"time": "2025-11-21T07:39:11+00:00"
},
{
"name": "rector/rector",
@@ -13125,16 +13133,16 @@
},
{
"name": "thecodingmachine/phpstan-safe-rule",
"version": "v1.4.1",
"version": "v1.4.3",
"source": {
"type": "git",
"url": "https://github.com/thecodingmachine/phpstan-safe-rule.git",
"reference": "5f9795eae8891dffa475965463a4281633651768"
"reference": "5c804889253ce9498ef185e108e9f94b6023208e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thecodingmachine/phpstan-safe-rule/zipball/5f9795eae8891dffa475965463a4281633651768",
"reference": "5f9795eae8891dffa475965463a4281633651768",
"url": "https://api.github.com/repos/thecodingmachine/phpstan-safe-rule/zipball/5c804889253ce9498ef185e108e9f94b6023208e",
"reference": "5c804889253ce9498ef185e108e9f94b6023208e",
"shasum": ""
},
"require": {
@@ -13177,22 +13185,22 @@
"description": "A PHPStan rule to detect safety issues. Must be used in conjunction with thecodingmachine/safe",
"support": {
"issues": "https://github.com/thecodingmachine/phpstan-safe-rule/issues",
"source": "https://github.com/thecodingmachine/phpstan-safe-rule/tree/v1.4.1"
"source": "https://github.com/thecodingmachine/phpstan-safe-rule/tree/v1.4.3"
},
"time": "2025-04-09T20:30:35+00:00"
"time": "2025-11-21T09:41:49+00:00"
},
{
"name": "theseer/tokenizer",
"version": "1.2.3",
"version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
"reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
"reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
"shasum": ""
},
"require": {
@@ -13221,7 +13229,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
"source": "https://github.com/theseer/tokenizer/tree/1.2.3"
"source": "https://github.com/theseer/tokenizer/tree/1.3.1"
},
"funding": [
{
@@ -13229,7 +13237,7 @@
"type": "github"
}
],
"time": "2024-03-03T12:36:25+00:00"
"time": "2025-11-17T20:03:58+00:00"
},
{
"name": "webmozart/assert",
@@ -13314,5 +13322,5 @@
"ext-xmlwriter": "*"
},
"platform-dev": {},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.9.0"
}

View File

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

310
package-lock.json generated
View File

@@ -2589,9 +2589,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz",
"integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
"cpu": [
"arm"
],
@@ -2603,9 +2603,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz",
"integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
"cpu": [
"arm64"
],
@@ -2617,9 +2617,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz",
"integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
"cpu": [
"arm64"
],
@@ -2631,9 +2631,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz",
"integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
"cpu": [
"x64"
],
@@ -2645,9 +2645,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz",
"integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
"cpu": [
"arm64"
],
@@ -2659,9 +2659,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz",
"integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
"cpu": [
"x64"
],
@@ -2673,9 +2673,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz",
"integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
"cpu": [
"arm"
],
@@ -2687,9 +2687,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz",
"integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
"cpu": [
"arm"
],
@@ -2701,9 +2701,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz",
"integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
"cpu": [
"arm64"
],
@@ -2715,9 +2715,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz",
"integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
"cpu": [
"arm64"
],
@@ -2729,9 +2729,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz",
"integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
"cpu": [
"loong64"
],
@@ -2743,9 +2743,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz",
"integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
"cpu": [
"ppc64"
],
@@ -2757,9 +2757,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz",
"integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
"cpu": [
"riscv64"
],
@@ -2771,9 +2771,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz",
"integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
"cpu": [
"riscv64"
],
@@ -2785,9 +2785,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz",
"integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
"cpu": [
"s390x"
],
@@ -2799,9 +2799,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz",
"integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
"cpu": [
"x64"
],
@@ -2813,9 +2813,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz",
"integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
"cpu": [
"x64"
],
@@ -2827,9 +2827,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz",
"integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
"cpu": [
"arm64"
],
@@ -2841,9 +2841,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz",
"integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
"cpu": [
"arm64"
],
@@ -2855,9 +2855,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz",
"integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
"cpu": [
"ia32"
],
@@ -2869,9 +2869,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz",
"integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
"cpu": [
"x64"
],
@@ -2883,9 +2883,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz",
"integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
"cpu": [
"x64"
],
@@ -3291,42 +3291,42 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.24",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz",
"integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==",
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
"integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/shared": "3.5.24",
"@vue/shared": "3.5.25",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.24",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz",
"integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==",
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
"integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.24",
"@vue/shared": "3.5.24"
"@vue/compiler-core": "3.5.25",
"@vue/shared": "3.5.25"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.24",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz",
"integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==",
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz",
"integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.24",
"@vue/compiler-dom": "3.5.24",
"@vue/compiler-ssr": "3.5.24",
"@vue/shared": "3.5.24",
"@vue/compiler-core": "3.5.25",
"@vue/compiler-dom": "3.5.25",
"@vue/compiler-ssr": "3.5.25",
"@vue/shared": "3.5.25",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.6",
@@ -3334,14 +3334,14 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.24",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz",
"integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==",
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
"integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.24",
"@vue/shared": "3.5.24"
"@vue/compiler-dom": "3.5.25",
"@vue/shared": "3.5.25"
}
},
"node_modules/@vue/component-compiler-utils": {
@@ -3423,9 +3423,9 @@
"license": "MIT"
},
"node_modules/@vue/shared": {
"version": "3.5.24",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz",
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz",
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
"dev": true,
"license": "MIT"
},
@@ -3776,9 +3776,9 @@
}
},
"node_modules/alpinejs": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.15.1.tgz",
"integrity": "sha512-HLO1TtiE92VajFHtLLPK8BWaK1YepV/uj31UrfoGnQ00lyFOJZ+oVY3F0DghPAwvg8sLU79pmjGQSytERa2gEg==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.15.2.tgz",
"integrity": "sha512-2kYF2aG+DTFkE6p0rHG5XmN4VEb6sO9b02aOdU4+i8QN6rL0DbRZQiypDE1gBcGO65yDcqMz5KKYUYgMUxgNkw==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "~3.1.1"
@@ -4075,9 +4075,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.8.27",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.27.tgz",
"integrity": "sha512-2CXFpkjVnY2FT+B6GrSYxzYf65BJWEqz5tIRHCvNsZZ2F3CmsCB37h8SpYgKG7y9C4YAeTipIPWG7EmFmhAeXA==",
"version": "2.8.31",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.31.tgz",
"integrity": "sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -4521,9 +4521,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001754",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz",
"integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==",
"version": "1.0.30001757",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
"integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==",
"dev": true,
"funding": [
{
@@ -4966,13 +4966,13 @@
"license": "MIT"
},
"node_modules/core-js-compat": {
"version": "3.46.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz",
"integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==",
"version": "3.47.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz",
"integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"browserslist": "^4.26.3"
"browserslist": "^4.28.0"
},
"funding": {
"type": "opencollective",
@@ -5365,9 +5365,9 @@
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"dev": true,
"license": "MIT"
},
@@ -5736,9 +5736,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
"version": "1.5.250",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz",
"integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==",
"version": "1.5.260",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.260.tgz",
"integrity": "sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==",
"dev": true,
"license": "ISC"
},
@@ -6443,9 +6443,9 @@
}
},
"node_modules/form-data": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7088,9 +7088,9 @@
}
},
"node_modules/i18next": {
"version": "25.6.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.2.tgz",
"integrity": "sha512-0GawNyVUw0yvJoOEBq1VHMAsqdM23XrHkMtl2gKEjviJQSLVXsrPqsoYAxBEugW5AB96I2pZkwRxyl8WZVoWdw==",
"version": "25.6.3",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.3.tgz",
"integrity": "sha512-AEQvoPDljhp67a1+NsnG/Wb1Nh6YoSvtrmeEd24sfGn3uujCtXCF3cXpr7ulhMywKNFF7p3TX1u2j7y+caLOJg==",
"funding": [
{
"type": "individual",
@@ -7107,7 +7107,7 @@
],
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6"
"@babel/runtime": "^7.28.4"
},
"peerDependencies": {
"typescript": "^5"
@@ -8400,9 +8400,9 @@
}
},
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
"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==",
"dev": true,
"license": "(BSD-3-Clause OR GPL-2.0)",
"engines": {
@@ -10110,9 +10110,9 @@
}
},
"node_modules/rollup": {
"version": "4.53.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz",
"integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==",
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10126,28 +10126,28 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.53.2",
"@rollup/rollup-android-arm64": "4.53.2",
"@rollup/rollup-darwin-arm64": "4.53.2",
"@rollup/rollup-darwin-x64": "4.53.2",
"@rollup/rollup-freebsd-arm64": "4.53.2",
"@rollup/rollup-freebsd-x64": "4.53.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.53.2",
"@rollup/rollup-linux-arm-musleabihf": "4.53.2",
"@rollup/rollup-linux-arm64-gnu": "4.53.2",
"@rollup/rollup-linux-arm64-musl": "4.53.2",
"@rollup/rollup-linux-loong64-gnu": "4.53.2",
"@rollup/rollup-linux-ppc64-gnu": "4.53.2",
"@rollup/rollup-linux-riscv64-gnu": "4.53.2",
"@rollup/rollup-linux-riscv64-musl": "4.53.2",
"@rollup/rollup-linux-s390x-gnu": "4.53.2",
"@rollup/rollup-linux-x64-gnu": "4.53.2",
"@rollup/rollup-linux-x64-musl": "4.53.2",
"@rollup/rollup-openharmony-arm64": "4.53.2",
"@rollup/rollup-win32-arm64-msvc": "4.53.2",
"@rollup/rollup-win32-ia32-msvc": "4.53.2",
"@rollup/rollup-win32-x64-gnu": "4.53.2",
"@rollup/rollup-win32-x64-msvc": "4.53.2",
"@rollup/rollup-android-arm-eabi": "4.53.3",
"@rollup/rollup-android-arm64": "4.53.3",
"@rollup/rollup-darwin-arm64": "4.53.3",
"@rollup/rollup-darwin-x64": "4.53.3",
"@rollup/rollup-freebsd-arm64": "4.53.3",
"@rollup/rollup-freebsd-x64": "4.53.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
"@rollup/rollup-linux-arm-musleabihf": "4.53.3",
"@rollup/rollup-linux-arm64-gnu": "4.53.3",
"@rollup/rollup-linux-arm64-musl": "4.53.3",
"@rollup/rollup-linux-loong64-gnu": "4.53.3",
"@rollup/rollup-linux-ppc64-gnu": "4.53.3",
"@rollup/rollup-linux-riscv64-gnu": "4.53.3",
"@rollup/rollup-linux-riscv64-musl": "4.53.3",
"@rollup/rollup-linux-s390x-gnu": "4.53.3",
"@rollup/rollup-linux-x64-gnu": "4.53.3",
"@rollup/rollup-linux-x64-musl": "4.53.3",
"@rollup/rollup-openharmony-arm64": "4.53.3",
"@rollup/rollup-win32-arm64-msvc": "4.53.3",
"@rollup/rollup-win32-ia32-msvc": "4.53.3",
"@rollup/rollup-win32-x64-gnu": "4.53.3",
"@rollup/rollup-win32-x64-msvc": "4.53.3",
"fsevents": "~2.3.2"
}
},
@@ -10203,9 +10203,9 @@
"license": "MIT"
},
"node_modules/sass": {
"version": "1.94.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.94.0.tgz",
"integrity": "sha512-Dqh7SiYcaFtdv5Wvku6QgS5IGPm281L+ZtVD1U2FJa7Q0EFRlq8Z3sjYtz6gYObsYThUOz9ArwFqPZx+1azILQ==",
"version": "1.94.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.94.2.tgz",
"integrity": "sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11517,9 +11517,9 @@
}
},
"node_modules/vite": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz",
"integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==",
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz",
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11840,9 +11840,9 @@
"license": "BSD-2-Clause"
},
"node_modules/webpack": {
"version": "5.102.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz",
"integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==",
"version": "5.103.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz",
"integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11863,7 +11863,7 @@
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"loader-runner": "^4.3.1",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^4.3.3",
@@ -12507,7 +12507,7 @@
"@fortawesome/fontawesome-free": "^7",
"@popperjs/core": "^2.11.8",
"admin-lte": "^4.0.0-rc4",
"alpinejs": "^3.13.7",
"alpinejs": "^3.15.2",
"bootstrap": "^5",
"bootstrap5-autocomplete": "^1",
"bootstrap5-tags": "^1",

View File

@@ -19,7 +19,7 @@
"@fortawesome/fontawesome-free": "^7",
"@popperjs/core": "^2.11.8",
"admin-lte": "^4.0.0-rc4",
"alpinejs": "^3.13.7",
"alpinejs": "^3.15.2",
"bootstrap": "^5",
"bootstrap5-autocomplete": "^1",
"bootstrap5-tags": "^1",

View File

@@ -62,6 +62,10 @@
<div class="box-body no-padding">
<table class="table table-hover">
<tbody>
<tr>
<td style="width:40%;">{{ trans('list.id') }}</td>
<td>#{{ transactionGroup.id }}</td>
</tr>
<tr>
<td style="width:40%;">{{ trans('list.type') }}</td>
<td>{{ first.transaction_type_type|_ }}</td>