From 5c73d238a05cda1bd3e803416ee7a22707a0e7f1 Mon Sep 17 00:00:00 2001 From: JC5 Date: Sat, 29 Nov 2025 07:23:38 +0100 Subject: [PATCH 01/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-29?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ci/php-cs-fixer/composer.lock | 12 ++++++------ config/firefly.php | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock index f5760437d6..262aecb0ec 100644 --- a/.ci/php-cs-fixer/composer.lock +++ b/.ci/php-cs-fixer/composer.lock @@ -402,16 +402,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.90.0", + "version": "v3.91.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155" + "reference": "c4a25f20390337789c26b693ae46faa125040352" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ad732c2e9299c9743f9c55ae53cc0e7642ab1155", - "reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c4a25f20390337789c26b693ae46faa125040352", + "reference": "c4a25f20390337789c26b693ae46faa125040352", "shasum": "" }, "require": { @@ -493,7 +493,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.90.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.91.0" }, "funding": [ { @@ -501,7 +501,7 @@ "type": "github" } ], - "time": "2025-11-20T15:15:16+00:00" + "time": "2025-11-28T22:07:42+00:00" }, { "name": "psr/container", diff --git a/config/firefly.php b/config/firefly.php index 2d8b05fb7b..8e250c41ea 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => '6.4.9', - 'build_time' => 1764362024, + 'version' => 'develop/2025-11-29', + 'build_time' => 1764397312, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. From c8edaee848ce9f87cd9d7cdba6fc2550c9e2272c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 03:03:40 +0000 Subject: [PATCH 02/27] Bump symfony/http-client from 7.4.0 to 8.0.0 Bumps [symfony/http-client](https://github.com/symfony/http-client) from 7.4.0 to 8.0.0. - [Release notes](https://github.com/symfony/http-client/releases) - [Changelog](https://github.com/symfony/http-client/blob/7.3/CHANGELOG.md) - [Commits](https://github.com/symfony/http-client/compare/v7.4.0...v8.0.0) --- updated-dependencies: - dependency-name: symfony/http-client dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- composer.lock | 45 ++++++++++++++++++++------------------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/composer.json b/composer.json index 38f19e3e14..339891f92a 100644 --- a/composer.json +++ b/composer.json @@ -108,7 +108,7 @@ "spatie/laravel-ignition": "^2", "spatie/period": "^2.4", "symfony/expression-language": "^7.0", - "symfony/http-client": "^7.1", + "symfony/http-client": "^8.0", "symfony/mailgun-mailer": "^7.1", "thecodingmachine/safe": "^3.1" }, diff --git a/composer.lock b/composer.lock index b594cdac45..4eb59b7b7b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "946638fa99da77780e75953c338d9a55", + "content-hash": "23fc4e822f7746801eb770935e5c0150", "packages": [ { "name": "bacon/bacon-qr-code", @@ -7531,31 +7531,27 @@ }, { "name": "symfony/http-client", - "version": "v7.4.0", + "version": "v8.0.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "ee5e0e0139ab506f6063a230e631bed677c650a4" + "reference": "b4be9eb608f5c7544e448908fb30472da77a975f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/ee5e0e0139ab506f6063a230e631bed677c650a4", - "reference": "ee5e0e0139ab506f6063a230e631bed677c650a4", + "url": "https://api.github.com/repos/symfony/http-client/zipball/b4be9eb608f5c7544e448908fb30472da77a975f", + "reference": "b4be9eb608f5c7544e448908fb30472da77a975f", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-client-contracts": "~3.4.4|^3.5.2", - "symfony/polyfill-php83": "^1.29", "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "amphp/amp": "<2.5", - "amphp/socket": "<1.1", - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.4" + "amphp/amp": "<3", + "php-http/discovery": "<1.15" }, "provide": { "php-http/async-client-implementation": "*", @@ -7564,20 +7560,19 @@ "symfony/http-client-implementation": "3.0" }, "require-dev": { - "amphp/http-client": "^4.2.1|^5.0", - "amphp/http-tunnel": "^1.0|^2.0", + "amphp/http-client": "^5.3.2", + "amphp/http-tunnel": "^2.0", "guzzlehttp/promises": "^1.4|^2.0", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", - "symfony/amphp-http-client-meta": "^1.0|^2.0", - "symfony/cache": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/rate-limiter": "^6.4|^7.0|^8.0", - "symfony/stopwatch": "^6.4|^7.0|^8.0" + "symfony/cache": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/rate-limiter": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7608,7 +7603,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.4.0" + "source": "https://github.com/symfony/http-client/tree/v8.0.0" }, "funding": [ { @@ -7628,7 +7623,7 @@ "type": "tidelift" } ], - "time": "2025-11-20T12:32:50+00:00" + "time": "2025-11-20T12:42:53+00:00" }, { "name": "symfony/http-client-contracts", @@ -13340,5 +13335,5 @@ "ext-xmlwriter": "*" }, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } From 51e8a1dbe2843b747f91cefd07d4e4a0c7623603 Mon Sep 17 00:00:00 2001 From: JC5 Date: Mon, 1 Dec 2025 04:37:38 +0100 Subject: [PATCH 03/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-12-01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.lock | 89 +++++++++++++++++++++++----------------------- config/firefly.php | 4 +-- package-lock.json | 15 ++++---- 3 files changed, 55 insertions(+), 53 deletions(-) diff --git a/composer.lock b/composer.lock index b594cdac45..2bdcfc127b 100644 --- a/composer.lock +++ b/composer.lock @@ -3543,22 +3543,22 @@ }, { "name": "mailersend/laravel-driver", - "version": "v2.12.0", + "version": "v2.9.1", "source": { "type": "git", "url": "https://github.com/mailersend/mailersend-laravel-driver.git", - "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb" + "reference": "87fd5ab76808bbaac9221be0d306baef13e98725" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb", - "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb", + "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725", + "reference": "87fd5ab76808bbaac9221be0d306baef13e98725", "shasum": "" }, "require": { "ext-json": "*", "illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0", - "mailersend/mailersend": "^0.35.0", + "mailersend/mailersend": "^0.31.0", "nyholm/psr7": "^1.5", "php": ">=8.0", "php-http/guzzle7-adapter": "^1.0", @@ -3606,28 +3606,29 @@ ], "support": { "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues", - "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0" + "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1" }, - "time": "2025-10-28T14:59:16+00:00" + "time": "2025-04-09T09:33:07+00:00" }, { "name": "mailersend/mailersend", - "version": "v0.35.0", + "version": "v0.31.0", "source": { "type": "git", "url": "https://github.com/mailersend/mailersend-php.git", - "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276" + "reference": "513ff83ee768526055ad52987cde401ea7218c67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276", - "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276", + "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67", + "reference": "513ff83ee768526055ad52987cde401ea7218c67", "shasum": "" }, "require": { "beberlei/assert": "^3.2", "ext-json": "*", - "php": "^7.4 || ^8.0 <8.5", + "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0", + "php": "^7.4|^8.0", "php-http/client-common": "^2.2", "php-http/discovery": "^1.9", "php-http/httplug": "^2.1", @@ -3672,9 +3673,9 @@ ], "support": { "issues": "https://github.com/mailersend/mailersend-php/issues", - "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0" + "source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0" }, - "time": "2025-10-28T13:11:43+00:00" + "time": "2025-04-03T12:16:11+00:00" }, { "name": "monolog/monolog", @@ -4423,16 +4424,16 @@ }, { "name": "php-http/client-common", - "version": "2.7.2", + "version": "2.7.3", "source": { "type": "git", "url": "https://github.com/php-http/client-common.git", - "reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46" + "reference": "dcc6de29c90dd74faab55f71b79d89409c4bf0c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/client-common/zipball/0cfe9858ab9d3b213041b947c881d5b19ceeca46", - "reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46", + "url": "https://api.github.com/repos/php-http/client-common/zipball/dcc6de29c90dd74faab55f71b79d89409c4bf0c1", + "reference": "dcc6de29c90dd74faab55f71b79d89409c4bf0c1", "shasum": "" }, "require": { @@ -4442,15 +4443,13 @@ "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0 || ^2.0", - "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0", + "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0 || ^8.0", "symfony/polyfill-php80": "^1.17" }, "require-dev": { "doctrine/instantiator": "^1.1", "guzzlehttp/psr7": "^1.4", "nyholm/psr7": "^1.2", - "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", - "phpspec/prophecy": "^1.10.2", "phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7" }, "suggest": { @@ -4486,9 +4485,9 @@ ], "support": { "issues": "https://github.com/php-http/client-common/issues", - "source": "https://github.com/php-http/client-common/tree/2.7.2" + "source": "https://github.com/php-http/client-common/tree/2.7.3" }, - "time": "2024-09-24T06:21:48+00:00" + "time": "2025-11-29T19:12:34+00:00" }, { "name": "php-http/discovery", @@ -10093,16 +10092,16 @@ }, { "name": "twig/twig", - "version": "v3.22.0", + "version": "v3.22.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "4509984193026de413baf4ba80f68590a7f2c51d" + "reference": "1de2ec1fc43ab58a4b7e80b214b96bfc895750f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/4509984193026de413baf4ba80f68590a7f2c51d", - "reference": "4509984193026de413baf4ba80f68590a7f2c51d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/1de2ec1fc43ab58a4b7e80b214b96bfc895750f3", + "reference": "1de2ec1fc43ab58a4b7e80b214b96bfc895750f3", "shasum": "" }, "require": { @@ -10156,7 +10155,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.22.0" + "source": "https://github.com/twigphp/Twig/tree/v3.22.1" }, "funding": [ { @@ -10168,7 +10167,7 @@ "type": "tidelift" } ], - "time": "2025-10-29T15:56:47+00:00" + "time": "2025-11-16T16:01:12+00:00" }, { "name": "vlucas/phpdotenv", @@ -10769,16 +10768,16 @@ }, { "name": "driftingly/rector-laravel", - "version": "2.1.3", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/driftingly/rector-laravel.git", - "reference": "2f1e9c3997bf45592d58916f0cedd775e844b9c6" + "reference": "b84b1877ac4f6686f718bc259c9a68d914b514fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/2f1e9c3997bf45592d58916f0cedd775e844b9c6", - "reference": "2f1e9c3997bf45592d58916f0cedd775e844b9c6", + "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/b84b1877ac4f6686f718bc259c9a68d914b514fa", + "reference": "b84b1877ac4f6686f718bc259c9a68d914b514fa", "shasum": "" }, "require": { @@ -10799,9 +10798,9 @@ "description": "Rector upgrades rules for Laravel Framework", "support": { "issues": "https://github.com/driftingly/rector-laravel/issues", - "source": "https://github.com/driftingly/rector-laravel/tree/2.1.3" + "source": "https://github.com/driftingly/rector-laravel/tree/2.1.4" }, - "time": "2025-11-04T18:32:57+00:00" + "time": "2025-11-30T21:38:38+00:00" }, { "name": "fakerphp/faker", @@ -11703,23 +11702,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "12.4.0", + "version": "12.5.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c" + "reference": "bca180c050dd3ae15f87c26d25cabb34fe1a0a5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c", - "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bca180c050dd3ae15f87c26d25cabb34fe1a0a5a", + "reference": "bca180c050dd3ae15f87c26d25cabb34fe1a0a5a", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.6.1", + "nikic/php-parser": "^5.6.2", "php": ">=8.3", "phpunit/php-file-iterator": "^6.0", "phpunit/php-text-template": "^5.0", @@ -11727,10 +11726,10 @@ "sebastian/environment": "^8.0.3", "sebastian/lines-of-code": "^4.0", "sebastian/version": "^6.0", - "theseer/tokenizer": "^1.2.3" + "theseer/tokenizer": "^1.3.1" }, "require-dev": { - "phpunit/phpunit": "^12.3.7" + "phpunit/phpunit": "^12.4.4" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -11739,7 +11738,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "12.4.x-dev" + "dev-main": "12.5.x-dev" } }, "autoload": { @@ -11768,7 +11767,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.4.0" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.0" }, "funding": [ { @@ -11788,7 +11787,7 @@ "type": "tidelift" } ], - "time": "2025-09-24T13:44:41+00:00" + "time": "2025-11-29T07:15:54+00:00" }, { "name": "phpunit/php-file-iterator", diff --git a/config/firefly.php b/config/firefly.php index 8e250c41ea..2e3c97b762 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-29', - 'build_time' => 1764397312, + 'version' => 'develop/2025-12-01', + 'build_time' => 1764560154, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index 45425ee814..9f68cb3d70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4237,9 +4237,9 @@ "license": "MIT" }, "node_modules/bootstrap5-tags": { - "version": "1.7.15", - "resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.7.15.tgz", - "integrity": "sha512-UnHmJC9p0ei5rZG1/5qOFBoKFJ+ZyXiVTi1+fJnN/+6d/htZZ9M4cALxsjxQR53K2PrOSApMBOR2QZDbIkdK+g==", + "version": "1.7.16", + "resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.7.16.tgz", + "integrity": "sha512-P5guDQc+DVFJFK0+udbBRgapRnU6dWWhi4FcuAoMOEX7JdhqW/WB0xUxZGOa338odYIi1HogYN/b24yvJpAxfw==", "license": "MIT" }, "node_modules/brace-expansion": { @@ -12438,9 +12438,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", "bin": { @@ -12448,6 +12448,9 @@ }, "engines": { "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { From 2cdd1aa147355e8cbb2d946ba9a1a9db34616431 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 08:17:15 +0000 Subject: [PATCH 04/27] Bump symfony/expression-language from 7.4.0 to 8.0.0 Bumps [symfony/expression-language](https://github.com/symfony/expression-language) from 7.4.0 to 8.0.0. - [Release notes](https://github.com/symfony/expression-language/releases) - [Changelog](https://github.com/symfony/expression-language/blob/7.3/CHANGELOG.md) - [Commits](https://github.com/symfony/expression-language/compare/v7.4.0...v8.0.0) --- updated-dependencies: - dependency-name: symfony/expression-language dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- composer.lock | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 339891f92a..2ab019f4aa 100644 --- a/composer.json +++ b/composer.json @@ -107,7 +107,7 @@ "spatie/laravel-html": "^3.2", "spatie/laravel-ignition": "^2", "spatie/period": "^2.4", - "symfony/expression-language": "^7.0", + "symfony/expression-language": "^8.0", "symfony/http-client": "^8.0", "symfony/mailgun-mailer": "^7.1", "thecodingmachine/safe": "^3.1" diff --git a/composer.lock b/composer.lock index 64405e85a1..8e18d219fc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "23fc4e822f7746801eb770935e5c0150", + "content-hash": "d4a02d3bedc066805eeb6f15ec1e3324", "packages": [ { "name": "bacon/bacon-qr-code", @@ -7394,22 +7394,21 @@ }, { "name": "symfony/expression-language", - "version": "v7.4.0", + "version": "v8.0.0", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "8b9bbbb8c71f79a09638f6ea77c531e511139efa" + "reference": "43f520aef59d2fd089662d721b39e0101bb69232" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/8b9bbbb8c71f79a09638f6ea77c531e511139efa", - "reference": "8b9bbbb8c71f79a09638f6ea77c531e511139efa", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/43f520aef59d2fd089662d721b39e0101bb69232", + "reference": "43f520aef59d2fd089662d721b39e0101bb69232", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/cache": "^6.4|^7.0|^8.0", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.4", + "symfony/cache": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -7438,7 +7437,7 @@ "description": "Provides an engine that can compile and evaluate expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/expression-language/tree/v7.4.0" + "source": "https://github.com/symfony/expression-language/tree/v8.0.0" }, "funding": [ { @@ -7458,7 +7457,7 @@ "type": "tidelift" } ], - "time": "2025-11-12T15:39:26+00:00" + "time": "2025-11-12T15:46:48+00:00" }, { "name": "symfony/finder", From 1f19f2073416bf1b469e0c8a730950baee997df1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 10:45:09 +0000 Subject: [PATCH 05/27] Bump symfony/mailgun-mailer from 7.4.0 to 8.0.0 Bumps [symfony/mailgun-mailer](https://github.com/symfony/mailgun-mailer) from 7.4.0 to 8.0.0. - [Release notes](https://github.com/symfony/mailgun-mailer/releases) - [Changelog](https://github.com/symfony/mailgun-mailer/blob/7.3/CHANGELOG.md) - [Commits](https://github.com/symfony/mailgun-mailer/compare/v7.4.0...v8.0.0) --- updated-dependencies: - dependency-name: symfony/mailgun-mailer dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- composer.lock | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 2ab019f4aa..51404b0790 100644 --- a/composer.json +++ b/composer.json @@ -109,7 +109,7 @@ "spatie/period": "^2.4", "symfony/expression-language": "^8.0", "symfony/http-client": "^8.0", - "symfony/mailgun-mailer": "^7.1", + "symfony/mailgun-mailer": "^8.0", "thecodingmachine/safe": "^3.1" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 8e18d219fc..047c6f4efb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d4a02d3bedc066805eeb6f15ec1e3324", + "content-hash": "8317b89f4d014debebcd301fde669321", "packages": [ { "name": "bacon/bacon-qr-code", @@ -7988,28 +7988,25 @@ }, { "name": "symfony/mailgun-mailer", - "version": "v7.4.0", + "version": "v8.0.0", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "ffbcdbf93ed0700f083a6307acfb8f78dd3f091b" + "reference": "c8567e2b9a64db3aebd701838402a3726061c36a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/ffbcdbf93ed0700f083a6307acfb8f78dd3f091b", - "reference": "ffbcdbf93ed0700f083a6307acfb8f78dd3f091b", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/c8567e2b9a64db3aebd701838402a3726061c36a", + "reference": "c8567e2b9a64db3aebd701838402a3726061c36a", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/mailer": "^7.2|^8.0" - }, - "conflict": { - "symfony/http-foundation": "<6.4" + "php": ">=8.4", + "symfony/mailer": "^7.4|^8.0" }, "require-dev": { - "symfony/http-client": "^6.4|^7.0|^8.0", - "symfony/webhook": "^6.4|^7.0|^8.0" + "symfony/http-client": "^7.4|^8.0", + "symfony/webhook": "^7.4|^8.0" }, "type": "symfony-mailer-bridge", "autoload": { @@ -8037,7 +8034,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.4.0" + "source": "https://github.com/symfony/mailgun-mailer/tree/v8.0.0" }, "funding": [ { @@ -8057,7 +8054,7 @@ "type": "tidelift" } ], - "time": "2025-08-04T07:05:15+00:00" + "time": "2025-08-04T07:36:47+00:00" }, { "name": "symfony/mime", From 566704434995d7cf364b0c300ace2a287f216a35 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Thu, 4 Dec 2025 17:27:20 +0100 Subject: [PATCH 06/27] Fix #11328 --- app/Http/Controllers/Budget/IndexController.php | 3 +++ resources/views/budgets/index.twig | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index efe15e03bb..95f6d2167d 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -122,6 +122,9 @@ class IndexController extends Controller $availableBudgets = $this->getAllAvailableBudgets($start, $end); // get all active budgets: $budgets = $this->getAllBudgets($start, $end, $currencies, $this->primaryCurrency); + +// echo '
';
+//        var_dump($budgets[0]);exit;
         $sums             = $this->getSums($budgets);
 
         // get budgeted for default currency:
diff --git a/resources/views/budgets/index.twig b/resources/views/budgets/index.twig
index 014742cc74..b80d34798d 100644
--- a/resources/views/budgets/index.twig
+++ b/resources/views/budgets/index.twig
@@ -366,13 +366,21 @@
                                                     
                                                     
{% endif %} - {% if spentInfo.currency_id == budgetLimit.currency_id and not budgetLimit.in_range %} + {% if spentInfo.currency_id == budgetLimit.currency_id and not budgetLimit.in_range and 0.0 == budgetLimit.total_days %} {{ formatAmountBySymbol(spentInfo.spent + budgetLimit.amount, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }} ({{ 'unknown'|_ }}) {% endif %} + {% if spentInfo.currency_id == budgetLimit.currency_id and not budgetLimit.in_range and 0.0 != budgetLimit.total_days %} + + {{ formatAmountBySymbol(spentInfo.spent + budgetLimit.amount, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }} + + ({{ formatAmountBySymbol((spentInfo.spent + budgetLimit.amount) / budgetLimit.total_days, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }}) + {% endif %} + {% endfor %} {% if countLimit == 0 %} From a93f2d66af57a10a4e692d3d9d403d1215ab6731 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 6 Dec 2025 07:27:41 +0100 Subject: [PATCH 07/27] Fix #11329 --- .../Actions/ConvertToTransfer.php | 109 ++++++++++-------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/app/TransactionRules/Actions/ConvertToTransfer.php b/app/TransactionRules/Actions/ConvertToTransfer.php index 0e4a7726b7..f09a4bcc57 100644 --- a/app/TransactionRules/Actions/ConvertToTransfer.php +++ b/app/TransactionRules/Actions/ConvertToTransfer.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace FireflyIII\TransactionRules\Actions; -use Illuminate\Support\Facades\Log; use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray; use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject; @@ -33,10 +32,13 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Models\RuleAction; use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Facades\Steam; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; /** * Class ConvertToTransfer @@ -54,18 +56,18 @@ class ConvertToTransfer implements ActionInterface */ public function actOnArray(array $journal): bool { - $accountName = $this->action->getValue($journal); + $accountName = $this->action->getValue($journal); // make object from array (so the data is fresh). /** @var null|TransactionJournal $object */ - $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); + $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); if (null === $object) { Log::error(sprintf('Cannot find journal #%d, cannot convert to transfer.', $journal['transaction_journal_id'])); event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found'))); return false; } - $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count(); + $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count(); if ($groupCount > 1) { Log::error(sprintf('Group #%d has more than one transaction in it, cannot convert to transfer.', $journal['transaction_group_id'])); event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group'))); @@ -73,14 +75,12 @@ class ConvertToTransfer implements ActionInterface return false; } - $type = $object->transactionType->type; - $user = $object->user; - $journalId = $object->id; + $type = $object->transactionType->type; + $user = $object->user; + $journalId = $object->id; if (TransactionTypeEnum::TRANSFER->value === $type) { - Log::error( - sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id) - ); - event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer'))); + Log::error(sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id)); + // event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer'))); return false; } @@ -92,7 +92,7 @@ class ConvertToTransfer implements ActionInterface // find the asset account in the action value. /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); + $repository = app(AccountRepositoryInterface::class); $repository->setUser($user); $expectedType = null; if (TransactionTypeEnum::WITHDRAWAL->value === $type) { @@ -103,18 +103,10 @@ class ConvertToTransfer implements ActionInterface $expectedType = $this->getDestinationType($journalId); // Deposit? Replace source with account with same type as destination. } - $opposing = $repository->findByName($accountName, [$expectedType]); + $opposing = $repository->findByName($accountName, [$expectedType]); if (null === $opposing) { - Log::error( - sprintf( - 'Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).', - $expectedType, - $journalId, - $accountName, - $this->action->rule_id - ) - ); + Log::error(sprintf('Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).', $expectedType, $journalId, $accountName, $this->action->rule_id)); event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_valid_opposing', ['name' => $accountName]))); return false; @@ -167,7 +159,7 @@ class ConvertToTransfer implements ActionInterface return ''; } - return (string) $journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type; + return (string)$journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type; } private function getDestinationType(int $journalId): string @@ -180,7 +172,7 @@ class ConvertToTransfer implements ActionInterface return ''; } - return (string) $journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type; + return (string)$journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type; } /** @@ -192,33 +184,54 @@ class ConvertToTransfer implements ActionInterface */ private function convertWithdrawalArray(TransactionJournal $journal, Account $opposing): bool { + $repository = app(AccountRepositoryInterface::class); $sourceAccount = $this->getSourceAccount($journal); + $repository->setUser($sourceAccount->user); if ($sourceAccount->id === $opposing->id) { - Log::error( - vsprintf( - 'Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).', - [$journal->id, $opposing->name, $this->action->rule_id] - ) - ); + Log::error(vsprintf('Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).', [$journal->id, $opposing->name, $this->action->rule_id])); event(new RuleActionFailedOnObject($this->action, $journal, trans('rules.already_has_source_asset', ['name' => $opposing->name]))); return false; } - + /** @var Transaction $sourceTransaction */ + $sourceTransaction = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '<', 0)->first(); + /** @var Transaction $destTransaction */ + $destTransaction = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '>', 0)->first(); // update destination transaction: - DB::table('transactions') - ->where('transaction_journal_id', '=', $journal->id) - ->where('amount', '>', 0) - ->update(['account_id' => $opposing->id]) - ; + $destTransaction->account_id = $opposing->id; + $destTransaction->save(); + + // check if the currencies are a match. + /** @var TransactionCurrency $sourceCurrency */ + $sourceCurrency = $repository->getAccountCurrency($sourceAccount); + /** @var TransactionCurrency $destCurrency */ + $destCurrency = $repository->getAccountCurrency($opposing); + + // if the currencies do not match, need to be smart about the involved amounts: + if ($sourceCurrency->id !== $destCurrency->id) { + Log::debug(sprintf('Accounts have different currencies. Source has %s, dest has %s', $sourceCurrency->code, $destCurrency->code)); + $foreignAmount = '' === (string)$sourceTransaction->foreign_amount ? $sourceTransaction->amount : $sourceTransaction->foreign_amount; + Log::debug(sprintf('Foreign amount: %s', $foreignAmount)); + + // source transaction: set the foreign currency ID and leave as is. + $sourceTransaction->foreign_currency_id = $destCurrency->id; + $sourceTransaction->foreign_amount = Steam::negative($foreignAmount); + $sourceTransaction->save(); + Log::debug(sprintf('Set source transaction #%d foreign currency ID to #%d (amount: %s)', $sourceTransaction->id, $destCurrency->id, $foreignAmount)); + + // dest transaction: set reverse amounts and currency IDs from source transaction. + $destTransaction->foreign_currency_id = $sourceCurrency->transaction_currency_id; + $destTransaction->transaction_currency_id = $sourceTransaction->foreign_currency_id; + $destTransaction->amount = Steam::positive($foreignAmount); + $destTransaction->foreign_amount = Steam::positive($sourceTransaction->amount); + $destTransaction->save(); + Log::debug(sprintf('Set dest transaction #%d to #%d %s and foreign #%d %s', $destTransaction->id, $destTransaction->transaction_currency_id, $destTransaction->amount, $destTransaction->foreign_currency_id, $destTransaction->foreign_amount)); + } // change transaction type of journal: - $newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first(); + $newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first(); - DB::table('transaction_journals') - ->where('id', '=', $journal->id) - ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]) - ; + DB::table('transaction_journals')->where('id', '=', $journal->id)->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); Log::debug('Converted withdrawal to transfer.'); @@ -262,18 +275,16 @@ class ConvertToTransfer implements ActionInterface // update source transaction: DB::table('transactions') - ->where('transaction_journal_id', '=', $journal->id) - ->where('amount', '<', 0) - ->update(['account_id' => $opposing->id]) - ; + ->where('transaction_journal_id', '=', $journal->id) + ->where('amount', '<', 0) + ->update(['account_id' => $opposing->id]); // change transaction type of journal: - $newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first(); + $newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first(); DB::table('transaction_journals') - ->where('id', '=', $journal->id) - ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]) - ; + ->where('id', '=', $journal->id) + ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); Log::debug('Converted deposit to transfer.'); From 1f89dddb084fda5defcb88e792ca3063af622d9e Mon Sep 17 00:00:00 2001 From: JC5 Date: Sat, 6 Dec 2025 07:31:41 +0100 Subject: [PATCH 08/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-12-06?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ci/php-cs-fixer/composer.lock | 14 +- .../Controllers/Budget/IndexController.php | 4 +- .../Actions/ConvertToTransfer.php | 53 +-- composer.lock | 227 ++++++------ config/firefly.php | 4 +- package-lock.json | 330 +++++++++++------- 6 files changed, 348 insertions(+), 284 deletions(-) diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock index 262aecb0ec..c9d5aa4d4f 100644 --- a/.ci/php-cs-fixer/composer.lock +++ b/.ci/php-cs-fixer/composer.lock @@ -402,16 +402,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.91.0", + "version": "v3.91.3", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "c4a25f20390337789c26b693ae46faa125040352" + "reference": "9f10aa6390cea91da175ea608880e942d7c0226e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c4a25f20390337789c26b693ae46faa125040352", - "reference": "c4a25f20390337789c26b693ae46faa125040352", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/9f10aa6390cea91da175ea608880e942d7c0226e", + "reference": "9f10aa6390cea91da175ea608880e942d7c0226e", "shasum": "" }, "require": { @@ -467,7 +467,7 @@ "PhpCsFixer\\": "src/" }, "exclude-from-classmap": [ - "src/Fixer/Internal/*" + "src/**/Internal/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -493,7 +493,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.91.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.91.3" }, "funding": [ { @@ -501,7 +501,7 @@ "type": "github" } ], - "time": "2025-11-28T22:07:42+00:00" + "time": "2025-12-05T19:45:37+00:00" }, { "name": "psr/container", diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index 95f6d2167d..476987f58c 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -123,8 +123,8 @@ class IndexController extends Controller // get all active budgets: $budgets = $this->getAllBudgets($start, $end, $currencies, $this->primaryCurrency); -// echo '
';
-//        var_dump($budgets[0]);exit;
+        //        echo '
';
+        //        var_dump($budgets[0]);exit;
         $sums             = $this->getSums($budgets);
 
         // get budgeted for default currency:
diff --git a/app/TransactionRules/Actions/ConvertToTransfer.php b/app/TransactionRules/Actions/ConvertToTransfer.php
index f09a4bcc57..b2e5385b88 100644
--- a/app/TransactionRules/Actions/ConvertToTransfer.php
+++ b/app/TransactionRules/Actions/ConvertToTransfer.php
@@ -56,18 +56,18 @@ class ConvertToTransfer implements ActionInterface
      */
     public function actOnArray(array $journal): bool
     {
-        $accountName = $this->action->getValue($journal);
+        $accountName  = $this->action->getValue($journal);
 
         // make object from array (so the data is fresh).
         /** @var null|TransactionJournal $object */
-        $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+        $object       = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
         if (null === $object) {
             Log::error(sprintf('Cannot find journal #%d, cannot convert to transfer.', $journal['transaction_journal_id']));
             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found')));
 
             return false;
         }
-        $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
+        $groupCount   = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
         if ($groupCount > 1) {
             Log::error(sprintf('Group #%d has more than one transaction in it, cannot convert to transfer.', $journal['transaction_group_id']));
             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group')));
@@ -75,9 +75,9 @@ class ConvertToTransfer implements ActionInterface
             return false;
         }
 
-        $type      = $object->transactionType->type;
-        $user      = $object->user;
-        $journalId = $object->id;
+        $type         = $object->transactionType->type;
+        $user         = $object->user;
+        $journalId    = $object->id;
         if (TransactionTypeEnum::TRANSFER->value === $type) {
             Log::error(sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id));
             // event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer')));
@@ -92,7 +92,7 @@ class ConvertToTransfer implements ActionInterface
 
         // find the asset account in the action value.
         /** @var AccountRepositoryInterface $repository */
-        $repository = app(AccountRepositoryInterface::class);
+        $repository   = app(AccountRepositoryInterface::class);
         $repository->setUser($user);
         $expectedType = null;
         if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
@@ -103,7 +103,7 @@ class ConvertToTransfer implements ActionInterface
             $expectedType = $this->getDestinationType($journalId);
             // Deposit? Replace source with account with same type as destination.
         }
-        $opposing = $repository->findByName($accountName, [$expectedType]);
+        $opposing     = $repository->findByName($accountName, [$expectedType]);
 
         if (null === $opposing) {
             Log::error(sprintf('Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).', $expectedType, $journalId, $accountName, $this->action->rule_id));
@@ -184,8 +184,8 @@ class ConvertToTransfer implements ActionInterface
      */
     private function convertWithdrawalArray(TransactionJournal $journal, Account $opposing): bool
     {
-        $repository    = app(AccountRepositoryInterface::class);
-        $sourceAccount = $this->getSourceAccount($journal);
+        $repository                  = app(AccountRepositoryInterface::class);
+        $sourceAccount               = $this->getSourceAccount($journal);
         $repository->setUser($sourceAccount->user);
         if ($sourceAccount->id === $opposing->id) {
             Log::error(vsprintf('Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).', [$journal->id, $opposing->name, $this->action->rule_id]));
@@ -193,29 +193,32 @@ class ConvertToTransfer implements ActionInterface
 
             return false;
         }
+
         /** @var Transaction $sourceTransaction */
-        $sourceTransaction = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '<', 0)->first();
+        $sourceTransaction           = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '<', 0)->first();
+
         /** @var Transaction $destTransaction */
-        $destTransaction = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '>', 0)->first();
+        $destTransaction             = Transaction::where('transaction_journal_id', '=', $journal->id)->where('amount', '>', 0)->first();
         // update destination transaction:
         $destTransaction->account_id = $opposing->id;
         $destTransaction->save();
 
         // check if the currencies are a match.
         /** @var TransactionCurrency $sourceCurrency */
-        $sourceCurrency = $repository->getAccountCurrency($sourceAccount);
+        $sourceCurrency              = $repository->getAccountCurrency($sourceAccount);
+
         /** @var TransactionCurrency $destCurrency */
-        $destCurrency = $repository->getAccountCurrency($opposing);
+        $destCurrency                = $repository->getAccountCurrency($opposing);
 
         // if the currencies do not match, need to be smart about the involved amounts:
         if ($sourceCurrency->id !== $destCurrency->id) {
             Log::debug(sprintf('Accounts have different currencies. Source has %s, dest has %s', $sourceCurrency->code, $destCurrency->code));
-            $foreignAmount = '' === (string)$sourceTransaction->foreign_amount ? $sourceTransaction->amount : $sourceTransaction->foreign_amount;
+            $foreignAmount                            = '' === (string)$sourceTransaction->foreign_amount ? $sourceTransaction->amount : $sourceTransaction->foreign_amount;
             Log::debug(sprintf('Foreign amount: %s', $foreignAmount));
 
             // source transaction: set the foreign currency ID and leave as is.
-            $sourceTransaction->foreign_currency_id = $destCurrency->id;
-            $sourceTransaction->foreign_amount      = Steam::negative($foreignAmount);
+            $sourceTransaction->foreign_currency_id   = $destCurrency->id;
+            $sourceTransaction->foreign_amount        = Steam::negative($foreignAmount);
             $sourceTransaction->save();
             Log::debug(sprintf('Set source transaction #%d foreign currency ID to #%d (amount: %s)', $sourceTransaction->id, $destCurrency->id, $foreignAmount));
 
@@ -229,7 +232,7 @@ class ConvertToTransfer implements ActionInterface
         }
 
         // change transaction type of journal:
-        $newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first();
+        $newType                     = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first();
 
         DB::table('transaction_journals')->where('id', '=', $journal->id)->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
 
@@ -275,16 +278,18 @@ class ConvertToTransfer implements ActionInterface
 
         // update source transaction:
         DB::table('transactions')
-          ->where('transaction_journal_id', '=', $journal->id)
-          ->where('amount', '<', 0)
-          ->update(['account_id' => $opposing->id]);
+            ->where('transaction_journal_id', '=', $journal->id)
+            ->where('amount', '<', 0)
+            ->update(['account_id' => $opposing->id])
+        ;
 
         // change transaction type of journal:
-        $newType = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first();
+        $newType     = TransactionType::whereType(TransactionTypeEnum::TRANSFER->value)->first();
 
         DB::table('transaction_journals')
-          ->where('id', '=', $journal->id)
-          ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
+            ->where('id', '=', $journal->id)
+            ->update(['transaction_type_id' => $newType->id, 'bill_id' => null])
+        ;
 
         Log::debug('Converted deposit to transfer.');
 
diff --git a/composer.lock b/composer.lock
index 047c6f4efb..33b3d4eeda 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1072,31 +1072,31 @@
         },
         {
             "name": "fruitcake/php-cors",
-            "version": "v1.3.0",
+            "version": "v1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/fruitcake/php-cors.git",
-                "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b"
+                "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b",
-                "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b",
+                "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379",
+                "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.4|^8.0",
-                "symfony/http-foundation": "^4.4|^5.4|^6|^7"
+                "php": "^8.1",
+                "symfony/http-foundation": "^5.4|^6.4|^7.3|^8"
             },
             "require-dev": {
-                "phpstan/phpstan": "^1.4",
+                "phpstan/phpstan": "^2",
                 "phpunit/phpunit": "^9",
-                "squizlabs/php_codesniffer": "^3.5"
+                "squizlabs/php_codesniffer": "^4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.3-dev"
                 }
             },
             "autoload": {
@@ -1127,7 +1127,7 @@
             ],
             "support": {
                 "issues": "https://github.com/fruitcake/php-cors/issues",
-                "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0"
+                "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0"
             },
             "funding": [
                 {
@@ -1139,7 +1139,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-10-12T05:21:21+00:00"
+            "time": "2025-12-03T09:33:47+00:00"
         },
         {
             "name": "gdbots/query-parser",
@@ -1938,16 +1938,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v12.40.2",
+            "version": "v12.41.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "1ccd99220b474500e672b373f32bd709ec38de50"
+                "reference": "3e229b05935fd0300c632fb1f718c73046d664fc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/1ccd99220b474500e672b373f32bd709ec38de50",
-                "reference": "1ccd99220b474500e672b373f32bd709ec38de50",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/3e229b05935fd0300c632fb1f718c73046d664fc",
+                "reference": "3e229b05935fd0300c632fb1f718c73046d664fc",
                 "shasum": ""
             },
             "require": {
@@ -2153,7 +2153,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2025-11-26T19:24:25+00:00"
+            "time": "2025-12-03T01:02:13+00:00"
         },
         {
             "name": "laravel/passport",
@@ -3543,22 +3543,22 @@
         },
         {
             "name": "mailersend/laravel-driver",
-            "version": "v2.9.1",
+            "version": "v2.12.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-laravel-driver.git",
-                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725"
+                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725",
-                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725",
+                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
+                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
                 "illuminate/support": "^9.0 || ^10.0  || ^11.0 || ^12.0",
-                "mailersend/mailersend": "^0.31.0",
+                "mailersend/mailersend": "^0.35.0",
                 "nyholm/psr7": "^1.5",
                 "php": ">=8.0",
                 "php-http/guzzle7-adapter": "^1.0",
@@ -3606,29 +3606,28 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
-                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1"
+                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
             },
-            "time": "2025-04-09T09:33:07+00:00"
+            "time": "2025-10-28T14:59:16+00:00"
         },
         {
             "name": "mailersend/mailersend",
-            "version": "v0.31.0",
+            "version": "v0.35.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-php.git",
-                "reference": "513ff83ee768526055ad52987cde401ea7218c67"
+                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67",
-                "reference": "513ff83ee768526055ad52987cde401ea7218c67",
+                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
+                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
                 "shasum": ""
             },
             "require": {
                 "beberlei/assert": "^3.2",
                 "ext-json": "*",
-                "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
-                "php": "^7.4|^8.0",
+                "php": "^7.4 || ^8.0 <8.5",
                 "php-http/client-common": "^2.2",
                 "php-http/discovery": "^1.9",
                 "php-http/httplug": "^2.1",
@@ -3673,9 +3672,9 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-php/issues",
-                "source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0"
+                "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
             },
-            "time": "2025-04-03T12:16:11+00:00"
+            "time": "2025-10-28T13:11:43+00:00"
         },
         {
             "name": "monolog/monolog",
@@ -3782,16 +3781,16 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "3.10.3",
+            "version": "3.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/CarbonPHP/carbon.git",
-                "reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f"
+                "reference": "bdb375400dcd162624531666db4799b36b64e4a1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f",
-                "reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f",
+                "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1",
+                "reference": "bdb375400dcd162624531666db4799b36b64e4a1",
                 "shasum": ""
             },
             "require": {
@@ -3799,9 +3798,9 @@
                 "ext-json": "*",
                 "php": "^8.1",
                 "psr/clock": "^1.0",
-                "symfony/clock": "^6.3.12 || ^7.0",
+                "symfony/clock": "^6.3.12 || ^7.0 || ^8.0",
                 "symfony/polyfill-mbstring": "^1.0",
-                "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0"
+                "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0"
             },
             "provide": {
                 "psr/clock-implementation": "1.0"
@@ -3883,7 +3882,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-09-06T13:39:36+00:00"
+            "time": "2025-12-02T21:04:28+00:00"
         },
         {
             "name": "nette/schema",
@@ -3952,20 +3951,20 @@
         },
         {
             "name": "nette/utils",
-            "version": "v4.0.9",
+            "version": "v4.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nette/utils.git",
-                "reference": "505a30ad386daa5211f08a318e47015b501cad30"
+                "reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nette/utils/zipball/505a30ad386daa5211f08a318e47015b501cad30",
-                "reference": "505a30ad386daa5211f08a318e47015b501cad30",
+                "url": "https://api.github.com/repos/nette/utils/zipball/fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
+                "reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
                 "shasum": ""
             },
             "require": {
-                "php": "8.0 - 8.5"
+                "php": "8.2 - 8.5"
             },
             "conflict": {
                 "nette/finder": "<3",
@@ -3988,7 +3987,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0-dev"
+                    "dev-master": "4.1-dev"
                 }
             },
             "autoload": {
@@ -4035,9 +4034,9 @@
             ],
             "support": {
                 "issues": "https://github.com/nette/utils/issues",
-                "source": "https://github.com/nette/utils/tree/v4.0.9"
+                "source": "https://github.com/nette/utils/tree/v4.1.0"
             },
-            "time": "2025-10-31T00:45:47+00:00"
+            "time": "2025-12-01T17:49:23+00:00"
         },
         {
             "name": "nunomaduro/collision",
@@ -5972,16 +5971,16 @@
         },
         {
             "name": "sentry/sentry",
-            "version": "4.19.0",
+            "version": "4.19.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/getsentry/sentry-php.git",
-                "reference": "1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053"
+                "reference": "1c21d60bebe67c0122335bd3fe977990435af0a3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053",
-                "reference": "1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053",
+                "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/1c21d60bebe67c0122335bd3fe977990435af0a3",
+                "reference": "1c21d60bebe67c0122335bd3fe977990435af0a3",
                 "shasum": ""
             },
             "require": {
@@ -6044,7 +6043,7 @@
             ],
             "support": {
                 "issues": "https://github.com/getsentry/sentry-php/issues",
-                "source": "https://github.com/getsentry/sentry-php/tree/4.19.0"
+                "source": "https://github.com/getsentry/sentry-php/tree/4.19.1"
             },
             "funding": [
                 {
@@ -6056,27 +6055,27 @@
                     "type": "custom"
                 }
             ],
-            "time": "2025-11-27T14:53:55+00:00"
+            "time": "2025-12-02T15:57:41+00:00"
         },
         {
             "name": "sentry/sentry-laravel",
-            "version": "4.19.0",
+            "version": "4.20.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/getsentry/sentry-laravel.git",
-                "reference": "7fdffd57e8fff0a6f9a18d9a83f32e960af63e3f"
+                "reference": "95f2542ee1ebc993529b63f5c8543184abd00650"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/7fdffd57e8fff0a6f9a18d9a83f32e960af63e3f",
-                "reference": "7fdffd57e8fff0a6f9a18d9a83f32e960af63e3f",
+                "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/95f2542ee1ebc993529b63f5c8543184abd00650",
+                "reference": "95f2542ee1ebc993529b63f5c8543184abd00650",
                 "shasum": ""
             },
             "require": {
                 "illuminate/support": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 | ^12.0",
                 "nyholm/psr7": "^1.0",
                 "php": "^7.2 | ^8.0",
-                "sentry/sentry": "^4.18.0",
+                "sentry/sentry": "^4.19.0",
                 "symfony/psr-http-message-bridge": "^1.0 | ^2.0 | ^6.0 | ^7.0"
             },
             "require-dev": {
@@ -6134,7 +6133,7 @@
             ],
             "support": {
                 "issues": "https://github.com/getsentry/sentry-laravel/issues",
-                "source": "https://github.com/getsentry/sentry-laravel/tree/4.19.0"
+                "source": "https://github.com/getsentry/sentry-laravel/tree/4.20.0"
             },
             "funding": [
                 {
@@ -6146,7 +6145,7 @@
                     "type": "custom"
                 }
             ],
-            "time": "2025-11-11T09:01:14+00:00"
+            "time": "2025-12-02T10:37:40+00:00"
         },
         {
             "name": "spatie/backtrace",
@@ -6839,22 +6838,21 @@
         },
         {
             "name": "symfony/clock",
-            "version": "v7.4.0",
+            "version": "v8.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/clock.git",
-                "reference": "9169f24776edde469914c1e7a1442a50f7a4e110"
+                "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/clock/zipball/9169f24776edde469914c1e7a1442a50f7a4e110",
-                "reference": "9169f24776edde469914c1e7a1442a50f7a4e110",
+                "url": "https://api.github.com/repos/symfony/clock/zipball/832119f9b8dbc6c8e6f65f30c5969eca1e88764f",
+                "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.2",
-                "psr/clock": "^1.0",
-                "symfony/polyfill-php83": "^1.28"
+                "php": ">=8.4",
+                "psr/clock": "^1.0"
             },
             "provide": {
                 "psr/clock-implementation": "1.0"
@@ -6893,7 +6891,7 @@
                 "time"
             ],
             "support": {
-                "source": "https://github.com/symfony/clock/tree/v7.4.0"
+                "source": "https://github.com/symfony/clock/tree/v8.0.0"
             },
             "funding": [
                 {
@@ -6913,7 +6911,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-12T15:39:26+00:00"
+            "time": "2025-11-12T15:46:48+00:00"
         },
         {
             "name": "symfony/console",
@@ -9462,34 +9460,27 @@
         },
         {
             "name": "symfony/translation",
-            "version": "v7.4.0",
+            "version": "v8.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68"
+                "reference": "82ab368a6fca6358d995b6dd5c41590fb42c03e6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/2d01ca0da3f092f91eeedb46f24aa30d2fca8f68",
-                "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/82ab368a6fca6358d995b6dd5c41590fb42c03e6",
+                "reference": "82ab368a6fca6358d995b6dd5c41590fb42c03e6",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.2",
-                "symfony/deprecation-contracts": "^2.5|^3",
-                "symfony/polyfill-mbstring": "~1.0",
-                "symfony/translation-contracts": "^2.5.3|^3.3"
+                "php": ">=8.4",
+                "symfony/polyfill-mbstring": "^1.0",
+                "symfony/translation-contracts": "^3.6.1"
             },
             "conflict": {
                 "nikic/php-parser": "<5.0",
-                "symfony/config": "<6.4",
-                "symfony/console": "<6.4",
-                "symfony/dependency-injection": "<6.4",
                 "symfony/http-client-contracts": "<2.5",
-                "symfony/http-kernel": "<6.4",
-                "symfony/service-contracts": "<2.5",
-                "symfony/twig-bundle": "<6.4",
-                "symfony/yaml": "<6.4"
+                "symfony/service-contracts": "<2.5"
             },
             "provide": {
                 "symfony/translation-implementation": "2.3|3.0"
@@ -9497,17 +9488,17 @@
             "require-dev": {
                 "nikic/php-parser": "^5.0",
                 "psr/log": "^1|^2|^3",
-                "symfony/config": "^6.4|^7.0|^8.0",
-                "symfony/console": "^6.4|^7.0|^8.0",
-                "symfony/dependency-injection": "^6.4|^7.0|^8.0",
-                "symfony/finder": "^6.4|^7.0|^8.0",
+                "symfony/config": "^7.4|^8.0",
+                "symfony/console": "^7.4|^8.0",
+                "symfony/dependency-injection": "^7.4|^8.0",
+                "symfony/finder": "^7.4|^8.0",
                 "symfony/http-client-contracts": "^2.5|^3.0",
-                "symfony/http-kernel": "^6.4|^7.0|^8.0",
-                "symfony/intl": "^6.4|^7.0|^8.0",
+                "symfony/http-kernel": "^7.4|^8.0",
+                "symfony/intl": "^7.4|^8.0",
                 "symfony/polyfill-intl-icu": "^1.21",
-                "symfony/routing": "^6.4|^7.0|^8.0",
+                "symfony/routing": "^7.4|^8.0",
                 "symfony/service-contracts": "^2.5|^3",
-                "symfony/yaml": "^6.4|^7.0|^8.0"
+                "symfony/yaml": "^7.4|^8.0"
             },
             "type": "library",
             "autoload": {
@@ -9538,7 +9529,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v7.4.0"
+                "source": "https://github.com/symfony/translation/tree/v8.0.0"
             },
             "funding": [
                 {
@@ -9558,7 +9549,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-27T13:27:24+00:00"
+            "time": "2025-11-27T08:09:45+00:00"
         },
         {
             "name": "symfony/translation-contracts",
@@ -10759,16 +10750,16 @@
         },
         {
             "name": "driftingly/rector-laravel",
-            "version": "2.1.4",
+            "version": "2.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/driftingly/rector-laravel.git",
-                "reference": "b84b1877ac4f6686f718bc259c9a68d914b514fa"
+                "reference": "682d1e73ac79aced7e645141fd61a9ac468a0c44"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/b84b1877ac4f6686f718bc259c9a68d914b514fa",
-                "reference": "b84b1877ac4f6686f718bc259c9a68d914b514fa",
+                "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/682d1e73ac79aced7e645141fd61a9ac468a0c44",
+                "reference": "682d1e73ac79aced7e645141fd61a9ac468a0c44",
                 "shasum": ""
             },
             "require": {
@@ -10789,9 +10780,9 @@
             "description": "Rector upgrades rules for Laravel Framework",
             "support": {
                 "issues": "https://github.com/driftingly/rector-laravel/issues",
-                "source": "https://github.com/driftingly/rector-laravel/tree/2.1.4"
+                "source": "https://github.com/driftingly/rector-laravel/tree/2.1.6"
             },
-            "time": "2025-11-30T21:38:38+00:00"
+            "time": "2025-12-04T13:37:33+00:00"
         },
         {
             "name": "fakerphp/faker",
@@ -11545,11 +11536,11 @@
         },
         {
             "name": "phpstan/phpstan",
-            "version": "2.1.32",
+            "version": "2.1.33",
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227",
-                "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227",
+                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f",
+                "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f",
                 "shasum": ""
             },
             "require": {
@@ -11594,7 +11585,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-11-11T15:18:17+00:00"
+            "time": "2025-12-05T10:24:31+00:00"
         },
         {
             "name": "phpstan/phpstan-deprecation-rules",
@@ -12027,16 +12018,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "12.4.4",
+            "version": "12.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7"
+                "reference": "fef037fe50d20ce826cdbd741b7a2afcdec5f45b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9253ec75a672e39fcc9d85bdb61448215b8162c7",
-                "reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fef037fe50d20ce826cdbd741b7a2afcdec5f45b",
+                "reference": "fef037fe50d20ce826cdbd741b7a2afcdec5f45b",
                 "shasum": ""
             },
             "require": {
@@ -12050,7 +12041,7 @@
                 "phar-io/manifest": "^2.0.4",
                 "phar-io/version": "^3.2.1",
                 "php": ">=8.3",
-                "phpunit/php-code-coverage": "^12.4.0",
+                "phpunit/php-code-coverage": "^12.5.0",
                 "phpunit/php-file-iterator": "^6.0.0",
                 "phpunit/php-invoker": "^6.0.0",
                 "phpunit/php-text-template": "^5.0.0",
@@ -12072,7 +12063,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "12.4-dev"
+                    "dev-main": "12.5-dev"
                 }
             },
             "autoload": {
@@ -12104,7 +12095,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/12.4.4"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.0"
             },
             "funding": [
                 {
@@ -12128,20 +12119,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-21T07:39:11+00:00"
+            "time": "2025-12-05T04:59:40+00:00"
         },
         {
             "name": "rector/rector",
-            "version": "2.2.9",
+            "version": "2.2.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/rectorphp/rector.git",
-                "reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05"
+                "reference": "7bd21a40b0332b93d4bfee284093d7400696902d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/rectorphp/rector/zipball/0b8e49ec234877b83244d2ecd0df7a4c16471f05",
-                "reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05",
+                "url": "https://api.github.com/repos/rectorphp/rector/zipball/7bd21a40b0332b93d4bfee284093d7400696902d",
+                "reference": "7bd21a40b0332b93d4bfee284093d7400696902d",
                 "shasum": ""
             },
             "require": {
@@ -12180,7 +12171,7 @@
             ],
             "support": {
                 "issues": "https://github.com/rectorphp/rector/issues",
-                "source": "https://github.com/rectorphp/rector/tree/2.2.9"
+                "source": "https://github.com/rectorphp/rector/tree/2.2.11"
             },
             "funding": [
                 {
@@ -12188,7 +12179,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-11-28T14:21:22+00:00"
+            "time": "2025-12-02T11:23:46+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -13330,5 +13321,5 @@
         "ext-xmlwriter": "*"
     },
     "platform-dev": {},
-    "plugin-api-version": "2.6.0"
+    "plugin-api-version": "2.9.0"
 }
diff --git a/config/firefly.php b/config/firefly.php
index 2e3c97b762..da9b272ada 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
         'running_balance_column' => env('USE_RUNNING_BALANCE', false),
         // see cer.php for exchange rates feature flag.
     ],
-    'version'                              => 'develop/2025-12-01',
-    'build_time'                           => 1764560154,
+    'version'                              => 'develop/2025-12-06',
+    'build_time'                           => 1765002600,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 
diff --git a/package-lock.json b/package-lock.json
index 9f68cb3d70..1b4ec416ab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4075,9 +4075,9 @@
             "license": "MIT"
         },
         "node_modules/baseline-browser-mapping": {
-            "version": "2.8.32",
-            "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz",
-            "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==",
+            "version": "2.9.3",
+            "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.3.tgz",
+            "integrity": "sha512-8QdH6czo+G7uBsNo0GiUfouPN1lRzKdJTGnKXwe12gkFbnnOUaUKGN55dMkfy+mnxmvjwl9zcI4VncczcVXDhA==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {
@@ -4129,24 +4129,24 @@
             "license": "MIT"
         },
         "node_modules/body-parser": {
-            "version": "1.20.3",
-            "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
-            "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+            "version": "1.20.4",
+            "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
+            "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "bytes": "3.1.2",
+                "bytes": "~3.1.2",
                 "content-type": "~1.0.5",
                 "debug": "2.6.9",
                 "depd": "2.0.0",
-                "destroy": "1.2.0",
-                "http-errors": "2.0.0",
-                "iconv-lite": "0.4.24",
-                "on-finished": "2.4.1",
-                "qs": "6.13.0",
-                "raw-body": "2.5.2",
+                "destroy": "~1.2.0",
+                "http-errors": "~2.0.1",
+                "iconv-lite": "~0.4.24",
+                "on-finished": "~2.4.1",
+                "qs": "~6.14.0",
+                "raw-body": "~2.5.3",
                 "type-is": "~1.6.18",
-                "unpipe": "1.0.0"
+                "unpipe": "~1.0.0"
             },
             "engines": {
                 "node": ">= 0.8",
@@ -4170,22 +4170,6 @@
             "dev": true,
             "license": "MIT"
         },
-        "node_modules/body-parser/node_modules/qs": {
-            "version": "6.13.0",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
-            "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
-            "dev": true,
-            "license": "BSD-3-Clause",
-            "dependencies": {
-                "side-channel": "^1.0.6"
-            },
-            "engines": {
-                "node": ">=0.6"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/ljharb"
-            }
-        },
         "node_modules/bonjour-service": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz",
@@ -4360,9 +4344,9 @@
             }
         },
         "node_modules/browserslist": {
-            "version": "4.28.0",
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
-            "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==",
+            "version": "4.28.1",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+            "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
             "dev": true,
             "funding": [
                 {
@@ -4380,11 +4364,11 @@
             ],
             "license": "MIT",
             "dependencies": {
-                "baseline-browser-mapping": "^2.8.25",
-                "caniuse-lite": "^1.0.30001754",
-                "electron-to-chromium": "^1.5.249",
+                "baseline-browser-mapping": "^2.9.0",
+                "caniuse-lite": "^1.0.30001759",
+                "electron-to-chromium": "^1.5.263",
                 "node-releases": "^2.0.27",
-                "update-browserslist-db": "^1.1.4"
+                "update-browserslist-db": "^1.2.0"
             },
             "bin": {
                 "browserslist": "cli.js"
@@ -4521,9 +4505,9 @@
             }
         },
         "node_modules/caniuse-lite": {
-            "version": "1.0.30001757",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz",
-            "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==",
+            "version": "1.0.30001759",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz",
+            "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==",
             "dev": true,
             "funding": [
                 {
@@ -4949,9 +4933,9 @@
             "license": "MIT"
         },
         "node_modules/cookie": {
-            "version": "0.7.1",
-            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
-            "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+            "version": "0.7.2",
+            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+            "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -4959,9 +4943,9 @@
             }
         },
         "node_modules/cookie-signature": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
-            "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
+            "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
             "dev": true,
             "license": "MIT"
         },
@@ -5736,9 +5720,9 @@
             "license": "MIT"
         },
         "node_modules/electron-to-chromium": {
-            "version": "1.5.262",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz",
-            "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==",
+            "version": "1.5.266",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz",
+            "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==",
             "dev": true,
             "license": "ISC"
         },
@@ -6084,40 +6068,40 @@
             }
         },
         "node_modules/express": {
-            "version": "4.21.2",
-            "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
-            "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+            "version": "4.22.1",
+            "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
+            "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "accepts": "~1.3.8",
                 "array-flatten": "1.1.1",
-                "body-parser": "1.20.3",
-                "content-disposition": "0.5.4",
+                "body-parser": "~1.20.3",
+                "content-disposition": "~0.5.4",
                 "content-type": "~1.0.4",
-                "cookie": "0.7.1",
-                "cookie-signature": "1.0.6",
+                "cookie": "~0.7.1",
+                "cookie-signature": "~1.0.6",
                 "debug": "2.6.9",
                 "depd": "2.0.0",
                 "encodeurl": "~2.0.0",
                 "escape-html": "~1.0.3",
                 "etag": "~1.8.1",
-                "finalhandler": "1.3.1",
-                "fresh": "0.5.2",
-                "http-errors": "2.0.0",
+                "finalhandler": "~1.3.1",
+                "fresh": "~0.5.2",
+                "http-errors": "~2.0.0",
                 "merge-descriptors": "1.0.3",
                 "methods": "~1.1.2",
-                "on-finished": "2.4.1",
+                "on-finished": "~2.4.1",
                 "parseurl": "~1.3.3",
-                "path-to-regexp": "0.1.12",
+                "path-to-regexp": "~0.1.12",
                 "proxy-addr": "~2.0.7",
-                "qs": "6.13.0",
+                "qs": "~6.14.0",
                 "range-parser": "~1.2.1",
                 "safe-buffer": "5.2.1",
-                "send": "0.19.0",
-                "serve-static": "1.16.2",
+                "send": "~0.19.0",
+                "serve-static": "~1.16.2",
                 "setprototypeof": "1.2.0",
-                "statuses": "2.0.1",
+                "statuses": "~2.0.1",
                 "type-is": "~1.6.18",
                 "utils-merge": "1.0.1",
                 "vary": "~1.1.2"
@@ -6147,22 +6131,6 @@
             "dev": true,
             "license": "MIT"
         },
-        "node_modules/express/node_modules/qs": {
-            "version": "6.13.0",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
-            "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
-            "dev": true,
-            "license": "BSD-3-Clause",
-            "dependencies": {
-                "side-channel": "^1.0.6"
-            },
-            "engines": {
-                "node": ">=0.6"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/ljharb"
-            }
-        },
         "node_modules/fast-deep-equal": {
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -6308,18 +6276,18 @@
             }
         },
         "node_modules/finalhandler": {
-            "version": "1.3.1",
-            "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
-            "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
+            "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "debug": "2.6.9",
                 "encodeurl": "~2.0.0",
                 "escape-html": "~1.0.3",
-                "on-finished": "2.4.1",
+                "on-finished": "~2.4.1",
                 "parseurl": "~1.3.3",
-                "statuses": "2.0.1",
+                "statuses": "~2.0.2",
                 "unpipe": "~1.0.0"
             },
             "engines": {
@@ -7007,20 +6975,24 @@
             "license": "MIT"
         },
         "node_modules/http-errors": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
-            "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+            "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "depd": "2.0.0",
-                "inherits": "2.0.4",
-                "setprototypeof": "1.2.0",
-                "statuses": "2.0.1",
-                "toidentifier": "1.0.1"
+                "depd": "~2.0.0",
+                "inherits": "~2.0.4",
+                "setprototypeof": "~1.2.0",
+                "statuses": "~2.0.2",
+                "toidentifier": "~1.0.1"
             },
             "engines": {
                 "node": ">= 0.8"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/express"
             }
         },
         "node_modules/http-parser-js": {
@@ -7088,9 +7060,9 @@
             }
         },
         "node_modules/i18next": {
-            "version": "25.6.3",
-            "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.3.tgz",
-            "integrity": "sha512-AEQvoPDljhp67a1+NsnG/Wb1Nh6YoSvtrmeEd24sfGn3uujCtXCF3cXpr7ulhMywKNFF7p3TX1u2j7y+caLOJg==",
+            "version": "25.7.1",
+            "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.1.tgz",
+            "integrity": "sha512-XbTnkh1yCZWSAZGnA9xcQfHcYNgZs2cNxm+c6v1Ma9UAUGCeJPplRe1ILia6xnDvXBjk0uXU+Z8FYWhA19SKFw==",
             "funding": [
                 {
                     "type": "individual",
@@ -7137,12 +7109,12 @@
             }
         },
         "node_modules/i18next-localstorage-backend": {
-            "version": "4.2.0",
-            "resolved": "https://registry.npmjs.org/i18next-localstorage-backend/-/i18next-localstorage-backend-4.2.0.tgz",
-            "integrity": "sha512-vglEQF0AnLriX7dLA2drHnqAYzHxnLwWQzBDw8YxcIDjOvYZz5rvpal59Dq4In+IHNmGNM32YgF0TDjBT0fHmA==",
+            "version": "4.3.1",
+            "resolved": "https://registry.npmjs.org/i18next-localstorage-backend/-/i18next-localstorage-backend-4.3.1.tgz",
+            "integrity": "sha512-ry8WNBanUs55rsRZs9+xaZWRxCoTEMMOf+2vNSfzzJqDPbHaf0eMFMrtYp/2ocxU6Xrxfwz17Fdz0rSs3Kw39Q==",
             "license": "MIT",
             "dependencies": {
-                "@babel/runtime": "^7.22.15"
+                "@babel/runtime": "^7.28.4"
             }
         },
         "node_modules/iconv-lite": {
@@ -8400,9 +8372,9 @@
             }
         },
         "node_modules/node-forge": {
-            "version": "1.3.2",
-            "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
-            "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==",
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz",
+            "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==",
             "dev": true,
             "license": "(BSD-3-Clause OR GPL-2.0)",
             "engines": {
@@ -9808,16 +9780,16 @@
             }
         },
         "node_modules/raw-body": {
-            "version": "2.5.2",
-            "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
-            "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+            "version": "2.5.3",
+            "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
+            "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "bytes": "3.1.2",
-                "http-errors": "2.0.0",
-                "iconv-lite": "0.4.24",
-                "unpipe": "1.0.0"
+                "bytes": "~3.1.2",
+                "http-errors": "~2.0.1",
+                "iconv-lite": "~0.4.24",
+                "unpipe": "~1.0.0"
             },
             "engines": {
                 "node": ">= 0.8"
@@ -10307,16 +10279,16 @@
             }
         },
         "node_modules/send": {
-            "version": "0.19.0",
-            "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
-            "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+            "version": "0.19.1",
+            "resolved": "https://registry.npmjs.org/send/-/send-0.19.1.tgz",
+            "integrity": "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "debug": "2.6.9",
                 "depd": "2.0.0",
                 "destroy": "1.2.0",
-                "encodeurl": "~1.0.2",
+                "encodeurl": "~2.0.0",
                 "escape-html": "~1.0.3",
                 "etag": "~1.8.1",
                 "fresh": "0.5.2",
@@ -10348,10 +10320,27 @@
             "dev": true,
             "license": "MIT"
         },
-        "node_modules/send/node_modules/encodeurl": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-            "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+        "node_modules/send/node_modules/http-errors": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+            "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "depd": "2.0.0",
+                "inherits": "2.0.4",
+                "setprototypeof": "1.2.0",
+                "statuses": "2.0.1",
+                "toidentifier": "1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/send/node_modules/statuses": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+            "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -10470,6 +10459,85 @@
                 "node": ">= 0.8.0"
             }
         },
+        "node_modules/serve-static/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/serve-static/node_modules/debug/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/serve-static/node_modules/http-errors": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+            "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "depd": "2.0.0",
+                "inherits": "2.0.4",
+                "setprototypeof": "1.2.0",
+                "statuses": "2.0.1",
+                "toidentifier": "1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/serve-static/node_modules/send": {
+            "version": "0.19.0",
+            "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+            "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "debug": "2.6.9",
+                "depd": "2.0.0",
+                "destroy": "1.2.0",
+                "encodeurl": "~1.0.2",
+                "escape-html": "~1.0.3",
+                "etag": "~1.8.1",
+                "fresh": "0.5.2",
+                "http-errors": "2.0.0",
+                "mime": "1.6.0",
+                "ms": "2.1.3",
+                "on-finished": "2.4.1",
+                "range-parser": "~1.2.1",
+                "statuses": "2.0.1"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/serve-static/node_modules/send/node_modules/encodeurl": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+            "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/serve-static/node_modules/statuses": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+            "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
         "node_modules/set-function-length": {
             "version": "1.2.2",
             "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
@@ -10778,9 +10846,9 @@
             "license": "MIT"
         },
         "node_modules/statuses": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
-            "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+            "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -11027,9 +11095,9 @@
             }
         },
         "node_modules/terser-webpack-plugin": {
-            "version": "5.3.14",
-            "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
-            "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
+            "version": "5.3.15",
+            "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.15.tgz",
+            "integrity": "sha512-PGkOdpRFK+rb1TzVz+msVhw4YMRT9txLF4kRqvJhGhCM324xuR3REBSHALN+l+sAhKUmz0aotnjp5D+P83mLhQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -11391,9 +11459,9 @@
             }
         },
         "node_modules/update-browserslist-db": {
-            "version": "1.1.4",
-            "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
-            "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
+            "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==",
             "dev": true,
             "funding": [
                 {
@@ -11517,9 +11585,9 @@
             }
         },
         "node_modules/vite": {
-            "version": "7.2.4",
-            "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz",
-            "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
+            "version": "7.2.6",
+            "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz",
+            "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {

From 5b395d870b3da65aab67822fd1ccc932be990463 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 6 Dec 2025 07:32:43 +0100
Subject: [PATCH 09/27] Fix #11333

---
 .../RemovesLinksToDeletedObjects.php          | 30 ++++++++++++-------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php b/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php
index 7b174418b0..d6fc1174f2 100644
--- a/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php
+++ b/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php
@@ -40,7 +40,7 @@ class RemovesLinksToDeletedObjects extends Command
      *
      * @var string
      */
-    protected $signature   = 'correction:remove-links-to-deleted-objects';
+    protected $signature = 'correction:remove-links-to-deleted-objects';
 
     /**
      * The console command description.
@@ -86,17 +86,27 @@ class RemovesLinksToDeletedObjects extends Command
 
     private function cleanupJournals(array $journals): void
     {
-        $count = DB::table('tag_transaction_journal')->whereIn('transaction_journal_id', $journals)->delete();
-        if ($count > 0) {
-            $this->friendlyInfo(sprintf('Removed %d old relationship(s) between tags and transactions.', $count));
+        $countTags = 0;
+        $countBudgets= 0;
+        $countCategories = 0;
+        // #11333
+        foreach (array_chunk($journals, 1337) as $set) {
+            $countTags += DB::table('tag_transaction_journal')->whereIn('transaction_journal_id', $set)->delete();
+            $countBudgets += DB::table('budget_transaction_journal')->whereIn('transaction_journal_id', $set)->delete();
+            $countCategories += DB::table('category_transaction_journal')->whereIn('transaction_journal_id', $set)->delete();
         }
-        $count = DB::table('budget_transaction_journal')->whereIn('transaction_journal_id', $journals)->delete();
-        if ($count > 0) {
-            $this->friendlyInfo(sprintf('Removed %d old relationship(s) between budgets and transactions.', $count));
+
+
+
+        if ($countTags > 0) {
+            $this->friendlyInfo(sprintf('Removed %d old relationship(s) between tags and transactions.', $countTags));
         }
-        $count = DB::table('category_transaction_journal')->whereIn('transaction_journal_id', $journals)->delete();
-        if ($count > 0) {
-            $this->friendlyInfo(sprintf('Removed %d old relationship(s) categories and transactions.', $count));
+
+        if ($countBudgets > 0) {
+            $this->friendlyInfo(sprintf('Removed %d old relationship(s) between budgets and transactions.', $countBudgets));
+        }
+        if ($countCategories > 0) {
+            $this->friendlyInfo(sprintf('Removed %d old relationship(s) categories and transactions.', $countCategories));
         }
     }
 

From 205169a8add7af82020c567821cc2b796dffabe0 Mon Sep 17 00:00:00 2001
From: JC5 
Date: Sat, 6 Dec 2025 07:55:38 +0100
Subject: [PATCH 10/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?=
 =?UTF-8?q?ase=20'develop'=20on=202025-12-06?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Commands/Correction/RemovesLinksToDeletedObjects.php    | 6 +++---
 config/firefly.php                                          | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php b/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php
index d6fc1174f2..45882fc38f 100644
--- a/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php
+++ b/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php
@@ -40,7 +40,7 @@ class RemovesLinksToDeletedObjects extends Command
      *
      * @var string
      */
-    protected $signature = 'correction:remove-links-to-deleted-objects';
+    protected $signature   = 'correction:remove-links-to-deleted-objects';
 
     /**
      * The console command description.
@@ -86,8 +86,8 @@ class RemovesLinksToDeletedObjects extends Command
 
     private function cleanupJournals(array $journals): void
     {
-        $countTags = 0;
-        $countBudgets= 0;
+        $countTags       = 0;
+        $countBudgets    = 0;
         $countCategories = 0;
         // #11333
         foreach (array_chunk($journals, 1337) as $set) {
diff --git a/config/firefly.php b/config/firefly.php
index da9b272ada..0b8046ea09 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -79,7 +79,7 @@ return [
         // see cer.php for exchange rates feature flag.
     ],
     'version'                              => 'develop/2025-12-06',
-    'build_time'                           => 1765002600,
+    'build_time'                           => 1765004025,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 

From aadb685b57b292e230cce1130336ead1d657f5c1 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 6 Dec 2025 08:12:18 +0100
Subject: [PATCH 11/27] Add YTD fix.

---
 app/Support/Navigation.php | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

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

From ca3922d00ab872871031313e1830946be725304b Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 6 Dec 2025 13:50:51 +0100
Subject: [PATCH 12/27] Fix #11313

---
 .../TriggeredStoredTransactionGroup.php       | 36 +++++++++++
 .../Events/StoredGroupEventHandler.php        | 27 +++++----
 .../RuleGroup/ExecutionController.php         | 59 ++++++++++---------
 app/Providers/EventServiceProvider.php        |  4 ++
 4 files changed, 89 insertions(+), 37 deletions(-)
 create mode 100644 app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php

diff --git a/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php b/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php
new file mode 100644
index 0000000000..858119b6b0
--- /dev/null
+++ b/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php
@@ -0,0 +1,36 @@
+.
+ */
+
+namespace FireflyIII\Events\Model\TransactionGroup;
+
+use FireflyIII\Events\Event;
+use FireflyIII\Models\TransactionGroup;
+use Illuminate\Queue\SerializesModels;
+
+class TriggeredStoredTransactionGroup extends Event
+{
+    use SerializesModels;
+
+    /**
+     * Create a new event instance.
+     */
+    public function __construct(public TransactionGroup $transactionGroup) {}
+}
diff --git a/app/Handlers/Events/StoredGroupEventHandler.php b/app/Handlers/Events/StoredGroupEventHandler.php
index fd33908b32..381cdd542e 100644
--- a/app/Handlers/Events/StoredGroupEventHandler.php
+++ b/app/Handlers/Events/StoredGroupEventHandler.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
 namespace FireflyIII\Handlers\Events;
 
 use FireflyIII\Enums\WebhookTrigger;
+use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
 use FireflyIII\Events\RequestedSendWebhookMessages;
 use FireflyIII\Events\StoredTransactionGroup;
 use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
@@ -51,6 +52,12 @@ class StoredGroupEventHandler
         $this->removePeriodStatistics($event);
     }
 
+    public function triggerRulesManually(TriggeredStoredTransactionGroup $event): void
+    {
+        $newEvent = new StoredTransactionGroup($event->transactionGroup, true, false);
+        $this->processRules($newEvent);
+    }
+
     /**
      * This method grabs all the users rules and processes them.
      */
@@ -63,14 +70,14 @@ class StoredGroupEventHandler
         }
         Log::debug('Now in StoredGroupEventHandler::processRules()');
 
-        $journals            = $storedGroupEvent->transactionGroup->transactionJournals;
-        $array               = [];
+        $journals = $storedGroupEvent->transactionGroup->transactionJournals;
+        $array    = [];
 
         /** @var TransactionJournal $journal */
         foreach ($journals as $journal) {
             $array[] = $journal->id;
         }
-        $journalIds          = implode(',', $array);
+        $journalIds = implode(',', $array);
         Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
 
         // collect rules:
@@ -79,10 +86,10 @@ class StoredGroupEventHandler
 
         // add the groups to the rule engine.
         // it should run the rules in the group and cancel the group if necessary.
-        $groups              = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
+        $groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
 
         // create and fire rule engine.
-        $newRuleEngine       = app(RuleEngineInterface::class);
+        $newRuleEngine = app(RuleEngineInterface::class);
         $newRuleEngine->setUser($storedGroupEvent->transactionGroup->user);
         $newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
         $newRuleEngine->setRuleGroups($groups);
@@ -91,7 +98,7 @@ class StoredGroupEventHandler
 
     private function recalculateCredit(StoredTransactionGroup $event): void
     {
-        $group  = $event->transactionGroup;
+        $group = $event->transactionGroup;
 
         /** @var CreditRecalculateService $object */
         $object = app(CreditRecalculateService::class);
@@ -107,10 +114,10 @@ class StoredGroupEventHandler
         /** @var TransactionJournal $journal */
         foreach ($event->transactionGroup->transactionJournals as $journal) {
             /** @var null|Transaction $source */
-            $source     = $journal->transactions()->where('amount', '<', '0')->first();
+            $source = $journal->transactions()->where('amount', '<', '0')->first();
 
             /** @var null|Transaction $dest */
-            $dest       = $journal->transactions()->where('amount', '>', '0')->first();
+            $dest = $journal->transactions()->where('amount', '>', '0')->first();
 
             if (null !== $source) {
                 $repository->deleteStatisticsForModel($source->account, $journal->date);
@@ -145,14 +152,14 @@ class StoredGroupEventHandler
     private function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void
     {
         Log::debug(__METHOD__);
-        $group  = $storedGroupEvent->transactionGroup;
+        $group = $storedGroupEvent->transactionGroup;
         if (false === $storedGroupEvent->fireWebhooks) {
             Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
 
             return;
         }
 
-        $user   = $group->user;
+        $user = $group->user;
 
         /** @var MessageGeneratorInterface $engine */
         $engine = app(MessageGeneratorInterface::class);
diff --git a/app/Http/Controllers/RuleGroup/ExecutionController.php b/app/Http/Controllers/RuleGroup/ExecutionController.php
index 3cd97826cc..3a96f6138c 100644
--- a/app/Http/Controllers/RuleGroup/ExecutionController.php
+++ b/app/Http/Controllers/RuleGroup/ExecutionController.php
@@ -26,14 +26,16 @@ namespace FireflyIII\Http\Controllers\RuleGroup;
 
 use Carbon\Carbon;
 use Exception;
+use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
+use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 use FireflyIII\Http\Controllers\Controller;
 use FireflyIII\Http\Requests\SelectTransactionsRequest;
 use FireflyIII\Models\RuleGroup;
-use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
-use FireflyIII\User;
+use FireflyIII\Models\TransactionGroup;
+use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 use Illuminate\Contracts\View\Factory;
 use Illuminate\Http\RedirectResponse;
-use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
 use Illuminate\View\View;
 
 /**
@@ -41,18 +43,20 @@ use Illuminate\View\View;
  */
 class ExecutionController extends Controller
 {
+    private AccountRepositoryInterface $repository;
+
     /**
      * ExecutionController constructor.
      */
     public function __construct()
     {
         parent::__construct();
-
+        $this->repository = app(AccountRepositoryInterface::class);
         $this->middleware(
             function ($request, $next) {
-                app('view')->share('title', (string) trans('firefly.rules'));
+                app('view')->share('title', (string)trans('firefly.rules'));
                 app('view')->share('mainTitleIcon', 'fa-random');
-
+                $this->repository->setUser(auth()->user());
 
                 return $next($request);
             }
@@ -67,34 +71,35 @@ class ExecutionController extends Controller
     public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
     {
         // Get parameters specified by the user
-        /** @var User $user */
-        $user          = auth()->user();
-        $accounts      = implode(',', $request->get('accounts'));
-        // create new rule engine:
-        $newRuleEngine = app(RuleEngineInterface::class);
-        $newRuleEngine->setUser($user);
-
+        $accounts = $request->get('accounts');
+        $set      = $this->repository->getAccountsById($accounts);
+        /** @var GroupCollectorInterface $collector */
+        $collector = app(GroupCollectorInterface::class);
+        $collector->setAccounts($set);
         // add date operators.
         if (null !== $request->get('start')) {
             $startDate = new Carbon($request->get('start'));
-            $newRuleEngine->addOperator(['type' => 'date_after', 'value' => $startDate->format('Y-m-d')]);
+            $collector->setStart($startDate);
         }
         if (null !== $request->get('end')) {
             $endDate = new Carbon($request->get('end'));
-            $newRuleEngine->addOperator(['type' => 'date_before', 'value' => $endDate->format('Y-m-d')]);
+            $collector->setEnd($endDate);
+        }
+        $final = $collector->getGroups();
+        $ids   = $final->pluck('id')->toArray();
+        Log::debug(sprintf('Found %d groups collected from %d account(s)', $final->count(), $set->count()));
+        foreach (array_chunk($ids, 1337) as $setOfIds) {
+            Log::debug(sprintf('Now processing %d groups', count($setOfIds)));
+            $groups = TransactionGroup::whereIn('id', $setOfIds)->get();
+            /** @var TransactionGroup $group */
+            foreach ($groups as $group) {
+                Log::debug(sprintf('Processing group #%d.', $group->id));
+                event(new TriggeredStoredTransactionGroup($group));
+            }
         }
 
-        // add extra operators:
-        $newRuleEngine->addOperator(['type' => 'account_id', 'value' => $accounts]);
-
-        // set rules:
-        // #10427, file rule group and not the set of rules.
-        $collection    = new Collection()->push($ruleGroup);
-        $newRuleEngine->setRuleGroups($collection);
-        $newRuleEngine->fire();
-
         // Tell the user that the job is queued
-        session()->flash('success', (string) trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
+        session()->flash('success', (string)trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
 
         return redirect()->route('rules.index');
     }
@@ -104,9 +109,9 @@ class ExecutionController extends Controller
      *
      * @return Factory|View
      */
-    public function selectTransactions(RuleGroup $ruleGroup): Factory|\Illuminate\Contracts\View\View
+    public function selectTransactions(RuleGroup $ruleGroup): Factory | \Illuminate\Contracts\View\View
     {
-        $subTitle = (string) trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
+        $subTitle = (string)trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
 
         return view('rules.rule-group.select-transactions', ['ruleGroup' => $ruleGroup, 'subTitle' => $subTitle]);
     }
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index 1b221013f5..4ced9fe70b 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -33,6 +33,7 @@ use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
 use FireflyIII\Events\Model\PiggyBank\ChangedName;
 use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
 use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject;
+use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
 use FireflyIII\Events\NewVersionAvailable;
 use FireflyIII\Events\Preferences\UserGroupChangedPrimaryCurrency;
 use FireflyIII\Events\RegisteredUser;
@@ -131,6 +132,9 @@ class EventServiceProvider extends ServiceProvider
             StoredTransactionGroup::class            => [
                 'FireflyIII\Handlers\Events\StoredGroupEventHandler@runAllHandlers',
             ],
+            TriggeredStoredTransactionGroup::class   => [
+                'FireflyIII\Handlers\Events\StoredGroupEventHandler@triggerRulesManually',
+            ],
             // is a Transaction Journal related event.
             UpdatedTransactionGroup::class           => [
                 'FireflyIII\Handlers\Events\UpdatedGroupEventHandler@runAllHandlers',

From babf9fe96f41d148b7a3b61edd4e24844d223b6b Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 6 Dec 2025 14:55:15 +0100
Subject: [PATCH 13/27] Add file permissions checks. #11323

---
 .../Integrity/ReportSkeleton.php.stub         | 26 -------
 .../Commands/Integrity/ReportsIntegrity.php   |  1 +
 .../Integrity/ValidatesFilePermissions.php    | 70 +++++++++++++++++++
 composer.lock                                 | 53 +++++++-------
 4 files changed, 98 insertions(+), 52 deletions(-)
 delete mode 100644 app/Console/Commands/Integrity/ReportSkeleton.php.stub
 create mode 100644 app/Console/Commands/Integrity/ValidatesFilePermissions.php

diff --git a/app/Console/Commands/Integrity/ReportSkeleton.php.stub b/app/Console/Commands/Integrity/ReportSkeleton.php.stub
deleted file mode 100644
index 5efa56a32a..0000000000
--- a/app/Console/Commands/Integrity/ReportSkeleton.php.stub
+++ /dev/null
@@ -1,26 +0,0 @@
-warn('Congrats, you found the skeleton command. Boo!');
-
-        return 0;
-    }
-}
diff --git a/app/Console/Commands/Integrity/ReportsIntegrity.php b/app/Console/Commands/Integrity/ReportsIntegrity.php
index 46e5427ad6..4684738cc9 100644
--- a/app/Console/Commands/Integrity/ReportsIntegrity.php
+++ b/app/Console/Commands/Integrity/ReportsIntegrity.php
@@ -48,6 +48,7 @@ class ReportsIntegrity extends Command
         $commands = [
             'integrity:empty-objects',
             'integrity:total-sums',
+            'integrity:file-permissions',
         ];
         foreach ($commands as $command) {
             $this->friendlyLine(sprintf('Now executing %s', $command));
diff --git a/app/Console/Commands/Integrity/ValidatesFilePermissions.php b/app/Console/Commands/Integrity/ValidatesFilePermissions.php
new file mode 100644
index 0000000000..e3849e6aa1
--- /dev/null
+++ b/app/Console/Commands/Integrity/ValidatesFilePermissions.php
@@ -0,0 +1,70 @@
+.
+ */
+
+namespace FireflyIII\Console\Commands\Integrity;
+
+use FireflyIII\Console\Commands\ShowsFriendlyMessages;
+use Illuminate\Console\Command;
+
+class ValidatesFilePermissions extends Command
+{
+    use ShowsFriendlyMessages;
+
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'integrity:file-permissions';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle(): int
+    {
+        $directories = [storage_path('upload')];
+        $errors = false;
+        /** @var string $directory */
+        foreach ($directories as $directory) {
+            if (!is_dir($directory)) {
+                $this->friendlyError(sprintf('Directory "%s" cannot found. It is necessary to allow files to be uploaded.', $uploadDir));
+                $errors = true;
+                continue;
+            }
+            if (!is_writable($directory)) {
+                $this->friendlyError(sprintf('Directory "%s" is not writeable. Uploading attachments may fail silently.', $uploadDir));
+                $errors = true;
+            }
+        }
+        if(false === $errors) {
+            $this->friendlyInfo('All necessary file paths seem to exist, and are writeable.');
+        }
+
+        return self::SUCCESS;
+    }
+}
diff --git a/composer.lock b/composer.lock
index 33b3d4eeda..0f738f9188 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3543,22 +3543,22 @@
         },
         {
             "name": "mailersend/laravel-driver",
-            "version": "v2.12.0",
+            "version": "v2.9.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-laravel-driver.git",
-                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
+                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
-                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
+                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725",
+                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
                 "illuminate/support": "^9.0 || ^10.0  || ^11.0 || ^12.0",
-                "mailersend/mailersend": "^0.35.0",
+                "mailersend/mailersend": "^0.31.0",
                 "nyholm/psr7": "^1.5",
                 "php": ">=8.0",
                 "php-http/guzzle7-adapter": "^1.0",
@@ -3606,28 +3606,29 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
-                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
+                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1"
             },
-            "time": "2025-10-28T14:59:16+00:00"
+            "time": "2025-04-09T09:33:07+00:00"
         },
         {
             "name": "mailersend/mailersend",
-            "version": "v0.35.0",
+            "version": "v0.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-php.git",
-                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
+                "reference": "513ff83ee768526055ad52987cde401ea7218c67"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
-                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
+                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67",
+                "reference": "513ff83ee768526055ad52987cde401ea7218c67",
                 "shasum": ""
             },
             "require": {
                 "beberlei/assert": "^3.2",
                 "ext-json": "*",
-                "php": "^7.4 || ^8.0 <8.5",
+                "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
+                "php": "^7.4|^8.0",
                 "php-http/client-common": "^2.2",
                 "php-http/discovery": "^1.9",
                 "php-http/httplug": "^2.1",
@@ -3672,9 +3673,9 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-php/issues",
-                "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
+                "source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0"
             },
-            "time": "2025-10-28T13:11:43+00:00"
+            "time": "2025-04-03T12:16:11+00:00"
         },
         {
             "name": "monolog/monolog",
@@ -11239,16 +11240,16 @@
         },
         {
             "name": "nikic/php-parser",
-            "version": "v5.6.2",
+            "version": "v5.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "3a454ca033b9e06b63282ce19562e892747449bb"
+                "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
-                "reference": "3a454ca033b9e06b63282ce19562e892747449bb",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
+                "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
                 "shasum": ""
             },
             "require": {
@@ -11291,9 +11292,9 @@
             ],
             "support": {
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
-                "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
+                "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
             },
-            "time": "2025-10-21T19:32:17+00:00"
+            "time": "2025-12-06T11:56:16+00:00"
         },
         {
             "name": "phar-io/manifest",
@@ -12018,16 +12019,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "12.5.0",
+            "version": "12.5.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "fef037fe50d20ce826cdbd741b7a2afcdec5f45b"
+                "reference": "e33a5132ea24119400f6ce5bce6665922e968bad"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fef037fe50d20ce826cdbd741b7a2afcdec5f45b",
-                "reference": "fef037fe50d20ce826cdbd741b7a2afcdec5f45b",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e33a5132ea24119400f6ce5bce6665922e968bad",
+                "reference": "e33a5132ea24119400f6ce5bce6665922e968bad",
                 "shasum": ""
             },
             "require": {
@@ -12095,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.5.0"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.1"
             },
             "funding": [
                 {
@@ -12119,7 +12120,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-12-05T04:59:40+00:00"
+            "time": "2025-12-06T12:19:17+00:00"
         },
         {
             "name": "rector/rector",

From f6037318f4f0b809b376abd17e0490cafdb5ea66 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sun, 7 Dec 2025 07:00:50 +0100
Subject: [PATCH 14/27] Fix #11337

---
 app/Http/Controllers/ProfileController.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index dabe7f6b2d..b50a552ff5 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -113,6 +113,8 @@ class ProfileController extends Controller
             throw new FireflyException('Invalid token.');
         }
         $repository->unblockUser($user);
+        // also remove the "remote_guard_alt_email" preference.
+        Preferences::delete('remote_guard_alt_email');
 
         // return to log in.
         session()->flash('success', (string) trans('firefly.login_with_new_email'));

From 346f2dfaeaa1b202bb14625c2bf8a988c7d6ce22 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sun, 7 Dec 2025 16:47:04 +0100
Subject: [PATCH 15/27] Add amount event.

---
 .../Internal/Update/GroupUpdateService.php    |   4 +-
 .../Internal/Update/JournalUpdateService.php  | 165 +++++++++---------
 2 files changed, 88 insertions(+), 81 deletions(-)

diff --git a/app/Services/Internal/Update/GroupUpdateService.php b/app/Services/Internal/Update/GroupUpdateService.php
index db983cff16..1b5e8f53f9 100644
--- a/app/Services/Internal/Update/GroupUpdateService.php
+++ b/app/Services/Internal/Update/GroupUpdateService.php
@@ -78,9 +78,7 @@ class GroupUpdateService
         if (1 === count($transactions) && 1 === $transactionGroup->transactionJournals()->count()) {
             /** @var TransactionJournal $first */
             $first = $transactionGroup->transactionJournals()->first();
-            Log::debug(
-                sprintf('Will now update journal #%d (only journal in group #%d)', $first->id, $transactionGroup->id)
-            );
+            Log::debug(sprintf('Will now update journal #%d (only journal in group #%d)', $first->id, $transactionGroup->id));
             $this->updateTransactionJournal($transactionGroup, $first, reset($transactions));
             $transactionGroup->touch();
             $transactionGroup->refresh();
diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php
index 64a901690b..824ab1c2f4 100644
--- a/app/Services/Internal/Update/JournalUpdateService.php
+++ b/app/Services/Internal/Update/JournalUpdateService.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
 
 namespace FireflyIII\Services\Internal\Update;
 
-use FireflyIII\Support\Facades\Preferences;
 use Carbon\Carbon;
 use Carbon\Exceptions\InvalidDateException;
 use Carbon\Exceptions\InvalidFormatException;
@@ -47,6 +46,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
 use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
 use FireflyIII\Services\Internal\Support\JournalServiceTrait;
 use FireflyIII\Support\Facades\FireflyConfig;
+use FireflyIII\Support\Facades\Preferences;
 use FireflyIII\Support\NullArrayObject;
 use FireflyIII\Validation\AccountValidator;
 use Illuminate\Support\Facades\Log;
@@ -60,34 +60,36 @@ class JournalUpdateService
 {
     use JournalServiceTrait;
 
-    private BillRepositoryInterface $billRepository;
-    private CurrencyRepositoryInterface $currencyRepository;
+    private BillRepositoryInterface             $billRepository;
+    private CurrencyRepositoryInterface         $currencyRepository;
     private TransactionGroupRepositoryInterface $transactionGroupRepository;
-    private array $data;
-    private ?Account $destinationAccount            = null;
-    private ?Transaction $destinationTransaction    = null;
-    private array $metaDate                         = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date',
-        'invoice_date', ];
-    private array $metaString                       = [
-        'sepa_cc',
-        'sepa_ct_op',
-        'sepa_ct_id',
-        'sepa_db',
-        'sepa_country',
-        'sepa_ep',
-        'sepa_ci',
-        'sepa_batch_id',
-        'recurrence_id',
-        'internal_reference',
-        'bunq_payment_id',
-        'external_id',
-        'external_url',
-    ];
-    private ?Account $sourceAccount                 = null;
-    private ?Transaction $sourceTransaction         = null;
-    private ?TransactionGroup $transactionGroup     = null;
-    private ?TransactionJournal $transactionJournal = null;
-    private string $startCompareHash                = '';
+    private array                               $data;
+    private ?Account                            $destinationAccount     = null;
+    private ?Transaction                        $destinationTransaction = null;
+    private array                               $metaDate
+                                                                        = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date',
+                                                                           'invoice_date',];
+    private array                               $metaString
+                                                                        = [
+            'sepa_cc',
+            'sepa_ct_op',
+            'sepa_ct_id',
+            'sepa_db',
+            'sepa_country',
+            'sepa_ep',
+            'sepa_ci',
+            'sepa_batch_id',
+            'recurrence_id',
+            'internal_reference',
+            'bunq_payment_id',
+            'external_id',
+            'external_url',
+        ];
+    private ?Account                            $sourceAccount          = null;
+    private ?Transaction                        $sourceTransaction      = null;
+    private ?TransactionGroup                   $transactionGroup       = null;
+    private ?TransactionJournal                 $transactionJournal     = null;
+    private string                              $startCompareHash       = '';
 
     /**
      * JournalUpdateService constructor.
@@ -110,7 +112,7 @@ class JournalUpdateService
 
     public function setTransactionGroup(TransactionGroup $transactionGroup): void
     {
-        $this->transactionGroup       = $transactionGroup;
+        $this->transactionGroup = $transactionGroup;
         $this->billRepository->setUser($transactionGroup->user);
         $this->categoryRepository->setUser($transactionGroup->user);
         $this->budgetRepository->setUser($transactionGroup->user);
@@ -181,8 +183,8 @@ class JournalUpdateService
 
     private function hasValidSourceAccount(): bool
     {
-        $sourceId     = $this->data['source_id'] ?? null;
-        $sourceName   = $this->data['source_name'] ?? null;
+        $sourceId   = $this->data['source_id'] ?? null;
+        $sourceName = $this->data['source_name'] ?? null;
         Log::debug(sprintf('Now in hasValidSourceAccount("%s","%s").', $sourceId, $sourceName));
 
         if (!$this->hasFields(['source_id', 'source_name'])) {
@@ -197,11 +199,11 @@ class JournalUpdateService
 
         // make a new validator.
         /** @var AccountValidator $validator */
-        $validator    = app(AccountValidator::class);
+        $validator = app(AccountValidator::class);
         $validator->setTransactionType($expectedType);
         $validator->setUser($this->transactionJournal->user);
 
-        $result       = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
+        $result = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
         Log::debug(
             sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true))
         );
@@ -214,7 +216,7 @@ class JournalUpdateService
 
     private function hasFields(array $fields): bool
     {
-        return array_any($fields, fn ($field): bool => array_key_exists($field, $this->data));
+        return array_any($fields, fn($field): bool => array_key_exists($field, $this->data));
     }
 
     private function getOriginalSourceAccount(): Account
@@ -259,8 +261,8 @@ class JournalUpdateService
     private function hasValidDestinationAccount(): bool
     {
         Log::debug('Now in hasValidDestinationAccount().');
-        $destId            = $this->data['destination_id'] ?? null;
-        $destName          = $this->data['destination_name'] ?? null;
+        $destId   = $this->data['destination_id'] ?? null;
+        $destName = $this->data['destination_name'] ?? null;
 
         if (!$this->hasFields(['destination_id', 'destination_name'])) {
             Log::debug('No destination info submitted, grab the original data.');
@@ -270,12 +272,12 @@ class JournalUpdateService
         }
 
         // make new account validator.
-        $expectedType      = $this->getExpectedType();
+        $expectedType = $this->getExpectedType();
         Log::debug(sprintf('(b) Expected type (new or unchanged) is %s', $expectedType));
 
         // make a new validator.
         /** @var AccountValidator $validator */
-        $validator         = app(AccountValidator::class);
+        $validator = app(AccountValidator::class);
         $validator->setTransactionType($expectedType);
         $validator->setUser($this->transactionJournal->user);
         $validator->source = $this->getValidSourceAccount();
@@ -330,7 +332,7 @@ class JournalUpdateService
             return $this->getOriginalSourceAccount();
         }
 
-        $sourceInfo   = [
+        $sourceInfo = [
             'id'     => (int)($this->data['source_id'] ?? null),
             'name'   => $this->data['source_name'] ?? null,
             'iban'   => $this->data['source_iban'] ?? null,
@@ -358,8 +360,8 @@ class JournalUpdateService
      */
     private function updateAccounts(): void
     {
-        $source                = $this->getValidSourceAccount();
-        $destination           = $this->getValidDestinationAccount();
+        $source      = $this->getValidSourceAccount();
+        $destination = $this->getValidDestinationAccount();
 
         // cowardly refuse to update if both accounts are the same.
         if ($source->id === $destination->id) {
@@ -372,7 +374,7 @@ class JournalUpdateService
         $origSourceTransaction->account()->associate($source);
         $origSourceTransaction->save();
 
-        $destTransaction       = $this->getDestinationTransaction();
+        $destTransaction = $this->getDestinationTransaction();
         $destTransaction->account()->associate($destination);
         $destTransaction->save();
 
@@ -394,7 +396,7 @@ class JournalUpdateService
             return $this->getOriginalDestinationAccount();
         }
 
-        $destInfo     = [
+        $destInfo = [
             'id'     => (int)($this->data['destination_id'] ?? null),
             'name'   => $this->data['destination_name'] ?? null,
             'iban'   => $this->data['destination_iban'] ?? null,
@@ -423,7 +425,7 @@ class JournalUpdateService
     {
         Log::debug('Now in updateType()');
         if ($this->hasFields(['type'])) {
-            $type        = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
+            $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
             Log::debug(
                 sprintf(
                     'Trying to change journal #%d from a %s to a %s.',
@@ -456,9 +458,9 @@ class JournalUpdateService
     {
         $type = $this->transactionJournal->transactionType->type;
         if ((
-            array_key_exists('bill_id', $this->data)
+                array_key_exists('bill_id', $this->data)
                 || array_key_exists('bill_name', $this->data)
-        )
+            )
             && TransactionTypeEnum::WITHDRAWAL->value === $type
         ) {
             $billId                            = (int)($this->data['bill_id'] ?? 0);
@@ -475,7 +477,7 @@ class JournalUpdateService
     private function updateField(string $fieldName): void
     {
         if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
-            $value                                  = $this->data[$fieldName];
+            $value = $this->data[$fieldName];
 
             if ('date' === $fieldName) {
                 if (!$value instanceof Carbon) {
@@ -492,15 +494,7 @@ class JournalUpdateService
                 Log::debug(sprintf('Create date value from string "%s".', $value));
                 $this->transactionJournal->date_tz = $value->format('e');
             }
-            event(
-                new TriggeredAuditLog(
-                    $this->transactionJournal->user,
-                    $this->transactionJournal,
-                    sprintf('update_%s', $fieldName),
-                    $this->transactionJournal->{$fieldName}, // @phpstan-ignore-line
-                    $value
-                )
-            );
+            event(new TriggeredAuditLog($this->transactionJournal->user, $this->transactionJournal, sprintf('update_%s', $fieldName), $this->transactionJournal->{$fieldName}, $value));
 
             $this->transactionJournal->{$fieldName} = $value; // @phpstan-ignore-line
             Log::debug(sprintf('Updated %s', $fieldName));
@@ -580,7 +574,7 @@ class JournalUpdateService
             if ($this->hasFields([$field])) {
                 $value = '' === $this->data[$field] ? null : $this->data[$field];
                 Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
-                $set   = [
+                $set = [
                     'journal' => $this->transactionJournal,
                     'name'    => $field,
                     'data'    => $value,
@@ -599,7 +593,7 @@ class JournalUpdateService
             if ($this->hasFields([$field])) {
                 try {
                     $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
-                } catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
+                } catch (InvalidDateException | InvalidFormatException $e) { // @phpstan-ignore-line
                     Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
 
                     return;
@@ -628,19 +622,19 @@ class JournalUpdateService
         if (!$this->hasFields(['currency_id', 'currency_code'])) {
             return;
         }
-        $currencyId                                        = $this->data['currency_id'] ?? null;
-        $currencyCode                                      = $this->data['currency_code'] ?? null;
-        $currency                                          = $this->currencyRepository->findCurrency($currencyId, $currencyCode);
+        $currencyId   = $this->data['currency_id'] ?? null;
+        $currencyCode = $this->data['currency_code'] ?? null;
+        $currency     = $this->currencyRepository->findCurrency($currencyId, $currencyCode);
         // update currency everywhere.
         $this->transactionJournal->transaction_currency_id = $currency->id;
         $this->transactionJournal->save();
 
-        $source                                            = $this->getSourceTransaction();
-        $source->transaction_currency_id                   = $currency->id;
+        $source                          = $this->getSourceTransaction();
+        $source->transaction_currency_id = $currency->id;
         $source->save();
 
-        $dest                                              = $this->getDestinationTransaction();
-        $dest->transaction_currency_id                     = $currency->id;
+        $dest                          = $this->getDestinationTransaction();
+        $dest->transaction_currency_id = $currency->id;
         $dest->save();
 
         // refresh transactions.
@@ -656,7 +650,7 @@ class JournalUpdateService
             return;
         }
 
-        $value                                = $this->data['amount'] ?? '';
+        $value = $this->data['amount'] ?? '';
         Log::debug(sprintf('Amount is now "%s"', $value));
 
         try {
@@ -670,14 +664,29 @@ class JournalUpdateService
         $origSourceTransaction->amount        = app('steam')->negative($amount);
         $origSourceTransaction->balance_dirty = true;
         $origSourceTransaction->save();
-        $destTransaction                      = $this->getDestinationTransaction();
-        $destTransaction->amount              = app('steam')->positive($amount);
-        $destTransaction->balance_dirty       = true;
+        $destTransaction                = $this->getDestinationTransaction();
+        $originalAmount                 = $destTransaction->amount;
+        $destTransaction->amount        = app('steam')->positive($amount);
+        $destTransaction->balance_dirty = true;
         $destTransaction->save();
         // refresh transactions.
         $this->sourceTransaction->refresh();
         $this->destinationTransaction->refresh();
         Log::debug(sprintf('Updated amount to "%s"', $amount));
+
+        event(new TriggeredAuditLog($this->transactionGroup->user, $this->transactionGroup, 'update_amount',
+                                    [
+                                        'currency_symbol' => $destTransaction->transactionCurrency->symbol,
+                                        'decimal_places'  => $destTransaction->transactionCurrency->decimal_places,
+                                        'amount'          => $originalAmount,
+                                    ],
+                                    [
+                                        'currency_symbol' => $destTransaction->transactionCurrency->symbol,
+                                        'decimal_places'  => $destTransaction->transactionCurrency->decimal_places,
+                                        'amount'          => $value,
+                                    ]
+              ));
+
     }
 
     private function updateForeignAmount(): void
@@ -697,7 +706,7 @@ class JournalUpdateService
         $newForeignId    = $this->data['foreign_currency_id'] ?? null;
         $newForeignCode  = $this->data['foreign_currency_code'] ?? null;
         $foreignCurrency = $this->currencyRepository->findCurrencyNull($newForeignId, $newForeignCode)
-            ?? $foreignCurrency;
+                           ?? $foreignCurrency;
 
         // not the same as normal currency
         if (null !== $foreignCurrency && $foreignCurrency->id === $this->transactionJournal->transaction_currency_id) {
@@ -715,9 +724,9 @@ class JournalUpdateService
             // if the transaction is a TRANSFER, and the foreign amount and currency are set (like they seem to be)
             // the correct fields to update in the destination transaction are NOT the foreign amount and currency
             // but rather the normal amount and currency. This is new behavior.
-            $isTransfer                  = TransactionTypeEnum::TRANSFER->value === $this->transactionJournal->transactionType->type;
+            $isTransfer = TransactionTypeEnum::TRANSFER->value === $this->transactionJournal->transactionType->type;
             // also check if it is not between an asset account and a liability, because then the same rule applies.
-            $isBetween                   = $this->isBetweenAssetAndLiability();
+            $isBetween = $this->isBetweenAssetAndLiability();
 
             if ($isTransfer || $isBetween) {
                 Log::debug('Switch amounts, store in amount and not foreign_amount');
@@ -753,8 +762,8 @@ class JournalUpdateService
             $source->foreign_amount      = null;
             $source->save();
 
-            $dest->foreign_currency_id   = null;
-            $dest->foreign_amount        = null;
+            $dest->foreign_currency_id = null;
+            $dest->foreign_amount      = null;
             $dest->save();
             Log::debug(sprintf('Foreign amount is "%s" so remove foreign amount info.', $amount));
         }
@@ -768,7 +777,7 @@ class JournalUpdateService
     private function isBetweenAssetAndLiability(): bool
     {
         /** @var null|Transaction $sourceTransaction */
-        $sourceTransaction      = $this->transactionJournal->transactions()->where('amount', '<', 0)->first();
+        $sourceTransaction = $this->transactionJournal->transactions()->where('amount', '<', 0)->first();
 
         /** @var null|Transaction $destinationTransaction */
         $destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
@@ -783,15 +792,15 @@ class JournalUpdateService
             return false;
         }
 
-        $source                 = $sourceTransaction->account;
-        $destination            = $destinationTransaction->account;
+        $source      = $sourceTransaction->account;
+        $destination = $destinationTransaction->account;
 
         if (null === $source || null === $destination) {
             Log::warning('Either is false, stop.');
 
             return false;
         }
-        $sourceTypes            = [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
+        $sourceTypes = [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
 
         // source is liability, destination is asset
         if (in_array($source->accountType->type, $sourceTypes, true) && AccountTypeEnum::ASSET->value === $destination->accountType->type) {

From d1332eb59256f83937f31b3064b7ec037ea99201 Mon Sep 17 00:00:00 2001
From: JC5 
Date: Sun, 7 Dec 2025 17:22:38 +0100
Subject: [PATCH 16/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?=
 =?UTF-8?q?ase=20'develop'=20on=202025-12-07?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Integrity/ValidatesFilePermissions.php    |  10 +-
 .../TriggeredStoredTransactionGroup.php       |   2 +
 .../Events/StoredGroupEventHandler.php        |  20 ++--
 .../RuleGroup/ExecutionController.php         |  12 +-
 .../Internal/Update/JournalUpdateService.php  | 111 +++++++++---------
 composer.lock                                 |  29 +++--
 config/firefly.php                            |   4 +-
 package-lock.json                             |   6 +-
 8 files changed, 102 insertions(+), 92 deletions(-)

diff --git a/app/Console/Commands/Integrity/ValidatesFilePermissions.php b/app/Console/Commands/Integrity/ValidatesFilePermissions.php
index e3849e6aa1..d03a9f876a 100644
--- a/app/Console/Commands/Integrity/ValidatesFilePermissions.php
+++ b/app/Console/Commands/Integrity/ValidatesFilePermissions.php
@@ -1,4 +1,6 @@
 friendlyError(sprintf('Directory "%s" cannot found. It is necessary to allow files to be uploaded.', $uploadDir));
                 $errors = true;
+
                 continue;
             }
             if (!is_writable($directory)) {
@@ -61,7 +65,7 @@ class ValidatesFilePermissions extends Command
                 $errors = true;
             }
         }
-        if(false === $errors) {
+        if (false === $errors) {
             $this->friendlyInfo('All necessary file paths seem to exist, and are writeable.');
         }
 
diff --git a/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php b/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php
index 858119b6b0..769208971f 100644
--- a/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php
+++ b/app/Events/Model/TransactionGroup/TriggeredStoredTransactionGroup.php
@@ -1,4 +1,6 @@
 transactionGroup->transactionJournals;
-        $array    = [];
+        $journals            = $storedGroupEvent->transactionGroup->transactionJournals;
+        $array               = [];
 
         /** @var TransactionJournal $journal */
         foreach ($journals as $journal) {
             $array[] = $journal->id;
         }
-        $journalIds = implode(',', $array);
+        $journalIds          = implode(',', $array);
         Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
 
         // collect rules:
@@ -86,10 +86,10 @@ class StoredGroupEventHandler
 
         // add the groups to the rule engine.
         // it should run the rules in the group and cancel the group if necessary.
-        $groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
+        $groups              = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
 
         // create and fire rule engine.
-        $newRuleEngine = app(RuleEngineInterface::class);
+        $newRuleEngine       = app(RuleEngineInterface::class);
         $newRuleEngine->setUser($storedGroupEvent->transactionGroup->user);
         $newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
         $newRuleEngine->setRuleGroups($groups);
@@ -98,7 +98,7 @@ class StoredGroupEventHandler
 
     private function recalculateCredit(StoredTransactionGroup $event): void
     {
-        $group = $event->transactionGroup;
+        $group  = $event->transactionGroup;
 
         /** @var CreditRecalculateService $object */
         $object = app(CreditRecalculateService::class);
@@ -114,10 +114,10 @@ class StoredGroupEventHandler
         /** @var TransactionJournal $journal */
         foreach ($event->transactionGroup->transactionJournals as $journal) {
             /** @var null|Transaction $source */
-            $source = $journal->transactions()->where('amount', '<', '0')->first();
+            $source     = $journal->transactions()->where('amount', '<', '0')->first();
 
             /** @var null|Transaction $dest */
-            $dest = $journal->transactions()->where('amount', '>', '0')->first();
+            $dest       = $journal->transactions()->where('amount', '>', '0')->first();
 
             if (null !== $source) {
                 $repository->deleteStatisticsForModel($source->account, $journal->date);
@@ -152,14 +152,14 @@ class StoredGroupEventHandler
     private function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void
     {
         Log::debug(__METHOD__);
-        $group = $storedGroupEvent->transactionGroup;
+        $group  = $storedGroupEvent->transactionGroup;
         if (false === $storedGroupEvent->fireWebhooks) {
             Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
 
             return;
         }
 
-        $user = $group->user;
+        $user   = $group->user;
 
         /** @var MessageGeneratorInterface $engine */
         $engine = app(MessageGeneratorInterface::class);
diff --git a/app/Http/Controllers/RuleGroup/ExecutionController.php b/app/Http/Controllers/RuleGroup/ExecutionController.php
index 3a96f6138c..f066f9f1a4 100644
--- a/app/Http/Controllers/RuleGroup/ExecutionController.php
+++ b/app/Http/Controllers/RuleGroup/ExecutionController.php
@@ -71,8 +71,9 @@ class ExecutionController extends Controller
     public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
     {
         // Get parameters specified by the user
-        $accounts = $request->get('accounts');
-        $set      = $this->repository->getAccountsById($accounts);
+        $accounts  = $request->get('accounts');
+        $set       = $this->repository->getAccountsById($accounts);
+
         /** @var GroupCollectorInterface $collector */
         $collector = app(GroupCollectorInterface::class);
         $collector->setAccounts($set);
@@ -85,12 +86,13 @@ class ExecutionController extends Controller
             $endDate = new Carbon($request->get('end'));
             $collector->setEnd($endDate);
         }
-        $final = $collector->getGroups();
-        $ids   = $final->pluck('id')->toArray();
+        $final     = $collector->getGroups();
+        $ids       = $final->pluck('id')->toArray();
         Log::debug(sprintf('Found %d groups collected from %d account(s)', $final->count(), $set->count()));
         foreach (array_chunk($ids, 1337) as $setOfIds) {
             Log::debug(sprintf('Now processing %d groups', count($setOfIds)));
             $groups = TransactionGroup::whereIn('id', $setOfIds)->get();
+
             /** @var TransactionGroup $group */
             foreach ($groups as $group) {
                 Log::debug(sprintf('Processing group #%d.', $group->id));
@@ -109,7 +111,7 @@ class ExecutionController extends Controller
      *
      * @return Factory|View
      */
-    public function selectTransactions(RuleGroup $ruleGroup): Factory | \Illuminate\Contracts\View\View
+    public function selectTransactions(RuleGroup $ruleGroup): Factory|\Illuminate\Contracts\View\View
     {
         $subTitle = (string)trans('firefly.apply_rule_group_selection', ['title' => $ruleGroup->title]);
 
diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php
index 824ab1c2f4..c1ce184cd6 100644
--- a/app/Services/Internal/Update/JournalUpdateService.php
+++ b/app/Services/Internal/Update/JournalUpdateService.php
@@ -68,7 +68,7 @@ class JournalUpdateService
     private ?Transaction                        $destinationTransaction = null;
     private array                               $metaDate
                                                                         = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date',
-                                                                           'invoice_date',];
+            'invoice_date', ];
     private array                               $metaString
                                                                         = [
             'sepa_cc',
@@ -112,7 +112,7 @@ class JournalUpdateService
 
     public function setTransactionGroup(TransactionGroup $transactionGroup): void
     {
-        $this->transactionGroup = $transactionGroup;
+        $this->transactionGroup       = $transactionGroup;
         $this->billRepository->setUser($transactionGroup->user);
         $this->categoryRepository->setUser($transactionGroup->user);
         $this->budgetRepository->setUser($transactionGroup->user);
@@ -183,8 +183,8 @@ class JournalUpdateService
 
     private function hasValidSourceAccount(): bool
     {
-        $sourceId   = $this->data['source_id'] ?? null;
-        $sourceName = $this->data['source_name'] ?? null;
+        $sourceId     = $this->data['source_id'] ?? null;
+        $sourceName   = $this->data['source_name'] ?? null;
         Log::debug(sprintf('Now in hasValidSourceAccount("%s","%s").', $sourceId, $sourceName));
 
         if (!$this->hasFields(['source_id', 'source_name'])) {
@@ -199,11 +199,11 @@ class JournalUpdateService
 
         // make a new validator.
         /** @var AccountValidator $validator */
-        $validator = app(AccountValidator::class);
+        $validator    = app(AccountValidator::class);
         $validator->setTransactionType($expectedType);
         $validator->setUser($this->transactionJournal->user);
 
-        $result = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
+        $result       = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
         Log::debug(
             sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true))
         );
@@ -216,7 +216,7 @@ class JournalUpdateService
 
     private function hasFields(array $fields): bool
     {
-        return array_any($fields, fn($field): bool => array_key_exists($field, $this->data));
+        return array_any($fields, fn ($field): bool => array_key_exists($field, $this->data));
     }
 
     private function getOriginalSourceAccount(): Account
@@ -261,8 +261,8 @@ class JournalUpdateService
     private function hasValidDestinationAccount(): bool
     {
         Log::debug('Now in hasValidDestinationAccount().');
-        $destId   = $this->data['destination_id'] ?? null;
-        $destName = $this->data['destination_name'] ?? null;
+        $destId            = $this->data['destination_id'] ?? null;
+        $destName          = $this->data['destination_name'] ?? null;
 
         if (!$this->hasFields(['destination_id', 'destination_name'])) {
             Log::debug('No destination info submitted, grab the original data.');
@@ -272,12 +272,12 @@ class JournalUpdateService
         }
 
         // make new account validator.
-        $expectedType = $this->getExpectedType();
+        $expectedType      = $this->getExpectedType();
         Log::debug(sprintf('(b) Expected type (new or unchanged) is %s', $expectedType));
 
         // make a new validator.
         /** @var AccountValidator $validator */
-        $validator = app(AccountValidator::class);
+        $validator         = app(AccountValidator::class);
         $validator->setTransactionType($expectedType);
         $validator->setUser($this->transactionJournal->user);
         $validator->source = $this->getValidSourceAccount();
@@ -332,7 +332,7 @@ class JournalUpdateService
             return $this->getOriginalSourceAccount();
         }
 
-        $sourceInfo = [
+        $sourceInfo   = [
             'id'     => (int)($this->data['source_id'] ?? null),
             'name'   => $this->data['source_name'] ?? null,
             'iban'   => $this->data['source_iban'] ?? null,
@@ -360,8 +360,8 @@ class JournalUpdateService
      */
     private function updateAccounts(): void
     {
-        $source      = $this->getValidSourceAccount();
-        $destination = $this->getValidDestinationAccount();
+        $source                = $this->getValidSourceAccount();
+        $destination           = $this->getValidDestinationAccount();
 
         // cowardly refuse to update if both accounts are the same.
         if ($source->id === $destination->id) {
@@ -374,7 +374,7 @@ class JournalUpdateService
         $origSourceTransaction->account()->associate($source);
         $origSourceTransaction->save();
 
-        $destTransaction = $this->getDestinationTransaction();
+        $destTransaction       = $this->getDestinationTransaction();
         $destTransaction->account()->associate($destination);
         $destTransaction->save();
 
@@ -396,7 +396,7 @@ class JournalUpdateService
             return $this->getOriginalDestinationAccount();
         }
 
-        $destInfo = [
+        $destInfo     = [
             'id'     => (int)($this->data['destination_id'] ?? null),
             'name'   => $this->data['destination_name'] ?? null,
             'iban'   => $this->data['destination_iban'] ?? null,
@@ -425,7 +425,7 @@ class JournalUpdateService
     {
         Log::debug('Now in updateType()');
         if ($this->hasFields(['type'])) {
-            $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
+            $type        = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
             Log::debug(
                 sprintf(
                     'Trying to change journal #%d from a %s to a %s.',
@@ -458,9 +458,9 @@ class JournalUpdateService
     {
         $type = $this->transactionJournal->transactionType->type;
         if ((
-                array_key_exists('bill_id', $this->data)
+            array_key_exists('bill_id', $this->data)
                 || array_key_exists('bill_name', $this->data)
-            )
+        )
             && TransactionTypeEnum::WITHDRAWAL->value === $type
         ) {
             $billId                            = (int)($this->data['bill_id'] ?? 0);
@@ -477,7 +477,7 @@ class JournalUpdateService
     private function updateField(string $fieldName): void
     {
         if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
-            $value = $this->data[$fieldName];
+            $value                                  = $this->data[$fieldName];
 
             if ('date' === $fieldName) {
                 if (!$value instanceof Carbon) {
@@ -574,7 +574,7 @@ class JournalUpdateService
             if ($this->hasFields([$field])) {
                 $value = '' === $this->data[$field] ? null : $this->data[$field];
                 Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
-                $set = [
+                $set   = [
                     'journal' => $this->transactionJournal,
                     'name'    => $field,
                     'data'    => $value,
@@ -593,7 +593,7 @@ class JournalUpdateService
             if ($this->hasFields([$field])) {
                 try {
                     $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
-                } catch (InvalidDateException | InvalidFormatException $e) { // @phpstan-ignore-line
+                } catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
                     Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
 
                     return;
@@ -622,19 +622,19 @@ class JournalUpdateService
         if (!$this->hasFields(['currency_id', 'currency_code'])) {
             return;
         }
-        $currencyId   = $this->data['currency_id'] ?? null;
-        $currencyCode = $this->data['currency_code'] ?? null;
-        $currency     = $this->currencyRepository->findCurrency($currencyId, $currencyCode);
+        $currencyId                                        = $this->data['currency_id'] ?? null;
+        $currencyCode                                      = $this->data['currency_code'] ?? null;
+        $currency                                          = $this->currencyRepository->findCurrency($currencyId, $currencyCode);
         // update currency everywhere.
         $this->transactionJournal->transaction_currency_id = $currency->id;
         $this->transactionJournal->save();
 
-        $source                          = $this->getSourceTransaction();
-        $source->transaction_currency_id = $currency->id;
+        $source                                            = $this->getSourceTransaction();
+        $source->transaction_currency_id                   = $currency->id;
         $source->save();
 
-        $dest                          = $this->getDestinationTransaction();
-        $dest->transaction_currency_id = $currency->id;
+        $dest                                              = $this->getDestinationTransaction();
+        $dest->transaction_currency_id                     = $currency->id;
         $dest->save();
 
         // refresh transactions.
@@ -650,7 +650,7 @@ class JournalUpdateService
             return;
         }
 
-        $value = $this->data['amount'] ?? '';
+        $value                                = $this->data['amount'] ?? '';
         Log::debug(sprintf('Amount is now "%s"', $value));
 
         try {
@@ -664,28 +664,31 @@ class JournalUpdateService
         $origSourceTransaction->amount        = app('steam')->negative($amount);
         $origSourceTransaction->balance_dirty = true;
         $origSourceTransaction->save();
-        $destTransaction                = $this->getDestinationTransaction();
-        $originalAmount                 = $destTransaction->amount;
-        $destTransaction->amount        = app('steam')->positive($amount);
-        $destTransaction->balance_dirty = true;
+        $destTransaction                      = $this->getDestinationTransaction();
+        $originalAmount                       = $destTransaction->amount;
+        $destTransaction->amount              = app('steam')->positive($amount);
+        $destTransaction->balance_dirty       = true;
         $destTransaction->save();
         // refresh transactions.
         $this->sourceTransaction->refresh();
         $this->destinationTransaction->refresh();
         Log::debug(sprintf('Updated amount to "%s"', $amount));
 
-        event(new TriggeredAuditLog($this->transactionGroup->user, $this->transactionGroup, 'update_amount',
-                                    [
-                                        'currency_symbol' => $destTransaction->transactionCurrency->symbol,
-                                        'decimal_places'  => $destTransaction->transactionCurrency->decimal_places,
-                                        'amount'          => $originalAmount,
-                                    ],
-                                    [
-                                        'currency_symbol' => $destTransaction->transactionCurrency->symbol,
-                                        'decimal_places'  => $destTransaction->transactionCurrency->decimal_places,
-                                        'amount'          => $value,
-                                    ]
-              ));
+        event(new TriggeredAuditLog(
+            $this->transactionGroup->user,
+            $this->transactionGroup,
+            'update_amount',
+            [
+                'currency_symbol' => $destTransaction->transactionCurrency->symbol,
+                'decimal_places'  => $destTransaction->transactionCurrency->decimal_places,
+                'amount'          => $originalAmount,
+            ],
+            [
+                'currency_symbol' => $destTransaction->transactionCurrency->symbol,
+                'decimal_places'  => $destTransaction->transactionCurrency->decimal_places,
+                'amount'          => $value,
+            ]
+        ));
 
     }
 
@@ -724,9 +727,9 @@ class JournalUpdateService
             // if the transaction is a TRANSFER, and the foreign amount and currency are set (like they seem to be)
             // the correct fields to update in the destination transaction are NOT the foreign amount and currency
             // but rather the normal amount and currency. This is new behavior.
-            $isTransfer = TransactionTypeEnum::TRANSFER->value === $this->transactionJournal->transactionType->type;
+            $isTransfer                  = TransactionTypeEnum::TRANSFER->value === $this->transactionJournal->transactionType->type;
             // also check if it is not between an asset account and a liability, because then the same rule applies.
-            $isBetween = $this->isBetweenAssetAndLiability();
+            $isBetween                   = $this->isBetweenAssetAndLiability();
 
             if ($isTransfer || $isBetween) {
                 Log::debug('Switch amounts, store in amount and not foreign_amount');
@@ -762,8 +765,8 @@ class JournalUpdateService
             $source->foreign_amount      = null;
             $source->save();
 
-            $dest->foreign_currency_id = null;
-            $dest->foreign_amount      = null;
+            $dest->foreign_currency_id   = null;
+            $dest->foreign_amount        = null;
             $dest->save();
             Log::debug(sprintf('Foreign amount is "%s" so remove foreign amount info.', $amount));
         }
@@ -777,7 +780,7 @@ class JournalUpdateService
     private function isBetweenAssetAndLiability(): bool
     {
         /** @var null|Transaction $sourceTransaction */
-        $sourceTransaction = $this->transactionJournal->transactions()->where('amount', '<', 0)->first();
+        $sourceTransaction      = $this->transactionJournal->transactions()->where('amount', '<', 0)->first();
 
         /** @var null|Transaction $destinationTransaction */
         $destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
@@ -792,15 +795,15 @@ class JournalUpdateService
             return false;
         }
 
-        $source      = $sourceTransaction->account;
-        $destination = $destinationTransaction->account;
+        $source                 = $sourceTransaction->account;
+        $destination            = $destinationTransaction->account;
 
         if (null === $source || null === $destination) {
             Log::warning('Either is false, stop.');
 
             return false;
         }
-        $sourceTypes = [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
+        $sourceTypes            = [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
 
         // source is liability, destination is asset
         if (in_array($source->accountType->type, $sourceTypes, true) && AccountTypeEnum::ASSET->value === $destination->accountType->type) {
diff --git a/composer.lock b/composer.lock
index 0f738f9188..89b32d86fc 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3543,22 +3543,22 @@
         },
         {
             "name": "mailersend/laravel-driver",
-            "version": "v2.9.1",
+            "version": "v2.12.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-laravel-driver.git",
-                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725"
+                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725",
-                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725",
+                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
+                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
                 "illuminate/support": "^9.0 || ^10.0  || ^11.0 || ^12.0",
-                "mailersend/mailersend": "^0.31.0",
+                "mailersend/mailersend": "^0.35.0",
                 "nyholm/psr7": "^1.5",
                 "php": ">=8.0",
                 "php-http/guzzle7-adapter": "^1.0",
@@ -3606,29 +3606,28 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
-                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1"
+                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
             },
-            "time": "2025-04-09T09:33:07+00:00"
+            "time": "2025-10-28T14:59:16+00:00"
         },
         {
             "name": "mailersend/mailersend",
-            "version": "v0.31.0",
+            "version": "v0.35.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-php.git",
-                "reference": "513ff83ee768526055ad52987cde401ea7218c67"
+                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67",
-                "reference": "513ff83ee768526055ad52987cde401ea7218c67",
+                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
+                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
                 "shasum": ""
             },
             "require": {
                 "beberlei/assert": "^3.2",
                 "ext-json": "*",
-                "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
-                "php": "^7.4|^8.0",
+                "php": "^7.4 || ^8.0 <8.5",
                 "php-http/client-common": "^2.2",
                 "php-http/discovery": "^1.9",
                 "php-http/httplug": "^2.1",
@@ -3673,9 +3672,9 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-php/issues",
-                "source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0"
+                "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
             },
-            "time": "2025-04-03T12:16:11+00:00"
+            "time": "2025-10-28T13:11:43+00:00"
         },
         {
             "name": "monolog/monolog",
diff --git a/config/firefly.php b/config/firefly.php
index 0b8046ea09..9be3e6f6dc 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
         'running_balance_column' => env('USE_RUNNING_BALANCE', false),
         // see cer.php for exchange rates feature flag.
     ],
-    'version'                              => 'develop/2025-12-06',
-    'build_time'                           => 1765004025,
+    'version'                              => 'develop/2025-12-07',
+    'build_time'                           => 1765124451,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 
diff --git a/package-lock.json b/package-lock.json
index 1b4ec416ab..76fe40a3b4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4075,9 +4075,9 @@
             "license": "MIT"
         },
         "node_modules/baseline-browser-mapping": {
-            "version": "2.9.3",
-            "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.3.tgz",
-            "integrity": "sha512-8QdH6czo+G7uBsNo0GiUfouPN1lRzKdJTGnKXwe12gkFbnnOUaUKGN55dMkfy+mnxmvjwl9zcI4VncczcVXDhA==",
+            "version": "2.9.4",
+            "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.4.tgz",
+            "integrity": "sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {

From 58ae0c1c9b142ef0e6b6d6df434ec2ab16f118d9 Mon Sep 17 00:00:00 2001
From: JC5 
Date: Mon, 8 Dec 2025 04:33:30 +0100
Subject: [PATCH 17/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?=
 =?UTF-8?q?ase=20'develop'=20on=202025-12-08?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .ci/php-cs-fixer/composer.lock |  36 +++++------
 composer.lock                  | 113 +++++++++++++++++----------------
 config/firefly.php             |   4 +-
 package-lock.json              |   6 +-
 4 files changed, 80 insertions(+), 79 deletions(-)

diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock
index c9d5aa4d4f..3a0216cff4 100644
--- a/.ci/php-cs-fixer/composer.lock
+++ b/.ci/php-cs-fixer/composer.lock
@@ -1251,16 +1251,16 @@
         },
         {
             "name": "symfony/console",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "307d3cf852f5ead3618ac60ecbedbdd512c348b1"
+                "reference": "fcb73f69d655b48fcb894a262f074218df08bd58"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/307d3cf852f5ead3618ac60ecbedbdd512c348b1",
-                "reference": "307d3cf852f5ead3618ac60ecbedbdd512c348b1",
+                "url": "https://api.github.com/repos/symfony/console/zipball/fcb73f69d655b48fcb894a262f074218df08bd58",
+                "reference": "fcb73f69d655b48fcb894a262f074218df08bd58",
                 "shasum": ""
             },
             "require": {
@@ -1317,7 +1317,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v8.0.0"
+                "source": "https://github.com/symfony/console/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -1337,7 +1337,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-21T13:19:49+00:00"
+            "time": "2025-12-05T15:25:33+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -1569,16 +1569,16 @@
         },
         {
             "name": "symfony/filesystem",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "7fc96ae83372620eaba3826874f46e26295768ca"
+                "reference": "d937d400b980523dc9ee946bb69972b5e619058d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/7fc96ae83372620eaba3826874f46e26295768ca",
-                "reference": "7fc96ae83372620eaba3826874f46e26295768ca",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/d937d400b980523dc9ee946bb69972b5e619058d",
+                "reference": "d937d400b980523dc9ee946bb69972b5e619058d",
                 "shasum": ""
             },
             "require": {
@@ -1615,7 +1615,7 @@
             "description": "Provides basic utilities for the filesystem",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/filesystem/tree/v8.0.0"
+                "source": "https://github.com/symfony/filesystem/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -1635,7 +1635,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-05T14:36:47+00:00"
+            "time": "2025-12-01T09:13:36+00:00"
         },
         {
             "name": "symfony/finder",
@@ -2575,16 +2575,16 @@
         },
         {
             "name": "symfony/string",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "f929eccf09531078c243df72398560e32fa4cf4f"
+                "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/f929eccf09531078c243df72398560e32fa4cf4f",
-                "reference": "f929eccf09531078c243df72398560e32fa4cf4f",
+                "url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
+                "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
                 "shasum": ""
             },
             "require": {
@@ -2641,7 +2641,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v8.0.0"
+                "source": "https://github.com/symfony/string/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -2661,7 +2661,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-09-11T14:37:55+00:00"
+            "time": "2025-12-01T09:13:36+00:00"
         }
     ],
     "packages-dev": [],
diff --git a/composer.lock b/composer.lock
index 89b32d86fc..7c6d9584c0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3543,22 +3543,22 @@
         },
         {
             "name": "mailersend/laravel-driver",
-            "version": "v2.12.0",
+            "version": "v2.9.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-laravel-driver.git",
-                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
+                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
-                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
+                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725",
+                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
                 "illuminate/support": "^9.0 || ^10.0  || ^11.0 || ^12.0",
-                "mailersend/mailersend": "^0.35.0",
+                "mailersend/mailersend": "^0.31.0",
                 "nyholm/psr7": "^1.5",
                 "php": ">=8.0",
                 "php-http/guzzle7-adapter": "^1.0",
@@ -3606,28 +3606,29 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
-                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
+                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1"
             },
-            "time": "2025-10-28T14:59:16+00:00"
+            "time": "2025-04-09T09:33:07+00:00"
         },
         {
             "name": "mailersend/mailersend",
-            "version": "v0.35.0",
+            "version": "v0.31.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-php.git",
-                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
+                "reference": "513ff83ee768526055ad52987cde401ea7218c67"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
-                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
+                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67",
+                "reference": "513ff83ee768526055ad52987cde401ea7218c67",
                 "shasum": ""
             },
             "require": {
                 "beberlei/assert": "^3.2",
                 "ext-json": "*",
-                "php": "^7.4 || ^8.0 <8.5",
+                "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
+                "php": "^7.4|^8.0",
                 "php-http/client-common": "^2.2",
                 "php-http/discovery": "^1.9",
                 "php-http/httplug": "^2.1",
@@ -3672,9 +3673,9 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-php/issues",
-                "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
+                "source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0"
             },
-            "time": "2025-10-28T13:11:43+00:00"
+            "time": "2025-04-03T12:16:11+00:00"
         },
         {
             "name": "monolog/monolog",
@@ -6662,16 +6663,16 @@
         },
         {
             "name": "symfony/cache",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache.git",
-                "reference": "1005fe1988f719db8e0c6db5b8ce24284336530f"
+                "reference": "0e67dc8145810d4e1c0d13c0e1d29ceb930b1c8e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache/zipball/1005fe1988f719db8e0c6db5b8ce24284336530f",
-                "reference": "1005fe1988f719db8e0c6db5b8ce24284336530f",
+                "url": "https://api.github.com/repos/symfony/cache/zipball/0e67dc8145810d4e1c0d13c0e1d29ceb930b1c8e",
+                "reference": "0e67dc8145810d4e1c0d13c0e1d29ceb930b1c8e",
                 "shasum": ""
             },
             "require": {
@@ -6738,7 +6739,7 @@
                 "psr6"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache/tree/v8.0.0"
+                "source": "https://github.com/symfony/cache/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -6758,7 +6759,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-16T10:17:21+00:00"
+            "time": "2025-12-04T18:17:06+00:00"
         },
         {
             "name": "symfony/cache-contracts",
@@ -6915,16 +6916,16 @@
         },
         {
             "name": "symfony/console",
-            "version": "v7.4.0",
+            "version": "v7.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8"
+                "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8",
-                "reference": "0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8",
+                "url": "https://api.github.com/repos/symfony/console/zipball/6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e",
+                "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e",
                 "shasum": ""
             },
             "require": {
@@ -6989,7 +6990,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v7.4.0"
+                "source": "https://github.com/symfony/console/tree/v7.4.1"
             },
             "funding": [
                 {
@@ -7009,7 +7010,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-27T13:27:24+00:00"
+            "time": "2025-12-05T15:23:39+00:00"
         },
         {
             "name": "symfony/css-selector",
@@ -7527,16 +7528,16 @@
         },
         {
             "name": "symfony/http-client",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "b4be9eb608f5c7544e448908fb30472da77a975f"
+                "reference": "727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/b4be9eb608f5c7544e448908fb30472da77a975f",
-                "reference": "b4be9eb608f5c7544e448908fb30472da77a975f",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0",
+                "reference": "727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0",
                 "shasum": ""
             },
             "require": {
@@ -7599,7 +7600,7 @@
                 "http"
             ],
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v8.0.0"
+                "source": "https://github.com/symfony/http-client/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -7619,7 +7620,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-20T12:42:53+00:00"
+            "time": "2025-12-05T14:08:45+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
@@ -7701,16 +7702,16 @@
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v7.4.0",
+            "version": "v7.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "769c1720b68e964b13b58529c17d4a385c62167b"
+                "reference": "bd1af1e425811d6f077db240c3a588bdb405cd27"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/769c1720b68e964b13b58529c17d4a385c62167b",
-                "reference": "769c1720b68e964b13b58529c17d4a385c62167b",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/bd1af1e425811d6f077db240c3a588bdb405cd27",
+                "reference": "bd1af1e425811d6f077db240c3a588bdb405cd27",
                 "shasum": ""
             },
             "require": {
@@ -7759,7 +7760,7 @@
             "description": "Defines an object-oriented layer for the HTTP specification",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-foundation/tree/v7.4.0"
+                "source": "https://github.com/symfony/http-foundation/tree/v7.4.1"
             },
             "funding": [
                 {
@@ -7779,20 +7780,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-13T08:49:24+00:00"
+            "time": "2025-12-07T11:13:10+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v7.4.0",
+            "version": "v7.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "7348193cd384495a755554382e4526f27c456085"
+                "reference": "171d2ec4002012a023e042c6041d7fde58b143c6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/7348193cd384495a755554382e4526f27c456085",
-                "reference": "7348193cd384495a755554382e4526f27c456085",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/171d2ec4002012a023e042c6041d7fde58b143c6",
+                "reference": "171d2ec4002012a023e042c6041d7fde58b143c6",
                 "shasum": ""
             },
             "require": {
@@ -7878,7 +7879,7 @@
             "description": "Provides a structured process for converting a Request into a Response",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-kernel/tree/v7.4.0"
+                "source": "https://github.com/symfony/http-kernel/tree/v7.4.1"
             },
             "funding": [
                 {
@@ -7898,7 +7899,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-27T13:38:24+00:00"
+            "time": "2025-12-07T16:28:51+00:00"
         },
         {
             "name": "symfony/mailer",
@@ -9370,16 +9371,16 @@
         },
         {
             "name": "symfony/string",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "f929eccf09531078c243df72398560e32fa4cf4f"
+                "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/f929eccf09531078c243df72398560e32fa4cf4f",
-                "reference": "f929eccf09531078c243df72398560e32fa4cf4f",
+                "url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
+                "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
                 "shasum": ""
             },
             "require": {
@@ -9436,7 +9437,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v8.0.0"
+                "source": "https://github.com/symfony/string/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -9456,20 +9457,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-09-11T14:37:55+00:00"
+            "time": "2025-12-01T09:13:36+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v8.0.0",
+            "version": "v8.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "82ab368a6fca6358d995b6dd5c41590fb42c03e6"
+                "reference": "770e3b8b0ba8360958abedcabacd4203467333ca"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/82ab368a6fca6358d995b6dd5c41590fb42c03e6",
-                "reference": "82ab368a6fca6358d995b6dd5c41590fb42c03e6",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/770e3b8b0ba8360958abedcabacd4203467333ca",
+                "reference": "770e3b8b0ba8360958abedcabacd4203467333ca",
                 "shasum": ""
             },
             "require": {
@@ -9529,7 +9530,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v8.0.0"
+                "source": "https://github.com/symfony/translation/tree/v8.0.1"
             },
             "funding": [
                 {
@@ -9549,7 +9550,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-27T08:09:45+00:00"
+            "time": "2025-12-01T09:13:36+00:00"
         },
         {
             "name": "symfony/translation-contracts",
diff --git a/config/firefly.php b/config/firefly.php
index 9be3e6f6dc..ae63cf67ce 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
         'running_balance_column' => env('USE_RUNNING_BALANCE', false),
         // see cer.php for exchange rates feature flag.
     ],
-    'version'                              => 'develop/2025-12-07',
-    'build_time'                           => 1765124451,
+    'version'                              => 'develop/2025-12-08',
+    'build_time'                           => 1765164703,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 
diff --git a/package-lock.json b/package-lock.json
index 76fe40a3b4..d53780e559 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11585,9 +11585,9 @@
             }
         },
         "node_modules/vite": {
-            "version": "7.2.6",
-            "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz",
-            "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
+            "version": "7.2.7",
+            "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.7.tgz",
+            "integrity": "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {

From 8f81cb8cc45c725658a6ea939bd5bff5eee0d287 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 13 Dec 2025 06:05:39 +0100
Subject: [PATCH 18/27] Fix #11346

---
 .../Correction/ClearsEmptyForeignAmounts.php  | 64 +++++++++++++++++++
 .../Commands/Correction/CorrectsDatabase.php  |  1 +
 resources/views/list/groups.twig              | 10 ++-
 3 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php

diff --git a/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php b/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php
new file mode 100644
index 0000000000..da980aaafa
--- /dev/null
+++ b/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php
@@ -0,0 +1,64 @@
+.
+ */
+
+namespace FireflyIII\Console\Commands\Correction;
+
+use FireflyIII\Console\Commands\ShowsFriendlyMessages;
+use FireflyIII\Models\Transaction;
+use Illuminate\Console\Command;
+
+class ClearsEmptyForeignAmounts extends Command
+{
+    use ShowsFriendlyMessages;
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'correction:clears-empty-foreign-amounts';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Removes references to foreign amounts if there is no amount.';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle():int
+    {
+        // transaction: has no amount, but reference to currency.
+        $count = Transaction::whereNull('foreign_amount')->whereNotNull('foreign_currency_id')->count();
+        if($count > 0) {
+            Transaction::whereNull('foreign_amount')->whereNotNull('foreign_currency_id')->update(['foreign_currency_id' => null]);
+            $this->friendlyInfo(sprintf('Corrected %d invalid foreign amount reference(s)', $count));
+        }
+        // transaction: has amount, but no currency.
+        $count = Transaction::whereNull('foreign_currency_id')->whereNotNull('foreign_amount')->count();
+        if($count > 0) {
+            Transaction::whereNull('foreign_currency_id')->whereNotNull('foreign_amount')->update(['foreign_amount' => null]);
+            $this->friendlyInfo(sprintf('Corrected %d invalid foreign amount reference(s)', $count));
+        }
+        return self::SUCCESS;
+    }
+}
diff --git a/app/Console/Commands/Correction/CorrectsDatabase.php b/app/Console/Commands/Correction/CorrectsDatabase.php
index 8a0c416d41..89d2818f07 100644
--- a/app/Console/Commands/Correction/CorrectsDatabase.php
+++ b/app/Console/Commands/Correction/CorrectsDatabase.php
@@ -78,6 +78,7 @@ class CorrectsDatabase extends Command
             // 'correction:transaction-types', // resource heavy, disabled.
             'correction:recalculate-pc-amounts',
             'correction:remove-links-to-deleted-objects',
+            'correction:clears-empty-foreign-amounts',
             'firefly-iii:report-integrity',
         ];
         foreach ($commands as $command) {
diff --git a/resources/views/list/groups.twig b/resources/views/list/groups.twig
index fe4ab310d5..0761699621 100644
--- a/resources/views/list/groups.twig
+++ b/resources/views/list/groups.twig
@@ -277,9 +277,17 @@
                             {%  endif %}
 
                         {% elseif transaction.transaction_type_type == 'Withdrawal' %}
+
                             {% if 'Loan' == transaction.destination_account_type or 'Mortgage' == transaction.destination_account_type or 'Debt' == transaction.destination_account_type %}
+
                                 {% if currency.id == transaction.currency_id %}
-                                    {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                    {% if account.id == transaction.source_account_id %}
+                                        {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                    {% endif %}
+                                    {% if account.id == transaction.destination_account_id %}
+                                        {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                    {% endif %}
+
                                 {% endif %}
                                 {% if currency.id == transaction.foreign_currency_id and null != transaction.destination_balance_after and null != transaction.destination_balance_after %}
                                     {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol ?? transaction.currency_symbol, transaction.foreign_currency_decimal_places ?? transaction.currency_decimal_places) }}

From 0b00f351019340a327d2c1e147a0f76263d2f1ea Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 13 Dec 2025 06:08:58 +0100
Subject: [PATCH 19/27] Update packages, another fix for the same issue.

---
 composer.lock                    | 167 ++++++++++++++++---------------
 resources/views/list/groups.twig |  14 +--
 2 files changed, 93 insertions(+), 88 deletions(-)

diff --git a/composer.lock b/composer.lock
index 7c6d9584c0..57159f1965 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1938,16 +1938,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v12.41.1",
+            "version": "v12.42.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "3e229b05935fd0300c632fb1f718c73046d664fc"
+                "reference": "509b33095564c5165366d81bbaa0afaac28abe75"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/3e229b05935fd0300c632fb1f718c73046d664fc",
-                "reference": "3e229b05935fd0300c632fb1f718c73046d664fc",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/509b33095564c5165366d81bbaa0afaac28abe75",
+                "reference": "509b33095564c5165366d81bbaa0afaac28abe75",
                 "shasum": ""
             },
             "require": {
@@ -2035,6 +2035,7 @@
                 "illuminate/process": "self.version",
                 "illuminate/queue": "self.version",
                 "illuminate/redis": "self.version",
+                "illuminate/reflection": "self.version",
                 "illuminate/routing": "self.version",
                 "illuminate/session": "self.version",
                 "illuminate/support": "self.version",
@@ -2059,7 +2060,7 @@
                 "league/flysystem-sftp-v3": "^3.25.1",
                 "mockery/mockery": "^1.6.10",
                 "opis/json-schema": "^2.4.1",
-                "orchestra/testbench-core": "^10.8.0",
+                "orchestra/testbench-core": "^10.8.1",
                 "pda/pheanstalk": "^5.0.6|^7.0.0",
                 "php-http/discovery": "^1.15",
                 "phpstan/phpstan": "^2.0",
@@ -2121,6 +2122,7 @@
                     "src/Illuminate/Filesystem/functions.php",
                     "src/Illuminate/Foundation/helpers.php",
                     "src/Illuminate/Log/functions.php",
+                    "src/Illuminate/Reflection/helpers.php",
                     "src/Illuminate/Support/functions.php",
                     "src/Illuminate/Support/helpers.php"
                 ],
@@ -2129,7 +2131,8 @@
                     "Illuminate\\Support\\": [
                         "src/Illuminate/Macroable/",
                         "src/Illuminate/Collections/",
-                        "src/Illuminate/Conditionable/"
+                        "src/Illuminate/Conditionable/",
+                        "src/Illuminate/Reflection/"
                     ]
                 }
             },
@@ -2153,7 +2156,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2025-12-03T01:02:13+00:00"
+            "time": "2025-12-09T15:51:23+00:00"
         },
         {
             "name": "laravel/passport",
@@ -3361,20 +3364,20 @@
         },
         {
             "name": "league/uri",
-            "version": "7.6.0",
+            "version": "7.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/uri.git",
-                "reference": "f625804987a0a9112d954f9209d91fec52182344"
+                "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/uri/zipball/f625804987a0a9112d954f9209d91fec52182344",
-                "reference": "f625804987a0a9112d954f9209d91fec52182344",
+                "url": "https://api.github.com/repos/thephpleague/uri/zipball/8d587cddee53490f9b82bf203d3a9aa7ea4f9807",
+                "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807",
                 "shasum": ""
             },
             "require": {
-                "league/uri-interfaces": "^7.6",
+                "league/uri-interfaces": "^7.7",
                 "php": "^8.1",
                 "psr/http-factory": "^1"
             },
@@ -3447,7 +3450,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.6.0"
+                "source": "https://github.com/thephpleague/uri/tree/7.7.0"
             },
             "funding": [
                 {
@@ -3455,20 +3458,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-11-18T12:17:23+00:00"
+            "time": "2025-12-07T16:02:06+00:00"
         },
         {
             "name": "league/uri-interfaces",
-            "version": "7.6.0",
+            "version": "7.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/uri-interfaces.git",
-                "reference": "ccbfb51c0445298e7e0b7f4481b942f589665368"
+                "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/ccbfb51c0445298e7e0b7f4481b942f589665368",
-                "reference": "ccbfb51c0445298e7e0b7f4481b942f589665368",
+                "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/62ccc1a0435e1c54e10ee6022df28d6c04c2946c",
+                "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c",
                 "shasum": ""
             },
             "require": {
@@ -3531,7 +3534,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.6.0"
+                "source": "https://github.com/thephpleague/uri-interfaces/tree/7.7.0"
             },
             "funding": [
                 {
@@ -3539,7 +3542,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-11-18T12:17:23+00:00"
+            "time": "2025-12-07T16:03:21+00:00"
         },
         {
             "name": "mailersend/laravel-driver",
@@ -7014,20 +7017,20 @@
         },
         {
             "name": "symfony/css-selector",
-            "version": "v7.4.0",
+            "version": "v8.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135"
+                "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/ab862f478513e7ca2fe9ec117a6f01a8da6e1135",
-                "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/6225bd458c53ecdee056214cb4a2ffaf58bd592b",
+                "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b",
                 "shasum": ""
             },
             "require": {
-                "php": ">=8.2"
+                "php": ">=8.4"
             },
             "type": "library",
             "autoload": {
@@ -7059,7 +7062,7 @@
             "description": "Converts CSS selectors to XPath expressions",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/css-selector/tree/v7.4.0"
+                "source": "https://github.com/symfony/css-selector/tree/v8.0.0"
             },
             "funding": [
                 {
@@ -7079,7 +7082,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-10-30T13:39:42+00:00"
+            "time": "2025-10-30T14:17:19+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -7784,16 +7787,16 @@
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v7.4.1",
+            "version": "v7.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "171d2ec4002012a023e042c6041d7fde58b143c6"
+                "reference": "f6e6f0a5fa8763f75a504b930163785fb6dd055f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/171d2ec4002012a023e042c6041d7fde58b143c6",
-                "reference": "171d2ec4002012a023e042c6041d7fde58b143c6",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6e6f0a5fa8763f75a504b930163785fb6dd055f",
+                "reference": "f6e6f0a5fa8763f75a504b930163785fb6dd055f",
                 "shasum": ""
             },
             "require": {
@@ -7879,7 +7882,7 @@
             "description": "Provides a structured process for converting a Request into a Response",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-kernel/tree/v7.4.1"
+                "source": "https://github.com/symfony/http-kernel/tree/v7.4.2"
             },
             "funding": [
                 {
@@ -7899,7 +7902,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-12-07T16:28:51+00:00"
+            "time": "2025-12-08T07:43:37+00:00"
         },
         {
             "name": "symfony/mailer",
@@ -10020,23 +10023,23 @@
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
-            "version": "v2.3.0",
+            "version": "v2.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
-                "reference": "0d72ac1c00084279c1816675284073c5a337c20d"
+                "reference": "f0292ccf0ec75843d65027214426b6b163b48b41"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d",
-                "reference": "0d72ac1c00084279c1816675284073c5a337c20d",
+                "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41",
+                "reference": "f0292ccf0ec75843d65027214426b6b163b48b41",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-libxml": "*",
                 "php": "^7.4 || ^8.0",
-                "symfony/css-selector": "^5.4 || ^6.0 || ^7.0"
+                "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.0"
             },
             "require-dev": {
                 "phpstan/phpstan": "^2.0",
@@ -10069,9 +10072,9 @@
             "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
             "support": {
                 "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
-                "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0"
+                "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.4.0"
             },
-            "time": "2024-12-21T16:25:41+00:00"
+            "time": "2025-12-02T11:56:42+00:00"
         },
         {
             "name": "twig/twig",
@@ -10399,16 +10402,16 @@
         },
         {
             "name": "barryvdh/laravel-ide-helper",
-            "version": "v3.6.0",
+            "version": "v3.6.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-ide-helper.git",
-                "reference": "8d00250cba25728373e92c1d8dcebcbf64623d29"
+                "reference": "b106f7ee85f263c4f103eca49e7bf3862c2e5e75"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/8d00250cba25728373e92c1d8dcebcbf64623d29",
-                "reference": "8d00250cba25728373e92c1d8dcebcbf64623d29",
+                "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/b106f7ee85f263c4f103eca49e7bf3862c2e5e75",
+                "reference": "b106f7ee85f263c4f103eca49e7bf3862c2e5e75",
                 "shasum": ""
             },
             "require": {
@@ -10477,7 +10480,7 @@
             ],
             "support": {
                 "issues": "https://github.com/barryvdh/laravel-ide-helper/issues",
-                "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.6.0"
+                "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.6.1"
             },
             "funding": [
                 {
@@ -10489,7 +10492,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-07-17T20:11:57+00:00"
+            "time": "2025-12-10T09:11:07+00:00"
         },
         {
             "name": "barryvdh/reflection-docblock",
@@ -10751,16 +10754,16 @@
         },
         {
             "name": "driftingly/rector-laravel",
-            "version": "2.1.6",
+            "version": "2.1.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/driftingly/rector-laravel.git",
-                "reference": "682d1e73ac79aced7e645141fd61a9ac468a0c44"
+                "reference": "2a64c96fa363bc85e4e6d4162c6a6bb7a78fd122"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/682d1e73ac79aced7e645141fd61a9ac468a0c44",
-                "reference": "682d1e73ac79aced7e645141fd61a9ac468a0c44",
+                "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/2a64c96fa363bc85e4e6d4162c6a6bb7a78fd122",
+                "reference": "2a64c96fa363bc85e4e6d4162c6a6bb7a78fd122",
                 "shasum": ""
             },
             "require": {
@@ -10781,9 +10784,9 @@
             "description": "Rector upgrades rules for Laravel Framework",
             "support": {
                 "issues": "https://github.com/driftingly/rector-laravel/issues",
-                "source": "https://github.com/driftingly/rector-laravel/tree/2.1.6"
+                "source": "https://github.com/driftingly/rector-laravel/tree/2.1.7"
             },
-            "time": "2025-12-04T13:37:33+00:00"
+            "time": "2025-12-10T11:30:42+00:00"
         },
         {
             "name": "fakerphp/faker",
@@ -11685,23 +11688,23 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "12.5.0",
+            "version": "12.5.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "bca180c050dd3ae15f87c26d25cabb34fe1a0a5a"
+                "reference": "c467c59a4f6e04b942be422844e7a6352fa01b57"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bca180c050dd3ae15f87c26d25cabb34fe1a0a5a",
-                "reference": "bca180c050dd3ae15f87c26d25cabb34fe1a0a5a",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c467c59a4f6e04b942be422844e7a6352fa01b57",
+                "reference": "c467c59a4f6e04b942be422844e7a6352fa01b57",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-libxml": "*",
                 "ext-xmlwriter": "*",
-                "nikic/php-parser": "^5.6.2",
+                "nikic/php-parser": "^5.7.0",
                 "php": ">=8.3",
                 "phpunit/php-file-iterator": "^6.0",
                 "phpunit/php-text-template": "^5.0",
@@ -11709,10 +11712,10 @@
                 "sebastian/environment": "^8.0.3",
                 "sebastian/lines-of-code": "^4.0",
                 "sebastian/version": "^6.0",
-                "theseer/tokenizer": "^1.3.1"
+                "theseer/tokenizer": "^2.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^12.4.4"
+                "phpunit/phpunit": "^12.5.1"
             },
             "suggest": {
                 "ext-pcov": "PHP extension that provides line coverage",
@@ -11750,7 +11753,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
                 "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.0"
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.1"
             },
             "funding": [
                 {
@@ -11770,7 +11773,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-11-29T07:15:54+00:00"
+            "time": "2025-12-08T07:17:58+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
@@ -12019,16 +12022,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "12.5.1",
+            "version": "12.5.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "e33a5132ea24119400f6ce5bce6665922e968bad"
+                "reference": "6dc2e076d09960efbb0c1272aa9bc156fc80955e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e33a5132ea24119400f6ce5bce6665922e968bad",
-                "reference": "e33a5132ea24119400f6ce5bce6665922e968bad",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6dc2e076d09960efbb0c1272aa9bc156fc80955e",
+                "reference": "6dc2e076d09960efbb0c1272aa9bc156fc80955e",
                 "shasum": ""
             },
             "require": {
@@ -12042,7 +12045,7 @@
                 "phar-io/manifest": "^2.0.4",
                 "phar-io/version": "^3.2.1",
                 "php": ">=8.3",
-                "phpunit/php-code-coverage": "^12.5.0",
+                "phpunit/php-code-coverage": "^12.5.1",
                 "phpunit/php-file-iterator": "^6.0.0",
                 "phpunit/php-invoker": "^6.0.0",
                 "phpunit/php-text-template": "^5.0.0",
@@ -12096,7 +12099,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.5.1"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.3"
             },
             "funding": [
                 {
@@ -12120,25 +12123,25 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-12-06T12:19:17+00:00"
+            "time": "2025-12-11T08:52:59+00:00"
         },
         {
             "name": "rector/rector",
-            "version": "2.2.11",
+            "version": "2.2.14",
             "source": {
                 "type": "git",
                 "url": "https://github.com/rectorphp/rector.git",
-                "reference": "7bd21a40b0332b93d4bfee284093d7400696902d"
+                "reference": "6d56bb0e94d4df4f57a78610550ac76ab403657d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/rectorphp/rector/zipball/7bd21a40b0332b93d4bfee284093d7400696902d",
-                "reference": "7bd21a40b0332b93d4bfee284093d7400696902d",
+                "url": "https://api.github.com/repos/rectorphp/rector/zipball/6d56bb0e94d4df4f57a78610550ac76ab403657d",
+                "reference": "6d56bb0e94d4df4f57a78610550ac76ab403657d",
                 "shasum": ""
             },
             "require": {
                 "php": "^7.4|^8.0",
-                "phpstan/phpstan": "^2.1.32"
+                "phpstan/phpstan": "^2.1.33"
             },
             "conflict": {
                 "rector/rector-doctrine": "*",
@@ -12172,7 +12175,7 @@
             ],
             "support": {
                 "issues": "https://github.com/rectorphp/rector/issues",
-                "source": "https://github.com/rectorphp/rector/tree/2.2.11"
+                "source": "https://github.com/rectorphp/rector/tree/2.2.14"
             },
             "funding": [
                 {
@@ -12180,7 +12183,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-12-02T11:23:46+00:00"
+            "time": "2025-12-09T10:57:55+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -13191,23 +13194,23 @@
         },
         {
             "name": "theseer/tokenizer",
-            "version": "1.3.1",
+            "version": "2.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/theseer/tokenizer.git",
-                "reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
+                "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
-                "reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4",
+                "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-tokenizer": "*",
                 "ext-xmlwriter": "*",
-                "php": "^7.2 || ^8.0"
+                "php": "^8.1"
             },
             "type": "library",
             "autoload": {
@@ -13229,7 +13232,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.3.1"
+                "source": "https://github.com/theseer/tokenizer/tree/2.0.1"
             },
             "funding": [
                 {
@@ -13237,7 +13240,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-11-17T20:03:58+00:00"
+            "time": "2025-12-08T11:19:18+00:00"
         },
         {
             "name": "webmozart/assert",
diff --git a/resources/views/list/groups.twig b/resources/views/list/groups.twig
index 0761699621..f10d927afd 100644
--- a/resources/views/list/groups.twig
+++ b/resources/views/list/groups.twig
@@ -272,14 +272,12 @@
                         {% if transaction.transaction_type_type == 'Deposit' %}
                             {% if transaction.source_account_id == account.id %}
                                 {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
-                                {% else %}
+                            {% else %}
                                 {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
                             {%  endif %}
 
                         {% elseif transaction.transaction_type_type == 'Withdrawal' %}
-
                             {% if 'Loan' == transaction.destination_account_type or 'Mortgage' == transaction.destination_account_type or 'Debt' == transaction.destination_account_type %}
-
                                 {% if currency.id == transaction.currency_id %}
                                     {% if account.id == transaction.source_account_id %}
                                         {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
@@ -287,14 +285,18 @@
                                     {% if account.id == transaction.destination_account_id %}
                                         {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
                                     {% endif %}
-
                                 {% endif %}
                                 {% if currency.id == transaction.foreign_currency_id and null != transaction.destination_balance_after and null != transaction.destination_balance_after %}
                                     {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol ?? transaction.currency_symbol, transaction.foreign_currency_decimal_places ?? transaction.currency_decimal_places) }}
                                 {% endif %}
-
                             {% else %}
-                                {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                {% if account.id == transaction.source_account_id %}
+                                    {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                {% endif %}
+                                {% if account.id == transaction.destination_account_id %}
+                                    {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                {% endif %}
+
                             {% endif %}
                         {% elseif transaction.transaction_type_type == 'Opening balance' %}
                             {% if transaction.source_account_type == 'Initial balance account' %}

From d74d67633dd6d20c79a60d1518f3509c0f56ed6a Mon Sep 17 00:00:00 2001
From: JC5 
Date: Sat, 13 Dec 2025 06:13:20 +0100
Subject: [PATCH 20/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?=
 =?UTF-8?q?ase=20'develop'=20on=202025-12-13?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .ci/php-cs-fixer/composer.lock                | 12 ++---
 .../Correction/ClearsEmptyForeignAmounts.php  | 12 +++--
 composer.lock                                 | 29 +++++-----
 config/firefly.php                            |  4 +-
 package-lock.json                             | 54 +++++++++----------
 resources/assets/v1/src/locales/ro.json       |  2 +-
 6 files changed, 58 insertions(+), 55 deletions(-)

diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock
index 3a0216cff4..8ff090574c 100644
--- a/.ci/php-cs-fixer/composer.lock
+++ b/.ci/php-cs-fixer/composer.lock
@@ -402,16 +402,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v3.91.3",
+            "version": "v3.92.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
-                "reference": "9f10aa6390cea91da175ea608880e942d7c0226e"
+                "reference": "5646c2cd99b7cb4b658ff681fe27069ba86c7280"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/9f10aa6390cea91da175ea608880e942d7c0226e",
-                "reference": "9f10aa6390cea91da175ea608880e942d7c0226e",
+                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/5646c2cd99b7cb4b658ff681fe27069ba86c7280",
+                "reference": "5646c2cd99b7cb4b658ff681fe27069ba86c7280",
                 "shasum": ""
             },
             "require": {
@@ -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.91.3"
+                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.0"
             },
             "funding": [
                 {
@@ -501,7 +501,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2025-12-05T19:45:37+00:00"
+            "time": "2025-12-12T10:29:19+00:00"
         },
         {
             "name": "psr/container",
diff --git a/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php b/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php
index da980aaafa..958140f759 100644
--- a/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php
+++ b/app/Console/Commands/Correction/ClearsEmptyForeignAmounts.php
@@ -1,4 +1,6 @@
 whereNotNull('foreign_currency_id')->count();
-        if($count > 0) {
+        if ($count > 0) {
             Transaction::whereNull('foreign_amount')->whereNotNull('foreign_currency_id')->update(['foreign_currency_id' => null]);
             $this->friendlyInfo(sprintf('Corrected %d invalid foreign amount reference(s)', $count));
         }
         // transaction: has amount, but no currency.
         $count = Transaction::whereNull('foreign_currency_id')->whereNotNull('foreign_amount')->count();
-        if($count > 0) {
+        if ($count > 0) {
             Transaction::whereNull('foreign_currency_id')->whereNotNull('foreign_amount')->update(['foreign_amount' => null]);
             $this->friendlyInfo(sprintf('Corrected %d invalid foreign amount reference(s)', $count));
         }
+
         return self::SUCCESS;
     }
 }
diff --git a/composer.lock b/composer.lock
index 57159f1965..8d70cb94a3 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3546,22 +3546,22 @@
         },
         {
             "name": "mailersend/laravel-driver",
-            "version": "v2.9.1",
+            "version": "v2.12.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-laravel-driver.git",
-                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725"
+                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/87fd5ab76808bbaac9221be0d306baef13e98725",
-                "reference": "87fd5ab76808bbaac9221be0d306baef13e98725",
+                "url": "https://api.github.com/repos/mailersend/mailersend-laravel-driver/zipball/15e1ec41e29e65d3ca226929c65804190aaa93eb",
+                "reference": "15e1ec41e29e65d3ca226929c65804190aaa93eb",
                 "shasum": ""
             },
             "require": {
                 "ext-json": "*",
                 "illuminate/support": "^9.0 || ^10.0  || ^11.0 || ^12.0",
-                "mailersend/mailersend": "^0.31.0",
+                "mailersend/mailersend": "^0.35.0",
                 "nyholm/psr7": "^1.5",
                 "php": ">=8.0",
                 "php-http/guzzle7-adapter": "^1.0",
@@ -3609,29 +3609,28 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-laravel-driver/issues",
-                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.9.1"
+                "source": "https://github.com/mailersend/mailersend-laravel-driver/tree/v2.12.0"
             },
-            "time": "2025-04-09T09:33:07+00:00"
+            "time": "2025-10-28T14:59:16+00:00"
         },
         {
             "name": "mailersend/mailersend",
-            "version": "v0.31.0",
+            "version": "v0.35.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mailersend/mailersend-php.git",
-                "reference": "513ff83ee768526055ad52987cde401ea7218c67"
+                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/513ff83ee768526055ad52987cde401ea7218c67",
-                "reference": "513ff83ee768526055ad52987cde401ea7218c67",
+                "url": "https://api.github.com/repos/mailersend/mailersend-php/zipball/f1696cf9e727e9503fbc5882d2a111bd966ad276",
+                "reference": "f1696cf9e727e9503fbc5882d2a111bd966ad276",
                 "shasum": ""
             },
             "require": {
                 "beberlei/assert": "^3.2",
                 "ext-json": "*",
-                "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
-                "php": "^7.4|^8.0",
+                "php": "^7.4 || ^8.0 <8.5",
                 "php-http/client-common": "^2.2",
                 "php-http/discovery": "^1.9",
                 "php-http/httplug": "^2.1",
@@ -3676,9 +3675,9 @@
             ],
             "support": {
                 "issues": "https://github.com/mailersend/mailersend-php/issues",
-                "source": "https://github.com/mailersend/mailersend-php/tree/v0.31.0"
+                "source": "https://github.com/mailersend/mailersend-php/tree/v0.35.0"
             },
-            "time": "2025-04-03T12:16:11+00:00"
+            "time": "2025-10-28T13:11:43+00:00"
         },
         {
             "name": "monolog/monolog",
diff --git a/config/firefly.php b/config/firefly.php
index ae63cf67ce..34123e1e02 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
         'running_balance_column' => env('USE_RUNNING_BALANCE', false),
         // see cer.php for exchange rates feature flag.
     ],
-    'version'                              => 'develop/2025-12-08',
-    'build_time'                           => 1765164703,
+    'version'                              => 'develop/2025-12-13',
+    'build_time'                           => 1765602694,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 
diff --git a/package-lock.json b/package-lock.json
index d53780e559..ce4f994a42 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3173,9 +3173,9 @@
             "license": "MIT"
         },
         "node_modules/@types/node": {
-            "version": "24.10.1",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
-            "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
+            "version": "25.0.1",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.1.tgz",
+            "integrity": "sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -3701,9 +3701,9 @@
             }
         },
         "node_modules/admin-lte": {
-            "version": "4.0.0-rc4",
-            "resolved": "https://registry.npmjs.org/admin-lte/-/admin-lte-4.0.0-rc4.tgz",
-            "integrity": "sha512-k+ILDKHO6Tn77nMqvQ+wmQoes0Eky/s23jp2P07nUbbILk+7RMnLkCW2jFgiXaO9eFQ2fhmes0LAXJmQbdfpjA==",
+            "version": "4.0.0-rc6",
+            "resolved": "https://registry.npmjs.org/admin-lte/-/admin-lte-4.0.0-rc6.tgz",
+            "integrity": "sha512-bJmCkfXesZKRD6OScTDSY6bYch5QsMDJv8pFnRESvSVKccH2WjUu3CuBC6qVcTggcaM2KPVO4DWDi0tRElMvqg==",
             "license": "MIT"
         },
         "node_modules/ajv": {
@@ -4075,9 +4075,9 @@
             "license": "MIT"
         },
         "node_modules/baseline-browser-mapping": {
-            "version": "2.9.4",
-            "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.4.tgz",
-            "integrity": "sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==",
+            "version": "2.9.7",
+            "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz",
+            "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {
@@ -4505,9 +4505,9 @@
             }
         },
         "node_modules/caniuse-lite": {
-            "version": "1.0.30001759",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz",
-            "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==",
+            "version": "1.0.30001760",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz",
+            "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==",
             "dev": true,
             "funding": [
                 {
@@ -5720,9 +5720,9 @@
             "license": "MIT"
         },
         "node_modules/electron-to-chromium": {
-            "version": "1.5.266",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz",
-            "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==",
+            "version": "1.5.267",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
+            "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
             "dev": true,
             "license": "ISC"
         },
@@ -5777,9 +5777,9 @@
             }
         },
         "node_modules/enhanced-resolve": {
-            "version": "5.18.3",
-            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
-            "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
+            "version": "5.18.4",
+            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
+            "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -7060,9 +7060,9 @@
             }
         },
         "node_modules/i18next": {
-            "version": "25.7.1",
-            "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.1.tgz",
-            "integrity": "sha512-XbTnkh1yCZWSAZGnA9xcQfHcYNgZs2cNxm+c6v1Ma9UAUGCeJPplRe1ILia6xnDvXBjk0uXU+Z8FYWhA19SKFw==",
+            "version": "25.7.2",
+            "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.2.tgz",
+            "integrity": "sha512-58b4kmLpLv1buWUEwegMDUqZVR5J+rT+WTRFaBGL7lxDuJQQ0NrJFrq+eT2N94aYVR1k1Sr13QITNOL88tZCuw==",
             "funding": [
                 {
                     "type": "individual",
@@ -10175,9 +10175,9 @@
             "license": "MIT"
         },
         "node_modules/sass": {
-            "version": "1.94.2",
-            "resolved": "https://registry.npmjs.org/sass/-/sass-1.94.2.tgz",
-            "integrity": "sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==",
+            "version": "1.96.0",
+            "resolved": "https://registry.npmjs.org/sass/-/sass-1.96.0.tgz",
+            "integrity": "sha512-8u4xqqUeugGNCYwr9ARNtQKTOj4KmYiJAVKXf2CTIivTCR51j96htbMKWDru8H5SaQWpyVgTfOF8Ylyf5pun1Q==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -11095,9 +11095,9 @@
             }
         },
         "node_modules/terser-webpack-plugin": {
-            "version": "5.3.15",
-            "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.15.tgz",
-            "integrity": "sha512-PGkOdpRFK+rb1TzVz+msVhw4YMRT9txLF4kRqvJhGhCM324xuR3REBSHALN+l+sAhKUmz0aotnjp5D+P83mLhQ==",
+            "version": "5.3.16",
+            "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz",
+            "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
diff --git a/resources/assets/v1/src/locales/ro.json b/resources/assets/v1/src/locales/ro.json
index eec1bf47de..73fca4dc35 100644
--- a/resources/assets/v1/src/locales/ro.json
+++ b/resources/assets/v1/src/locales/ro.json
@@ -7,7 +7,7 @@
         "administration_currency_form_help": "It may take a long time for the page to load if you change the primary currency because transaction may need to be converted to your (new) primary currency.",
         "administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
         "table": "Tabel",
-        "welcome_back": "Ce se red\u0103?",
+        "welcome_back": "Situa\u021bia ta financiar\u0103",
         "flash_error": "Eroare!",
         "flash_warning": "Avertizare!",
         "flash_success": "Succes!",

From d747ac237bf575a7870e6704c4b695acf18b770f Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sat, 13 Dec 2025 06:36:20 +0100
Subject: [PATCH 21/27] Validate title, fix running balance display

---
 .../Requests/Models/Transaction/UpdateRequest.php  |  3 +++
 resources/views/list/groups.twig                   | 14 +++++++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php b/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php
index 1578b4ba12..fbde30a61b 100644
--- a/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php
@@ -339,6 +339,9 @@ class UpdateRequest extends FormRequest
                 // if more than one, verify that there are journal ID's present.
                 $this->validateJournalIds($validator, $transactionGroup);
 
+                // if more than one split, needs group title
+                $this->validateGroupDescription($validator);
+
                 // all transaction types must be equal:
                 $this->validateTransactionTypesForUpdate($validator);
 
diff --git a/resources/views/list/groups.twig b/resources/views/list/groups.twig
index f10d927afd..196c7a469a 100644
--- a/resources/views/list/groups.twig
+++ b/resources/views/list/groups.twig
@@ -277,26 +277,30 @@
                             {%  endif %}
 
                         {% elseif transaction.transaction_type_type == 'Withdrawal' %}
+
+                            {# withdrawal into a liability #}
                             {% if 'Loan' == transaction.destination_account_type or 'Mortgage' == transaction.destination_account_type or 'Debt' == transaction.destination_account_type %}
                                 {% if currency.id == transaction.currency_id %}
                                     {% if account.id == transaction.source_account_id %}
                                         {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
-                                    {% endif %}
-                                    {% if account.id == transaction.destination_account_id %}
+                                    {% elseif account.id == transaction.destination_account_id %}
                                         {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                    {% else %}
+                                        -
                                     {% endif %}
                                 {% endif %}
                                 {% if currency.id == transaction.foreign_currency_id and null != transaction.destination_balance_after and null != transaction.destination_balance_after %}
                                     {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol ?? transaction.currency_symbol, transaction.foreign_currency_decimal_places ?? transaction.currency_decimal_places) }}
                                 {% endif %}
+                            {# withdrawal into an expense account #}
                             {% else %}
                                 {% if account.id == transaction.source_account_id %}
                                     {{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
-                                {% endif %}
-                                {% if account.id == transaction.destination_account_id %}
+                                {% elseif account.id == transaction.destination_account_id %}
                                     {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
+                                {% else %}
+                                    -
                                 {% endif %}
-
                             {% endif %}
                         {% elseif transaction.transaction_type_type == 'Opening balance' %}
                             {% if transaction.source_account_type == 'Initial balance account' %}

From 73312a4cccba4c40514010cf9689cf6ddacfe841 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sun, 14 Dec 2025 10:24:27 +0100
Subject: [PATCH 22/27] Fix #11310

---
 .../Controllers/Chart/AccountController.php   | 31 ++++++++++---------
 .../RuleGroup/ExecutionController.php         |  2 +-
 .../Calendar/Periodicity/BimonthlyTest.php    |  3 +-
 .../Calendar/Periodicity/DailyTest.php        |  3 +-
 .../Calendar/Periodicity/FortnightlyTest.php  |  3 +-
 .../Calendar/Periodicity/HalfYearlyTest.php   |  3 +-
 .../Calendar/Periodicity/MonthlyTest.php      |  3 +-
 .../Calendar/Periodicity/QuarterlyTest.php    |  3 +-
 .../Calendar/Periodicity/WeeklyTest.php       |  3 +-
 .../Calendar/Periodicity/YearlyTest.php       |  3 +-
 10 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php
index c097ec0372..00d0e8365d 100644
--- a/app/Api/V1/Controllers/Chart/AccountController.php
+++ b/app/Api/V1/Controllers/Chart/AccountController.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
 
 namespace FireflyIII\Api\V1\Controllers\Chart;
 
-use Illuminate\Http\Request;
 use FireflyIII\Api\V1\Controllers\Controller;
 use FireflyIII\Api\V1\Requests\Chart\ChartRequest;
 use FireflyIII\Enums\UserRoleEnum;
@@ -32,11 +31,13 @@ use FireflyIII\Exceptions\FireflyException;
 use FireflyIII\Models\Account;
 use FireflyIII\Models\TransactionCurrency;
 use FireflyIII\Repositories\Account\AccountRepositoryInterface;
+use FireflyIII\Support\Facades\Navigation;
 use FireflyIII\Support\Facades\Steam;
 use FireflyIII\Support\Http\Api\ApiSupport;
 use FireflyIII\Support\Http\Api\CleansChartData;
 use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Log;
 
 /**
@@ -48,9 +49,9 @@ class AccountController extends Controller
     use CleansChartData;
     use CollectsAccountsFromFilter;
 
-    protected array $acceptedRoles            = [UserRoleEnum::READ_ONLY];
+    protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
 
-    private array                  $chartData = [];
+    private array                      $chartData = [];
     private AccountRepositoryInterface $repository;
 
     /**
@@ -100,17 +101,17 @@ class AccountController extends Controller
     private function renderAccountData(array $params, Account $account): void
     {
         Log::debug(sprintf('Now in %s(array, #%d)', __METHOD__, $account->id));
-        $currency          = $this->repository->getAccountCurrency($account);
-        $currentStart      = clone $params['start'];
-        $range             = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToPrimary);
+        $currency     = $this->repository->getAccountCurrency($account);
+        $currentStart = clone $params['start'];
+        $range        = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToPrimary);
+        $period       = $params['period'] ?? '1D';
 
-
-        $previous          = array_values($range)[0]['balance'];
-        $pcPrevious        = null;
+        $previous   = array_values($range)[0]['balance'];
+        $pcPrevious = null;
         if (!$currency instanceof TransactionCurrency) {
             $currency = $this->primaryCurrency;
         }
-        $currentSet        = [
+        $currentSet = [
             'label'                   => $account->name,
 
             // the currency that belongs to the account.
@@ -129,7 +130,7 @@ class AccountController extends Controller
             'end_date'                => $params['end']->toAtomString(),
             'type'                    => 'line',
             'yAxisID'                 => 0,
-            'period'                  => '1D',
+            'period'                  => $period,
             'entries'                 => [],
             'pc_entries'              => [],
         ];
@@ -141,7 +142,7 @@ class AccountController extends Controller
             $currentSet['primary_currency_decimal_places'] = $this->primaryCurrency->decimal_places;
             $pcPrevious                                    = array_values($range)[0]['pc_balance'];
         }
-
+        // create array of values to collect.
 
         while ($currentStart <= $params['end']) {
             $format                        = $currentStart->format('Y-m-d');
@@ -152,14 +153,14 @@ class AccountController extends Controller
 
 
             // do the same for the primary currency balance, if relevant:
-            $pcBalance                     = null;
+            $pcBalance = null;
             if ($this->convertToPrimary) {
                 $pcBalance                        = array_key_exists($format, $range) ? $range[$format]['pc_balance'] : $pcPrevious;
                 $pcPrevious                       = $pcBalance;
                 $currentSet['pc_entries'][$label] = $pcBalance;
             }
-
-            $currentStart->addDay();
+            $currentStart = Navigation::addPeriod($currentStart, $period);
+            // $currentStart->addDay();
         }
         $this->chartData[] = $currentSet;
     }
diff --git a/app/Http/Controllers/RuleGroup/ExecutionController.php b/app/Http/Controllers/RuleGroup/ExecutionController.php
index f066f9f1a4..80628fd116 100644
--- a/app/Http/Controllers/RuleGroup/ExecutionController.php
+++ b/app/Http/Controllers/RuleGroup/ExecutionController.php
@@ -43,7 +43,7 @@ use Illuminate\View\View;
  */
 class ExecutionController extends Controller
 {
-    private AccountRepositoryInterface $repository;
+    private readonly AccountRepositoryInterface $repository;
 
     /**
      * ExecutionController constructor.
diff --git a/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php b/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php
index b667107a3c..71bed2a545 100644
--- a/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Bimonthly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class BimonthlyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Bimonthly
     {
         return new Bimonthly();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/DailyTest.php b/tests/unit/Support/Calendar/Periodicity/DailyTest.php
index 1c5dd1560c..0921b3f0a1 100644
--- a/tests/unit/Support/Calendar/Periodicity/DailyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/DailyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Daily;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class DailyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Daily
     {
         return new Daily();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php b/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php
index fdb8eac236..095b11b1ac 100644
--- a/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Fortnightly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class FortnightlyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Fortnightly
     {
         return new Fortnightly();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php b/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php
index f71779ce59..a30094e41f 100644
--- a/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\HalfYearly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class HalfYearlyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): HalfYearly
     {
         return new HalfYearly();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php b/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php
index afe440e976..1e224da5b6 100644
--- a/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Monthly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class MonthlyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Monthly
     {
         return new Monthly();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php b/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php
index 3e73794f24..4c27daea39 100644
--- a/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Quarterly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class QuarterlyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Quarterly
     {
         return new Quarterly();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php b/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php
index f347d11222..23020042ce 100644
--- a/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Weekly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class WeeklyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Weekly
     {
         return new Weekly();
     }
diff --git a/tests/unit/Support/Calendar/Periodicity/YearlyTest.php b/tests/unit/Support/Calendar/Periodicity/YearlyTest.php
index 27fbc1c56e..36464498a8 100644
--- a/tests/unit/Support/Calendar/Periodicity/YearlyTest.php
+++ b/tests/unit/Support/Calendar/Periodicity/YearlyTest.php
@@ -27,7 +27,6 @@ namespace Tests\unit\Support\Calendar\Periodicity;
 use FireflyIII\Support\Calendar\Periodicity\Yearly;
 use Carbon\Carbon;
 use FireflyIII\Support\Calendar\Periodicity;
-use FireflyIII\Support\Calendar\Periodicity\Interval;
 
 /**
  * @group unit-test
@@ -41,7 +40,7 @@ use FireflyIII\Support\Calendar\Periodicity\Interval;
  */
 final class YearlyTest extends IntervalTestCase
 {
-    public static function factory(): Interval
+    public static function factory(): Yearly
     {
         return new Yearly();
     }

From 40ecba4b5a914b9abbbc09180388106dbbbb5730 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sun, 14 Dec 2025 10:31:35 +0100
Subject: [PATCH 23/27] No longer need patch.

---
 patches/admin-lte+4.0.0-rc4.patch | 14 --------------
 1 file changed, 14 deletions(-)
 delete mode 100644 patches/admin-lte+4.0.0-rc4.patch

diff --git a/patches/admin-lte+4.0.0-rc4.patch b/patches/admin-lte+4.0.0-rc4.patch
deleted file mode 100644
index 24656efc22..0000000000
--- a/patches/admin-lte+4.0.0-rc4.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/node_modules/admin-lte/src/scss/_app-sidebar.scss b/node_modules/admin-lte/src/scss/_app-sidebar.scss
-old mode 100644
-new mode 100755
-index 69dfc16..dc341eb
---- a/node_modules/admin-lte/src/scss/_app-sidebar.scss
-+++ b/node_modules/admin-lte/src/scss/_app-sidebar.scss
-@@ -577,7 +577,6 @@ body:not(.app-loaded) {
- 
- @if $enable-dark-mode {
-   @include color-mode(dark) {
--    &.app-sidebar,
-     .app-sidebar {
-       --#{$lte-prefix}sidebar-hover-bg: #{$lte-sidebar-hover-bg-dark};
-       --#{$lte-prefix}sidebar-color: #{$lte-sidebar-color-dark};

From 9af95907e35546d0bf1b07f6ecde5d1f7940beb9 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sun, 14 Dec 2025 16:10:21 +0100
Subject: [PATCH 24/27] Fix patch etc.

---
 package-lock.json                 | 59 ++-----------------------------
 package.json                      |  3 ++
 patches/admin-lte+4.0.0-rc6.patch | 12 +++++++
 3 files changed, 18 insertions(+), 56 deletions(-)
 create mode 100644 patches/admin-lte+4.0.0-rc6.patch

diff --git a/package-lock.json b/package-lock.json
index ce4f994a42..48e7661223 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,9 @@
                 "resources/assets/v1",
                 "resources/assets/v2"
             ],
+            "dependencies": {
+                "patch-package": "^8.0.1"
+            },
             "devDependencies": {
                 "postcss": "^8.4.47"
             }
@@ -3647,7 +3650,6 @@
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
             "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
-            "dev": true,
             "license": "BSD-2-Clause"
         },
         "node_modules/accepts": {
@@ -3811,7 +3813,6 @@
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
             "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "color-convert": "^2.0.1"
@@ -4241,7 +4242,6 @@
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
             "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "fill-range": "^7.1.1"
@@ -4424,7 +4424,6 @@
             "version": "1.0.8",
             "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
             "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "call-bind-apply-helpers": "^1.0.0",
@@ -4443,7 +4442,6 @@
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
             "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "es-errors": "^1.3.0",
@@ -4457,7 +4455,6 @@
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
             "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "call-bind-apply-helpers": "^1.0.2",
@@ -4529,7 +4526,6 @@
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
             "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "ansi-styles": "^4.1.0",
@@ -4622,7 +4618,6 @@
             "version": "3.9.0",
             "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
             "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
-            "dev": true,
             "funding": [
                 {
                     "type": "github",
@@ -4719,7 +4714,6 @@
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
             "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "color-name": "~1.1.4"
@@ -4732,7 +4726,6 @@
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
             "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-            "dev": true,
             "license": "MIT"
         },
         "node_modules/colord": {
@@ -5075,7 +5068,6 @@
             "version": "7.0.6",
             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
             "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "path-key": "^3.1.0",
@@ -5407,7 +5399,6 @@
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
             "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "es-define-property": "^1.0.0",
@@ -5701,7 +5692,6 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
             "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "call-bind-apply-helpers": "^1.0.1",
@@ -5830,7 +5820,6 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
             "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
@@ -5840,7 +5829,6 @@
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
             "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
@@ -5857,7 +5845,6 @@
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
             "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "es-errors": "^1.3.0"
@@ -6266,7 +6253,6 @@
             "version": "7.1.1",
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
             "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "to-regex-range": "^5.0.1"
@@ -6347,7 +6333,6 @@
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
             "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
-            "dev": true,
             "license": "Apache-2.0",
             "dependencies": {
                 "micromatch": "^4.0.2"
@@ -6465,7 +6450,6 @@
             "version": "10.1.0",
             "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
             "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "graceful-fs": "^4.2.0",
@@ -6509,7 +6493,6 @@
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
             "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-            "dev": true,
             "license": "MIT",
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
@@ -6539,7 +6522,6 @@
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
             "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "call-bind-apply-helpers": "^1.0.2",
@@ -6564,7 +6546,6 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
             "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "dunder-proto": "^1.0.1",
@@ -6653,7 +6634,6 @@
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
             "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
@@ -6666,7 +6646,6 @@
             "version": "4.2.11",
             "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
             "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-            "dev": true,
             "license": "ISC"
         },
         "node_modules/growly": {
@@ -6687,7 +6666,6 @@
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
             "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=8"
@@ -6697,7 +6675,6 @@
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
             "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "es-define-property": "^1.0.0"
@@ -6710,7 +6687,6 @@
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
             "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
@@ -6771,7 +6747,6 @@
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
             "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "function-bind": "^1.1.2"
@@ -7379,7 +7354,6 @@
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
             "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
-            "dev": true,
             "license": "MIT",
             "bin": {
                 "is-docker": "cli.js"
@@ -7428,7 +7402,6 @@
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
             "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=0.12.0"
@@ -7493,7 +7466,6 @@
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
             "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "is-docker": "^2.0.0"
@@ -7513,7 +7485,6 @@
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-            "dev": true,
             "license": "ISC"
         },
         "node_modules/isobject": {
@@ -7602,7 +7573,6 @@
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz",
             "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "call-bind": "^1.0.8",
@@ -7622,7 +7592,6 @@
             "version": "2.0.5",
             "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
             "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
-            "dev": true,
             "license": "MIT"
         },
         "node_modules/json5": {
@@ -7642,7 +7611,6 @@
             "version": "6.2.0",
             "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
             "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "universalify": "^2.0.0"
@@ -7655,7 +7623,6 @@
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
             "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
-            "dev": true,
             "license": "Public Domain",
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
@@ -7685,7 +7652,6 @@
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
             "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "graceful-fs": "^4.1.11"
@@ -8009,7 +7975,6 @@
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
             "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
@@ -8120,7 +8085,6 @@
             "version": "4.0.8",
             "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
             "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "braces": "^3.0.3",
@@ -8269,7 +8233,6 @@
             "version": "1.2.8",
             "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
             "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-            "dev": true,
             "license": "MIT",
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
@@ -8522,7 +8485,6 @@
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
             "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 0.4"
@@ -8609,7 +8571,6 @@
             "version": "7.4.2",
             "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
             "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "is-docker": "^2.0.0",
@@ -8787,7 +8748,6 @@
             "version": "8.0.1",
             "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz",
             "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "@yarnpkg/lockfile": "^1.1.0",
@@ -8817,7 +8777,6 @@
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
             "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=6"
@@ -8854,7 +8813,6 @@
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=8"
@@ -8913,7 +8871,6 @@
             "version": "2.3.1",
             "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
             "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=8.6"
@@ -10269,7 +10226,6 @@
             "version": "7.7.3",
             "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
             "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
-            "dev": true,
             "license": "ISC",
             "bin": {
                 "semver": "bin/semver.js"
@@ -10542,7 +10498,6 @@
             "version": "1.2.2",
             "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
             "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "define-data-property": "^1.1.4",
@@ -10608,7 +10563,6 @@
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "shebang-regex": "^3.0.0"
@@ -10621,7 +10575,6 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=8"
@@ -11017,7 +10970,6 @@
             "version": "7.2.0",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
             "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "has-flag": "^4.0.0"
@@ -11265,7 +11217,6 @@
             "version": "0.2.5",
             "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
             "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=14.14"
@@ -11304,7 +11255,6 @@
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
             "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-            "dev": true,
             "license": "MIT",
             "dependencies": {
                 "is-number": "^7.0.0"
@@ -11442,7 +11392,6 @@
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
             "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-            "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">= 10.0.0"
@@ -12390,7 +12339,6 @@
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-            "dev": true,
             "license": "ISC",
             "dependencies": {
                 "isexe": "^2.0.0"
@@ -12509,7 +12457,6 @@
             "version": "2.8.2",
             "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
             "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
-            "dev": true,
             "license": "ISC",
             "bin": {
                 "yaml": "bin.mjs"
diff --git a/package.json b/package.json
index 9e54e2de7e..a14d1b669e 100644
--- a/package.json
+++ b/package.json
@@ -8,5 +8,8 @@
     ],
     "devDependencies": {
         "postcss": "^8.4.47"
+    },
+    "dependencies": {
+        "patch-package": "^8.0.1"
     }
 }
diff --git a/patches/admin-lte+4.0.0-rc6.patch b/patches/admin-lte+4.0.0-rc6.patch
new file mode 100644
index 0000000000..ffd45824b2
--- /dev/null
+++ b/patches/admin-lte+4.0.0-rc6.patch
@@ -0,0 +1,12 @@
+diff --git a/node_modules/admin-lte/src/scss/_app-sidebar.scss b/node_modules/admin-lte/src/scss/_app-sidebar.scss
+index 4420bd0..35da532
+--- a/node_modules/admin-lte/src/scss/_app-sidebar.scss
++++ b/node_modules/admin-lte/src/scss/_app-sidebar.scss
+@@ -599,7 +599,6 @@ body:not(.app-loaded) {
+ 
+ @if $enable-dark-mode {
+   @include color-mode(dark) {
+-    &.app-sidebar,
+     .app-sidebar {
+       --#{$lte-prefix}sidebar-hover-bg: #{$lte-sidebar-hover-bg-dark};
+       --#{$lte-prefix}sidebar-color: #{$lte-sidebar-color-dark};

From 18bb0eecff206ef234f047e48c890b155918e222 Mon Sep 17 00:00:00 2001
From: JC5 
Date: Sun, 14 Dec 2025 16:14:03 +0100
Subject: [PATCH 25/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?=
 =?UTF-8?q?ase=20'develop'=20on=202025-12-14?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Controllers/Chart/AccountController.php   | 20 +++---
 composer.lock                                 | 14 ++--
 config/firefly.php                            |  4 +-
 package-lock.json                             | 68 +++++++++----------
 4 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php
index 00d0e8365d..5d1436ada2 100644
--- a/app/Api/V1/Controllers/Chart/AccountController.php
+++ b/app/Api/V1/Controllers/Chart/AccountController.php
@@ -49,7 +49,7 @@ class AccountController extends Controller
     use CleansChartData;
     use CollectsAccountsFromFilter;
 
-    protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
+    protected array $acceptedRoles                = [UserRoleEnum::READ_ONLY];
 
     private array                      $chartData = [];
     private AccountRepositoryInterface $repository;
@@ -101,17 +101,17 @@ class AccountController extends Controller
     private function renderAccountData(array $params, Account $account): void
     {
         Log::debug(sprintf('Now in %s(array, #%d)', __METHOD__, $account->id));
-        $currency     = $this->repository->getAccountCurrency($account);
-        $currentStart = clone $params['start'];
-        $range        = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToPrimary);
-        $period       = $params['period'] ?? '1D';
+        $currency          = $this->repository->getAccountCurrency($account);
+        $currentStart      = clone $params['start'];
+        $range             = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToPrimary);
+        $period            = $params['period'] ?? '1D';
 
-        $previous   = array_values($range)[0]['balance'];
-        $pcPrevious = null;
+        $previous          = array_values($range)[0]['balance'];
+        $pcPrevious        = null;
         if (!$currency instanceof TransactionCurrency) {
             $currency = $this->primaryCurrency;
         }
-        $currentSet = [
+        $currentSet        = [
             'label'                   => $account->name,
 
             // the currency that belongs to the account.
@@ -153,13 +153,13 @@ class AccountController extends Controller
 
 
             // do the same for the primary currency balance, if relevant:
-            $pcBalance = null;
+            $pcBalance                     = null;
             if ($this->convertToPrimary) {
                 $pcBalance                        = array_key_exists($format, $range) ? $range[$format]['pc_balance'] : $pcPrevious;
                 $pcPrevious                       = $pcBalance;
                 $currentSet['pc_entries'][$label] = $pcBalance;
             }
-            $currentStart = Navigation::addPeriod($currentStart, $period);
+            $currentStart                  = Navigation::addPeriod($currentStart, $period);
             // $currentStart->addDay();
         }
         $this->chartData[] = $currentSet;
diff --git a/composer.lock b/composer.lock
index 8d70cb94a3..107a80b8ba 100644
--- a/composer.lock
+++ b/composer.lock
@@ -5824,20 +5824,20 @@
         },
         {
             "name": "ramsey/uuid",
-            "version": "4.9.1",
+            "version": "4.9.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ramsey/uuid.git",
-                "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440"
+                "reference": "8429c78ca35a09f27565311b98101e2826affde0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440",
-                "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0",
+                "reference": "8429c78ca35a09f27565311b98101e2826affde0",
                 "shasum": ""
             },
             "require": {
-                "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14",
+                "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14",
                 "php": "^8.0",
                 "ramsey/collection": "^1.2 || ^2.0"
             },
@@ -5896,9 +5896,9 @@
             ],
             "support": {
                 "issues": "https://github.com/ramsey/uuid/issues",
-                "source": "https://github.com/ramsey/uuid/tree/4.9.1"
+                "source": "https://github.com/ramsey/uuid/tree/4.9.2"
             },
-            "time": "2025-09-04T20:59:21+00:00"
+            "time": "2025-12-14T04:43:48+00:00"
         },
         {
             "name": "rcrowe/twigbridge",
diff --git a/config/firefly.php b/config/firefly.php
index 34123e1e02..3ccdf90c5f 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
         'running_balance_column' => env('USE_RUNNING_BALANCE', false),
         // see cer.php for exchange rates feature flag.
     ],
-    'version'                              => 'develop/2025-12-13',
-    'build_time'                           => 1765602694,
+    'version'                              => 'develop/2025-12-14',
+    'build_time'                           => 1765725141,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 
diff --git a/package-lock.json b/package-lock.json
index 48e7661223..3e62e64b75 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3176,9 +3176,9 @@
             "license": "MIT"
         },
         "node_modules/@types/node": {
-            "version": "25.0.1",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.1.tgz",
-            "integrity": "sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==",
+            "version": "25.0.2",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.2.tgz",
+            "integrity": "sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -4403,6 +4403,13 @@
             "dev": true,
             "license": "MIT"
         },
+        "node_modules/buffer/node_modules/isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/builtin-status-codes": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@@ -6630,6 +6637,16 @@
                 "node": ">=8"
             }
         },
+        "node_modules/globby/node_modules/slash": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+            "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/gopd": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -7475,10 +7492,9 @@
             }
         },
         "node_modules/isarray": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
-            "dev": true,
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+            "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
             "license": "MIT"
         },
         "node_modules/isexe": {
@@ -7588,12 +7604,6 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
-        "node_modules/json-stable-stringify/node_modules/isarray": {
-            "version": "2.0.5",
-            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
-            "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
-            "license": "MIT"
-        },
         "node_modules/json5": {
             "version": "2.2.3",
             "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -8773,15 +8783,6 @@
                 "npm": ">5"
             }
         },
-        "node_modules/patch-package/node_modules/slash": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
-            "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
-            "license": "MIT",
-            "engines": {
-                "node": ">=6"
-            }
-        },
         "node_modules/path-browserify": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
@@ -9768,6 +9769,13 @@
                 "util-deprecate": "~1.0.1"
             }
         },
+        "node_modules/readable-stream/node_modules/isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/readable-stream/node_modules/safe-buffer": {
             "version": "5.1.2",
             "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -10684,13 +10692,12 @@
             "license": "ISC"
         },
         "node_modules/slash": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-            "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-            "dev": true,
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+            "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
             "license": "MIT",
             "engines": {
-                "node": ">=8"
+                "node": ">=6"
             }
         },
         "node_modules/sockjs": {
@@ -11244,13 +11251,6 @@
                 "node": ">= 0.4"
             }
         },
-        "node_modules/to-buffer/node_modules/isarray": {
-            "version": "2.0.5",
-            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
-            "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
-            "dev": true,
-            "license": "MIT"
-        },
         "node_modules/to-regex-range": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",

From 564dcb1c6db81d926fa9c50167c66c4a9b7c3025 Mon Sep 17 00:00:00 2001
From: James Cole 
Date: Sun, 14 Dec 2025 19:09:08 +0100
Subject: [PATCH 26/27] Expand changelog.

---
 changelog.md | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/changelog.md b/changelog.md
index ff77631060..f431f2a866 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,7 +3,24 @@
 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
+## v6.4.10 - 2025-12-15
+
+### Added
+
+- Added amount event audit log
+
+### Fixed
+
+- #11328
+- #11329
+- #11333
+- #11313
+- #11323
+- #11337
+- #11346
+- #11310
+
+## 6.4.9 - 2025-11-28
 
 ### Fixed
 

From f60c64c9c17a6c88cb1a93c740743b7ad35da4b3 Mon Sep 17 00:00:00 2001
From: JC5 
Date: Sun, 14 Dec 2025 19:13:09 +0100
Subject: [PATCH 27/27] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?=
 =?UTF-8?q?ase=20'v6.4.10'=20on=202025-12-14?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 changelog.md       | 16 ++++++++--------
 config/firefly.php |  4 ++--
 package-lock.json  | 21 +++++----------------
 3 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/changelog.md b/changelog.md
index f431f2a866..7fae697214 100644
--- a/changelog.md
+++ b/changelog.md
@@ -11,14 +11,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Fixed
 
-- #11328
-- #11329
-- #11333
-- #11313
-- #11323
-- #11337
-- #11346
-- #11310
+- [Issue 11328](https://github.com/firefly-iii/firefly-iii/issues/11328) (Three budget / account display bugs in latest version (annual budget + account list balance)) reported by @qingxianaaa
+- [Issue 11329](https://github.com/firefly-iii/firefly-iii/issues/11329) (Imported and auto-converted transfer from different currency issue) reported by @bozho
+- [Issue 11333](https://github.com/firefly-iii/firefly-iii/issues/11333) (Prepared statement contains too many placeholders) reported by @wendyliga
+- [Issue 11313](https://github.com/firefly-iii/firefly-iii/issues/11313) (Stop Processing and Executing Rule Group on Existing Transaction) reported by @watertrainer
+- [Discussion 11323](https://github.com/orgs/firefly-iii/discussions/11323) (File ownership problem) started by @enboig
+- [Issue 11337](https://github.com/firefly-iii/firefly-iii/issues/11337) (email notifications are sent to old email address after changing it through the web UI) reported by @xsolinsx
+- [Issue 11346](https://github.com/firefly-iii/firefly-iii/issues/11346) (Running balance restart from zero for no reason) reported by @Arkarr
+- [Issue 11310](https://github.com/firefly-iii/firefly-iii/issues/11310) (Period parameter doesn't work in API) reported by @kvdb06
 
 ## 6.4.9 - 2025-11-28
 
diff --git a/config/firefly.php b/config/firefly.php
index 3ccdf90c5f..ae6ed1147f 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
         'running_balance_column' => env('USE_RUNNING_BALANCE', false),
         // see cer.php for exchange rates feature flag.
     ],
-    'version'                              => 'develop/2025-12-14',
-    'build_time'                           => 1765725141,
+    'version'                              => '6.4.10',
+    'build_time'                           => 1765735883,
     'api_version'                          => '2.1.0', // field is no longer used.
     'db_version'                           => 28, // field is no longer used.
 
diff --git a/package-lock.json b/package-lock.json
index 3e62e64b75..75c6368a1b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3910,9 +3910,9 @@
             "license": "MIT"
         },
         "node_modules/autoprefixer": {
-            "version": "10.4.22",
-            "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz",
-            "integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==",
+            "version": "10.4.23",
+            "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz",
+            "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==",
             "dev": true,
             "funding": [
                 {
@@ -3930,10 +3930,9 @@
             ],
             "license": "MIT",
             "dependencies": {
-                "browserslist": "^4.27.0",
-                "caniuse-lite": "^1.0.30001754",
+                "browserslist": "^4.28.1",
+                "caniuse-lite": "^1.0.30001760",
                 "fraction.js": "^5.3.4",
-                "normalize-range": "^0.1.2",
                 "picocolors": "^1.1.1",
                 "postcss-value-parser": "^4.2.0"
             },
@@ -8429,16 +8428,6 @@
                 "node": ">=0.10.0"
             }
         },
-        "node_modules/normalize-range": {
-            "version": "0.1.2",
-            "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-            "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
-            "dev": true,
-            "license": "MIT",
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
         "node_modules/normalize-url": {
             "version": "6.1.0",
             "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",