mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Compare commits
	
		
			92 Commits
		
	
	
		
			develop-20
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | d38c59c5b1 | ||
|  | a4205afb7b | ||
|  | 75e187ee34 | ||
|  | a37ed82bb4 | ||
|  | a7233de561 | ||
|  | e87c5eee6b | ||
|  | 7a75290709 | ||
|  | 981f6df9ee | ||
|  | c4572c66d3 | ||
|  | 8e7d750a5a | ||
|  | 94961466f9 | ||
|  | 0f3fe45b06 | ||
|  | 0650457ea5 | ||
|  | 2e1ce03f13 | ||
|  | 9b345db623 | ||
|  | c1afcc5219 | ||
|  | fb394b7f45 | ||
|  | 381598f1bb | ||
|  | 25b7a76da9 | ||
|  | 4b03ebe3cb | ||
|  | 664c59136a | ||
|  | 27b61aae73 | ||
|  | d90fcd1889 | ||
|  | 979d5c579b | ||
|  | 5124ca1738 | ||
|  | ac5d9b656a | ||
|  | 9a02739251 | ||
|  | 4af2aadc48 | ||
|  | 84779b8d02 | ||
|  | 145e8d23f0 | ||
|  | d0ba0583a5 | ||
|  | 17d8b54280 | ||
|  | 2cf0bfe3c4 | ||
|  | 070a8cf148 | ||
|  | f94c21446a | ||
|  | 1ef1873016 | ||
|  | 32e4e29e7c | ||
|  | 65ca0dd9e0 | ||
|  | 3385e12c01 | ||
|  | 3566a4afa3 | ||
|  | 68ff033342 | ||
|  | f141b0be5c | ||
|  | d399dd160f | ||
|  | 4c8ed784cd | ||
|  | fb3402acd4 | ||
|  | 8cad430816 | ||
|  | 01502b456e | ||
|  | 9b6314066b | ||
|  | e61dadcbc6 | ||
|  | f7baf5b2fd | ||
|  | 0545826d57 | ||
|  | a29904704c | ||
|  | 899d374222 | ||
|  | 07ff2305fd | ||
|  | ee96dd3ab6 | ||
|  | a766d3a133 | ||
|  | 67545b0371 | ||
|  | 6b86d825ea | ||
|  | 31dbc57e8b | ||
|  | 00050f629c | ||
|  | 3760aabf13 | ||
|  | 22e092b513 | ||
|  | a4f7c90e09 | ||
|  | 4b92ab46a3 | ||
|  | 0573bf2402 | ||
|  | e28e538272 | ||
|  | 6f8f175890 | ||
|  | fbf9ab6c5f | ||
|  | 3c67175e68 | ||
|  | b0d25a1d33 | ||
|  | 9ea8709835 | ||
|  | ae22c59f21 | ||
|  | 12b8ba68b3 | ||
|  | 6b086c9bff | ||
|  | 546a1198a1 | ||
|  | 1001e04b63 | ||
|  | 2c96729d76 | ||
|  | 194d22ad90 | ||
|  | 51e86448c7 | ||
|  | e42107c03c | ||
|  | abd9260193 | ||
|  | 042e2ba97d | ||
|  | d5240f7afd | ||
|  | cda90df995 | ||
|  | 446e855b74 | ||
|  | fb31f25d71 | ||
|  | ba43d8c3f5 | ||
|  | 3924781797 | ||
|  | b99a6a9fc9 | ||
|  | 2967f4d4c7 | ||
|  | 285eeb1d12 | ||
|  | 6374215ebc | 
							
								
								
									
										65
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										65
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -1256,16 +1256,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/console", | ||||
|             "version": "v7.2.5", | ||||
|             "version": "v7.2.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/console.git", | ||||
|                 "reference": "e51498ea18570c062e7df29d05a7003585b19b88" | ||||
|                 "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88", | ||||
|                 "reference": "e51498ea18570c062e7df29d05a7003585b19b88", | ||||
|                 "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", | ||||
|                 "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1329,7 +1329,7 @@ | ||||
|                 "terminal" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/console/tree/v7.2.5" | ||||
|                 "source": "https://github.com/symfony/console/tree/v7.2.6" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1345,7 +1345,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-03-12T08:11:12+00:00" | ||||
|             "time": "2025-04-07T19:09:28+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/deprecation-contracts", | ||||
| @@ -1769,7 +1769,7 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-ctype", | ||||
|             "version": "v1.31.0", | ||||
|             "version": "v1.32.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-ctype.git", | ||||
| @@ -1828,7 +1828,7 @@ | ||||
|                 "portable" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1848,7 +1848,7 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-intl-grapheme", | ||||
|             "version": "v1.31.0", | ||||
|             "version": "v1.32.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-intl-grapheme.git", | ||||
| @@ -1906,7 +1906,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1926,7 +1926,7 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-intl-normalizer", | ||||
|             "version": "v1.31.0", | ||||
|             "version": "v1.32.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-intl-normalizer.git", | ||||
| @@ -1987,7 +1987,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2007,19 +2007,20 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-mbstring", | ||||
|             "version": "v1.31.0", | ||||
|             "version": "v1.32.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-mbstring.git", | ||||
|                 "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" | ||||
|                 "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", | ||||
|                 "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", | ||||
|                 "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "ext-iconv": "*", | ||||
|                 "php": ">=7.2" | ||||
|             }, | ||||
|             "provide": { | ||||
| @@ -2067,7 +2068,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2083,20 +2084,20 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-09-09T11:45:10+00:00" | ||||
|             "time": "2024-12-23T08:48:59+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-php80", | ||||
|             "version": "v1.31.0", | ||||
|             "version": "v1.32.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-php80.git", | ||||
|                 "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" | ||||
|                 "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", | ||||
|                 "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", | ||||
|                 "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2147,7 +2148,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2163,11 +2164,11 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-09-09T11:45:10+00:00" | ||||
|             "time": "2025-01-02T08:10:11+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-php81", | ||||
|             "version": "v1.31.0", | ||||
|             "version": "v1.32.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-php81.git", | ||||
| @@ -2223,7 +2224,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-php81/tree/v1.32.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2449,16 +2450,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/string", | ||||
|             "version": "v7.2.0", | ||||
|             "version": "v7.2.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/string.git", | ||||
|                 "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" | ||||
|                 "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", | ||||
|                 "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", | ||||
|                 "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", | ||||
|                 "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2516,7 +2517,7 @@ | ||||
|                 "utf8" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/string/tree/v7.2.0" | ||||
|                 "source": "https://github.com/symfony/string/tree/v7.2.6" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2532,7 +2533,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-11-13T13:31:26+00:00" | ||||
|             "time": "2025-04-20T20:18:16+00:00" | ||||
|         } | ||||
|     ], | ||||
|     "packages-dev": [], | ||||
|   | ||||
							
								
								
									
										64
									
								
								.ci/rector.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								.ci/rector.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| <?php | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  * rector.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use Rector\Config\RectorConfig; | ||||
| 
 | ||||
| return RectorConfig::configure() | ||||
|                    ->withPaths([ | ||||
| //                                   __DIR__ . '/../app',
 | ||||
| __DIR__ . '/../app/Http', | ||||
| //                                   __DIR__ . '/../bootstrap',
 | ||||
| //                                   __DIR__ . '/../config',
 | ||||
| //                                   __DIR__ . '/../public',
 | ||||
| //                                   __DIR__ . '/../resources',
 | ||||
| //                                   __DIR__ . '/../routes',
 | ||||
| // __DIR__ . '/../tests',
 | ||||
|                                ]) | ||||
|                                                    // uncomment to reach your current PHP version
 | ||||
|                    ->withPhpSets() | ||||
|                    ->withPreparedSets( | ||||
|                        codingStyle        : false, // leave false
 | ||||
|                        privatization: false, // leave false.
 | ||||
|                        naming             : false, // leave false
 | ||||
|                        instanceOf         : true, | ||||
|                        earlyReturn        : false, | ||||
|                        strictBooleans     : false, | ||||
|                        carbon             : false, | ||||
|                        rectorPreset       : false, | ||||
|                        phpunitCodeQuality : false, | ||||
|                        doctrineCodeQuality: false, | ||||
|                        symfonyCodeQuality : false, | ||||
|                        symfonyConfigs     : false | ||||
| 
 | ||||
|                    ) | ||||
|                    ->withComposerBased( | ||||
|                        twig: true, | ||||
|                        doctrine: true, | ||||
|                        phpunit: true, | ||||
|                        symfony: true) | ||||
|                    ->withTypeCoverageLevel(0) | ||||
|                    ->withDeadCodeLevel(0) | ||||
|                    ->withCodeQualityLevel(0) | ||||
|                    ->withImportNames(removeUnusedImports: true);// import statements instead of full classes.
 | ||||
							
								
								
									
										28
									
								
								.ci/rector.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								.ci/rector.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # | ||||
| # phpstan.sh | ||||
| # Copyright (c) 2021 james@firefly-iii.org | ||||
| # | ||||
| # This file is part of Firefly III (https://github.com/firefly-iii). | ||||
| # | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Affero General Public License as | ||||
| # published by the Free Software Foundation, either version 3 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU Affero General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Affero General Public License | ||||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| # Install composer packages | ||||
| #composer install --no-scripts --no-ansi | ||||
|  | ||||
| SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" | ||||
|  | ||||
| $SCRIPT_DIR/../vendor/bin/rector --config $SCRIPT_DIR/rector.php | ||||
| @@ -296,13 +296,6 @@ STATIC_CRON_TOKEN= | ||||
| # However if you know what you're doing you can significantly speed up container start times. | ||||
| # Set each value to true to enable, or false to disable. | ||||
|  | ||||
| # Set this to true to build all locales supported by Firefly III. | ||||
| # This may take quite some time (several minutes) and is generally not recommended. | ||||
| # If you wish to change or alter the list of locales, start your Docker container with | ||||
| # `docker run -v locale.gen:/etc/locale.gen -e DKR_BUILD_LOCALE=true` | ||||
| # and make sure your preferred locales are in your own locale.gen. | ||||
| DKR_BUILD_LOCALE=false | ||||
|  | ||||
| # Check if the SQLite database exists. Can be skipped if you're not using SQLite. | ||||
| # Won't significantly speed up things. | ||||
| DKR_CHECK_SQLITE=true | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -21,5 +21,3 @@ Changes in this pull request: | ||||
| - | ||||
| - | ||||
| - | ||||
| 
 | ||||
| @JC5 | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/close-duplicates.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/close-duplicates.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,7 +13,7 @@ jobs: | ||||
|   close_duplicates: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: github/command@v2.0.0 | ||||
|       - uses: github/command@v2.0.1 | ||||
|         id: command | ||||
|         with: | ||||
|           allowed_contexts: "issue" | ||||
|   | ||||
| @@ -43,6 +43,7 @@ use Illuminate\Support\Facades\Log; | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     use AccountFilter; | ||||
| 
 | ||||
|     // this array only exists to test if the constructor will use it properly.
 | ||||
|     protected array $accepts = ['application/json', 'application/vnd.api+json']; | ||||
| 
 | ||||
|   | ||||
| @@ -65,13 +65,11 @@ class BillController extends Controller | ||||
|         $data     = $request->getData(); | ||||
|         $result   = $this->repository->searchBill($data['query'], $this->parameters->get('limit')); | ||||
|         $filtered = $result->map( | ||||
|             static function (Bill $item) { | ||||
|                 return [ | ||||
|             static fn (Bill $item) => [ | ||||
|                 'id'     => (string) $item->id, | ||||
|                 'name'   => $item->name, | ||||
|                 'active' => $item->active, | ||||
|                 ]; | ||||
|             } | ||||
|             ] | ||||
|         ); | ||||
| 
 | ||||
|         return response()->api($filtered->toArray()); | ||||
|   | ||||
| @@ -65,12 +65,10 @@ class BudgetController extends Controller | ||||
|         $data     = $request->getData(); | ||||
|         $result   = $this->repository->searchBudget($data['query'], $this->parameters->get('limit')); | ||||
|         $filtered = $result->map( | ||||
|             static function (Budget $item) { | ||||
|                 return [ | ||||
|             static fn (Budget $item) => [ | ||||
|                 'id'   => (string) $item->id, | ||||
|                 'name' => $item->name, | ||||
|                 ]; | ||||
|             } | ||||
|             ] | ||||
|         ); | ||||
| 
 | ||||
|         return response()->api($filtered->toArray()); | ||||
|   | ||||
| @@ -65,12 +65,10 @@ class CategoryController extends Controller | ||||
|         $data     = $request->getData(); | ||||
|         $result   = $this->repository->searchCategory($data['query'], $this->parameters->get('limit')); | ||||
|         $filtered = $result->map( | ||||
|             static function (Category $item) { | ||||
|                 return [ | ||||
|             static fn (Category $item) => [ | ||||
|                 'id'   => (string) $item->id, | ||||
|                 'name' => $item->name, | ||||
|                 ]; | ||||
|             } | ||||
|             ] | ||||
|         ); | ||||
| 
 | ||||
|         return response()->api($filtered->toArray()); | ||||
|   | ||||
| @@ -39,11 +39,10 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class TransactionController extends Controller | ||||
| { | ||||
|     protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; | ||||
|     private TransactionGroupRepositoryInterface $groupRepository; | ||||
|     private JournalRepositoryInterface          $repository; | ||||
| 
 | ||||
|     protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; | ||||
| 
 | ||||
|     /** | ||||
|      * TransactionController constructor. | ||||
|      */ | ||||
|   | ||||
| @@ -26,8 +26,8 @@ namespace FireflyIII\Api\V1\Controllers\Chart; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Data\DateRequest; | ||||
| use FireflyIII\Api\V1\Requests\Chart\ChartRequest; | ||||
| use FireflyIII\Api\V1\Requests\Data\DateRequest; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Account; | ||||
| @@ -48,8 +48,8 @@ class AccountController extends Controller | ||||
|     use ApiSupport; | ||||
|     use CollectsAccountsFromFilter; | ||||
| 
 | ||||
|     private AccountRepositoryInterface $repository; | ||||
|     private ChartData                  $chartData; | ||||
|     private AccountRepositoryInterface $repository; | ||||
| 
 | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
| @@ -93,6 +93,47 @@ class AccountController extends Controller | ||||
|         return response()->json($this->chartData->render()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function renderAccountData(array $params, Account $account): void | ||||
|     { | ||||
|         $currency     = $this->repository->getAccountCurrency($account); | ||||
|         if (null === $currency) { | ||||
|             $currency = $this->default; | ||||
|         } | ||||
|         $currentSet   = [ | ||||
|             'label'                   => $account->name, | ||||
| 
 | ||||
|             // the currency that belongs to the account.
 | ||||
|             'currency_id'             => (string) $currency->id, | ||||
|             'currency_code'           => $currency->code, | ||||
|             'currency_symbol'         => $currency->symbol, | ||||
|             'currency_decimal_places' => $currency->decimal_places, | ||||
| 
 | ||||
|             // the default currency of the user (could be the same!)
 | ||||
|             'date'                    => $params['start']->toAtomString(), | ||||
|             'start'                   => $params['start']->toAtomString(), | ||||
|             'end'                     => $params['end']->toAtomString(), | ||||
|             'period'                  => '1D', | ||||
|             'entries'                 => [], | ||||
|         ]; | ||||
|         $currentStart = clone $params['start']; | ||||
|         $range        = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative); | ||||
| 
 | ||||
|         $previous     = array_values($range)[0]['balance']; | ||||
|         while ($currentStart <= $params['end']) { | ||||
|             $format                        = $currentStart->format('Y-m-d'); | ||||
|             $label                         = $currentStart->toAtomString(); | ||||
|             $balance                       = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous; | ||||
|             $previous                      = $balance; | ||||
| 
 | ||||
|             $currentStart->addDay(); | ||||
|             $currentSet['entries'][$label] = $balance; | ||||
|         } | ||||
|         $this->chartData->add($currentSet); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
 | ||||
| @@ -162,45 +203,4 @@ class AccountController extends Controller | ||||
| 
 | ||||
|         return response()->json($chartData); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function renderAccountData(array $params, Account $account): void | ||||
|     { | ||||
|         $currency     = $this->repository->getAccountCurrency($account); | ||||
|         if (null === $currency) { | ||||
|             $currency = $this->default; | ||||
|         } | ||||
|         $currentSet   = [ | ||||
|             'label'                          => $account->name, | ||||
| 
 | ||||
|             // the currency that belongs to the account.
 | ||||
|             'currency_id'                    => (string) $currency->id, | ||||
|             'currency_code'                  => $currency->code, | ||||
|             'currency_symbol'                => $currency->symbol, | ||||
|             'currency_decimal_places'        => $currency->decimal_places, | ||||
| 
 | ||||
|             // the default currency of the user (could be the same!)
 | ||||
|             'date'                           => $params['start']->toAtomString(), | ||||
|             'start'                          => $params['start']->toAtomString(), | ||||
|             'end'                            => $params['end']->toAtomString(), | ||||
|             'period'                         => '1D', | ||||
|             'entries'                        => [], | ||||
|         ]; | ||||
|         $currentStart = clone $params['start']; | ||||
|         $range        = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative); | ||||
| 
 | ||||
|         $previous     = array_values($range)[0]['balance']; | ||||
|         while ($currentStart <= $params['end']) { | ||||
|             $format                        = $currentStart->format('Y-m-d'); | ||||
|             $label                         = $currentStart->toAtomString(); | ||||
|             $balance                       = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous; | ||||
|             $previous                      = $balance; | ||||
| 
 | ||||
|             $currentStart->addDay(); | ||||
|             $currentSet['entries'][$label] = $balance; | ||||
|         } | ||||
|         $this->chartData->add($currentSet); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -193,7 +193,7 @@ class BudgetController extends Controller | ||||
|             // var_dump($return);
 | ||||
|             /** @var array $journal */ | ||||
|             foreach ($currentBudgetArray['transaction_journals'] as $journal) { | ||||
|                 $return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']); | ||||
|                 $return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string) $journal['amount']); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @@ -245,13 +245,13 @@ class BudgetController extends Controller | ||||
|         } | ||||
|         $result          = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end); | ||||
|         if (1 === count($result)) { | ||||
|             $compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent'])); | ||||
|             $compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent'])); | ||||
|             if (1 === $compare) { | ||||
|                 // convert this amount into the native currency:
 | ||||
|                 $result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']); | ||||
|                 $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']); | ||||
|             } | ||||
|             if ($compare <= 0) { | ||||
|                 $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent'])); | ||||
|                 $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent'])); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -96,7 +96,7 @@ class CategoryController extends Controller | ||||
|             $currencyId              = (int) $journal['currency_id']; | ||||
|             $currency                = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId); | ||||
|             $currencies[$currencyId] = $currency; | ||||
|             $categoryName            = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name']; | ||||
|             $categoryName            = $journal['category_name'] ?? (string) trans('firefly.no_category'); | ||||
|             $amount                  = app('steam')->positive($journal['amount']); | ||||
|             $key                     = sprintf('%s-%s', $categoryName, $currency->code); | ||||
|             // create arrays
 | ||||
| @@ -114,14 +114,12 @@ class CategoryController extends Controller | ||||
|             ]; | ||||
| 
 | ||||
|             // add monies
 | ||||
|             $return[$key]['amount']  = bcadd($return[$key]['amount'], $amount); | ||||
|             $return[$key]['amount']  = bcadd($return[$key]['amount'], (string) $amount); | ||||
|         } | ||||
|         $return     = array_values($return); | ||||
| 
 | ||||
|         // order by amount
 | ||||
|         usort($return, static function (array $a, array $b) { | ||||
|             return (float) $a['amount'] < (float) $b['amount'] ? 1 : -1; | ||||
|         }); | ||||
|         usort($return, static fn (array $a, array $b) => (float) $a['amount'] < (float) $b['amount'] ? 1 : -1); | ||||
| 
 | ||||
|         return response()->json($this->clean($return)); | ||||
|     } | ||||
|   | ||||
| @@ -40,7 +40,6 @@ use Illuminate\Foundation\Bus\DispatchesJobs; | ||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Routing\Controller as BaseController; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| @@ -64,13 +63,13 @@ abstract class Controller extends BaseController | ||||
| 
 | ||||
|     protected const string CONTENT_TYPE            = 'application/vnd.api+json'; | ||||
|     protected const string JSON_CONTENT_TYPE       = 'application/json'; | ||||
|     protected array               $accepts         = ['application/json', 'application/vnd.api+json']; | ||||
| 
 | ||||
|     /** @var array<int, string> */ | ||||
|     protected array               $allowedSort; | ||||
|     protected ParameterBag $parameters; | ||||
|     protected bool                $convertToNative = false; | ||||
|     protected array $accepts                 = ['application/json', 'application/vnd.api+json']; | ||||
|     protected TransactionCurrency $nativeCurrency; | ||||
|     protected ParameterBag        $parameters; | ||||
| 
 | ||||
|     /** | ||||
|      * Controller constructor. | ||||
|   | ||||
| @@ -30,6 +30,8 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Support\Export\ExportDataGenerator; | ||||
| use Illuminate\Http\Response as LaravelResponse; | ||||
| 
 | ||||
| use function Safe\date; | ||||
| 
 | ||||
| /** | ||||
|  * Class ExportController | ||||
|  */ | ||||
| @@ -88,7 +90,7 @@ class ExportController extends Controller | ||||
|             ->header('Expires', '0') | ||||
|             ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') | ||||
|             ->header('Pragma', 'public') | ||||
|             ->header('Content-Length', (string) strlen($data[$key])) | ||||
|             ->header('Content-Length', (string) strlen((string) $data[$key])) | ||||
|         ; | ||||
| 
 | ||||
|         return $response; | ||||
|   | ||||
| @@ -160,7 +160,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $currencyId, | ||||
|                         'currency_code'    => $journal['currency_code'], | ||||
|                     ]; | ||||
|                     $response[$key]['difference']       = bcadd($response[$key]['difference'], $journal['amount']); | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], (string) $journal['amount']); | ||||
|                     $response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
 | ||||
|                 } | ||||
| 
 | ||||
| @@ -172,7 +172,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $foreignCurrencyId, | ||||
|                         'currency_code'    => $journal['foreign_currency_code'], | ||||
|                     ]; | ||||
|                     $response[$foreignKey]['difference']       = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']); | ||||
|                     $response[$foreignKey]['difference']       = bcadd((string) $response[$foreignKey]['difference'], (string) $journal['foreign_amount']); | ||||
|                     $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
 | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -75,7 +75,7 @@ class PeriodController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
 | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class TagController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; | ||||
| 
 | ||||
|         } | ||||
| @@ -154,7 +154,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $currencyId, | ||||
|                         'currency_code'    => $journal['currency_code'], | ||||
|                     ]; | ||||
|                     $response[$key]['difference']       = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference_float'] = (float) $response[$key]['difference']; | ||||
|                 } | ||||
| 
 | ||||
| @@ -167,8 +167,8 @@ class TagController extends Controller | ||||
|                         'currency_code'    => $journal['foreign_currency_code'], | ||||
|                     ]; | ||||
|                     $response[$foreignKey]['difference']       = bcadd( | ||||
|                         $response[$foreignKey]['difference'], | ||||
|                         app('steam')->positive($journal['foreign_amount']) | ||||
|                         (string) $response[$foreignKey]['difference'], | ||||
|                         (string) app('steam')->positive($journal['foreign_amount']) | ||||
|                     ); | ||||
|                     $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; | ||||
|                 } | ||||
|   | ||||
| @@ -75,7 +75,7 @@ class PeriodController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; | ||||
| 
 | ||||
|         } | ||||
|   | ||||
| @@ -99,7 +99,7 @@ class TagController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; | ||||
| 
 | ||||
|         } | ||||
| @@ -153,7 +153,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $currencyId, | ||||
|                         'currency_code'    => $journal['currency_code'], | ||||
|                     ]; | ||||
|                     $response[$key]['difference']       = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference_float'] = (float) $response[$key]['difference']; | ||||
|                 } | ||||
| 
 | ||||
| @@ -166,8 +166,8 @@ class TagController extends Controller | ||||
|                         'currency_code'    => $journal['foreign_currency_code'], | ||||
|                     ]; | ||||
|                     $response[$foreignKey]['difference']       = bcadd( | ||||
|                         $response[$foreignKey]['difference'], | ||||
|                         app('steam')->positive($journal['foreign_amount']) | ||||
|                         (string) $response[$foreignKey]['difference'], | ||||
|                         (string) app('steam')->positive($journal['foreign_amount']) | ||||
|                     ); | ||||
|                     $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
 | ||||
|                 } | ||||
|   | ||||
| @@ -39,10 +39,8 @@ class DestroyController extends Controller | ||||
| { | ||||
|     use ValidatesUserGroupTrait; | ||||
| 
 | ||||
|     protected array $acceptedRoles   = [UserRoleEnum::OWNER]; | ||||
| 
 | ||||
|     public const string RESOURCE_KEY = 'exchange-rates'; | ||||
| 
 | ||||
|     protected array $acceptedRoles   = [UserRoleEnum::OWNER]; | ||||
|     private ExchangeRateRepositoryInterface $repository; | ||||
| 
 | ||||
|     public function __construct() | ||||
|   | ||||
| @@ -50,9 +50,8 @@ class StoreController extends Controller | ||||
| { | ||||
|     use TransactionFilter; | ||||
| 
 | ||||
|     private TransactionGroupRepositoryInterface $groupRepository; | ||||
| 
 | ||||
|     protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS]; | ||||
|     private TransactionGroupRepositoryInterface $groupRepository; | ||||
| 
 | ||||
|     /** | ||||
|      * TransactionController constructor. | ||||
|   | ||||
| @@ -27,8 +27,8 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
|   | ||||
| @@ -177,9 +177,7 @@ class ListController extends Controller | ||||
| 
 | ||||
|         // filter and paginate list:
 | ||||
|         $collection  = $unfiltered->filter( | ||||
|             static function (Bill $bill) use ($currency) { | ||||
|                 return $bill->transaction_currency_id === $currency->id; | ||||
|             } | ||||
|             static fn (Bill $bill) => $bill->transaction_currency_id === $currency->id | ||||
|         ); | ||||
|         $count       = $collection->count(); | ||||
|         $bills       = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|   | ||||
| @@ -191,14 +191,14 @@ class BasicController extends Controller | ||||
| 
 | ||||
|                     // if it is the native currency already.
 | ||||
|                     if ($entry['currency_id'] === $default->id) { | ||||
|                         $sums[$default->id]['sum'] = bcadd($entry['sum'], $sums[$default->id]['sum']); | ||||
|                         $sums[$default->id]['sum'] = bcadd((string) $entry['sum'], $sums[$default->id]['sum']); | ||||
| 
 | ||||
|                         // don't forget to add it to newExpenses and newIncome
 | ||||
|                         if (0 === $index) { | ||||
|                             $newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], $entry['sum']); | ||||
|                             $newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], (string) $entry['sum']); | ||||
|                         } | ||||
|                         if (1 === $index) { | ||||
|                             $newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], $entry['sum']); | ||||
|                             $newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], (string) $entry['sum']); | ||||
|                         } | ||||
| 
 | ||||
|                         continue; | ||||
| @@ -229,7 +229,7 @@ class BasicController extends Controller | ||||
|                         'currency_decimal_places' => $entry['currency_decimal_places'], | ||||
|                         'sum'                     => '0', | ||||
|                     ]; | ||||
|                     $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $entry['sum']); | ||||
|                     $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], (string) $entry['sum']); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -362,7 +362,7 @@ class BasicController extends Controller | ||||
|                     if (0 === $index) { | ||||
|                         // paid amount
 | ||||
|                         if ($currencyId === $this->nativeCurrency->id) { | ||||
|                             $newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], $item['sum']); | ||||
|                             $newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], (string) $item['sum']); | ||||
| 
 | ||||
|                             continue; | ||||
|                         } | ||||
| @@ -374,7 +374,7 @@ class BasicController extends Controller | ||||
|                     } | ||||
|                     // unpaid amount
 | ||||
|                     if ($currencyId === $this->nativeCurrency->id) { | ||||
|                         $newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], $item['sum']); | ||||
|                         $newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], (string) $item['sum']); | ||||
| 
 | ||||
|                         continue; | ||||
|                     } | ||||
| @@ -397,7 +397,7 @@ class BasicController extends Controller | ||||
|          * @var array $info | ||||
|          */ | ||||
|         foreach ($paidAmount as $info) { | ||||
|             $amount   = bcmul($info['sum'], '-1'); | ||||
|             $amount   = bcmul((string) $info['sum'], '-1'); | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('bills-paid-in-%s', $info['code']), | ||||
|                 'title'                   => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]), | ||||
| @@ -416,7 +416,7 @@ class BasicController extends Controller | ||||
|          * @var array $info | ||||
|          */ | ||||
|         foreach ($unpaidAmount as $info) { | ||||
|             $amount   = bcmul($info['sum'], '-1'); | ||||
|             $amount   = bcmul((string) $info['sum'], '-1'); | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('bills-unpaid-in-%s', $info['code']), | ||||
|                 'title'                   => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]), | ||||
| @@ -513,7 +513,7 @@ class BasicController extends Controller | ||||
|                 continue; | ||||
|             } | ||||
|             $spentInCurrency     = $row['sum']; | ||||
|             $leftToSpend         = bcadd($amount, $spentInCurrency); | ||||
|             $leftToSpend         = bcadd($amount, (string) $spentInCurrency); | ||||
|             $perDay              = '0'; | ||||
|             if (0 !== $days && bccomp($leftToSpend, '0') > -1) { | ||||
|                 $perDay = bcdiv($leftToSpend, (string) $days); | ||||
| @@ -549,8 +549,8 @@ class BasicController extends Controller | ||||
|                 $currencyId          = (int) $row['currency_id']; | ||||
|                 $spentInCurrency     = $row['sum']; | ||||
|                 $perDay              = '0'; | ||||
|                 if (0 !== $days && -1 === bccomp($spentInCurrency, '0')) { | ||||
|                     $perDay = bcdiv($spentInCurrency, (string) $days); | ||||
|                 if (0 !== $days && -1 === bccomp((string) $spentInCurrency, '0')) { | ||||
|                     $perDay = bcdiv((string) $spentInCurrency, (string) $days); | ||||
|                 } | ||||
| 
 | ||||
|                 Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum'])); | ||||
| @@ -631,7 +631,7 @@ class BasicController extends Controller | ||||
|                 continue; | ||||
|             } | ||||
|             $amount   = $data['balance']; | ||||
|             if (0 === bccomp($amount, '0')) { | ||||
|             if (0 === bccomp((string) $amount, '0')) { | ||||
|                 continue; | ||||
|             } | ||||
|             // return stuff
 | ||||
|   | ||||
| @@ -85,7 +85,7 @@ class ChartRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -74,7 +74,7 @@ class MoveTransactionsRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -33,6 +33,8 @@ use Illuminate\Foundation\Http\FormRequest; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Validation\Validator; | ||||
| 
 | ||||
| use function Safe\json_decode; | ||||
| 
 | ||||
| /** | ||||
|  * Class TransactionRequest | ||||
|  */ | ||||
| @@ -74,7 +76,7 @@ class TransactionRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -144,7 +144,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -58,9 +58,7 @@ class StoreRequest extends FormRequest | ||||
|     { | ||||
|         $models = config('firefly.valid_attachment_models'); | ||||
|         $models = array_map( | ||||
|             static function (string $className) { | ||||
|                 return str_replace('FireflyIII\Models\\', '', $className); | ||||
|             }, | ||||
|             static fn (string $className) => str_replace('FireflyIII\Models\\', '', $className), | ||||
|             $models | ||||
|         ); | ||||
|         $models = implode(',', $models); | ||||
|   | ||||
| @@ -60,9 +60,7 @@ class UpdateRequest extends FormRequest | ||||
|     { | ||||
|         $models = config('firefly.valid_attachment_models'); | ||||
|         $models = array_map( | ||||
|             static function (string $className) { | ||||
|                 return str_replace('FireflyIII\Models\\', '', $className); | ||||
|             }, | ||||
|             static fn (string $className) => str_replace('FireflyIII\Models\\', '', $className), | ||||
|             $models | ||||
|         ); | ||||
|         $models = implode(',', $models); | ||||
|   | ||||
| @@ -90,7 +90,7 @@ class Request extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -129,7 +129,7 @@ class StoreRequest extends FormRequest | ||||
|             $failed = false; | ||||
|         } | ||||
|         if ($failed) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -110,7 +110,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -94,7 +94,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -106,7 +106,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -96,7 +96,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -40,16 +40,16 @@ class StoreRequest extends FormRequest | ||||
|         return $this->getCarbonDate('date'); | ||||
|     } | ||||
| 
 | ||||
|     public function getRate(): string | ||||
|     { | ||||
|         return (string) $this->get('rate'); | ||||
|     } | ||||
| 
 | ||||
|     public function getFromCurrency(): TransactionCurrency | ||||
|     { | ||||
|         return TransactionCurrency::where('code', $this->get('from'))->first(); | ||||
|     } | ||||
| 
 | ||||
|     public function getRate(): string | ||||
|     { | ||||
|         return (string) $this->get('rate'); | ||||
|     } | ||||
| 
 | ||||
|     public function getToCurrency(): TransactionCurrency | ||||
|     { | ||||
|         return TransactionCurrency::where('code', $this->get('to'))->first(); | ||||
|   | ||||
| @@ -126,7 +126,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -193,7 +193,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -208,7 +208,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -148,7 +148,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -168,7 +168,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -300,7 +300,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -359,7 +359,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -80,7 +80,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -80,7 +80,7 @@ class UpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -99,7 +99,7 @@ class UserUpdateRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -61,13 +61,11 @@ class CategoryController extends Controller | ||||
|         $queryParameters = $request->getParameters(); | ||||
|         $result          = $this->repository->searchCategory($queryParameters['query'], $queryParameters['size']); | ||||
|         $filtered        = $result->map( | ||||
|             static function (Category $item) { | ||||
|                 return [ | ||||
|             static fn (Category $item) => [ | ||||
|                 'id'    => (string) $item->id, | ||||
|                 'title' => $item->name, | ||||
|                 'meta'  => [], | ||||
|                 ]; | ||||
|             } | ||||
|             ] | ||||
|         ); | ||||
| 
 | ||||
|         return response()->json($filtered); | ||||
|   | ||||
| @@ -61,15 +61,13 @@ class TagController extends Controller | ||||
|         $queryParameters = $request->getParameters(); | ||||
|         $result          = $this->repository->searchTag($queryParameters['query']); | ||||
|         $filtered        = $result->map( | ||||
|             static function (Tag $item) { | ||||
|                 return [ | ||||
|             static fn (Tag $item) => [ | ||||
|                 'id'    => (string) $item->id, | ||||
|                 'title' => $item->tag, | ||||
|                 'value' => (string) $item->id, | ||||
|                 'label' => $item->tag, | ||||
|                 'meta'  => [], | ||||
|                 ]; | ||||
|             } | ||||
|             ] | ||||
|         ); | ||||
| 
 | ||||
|         return response()->json($filtered); | ||||
|   | ||||
| @@ -212,13 +212,13 @@ class BudgetController extends Controller | ||||
|             foreach ($currentBudgetArray['transaction_journals'] as $journal) { | ||||
|                 // convert the amount to the native currency.
 | ||||
|                 $rate                                = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']); | ||||
|                 $convertedAmount                     = bcmul($journal['amount'], $rate); | ||||
|                 $convertedAmount                     = bcmul((string) $journal['amount'], $rate); | ||||
|                 if ($journal['foreign_currency_id'] === $this->currency->id) { | ||||
|                     $convertedAmount = $journal['foreign_amount']; | ||||
|                 } | ||||
| 
 | ||||
|                 $return[$currencyId]['spent']        = bcadd($return[$currencyId]['spent'], $journal['amount']); | ||||
|                 $return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount); | ||||
|                 $return[$currencyId]['spent']        = bcadd($return[$currencyId]['spent'], (string) $journal['amount']); | ||||
|                 $return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], (string) $convertedAmount); | ||||
|             } | ||||
|         } | ||||
|         $converter->summarize(); | ||||
| @@ -275,15 +275,15 @@ class BudgetController extends Controller | ||||
|         } | ||||
|         $result               = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end); | ||||
|         if (1 === count($result)) { | ||||
|             $compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent'])); | ||||
|             $compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent'])); | ||||
|             if (1 === $compare) { | ||||
|                 // convert this amount into the native currency:
 | ||||
|                 $result[$limitCurrencyId]['left']        = bcadd($limit->amount, $result[$limitCurrencyId]['spent']); | ||||
|                 $result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']); | ||||
|                 $result[$limitCurrencyId]['left']        = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']); | ||||
|                 $result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, (string) $result[$limitCurrencyId]['native_spent']); | ||||
|             } | ||||
|             if ($compare <= 0) { | ||||
|                 $result[$limitCurrencyId]['overspent']        = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent'])); | ||||
|                 $result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent'])); | ||||
|                 $result[$limitCurrencyId]['overspent']        = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent'])); | ||||
|                 $result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, (string) $result[$limitCurrencyId]['native_spent'])); | ||||
|             } | ||||
|         } | ||||
|         $converter->summarize(); | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class CategoryController extends Controller | ||||
|             $currencyId                    = (int) $journal['currency_id']; | ||||
|             $currency                      = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId); | ||||
|             $currencies[$currencyId]       = $currency; | ||||
|             $categoryName                  = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name']; | ||||
|             $categoryName                  = $journal['category_name'] ?? (string) trans('firefly.no_category'); | ||||
|             $amount                        = app('steam')->positive($journal['amount']); | ||||
|             $nativeAmount                  = $converter->convert($default, $currency, $journal['date'], $amount); | ||||
|             $key                           = sprintf('%s-%s', $categoryName, $currency->code); | ||||
| @@ -128,15 +128,13 @@ class CategoryController extends Controller | ||||
|             ]; | ||||
| 
 | ||||
|             // add monies
 | ||||
|             $return[$key]['amount']        = bcadd($return[$key]['amount'], $amount); | ||||
|             $return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], $nativeAmount); | ||||
|             $return[$key]['amount']        = bcadd($return[$key]['amount'], (string) $amount); | ||||
|             $return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], (string) $nativeAmount); | ||||
|         } | ||||
|         $return     = array_values($return); | ||||
| 
 | ||||
|         // order by native amount
 | ||||
|         usort($return, static function (array $a, array $b) { | ||||
|             return (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1; | ||||
|         }); | ||||
|         usort($return, static fn (array $a, array $b) => (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1); | ||||
|         $converter->summarize(); | ||||
| 
 | ||||
|         return response()->json($this->clean($return)); | ||||
|   | ||||
| @@ -33,7 +33,6 @@ use FireflyIII\Transformers\AbstractTransformer; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Routing\Controller as BaseController; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| @@ -56,8 +55,8 @@ class Controller extends BaseController | ||||
| 
 | ||||
|     protected const string CONTENT_TYPE     = 'application/vnd.api+json'; | ||||
|     protected array        $acceptedRoles   = [UserRoleEnum::READ_ONLY]; | ||||
|     protected ParameterBag $parameters; | ||||
|     protected bool         $convertToNative = false; | ||||
|     protected ParameterBag $parameters; | ||||
| 
 | ||||
|     public function __construct() | ||||
|     { | ||||
|   | ||||
| @@ -174,8 +174,8 @@ class BasicController extends Controller | ||||
|          * @var array $info | ||||
|          */ | ||||
|         foreach ($paidAmount as $info) { | ||||
|             $amount       = bcmul($info['sum'], '-1'); | ||||
|             $nativeAmount = bcmul($info['native_sum'], '-1'); | ||||
|             $amount       = bcmul((string) $info['sum'], '-1'); | ||||
|             $nativeAmount = bcmul((string) $info['native_sum'], '-1'); | ||||
|             $return[]     = [ | ||||
|                 'key'                     => sprintf('bills-paid-in-%s', $info['currency_code']), | ||||
|                 'value'                   => $amount, | ||||
| @@ -198,8 +198,8 @@ class BasicController extends Controller | ||||
|          * @var array $info | ||||
|          */ | ||||
|         foreach ($unpaidAmount as $info) { | ||||
|             $amount       = bcmul($info['sum'], '-1'); | ||||
|             $nativeAmount = bcmul($info['native_sum'], '-1'); | ||||
|             $amount       = bcmul((string) $info['sum'], '-1'); | ||||
|             $nativeAmount = bcmul((string) $info['native_sum'], '-1'); | ||||
|             $return[]     = [ | ||||
|                 'key'                     => sprintf('bills-unpaid-in-%s', $info['currency_code']), | ||||
|                 'value'                   => $amount, | ||||
| @@ -279,8 +279,8 @@ class BasicController extends Controller | ||||
|                     if ((int) $journal['foreign_currency_id'] === $default->id) { | ||||
|                         $amountNative = $journal['foreign_amount']; | ||||
|                     } | ||||
|                     $spent                   = bcadd($spent, $amount); | ||||
|                     $spentNative             = bcadd($spentNative, $amountNative); | ||||
|                     $spent                   = bcadd($spent, (string) $amount); | ||||
|                     $spentNative             = bcadd($spentNative, (string) $amountNative); | ||||
|                 } | ||||
|                 app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent)); | ||||
|             } | ||||
|   | ||||
| @@ -84,7 +84,7 @@ class BalanceChartRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -86,7 +86,7 @@ class ChartRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -83,7 +83,7 @@ class DashboardChartRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -311,7 +311,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -64,6 +64,7 @@ class UpdateRequest extends Request | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     #[\Override]
 | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__)); | ||||
| @@ -247,6 +248,7 @@ class UpdateRequest extends Request | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      */ | ||||
|     #[\Override]
 | ||||
|     public function rules(): array | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__)); | ||||
| @@ -330,6 +332,7 @@ class UpdateRequest extends Request | ||||
|     /** | ||||
|      * Configure the validator instance. | ||||
|      */ | ||||
|     #[\Override]
 | ||||
|     public function withValidator(Validator $validator): void | ||||
|     { | ||||
|         app('log')->debug('Now in withValidator'); | ||||
| @@ -361,7 +364,7 @@ class UpdateRequest extends Request | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -75,6 +75,65 @@ class CorrectsAmounts extends Command | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     private function correctTransfers(): void | ||||
|     { | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $type       = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first(); | ||||
|         $journals   = TransactionJournal::where('transaction_type_id', $type->id)->get(); | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $repository->setUser($journal->user); | ||||
|             $native         = Amount::getNativeCurrencyByUserGroup($journal->userGroup); | ||||
| 
 | ||||
|             /** @var null|Transaction $source */ | ||||
|             $source         = $journal->transactions()->where('amount', '<', 0)->first(); | ||||
| 
 | ||||
|             /** @var null|Transaction $destination */ | ||||
|             $destination    = $journal->transactions()->where('amount', '>', 0)->first(); | ||||
|             if (null === $source || null === $destination) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) { | ||||
|                 continue; | ||||
|             } | ||||
|             $sourceAccount  = $source->account; | ||||
|             $destAccount    = $destination->account; | ||||
|             if (null === $sourceAccount || null === $destAccount) { | ||||
|                 continue; | ||||
|             } | ||||
|             $sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native; | ||||
|             $destCurrency   = $repository->getAccountCurrency($destAccount) ?? $native; | ||||
| 
 | ||||
|             if ($sourceCurrency->id === $destCurrency->id) { | ||||
|                 Log::debug('Both accounts have the same currency. Removing foreign currency info.'); | ||||
|                 $source->foreign_currency_id      = null; | ||||
|                 $source->foreign_amount           = null; | ||||
|                 $source->save(); | ||||
|                 $destination->foreign_currency_id = null; | ||||
|                 $destination->foreign_amount      = null; | ||||
|                 $destination->save(); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             // validate source
 | ||||
|             if ($destCurrency->id !== $source->foreign_currency_id) { | ||||
|                 Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code)); | ||||
|                 $source->foreign_currency_id = $destCurrency->id; | ||||
|                 $source->save(); | ||||
|             } | ||||
| 
 | ||||
|             // validate destination:
 | ||||
|             if ($sourceCurrency->id !== $destination->foreign_currency_id) { | ||||
|                 Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code)); | ||||
|                 $destination->foreign_currency_id = $sourceCurrency->id; | ||||
|                 $destination->save(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private function fixAutoBudgets(): void | ||||
|     { | ||||
|         $count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]); | ||||
| @@ -175,7 +234,7 @@ class CorrectsAmounts extends Command | ||||
|     { | ||||
|         try { | ||||
|             $check = bccomp((string) $item->trigger_value, '0'); | ||||
|         } catch (\ValueError $e) { | ||||
|         } catch (\ValueError) { | ||||
|             $this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value)); | ||||
|             $item->rule->active = false; | ||||
|             $item->rule->save(); | ||||
| @@ -192,63 +251,4 @@ class CorrectsAmounts extends Command | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     private function correctTransfers(): void | ||||
|     { | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $type       = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first(); | ||||
|         $journals   = TransactionJournal::where('transaction_type_id', $type->id)->get(); | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $repository->setUser($journal->user); | ||||
|             $native         = Amount::getNativeCurrencyByUserGroup($journal->userGroup); | ||||
| 
 | ||||
|             /** @var null|Transaction $source */ | ||||
|             $source         = $journal->transactions()->where('amount', '<', 0)->first(); | ||||
| 
 | ||||
|             /** @var null|Transaction $destination */ | ||||
|             $destination    = $journal->transactions()->where('amount', '>', 0)->first(); | ||||
|             if (null === $source || null === $destination) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) { | ||||
|                 continue; | ||||
|             } | ||||
|             $sourceAccount  = $source->account; | ||||
|             $destAccount    = $destination->account; | ||||
|             if (null === $sourceAccount || null === $destAccount) { | ||||
|                 continue; | ||||
|             } | ||||
|             $sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native; | ||||
|             $destCurrency   = $repository->getAccountCurrency($destAccount) ?? $native; | ||||
| 
 | ||||
|             if ($sourceCurrency->id === $destCurrency->id) { | ||||
|                 Log::debug('Both accounts have the same currency. Removing foreign currency info.'); | ||||
|                 $source->foreign_currency_id      = null; | ||||
|                 $source->foreign_amount           = null; | ||||
|                 $source->save(); | ||||
|                 $destination->foreign_currency_id = null; | ||||
|                 $destination->foreign_amount      = null; | ||||
|                 $destination->save(); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             // validate source
 | ||||
|             if ($destCurrency->id !== $source->foreign_currency_id) { | ||||
|                 Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code)); | ||||
|                 $source->foreign_currency_id = $destCurrency->id; | ||||
|                 $source->save(); | ||||
|             } | ||||
| 
 | ||||
|             // validate destination:
 | ||||
|             if ($sourceCurrency->id !== $destination->foreign_currency_id) { | ||||
|                 Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code)); | ||||
|                 $destination->foreign_currency_id = $sourceCurrency->id; | ||||
|                 $destination->save(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -115,9 +115,7 @@ class CorrectsCurrencies extends Command | ||||
|         $found           = array_values( | ||||
|             array_filter( | ||||
|                 $found, | ||||
|                 static function (int $currencyId) { | ||||
|                     return 0 !== $currencyId; | ||||
|                 } | ||||
|                 static fn (int $currencyId) => 0 !== $currencyId | ||||
|             ) | ||||
|         ); | ||||
| 
 | ||||
|   | ||||
| @@ -48,8 +48,8 @@ class CorrectsLongDescriptions extends Command | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             if (strlen($journal->description) > self::MAX_LENGTH) { | ||||
|                 $journal->description = substr($journal->description, 0, self::MAX_LENGTH); | ||||
|             if (strlen((string) $journal->description) > self::MAX_LENGTH) { | ||||
|                 $journal->description = substr((string) $journal->description, 0, self::MAX_LENGTH); | ||||
|                 $journal->save(); | ||||
|                 $this->friendlyWarning(sprintf('Truncated description of transaction journal #%d', $journal->id)); | ||||
|                 ++$count; | ||||
| @@ -61,7 +61,7 @@ class CorrectsLongDescriptions extends Command | ||||
|         /** @var TransactionGroup $group */ | ||||
|         foreach ($groups as $group) { | ||||
|             if (strlen((string) $group->title) > self::MAX_LENGTH) { | ||||
|                 $group->title = substr($group->title, 0, self::MAX_LENGTH); | ||||
|                 $group->title = substr((string) $group->title, 0, self::MAX_LENGTH); | ||||
|                 $group->save(); | ||||
|                 $this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id)); | ||||
|                 ++$count; | ||||
|   | ||||
| @@ -38,8 +38,8 @@ use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Preferences; | ||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; | ||||
| use Illuminate\Console\Command; | ||||
| @@ -128,9 +128,7 @@ class CorrectsNativeAmounts extends Command | ||||
|         $repository->setUserGroup($userGroup); | ||||
|         $set        = $repository->getPiggyBanks(); | ||||
|         $set        = $set->filter( | ||||
|             static function (PiggyBank $piggyBank) use ($currency) { | ||||
|                 return $currency->id !== $piggyBank->transaction_currency_id; | ||||
|             } | ||||
|             static fn (PiggyBank $piggyBank) => $currency->id !== $piggyBank->transaction_currency_id | ||||
|         ); | ||||
|         foreach ($set as $piggyBank) { | ||||
|             $piggyBank->encrypted = false; | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class CorrectsRecurringTransactions extends Command | ||||
|         $destination = $transaction->destinationAccount; | ||||
|         $type        = $recurrence->transactionType; | ||||
|         $link        = config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type)); | ||||
|         if (null !== $link && strtolower($type->type) !== strtolower($link)) { | ||||
|         if (null !== $link && strtolower((string) $type->type) !== strtolower($link)) { | ||||
|             $this->friendlyWarning( | ||||
|                 sprintf('Recurring transaction #%d should be a "%s" but is a "%s" and will be corrected.', $recurrence->id, $link, $type->type) | ||||
|             ); | ||||
|   | ||||
| @@ -115,9 +115,7 @@ class CorrectsTransactionTypes extends Command | ||||
|     private function getSourceAccount(TransactionJournal $journal): Account | ||||
|     { | ||||
|         $collection  = $journal->transactions->filter( | ||||
|             static function (Transaction $transaction) { | ||||
|                 return $transaction->amount < 0; | ||||
|             } | ||||
|             static fn (Transaction $transaction) => $transaction->amount < 0 | ||||
|         ); | ||||
|         if (0 === $collection->count()) { | ||||
|             throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id)); | ||||
| @@ -144,9 +142,7 @@ class CorrectsTransactionTypes extends Command | ||||
|     private function getDestinationAccount(TransactionJournal $journal): Account | ||||
|     { | ||||
|         $collection  = $journal->transactions->filter( | ||||
|             static function (Transaction $transaction) { | ||||
|                 return $transaction->amount > 0; | ||||
|             } | ||||
|             static fn (Transaction $transaction) => $transaction->amount > 0 | ||||
|         ); | ||||
|         if (0 === $collection->count()) { | ||||
|             throw new FireflyException(sprintf('300004: Journal #%d has no destination transaction.', $journal->id)); | ||||
|   | ||||
| @@ -25,9 +25,11 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Models\AccountBalanceCalculator; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| @@ -47,7 +49,12 @@ class CorrectsUnevenAmount extends Command | ||||
|     public function handle(): int | ||||
|     { | ||||
|         $this->count = 0; | ||||
|         // convert transfers with foreign currency info where the amount is NOT uneven (it should be)
 | ||||
|         $this->convertOldStyleTransfers(); | ||||
| 
 | ||||
|         // convert old-style transactions between assets and liabilities.
 | ||||
|         $this->convertOldStyleTransactions(); | ||||
| 
 | ||||
|         $this->fixUnevenAmounts(); | ||||
|         $this->matchCurrencies(); | ||||
|         if (true === config('firefly.feature_flags.running_balance_column')) { | ||||
| @@ -72,8 +79,6 @@ class CorrectsUnevenAmount extends Command | ||||
|         ; | ||||
|         $count        = 0; | ||||
| 
 | ||||
|         Log::debug(sprintf('Found %d potential journal(s)', $transactions->count())); | ||||
| 
 | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($transactions as $transaction) { | ||||
|             /** @var null|TransactionJournal $journal */ | ||||
| @@ -115,10 +120,15 @@ class CorrectsUnevenAmount extends Command | ||||
|                 ++$count; | ||||
|             } | ||||
|         } | ||||
|         if (0 === $count) { | ||||
|             return; | ||||
|         } | ||||
|         $this->friendlyPositive(sprintf('Fixed %d transfer(s) with unbalanced amounts.', $count)); | ||||
|     } | ||||
| 
 | ||||
|     private function fixUnevenAmounts(): void | ||||
|     { | ||||
|         Log::debug('fixUnevenAmounts()'); | ||||
|         $journals = DB::table('transactions') | ||||
|             ->groupBy('transaction_journal_id') | ||||
|             ->whereNull('deleted_at') | ||||
| @@ -184,7 +194,7 @@ class CorrectsUnevenAmount extends Command | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         $amount              = bcmul('-1', $source->amount); | ||||
|         $amount              = bcmul('-1', (string) $source->amount); | ||||
| 
 | ||||
|         // fix amount of destination:
 | ||||
|         /** @var null|Transaction $destination */ | ||||
| @@ -207,8 +217,8 @@ class CorrectsUnevenAmount extends Command | ||||
|         } | ||||
| 
 | ||||
|         // may still be able to salvage this journal if it is a transfer with foreign currency info
 | ||||
|         if ($this->isForeignCurrencyTransfer($journal)) { | ||||
|             Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id)); | ||||
|         if ($this->isForeignCurrencyTransfer($journal) || $this->isBetweenAssetAndLiability($journal)) { | ||||
|             Log::debug(sprintf('Can skip foreign currency transfer / asset+liability transaction #%d.', $journal->id)); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| @@ -249,9 +259,9 @@ class CorrectsUnevenAmount extends Command | ||||
|         //        Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true)));
 | ||||
|         //        Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int)  $source->foreign_currency_id, true)));
 | ||||
| 
 | ||||
|         if (0 === bccomp(app('steam')->positive($source->amount), app('steam')->positive($destination->foreign_amount)) | ||||
|         if (0 === bccomp((string) app('steam')->positive($source->amount), (string) app('steam')->positive($destination->foreign_amount)) | ||||
|             && $source->transaction_currency_id === $destination->foreign_currency_id | ||||
|             && 0 === bccomp(app('steam')->positive($destination->amount), app('steam')->positive($source->foreign_amount)) | ||||
|             && 0 === bccomp((string) app('steam')->positive($destination->amount), (string) app('steam')->positive($source->foreign_amount)) | ||||
|             && (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id | ||||
|         ) { | ||||
|             return true; | ||||
| @@ -271,13 +281,13 @@ class CorrectsUnevenAmount extends Command | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             if (!$this->isForeignCurrencyTransfer($journal)) { | ||||
|             if (!$this->isForeignCurrencyTransfer($journal) && !$this->isBetweenAssetAndLiability($journal)) { | ||||
|                 Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]); | ||||
|                 ++$count; | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id)); | ||||
|             Log::debug(sprintf('Can skip foreign currency transfer or transaction between asset and liability #%d.', $journal->id)); | ||||
|         } | ||||
|         if (0 === $count) { | ||||
|             return; | ||||
| @@ -285,4 +295,155 @@ class CorrectsUnevenAmount extends Command | ||||
| 
 | ||||
|         $this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count())); | ||||
|     } | ||||
| 
 | ||||
|     private function isBetweenAssetAndLiability(TransactionJournal $journal): bool | ||||
|     { | ||||
|         /** @var Transaction $sourceTransaction */ | ||||
|         $sourceTransaction      = $journal->transactions()->where('amount', '<', 0)->first(); | ||||
| 
 | ||||
|         /** @var Transaction $destinationTransaction */ | ||||
|         $destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first(); | ||||
|         if (null === $sourceTransaction || null === $destinationTransaction) { | ||||
|             Log::warning('Either transaction is false, stop.'); | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
|         if (null === $sourceTransaction->foreign_amount || null === $destinationTransaction->foreign_amount) { | ||||
|             Log::warning('Either foreign amount is false, stop.'); | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         $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]; | ||||
| 
 | ||||
|         // source is liability, destination is asset
 | ||||
|         if (in_array($source->accountType->type, $sourceTypes, true) && AccountTypeEnum::ASSET->value === $destination->accountType->type) { | ||||
|             Log::debug('Source is a liability account, destination is an asset account, return TRUE.'); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
|         // source is asset, destination is liability
 | ||||
|         if (in_array($destination->accountType->type, $sourceTypes, true) && AccountTypeEnum::ASSET->value === $source->accountType->type) { | ||||
|             Log::debug('Destination is a liability account, source is an asset account, return TRUE.'); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     private function convertOldStyleTransactions(): void | ||||
|     { | ||||
| 
 | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository   = app(AccountRepositoryInterface::class); | ||||
|         Log::debug('convertOldStyleTransactions()'); | ||||
|         $count        = 0; | ||||
|         $transactions = Transaction::distinct() | ||||
|             ->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id') | ||||
|             ->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id') | ||||
|             ->leftJoin('accounts', 'accounts.id', 'transactions.account_id') | ||||
|             ->leftJoin('account_types', 'account_types.id', 'accounts.account_type_id') | ||||
|             ->whereNot('transaction_types.type', TransactionTypeEnum::TRANSFER->value) | ||||
|             ->whereNotNull('foreign_currency_id') | ||||
|             ->whereNotNull('foreign_amount') | ||||
|             ->whereIn('account_types.type', [AccountTypeEnum::ASSET->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::LOAN->value]) | ||||
|             ->get(['transactions.transaction_journal_id']) | ||||
|         ; | ||||
| 
 | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($transactions as $transaction) { | ||||
|             /** @var null|TransactionJournal $journal */ | ||||
|             $journal        = TransactionJournal::find($transaction->transaction_journal_id); | ||||
|             $repository->setUser($journal->user); | ||||
|             if (null === $journal) { | ||||
|                 Log::debug('Found no journal, continue.'); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             if (!$this->isBetweenAssetAndLiability($journal)) { | ||||
|                 Log::debug('Not between asset and liability, continue.'); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             $source         = $journal->transactions()->where('amount', '<', 0)->first(); | ||||
|             $destination    = $journal->transactions()->where('amount', '>', 0)->first(); | ||||
|             $sourceAccount  = $source->account; | ||||
|             $destAccount    = $destination->account; | ||||
|             $sourceCurrency = $repository->getAccountCurrency($sourceAccount); | ||||
|             $destCurrency   = $repository->getAccountCurrency($destAccount); | ||||
|             if (null === $source || null === $destination) { | ||||
|                 Log::debug('Either transaction is NULL, continue.'); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             if (0 === bccomp($source->amount, $source->foreign_amount) && 0 === bccomp($source->foreign_amount, $source->amount)) { | ||||
|                 Log::debug('Already fixed, continue.'); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             // source transaction. Switch info when does not match.
 | ||||
|             if ((int) $source->transaction_currency_id !== (int) $sourceCurrency->id) { | ||||
|                 Log::debug(sprintf('Ready to swap data in transaction #%d.', $source->id)); | ||||
|                 // swap amounts.
 | ||||
|                 $amount                          = $source->amount; | ||||
|                 $currency                        = $source->transaction_currency_id; | ||||
|                 $source->amount                  = $source->foreign_amount; | ||||
|                 $source->transaction_currency_id = $source->foreign_currency_id; | ||||
|                 $source->foreign_amount          = $amount; | ||||
|                 $source->foreign_currency_id     = $currency; | ||||
|                 $source->saveQuietly(); | ||||
|                 $source->refresh(); | ||||
|                 //                Log::debug(sprintf('source->amount                  = %s', $source->amount));
 | ||||
|                 //                Log::debug(sprintf('source->transaction_currency_id = %s', $source->transaction_currency_id));
 | ||||
|                 //                Log::debug(sprintf('source->foreign_amount          = %s', $source->foreign_amount));
 | ||||
|                 //                Log::debug(sprintf('source->foreign_currency_id     = %s', $source->foreign_currency_id));
 | ||||
|                 ++$count; | ||||
|             } | ||||
|             // same but for destination
 | ||||
|             if ((int) $destination->transaction_currency_id !== (int) $destCurrency->id) { | ||||
|                 ++$count; | ||||
|                 Log::debug(sprintf('Ready to swap data in transaction #%d.', $destination->id)); | ||||
|                 // swap amounts.
 | ||||
|                 $amount                               = $destination->amount; | ||||
|                 $currency                             = $destination->transaction_currency_id; | ||||
|                 $destination->amount                  = $destination->foreign_amount; | ||||
|                 $destination->transaction_currency_id = $destination->foreign_currency_id; | ||||
|                 $destination->foreign_amount          = $amount; | ||||
|                 $destination->foreign_currency_id     = $currency; | ||||
|                 $destination->balance_dirty           = true; | ||||
|                 $destination->saveQuietly(); | ||||
|                 $destination->refresh(); | ||||
|                 //                Log::debug(sprintf('destination->amount                  = %s', $destination->amount));
 | ||||
|                 //                Log::debug(sprintf('destination->transaction_currency_id = %s', $destination->transaction_currency_id));
 | ||||
|                 //                Log::debug(sprintf('destination->foreign_amount          = %s', $destination->foreign_amount));
 | ||||
|                 //                Log::debug(sprintf('destination->foreign_currency_id     = %s', $destination->foreign_currency_id));
 | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             //            // only fix the destination transaction
 | ||||
|             //            $destination->foreign_currency_id     = $source->transaction_currency_id;
 | ||||
|             //            $destination->foreign_amount          = app('steam')->positive($source->amount);
 | ||||
|             //            $destination->transaction_currency_id = $source->foreign_currency_id;
 | ||||
|             //            $destination->amount                  = app('steam')->positive($source->foreign_amount);
 | ||||
|             //            $destination->balance_dirty           = true;
 | ||||
|             //            $source->balance_dirty                = true;
 | ||||
|             //            $destination->save();
 | ||||
|             //            $source->save();
 | ||||
|             //            $this->friendlyWarning(sprintf('Corrected foreign amounts of transaction #%d.', $journal->id));
 | ||||
|         } | ||||
|         if (0 === $count) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         $this->friendlyPositive(sprintf('Fixed %d journal(s) with unbalanced amounts.', $count)); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -283,7 +283,7 @@ class ExportsData extends Command | ||||
|                 $this->friendlyWarning(sprintf('File "%s" exists already but will be replaced.', $file)); | ||||
|             } | ||||
|             // continue to write to file.
 | ||||
|             file_put_contents($file, $content); | ||||
|             \Safe\file_put_contents($file, $content); | ||||
|             $this->friendlyPositive(sprintf('Wrote %s-export to file "%s".', $key, $file)); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -30,13 +30,6 @@ class ValidatesEnvironmentVariables extends Command | ||||
| { | ||||
|     use ShowsFriendlyMessages; | ||||
| 
 | ||||
|     /** | ||||
|      * The name and signature of the console command. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $signature   = 'integrity:validates-environment-variables'; | ||||
| 
 | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
| @@ -44,6 +37,13 @@ class ValidatesEnvironmentVariables extends Command | ||||
|      */ | ||||
|     protected $description = 'Makes sure you use the correct variables.'; | ||||
| 
 | ||||
|     /** | ||||
|      * The name and signature of the console command. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $signature   = 'integrity:validates-environment-variables'; | ||||
| 
 | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|   | ||||
| @@ -130,7 +130,7 @@ class ForcesDecimalSize extends Command | ||||
|         // if sqlite, add function?
 | ||||
|         if ('sqlite' === (string) config('database.default')) { | ||||
|             DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', static function ($pattern, $value) { | ||||
|                 mb_regex_encoding('UTF-8'); | ||||
|                 \Safe\mb_regex_encoding('UTF-8'); | ||||
|                 $pattern = trim($pattern, '"'); | ||||
| 
 | ||||
|                 return (false !== mb_ereg($pattern, (string) $value)) ? 1 : 0; | ||||
| @@ -234,7 +234,7 @@ class ForcesDecimalSize extends Command | ||||
|         /** @var Builder $query */ | ||||
|         $query             = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') | ||||
|             ->where('account_meta.name', 'currency_id') | ||||
|             ->where('account_meta.data', json_encode((string) $currency->id)) | ||||
|             ->where('account_meta.data', \Safe\json_encode((string) $currency->id)) | ||||
|         ; | ||||
|         $query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { | ||||
|             foreach ($fields as $field) { | ||||
| @@ -338,7 +338,7 @@ class ForcesDecimalSize extends Command | ||||
|             ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') | ||||
|             ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') | ||||
|             ->where('account_meta.name', 'currency_id') | ||||
|             ->where('account_meta.data', json_encode((string) $currency->id)) | ||||
|             ->where('account_meta.data', \Safe\json_encode((string) $currency->id)) | ||||
|             ->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression): void { | ||||
|                 foreach ($fields as $field) { | ||||
|                     $q->orWhere( | ||||
| @@ -394,7 +394,7 @@ class ForcesDecimalSize extends Command | ||||
|             ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') | ||||
|             ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') | ||||
|             ->where('account_meta.name', 'currency_id') | ||||
|             ->where('account_meta.data', json_encode((string) $currency->id)) | ||||
|             ->where('account_meta.data', \Safe\json_encode((string) $currency->id)) | ||||
|             ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { | ||||
|                 foreach ($fields as $field) { | ||||
|                     $q->orWhere( | ||||
| @@ -448,7 +448,7 @@ class ForcesDecimalSize extends Command | ||||
|         $query             = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id') | ||||
|             ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id') | ||||
|             ->where('account_meta.name', 'currency_id') | ||||
|             ->where('account_meta.data', json_encode((string) $currency->id)) | ||||
|             ->where('account_meta.data', \Safe\json_encode((string) $currency->id)) | ||||
|             ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void { | ||||
|                 foreach ($fields as $field) { | ||||
|                     $q->orWhere( | ||||
|   | ||||
| @@ -147,10 +147,7 @@ class OutputsInstructions extends Command | ||||
|      */ | ||||
|     private function showLine(): void | ||||
|     { | ||||
|         $line = '+'; | ||||
|         $line .= str_repeat('-', 78); | ||||
|         $line .= '+'; | ||||
|         $this->line($line); | ||||
|         $this->line(sprintf('+%s+', str_repeat('-', 78))); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -175,6 +172,13 @@ class OutputsInstructions extends Command | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private function donationText(): void | ||||
|     { | ||||
|         $this->boxed('Did you know you can support the development of Firefly III?'); | ||||
|         $this->boxed('You can donate in many ways, like GitHub Sponsors or Patreon.'); | ||||
|         $this->boxed('For more information, please visit https://bit.ly/donate-to-Firefly-III'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Render instructions. | ||||
|      */ | ||||
| @@ -228,11 +232,4 @@ class OutputsInstructions extends Command | ||||
|         $this->boxed(''); | ||||
|         $this->showLine(); | ||||
|     } | ||||
| 
 | ||||
|     private function donationText(): void | ||||
|     { | ||||
|         $this->boxed('Did you know you can support the development of Firefly III?'); | ||||
|         $this->boxed('You can donate in many ways, like GitHub Sponsors or Patreon.'); | ||||
|         $this->boxed('For more information, please visit https://bit.ly/donate-to-Firefly-III'); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -31,13 +31,6 @@ class RecalculatesRunningBalance extends Command | ||||
| { | ||||
|     use ShowsFriendlyMessages; | ||||
| 
 | ||||
|     /** | ||||
|      * The name and signature of the console command. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $signature   = 'firefly-iii:refresh-running-balance {--F|force : Force the execution of this command.}'; | ||||
| 
 | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
| @@ -45,6 +38,13 @@ class RecalculatesRunningBalance extends Command | ||||
|      */ | ||||
|     protected $description = 'Refreshes all running balances. May take a long time to run if forced.'; | ||||
| 
 | ||||
|     /** | ||||
|      * The name and signature of the console command. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $signature   = 'firefly-iii:refresh-running-balance {--F|force : Force the execution of this command.}'; | ||||
| 
 | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|   | ||||
| @@ -63,15 +63,15 @@ class ScansAttachments extends Command | ||||
|                 app('log')->error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage())); | ||||
|                 $decryptedContent = $encryptedContent; | ||||
|             } | ||||
|             $tempFileName     = tempnam(sys_get_temp_dir(), 'FireflyIII'); | ||||
|             $tempFileName     = \Safe\tempnam(sys_get_temp_dir(), 'FireflyIII'); | ||||
|             if (false === $tempFileName) { | ||||
|                 app('log')->error(sprintf('Could not create temporary file for attachment #%d', $attachment->id)); | ||||
| 
 | ||||
|                 exit(1); | ||||
|             } | ||||
|             file_put_contents($tempFileName, $decryptedContent); | ||||
|             $attachment->md5  = (string) md5_file($tempFileName); | ||||
|             $attachment->mime = (string) mime_content_type($tempFileName); | ||||
|             \Safe\file_put_contents($tempFileName, $decryptedContent); | ||||
|             $attachment->md5  = (string) \Safe\md5_file($tempFileName); | ||||
|             $attachment->mime = (string) \Safe\mime_content_type($tempFileName); | ||||
|             $attachment->save(); | ||||
|             $this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id)); | ||||
|         } | ||||
|   | ||||
| @@ -57,7 +57,7 @@ class VerifySecurityAlerts extends Command | ||||
|             return 0; | ||||
|         } | ||||
|         $content = $disk->get('alerts.json'); | ||||
|         $json    = json_decode($content, true, 10); | ||||
|         $json    = \Safe\json_decode($content, true, 10); | ||||
| 
 | ||||
|         /** @var array $array */ | ||||
|         foreach ($json as $array) { | ||||
|   | ||||
| @@ -150,6 +150,23 @@ class Cron extends Command | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private function checkForUpdates(bool $force): void | ||||
|     { | ||||
|         $updateCheck = new UpdateCheckCronjob(); | ||||
|         $updateCheck->setForce($force); | ||||
|         $updateCheck->fire(); | ||||
| 
 | ||||
|         if ($updateCheck->jobErrored) { | ||||
|             $this->friendlyError(sprintf('Error in "update check" cron: %s', $updateCheck->message)); | ||||
|         } | ||||
|         if ($updateCheck->jobFired) { | ||||
|             $this->friendlyInfo(sprintf('"Update check" cron fired: %s', $updateCheck->message)); | ||||
|         } | ||||
|         if ($updateCheck->jobSucceeded) { | ||||
|             $this->friendlyPositive(sprintf('"Update check" cron ran with success: %s', $updateCheck->message)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
| @@ -221,21 +238,4 @@ class Cron extends Command | ||||
|             $this->friendlyPositive(sprintf('"Send bill warnings" cron ran with success: %s', $autoBudget->message)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private function checkForUpdates(bool $force): void | ||||
|     { | ||||
|         $updateCheck = new UpdateCheckCronjob(); | ||||
|         $updateCheck->setForce($force); | ||||
|         $updateCheck->fire(); | ||||
| 
 | ||||
|         if ($updateCheck->jobErrored) { | ||||
|             $this->friendlyError(sprintf('Error in "update check" cron: %s', $updateCheck->message)); | ||||
|         } | ||||
|         if ($updateCheck->jobFired) { | ||||
|             $this->friendlyInfo(sprintf('"Update check" cron fired: %s', $updateCheck->message)); | ||||
|         } | ||||
|         if ($updateCheck->jobSucceeded) { | ||||
|             $this->friendlyPositive(sprintf('"Update check" cron ran with success: %s', $updateCheck->message)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -167,7 +167,7 @@ class RemovesDatabaseDecryption extends Command | ||||
|     { | ||||
|         // try to json_decrypt the value.
 | ||||
|         try { | ||||
|             $newValue = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value; | ||||
|             $newValue = \Safe\json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value; | ||||
|         } catch (\JsonException $e) { | ||||
|             $message = sprintf('Could not JSON decode preference row #%d: %s. This does not have to be a problem.', $id, $e->getMessage()); | ||||
|             $this->friendlyError($message); | ||||
|   | ||||
| @@ -24,7 +24,14 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Console\Commands\Upgrade; | ||||
| 
 | ||||
| set_time_limit(0); | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Safe\Exceptions\InfoException; | ||||
| 
 | ||||
| try { | ||||
|     \Safe\set_time_limit(0); | ||||
| } catch (InfoException) { | ||||
|     Log::warning('set_time_limit returned false. This could be an issue, unless you also run XDebug.'); | ||||
| } | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use Illuminate\Console\Command; | ||||
|   | ||||
| @@ -32,6 +32,7 @@ use Illuminate\Support\Facades\Artisan; | ||||
| class UpgradesNativeAmounts extends Command | ||||
| { | ||||
|     use ShowsFriendlyMessages; | ||||
| 
 | ||||
|     public const string CONFIG_NAME = '620_native_amounts'; | ||||
| 
 | ||||
|     protected $description          = 'Runs the native amounts calculations.'; | ||||
| @@ -61,7 +62,7 @@ class UpgradesNativeAmounts extends Command | ||||
|     { | ||||
|         $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); | ||||
|         if (null !== $configVar) { | ||||
|             return (bool)$configVar->data; | ||||
|             return (bool) $configVar->data; | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class UpgradesRecurrenceMetaData extends Command | ||||
| 
 | ||||
|         if ('tags' === $meta->name) { | ||||
|             $array = explode(',', $meta->value); | ||||
|             $value = json_encode($array, JSON_THROW_ON_ERROR); | ||||
|             $value = \Safe\json_encode($array, JSON_THROW_ON_ERROR); | ||||
|         } | ||||
| 
 | ||||
|         RecurrenceTransactionMeta::create( | ||||
|   | ||||
| @@ -78,8 +78,8 @@ class UpgradesRuleActions extends Command | ||||
| 
 | ||||
|         /** @var RuleAction $action */ | ||||
|         foreach ($actions as $action) { | ||||
|             if (str_starts_with($action->action_value, '=')) { | ||||
|                 $action->action_value = sprintf('%s%s', '\=', substr($action->action_value, 1)); | ||||
|             if (str_starts_with((string) $action->action_value, '=')) { | ||||
|                 $action->action_value = sprintf('%s%s', '\=', substr((string) $action->action_value, 1)); | ||||
|                 $action->save(); | ||||
|                 ++$count; | ||||
|             } | ||||
|   | ||||
| @@ -179,9 +179,7 @@ class UpgradesToGroups extends Command | ||||
|     private function getDestinationTransactions(TransactionJournal $journal): Collection | ||||
|     { | ||||
|         return $journal->transactions->filter( | ||||
|             static function (Transaction $transaction) { | ||||
|                 return $transaction->amount > 0; | ||||
|             } | ||||
|             static fn (Transaction $transaction) => $transaction->amount > 0 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
| @@ -236,7 +234,7 @@ class UpgradesToGroups extends Command | ||||
|         $categoryId     = $this->getTransactionCategory($transaction, $opposingTr) ?? $categoryId; | ||||
| 
 | ||||
|         return [ | ||||
|             'type'                => strtolower($journal->transactionType->type), | ||||
|             'type'                => strtolower((string) $journal->transactionType->type), | ||||
|             'date'                => $journal->date, | ||||
|             'user'                => $journal->user, | ||||
|             'user_group'          => $journal->user->userGroup, | ||||
|   | ||||
| @@ -46,12 +46,12 @@ class UpgradesTransferCurrencies extends Command | ||||
|     private JournalCLIRepositoryInterface $cliRepos; | ||||
|     private int                           $count; | ||||
| 
 | ||||
|     private ?Account             $destinationAccount; | ||||
|     private ?TransactionCurrency $destinationCurrency; | ||||
|     private ?Transaction         $destinationTransaction; | ||||
|     private ?Account             $sourceAccount; | ||||
|     private ?TransactionCurrency $sourceCurrency; | ||||
|     private ?Transaction         $sourceTransaction; | ||||
|     private ?Account             $destinationAccount     = null; | ||||
|     private ?TransactionCurrency $destinationCurrency    = null; | ||||
|     private ?Transaction         $destinationTransaction = null; | ||||
|     private ?Account             $sourceAccount          = null; | ||||
|     private ?TransactionCurrency $sourceCurrency         = null; | ||||
|     private ?Transaction         $sourceTransaction      = null; | ||||
| 
 | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|   | ||||
| @@ -35,6 +35,7 @@ class Kernel extends ConsoleKernel | ||||
|     /** | ||||
|      * Register the commands for the application. | ||||
|      */ | ||||
|     #[\Override]
 | ||||
|     protected function commands(): void | ||||
|     { | ||||
|         $this->load(__DIR__.'/Commands'); | ||||
| @@ -45,6 +46,7 @@ class Kernel extends ConsoleKernel | ||||
|     /** | ||||
|      * Define the application's command schedule. | ||||
|      */ | ||||
|     #[\Override]
 | ||||
|     protected function schedule(Schedule $schedule): void | ||||
|     { | ||||
|         $schedule->call( | ||||
|   | ||||
| @@ -36,15 +36,10 @@ class InvitationCreated extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public InvitedUser $invitee; | ||||
| 
 | ||||
|     public TransactionGroup $transactionGroup; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      */ | ||||
|     public function __construct(InvitedUser $invitee) | ||||
|     { | ||||
|         $this->invitee = $invitee; | ||||
|     } | ||||
|     public function __construct(public InvitedUser $invitee) {} | ||||
| } | ||||
|   | ||||
| @@ -34,14 +34,11 @@ class DestroyedTransactionGroup extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public TransactionGroup $transactionGroup; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      */ | ||||
|     public function __construct(TransactionGroup $transactionGroup) | ||||
|     public function __construct(public TransactionGroup $transactionGroup) | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__)); | ||||
|         $this->transactionGroup = $transactionGroup; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -34,13 +34,10 @@ class DestroyedTransactionLink extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     private TransactionJournalLink $link; // @phpstan-ignore-line
 | ||||
|     // @phpstan-ignore-line
 | ||||
| 
 | ||||
|     /** | ||||
|      * DestroyedTransactionLink constructor. | ||||
|      */ | ||||
|     public function __construct(TransactionJournalLink $link) | ||||
|     { | ||||
|         $this->link = $link; | ||||
|     } | ||||
|     public function __construct(private TransactionJournalLink $link) {} | ||||
| } | ||||
|   | ||||
| @@ -34,13 +34,8 @@ class DetectedNewIPAddress extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public User $user; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. This event is triggered when a new user registers. | ||||
|      */ | ||||
|     public function __construct(User $user) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|     } | ||||
|     public function __construct(public User $user) {} | ||||
| } | ||||
|   | ||||
| @@ -31,10 +31,5 @@ class Updated | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public Account $account; | ||||
| 
 | ||||
|     public function __construct(Account $account) | ||||
|     { | ||||
|         $this->account = $account; | ||||
|     } | ||||
|     public function __construct(public Account $account) {} | ||||
| } | ||||
|   | ||||
| @@ -35,10 +35,5 @@ class Created extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public BudgetLimit $budgetLimit; | ||||
| 
 | ||||
|     public function __construct(BudgetLimit $budgetLimit) | ||||
|     { | ||||
|         $this->budgetLimit = $budgetLimit; | ||||
|     } | ||||
|     public function __construct(public BudgetLimit $budgetLimit) {} | ||||
| } | ||||
|   | ||||
| @@ -35,10 +35,5 @@ class Deleted extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public BudgetLimit $budgetLimit; | ||||
| 
 | ||||
|     public function __construct(BudgetLimit $budgetLimit) | ||||
|     { | ||||
|         $this->budgetLimit = $budgetLimit; | ||||
|     } | ||||
|     public function __construct(public BudgetLimit $budgetLimit) {} | ||||
| } | ||||
|   | ||||
| @@ -35,10 +35,5 @@ class Updated extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public BudgetLimit $budgetLimit; | ||||
| 
 | ||||
|     public function __construct(BudgetLimit $budgetLimit) | ||||
|     { | ||||
|         $this->budgetLimit = $budgetLimit; | ||||
|     } | ||||
|     public function __construct(public BudgetLimit $budgetLimit) {} | ||||
| } | ||||
|   | ||||
| @@ -39,18 +39,14 @@ class ChangedAmount extends Event | ||||
| 
 | ||||
|     public string    $amount; | ||||
|     public PiggyBank $piggyBank; | ||||
|     public ?TransactionGroup   $transactionGroup; | ||||
|     public ?TransactionJournal $transactionJournal; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      */ | ||||
|     public function __construct(PiggyBank $piggyBank, string $amount, ?TransactionJournal $transactionJournal, ?TransactionGroup $transactionGroup) | ||||
|     public function __construct(PiggyBank $piggyBank, string $amount, public ?TransactionJournal $transactionJournal, public ?TransactionGroup $transactionGroup) | ||||
|     { | ||||
|         app('log')->debug(sprintf('Created piggy bank event for piggy bank #%d with amount %s', $piggyBank->id, $amount)); | ||||
|         $this->piggyBank = $piggyBank; | ||||
|         $this->transactionJournal = $transactionJournal; | ||||
|         $this->transactionGroup   = $transactionGroup; | ||||
|         $this->amount    = $amount; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -34,15 +34,8 @@ class RuleActionFailedOnArray | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public string     $error; | ||||
|     public array      $journal; | ||||
|     public RuleAction $ruleAction; | ||||
| 
 | ||||
|     public function __construct(RuleAction $ruleAction, array $journal, string $error) | ||||
|     public function __construct(public RuleAction $ruleAction, public array $journal, public string $error) | ||||
|     { | ||||
|         app('log')->debug('Created new RuleActionFailedOnArray'); | ||||
|         $this->ruleAction = $ruleAction; | ||||
|         $this->journal    = $journal; | ||||
|         $this->error      = $error; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -35,15 +35,8 @@ class RuleActionFailedOnObject | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public string             $error; | ||||
|     public TransactionJournal $journal; | ||||
|     public RuleAction         $ruleAction; | ||||
| 
 | ||||
|     public function __construct(RuleAction $ruleAction, TransactionJournal $journal, string $error) | ||||
|     public function __construct(public RuleAction $ruleAction, public TransactionJournal $journal, public string $error) | ||||
|     { | ||||
|         app('log')->debug('Created new RuleActionFailedOnObject'); | ||||
|         $this->ruleAction = $ruleAction; | ||||
|         $this->journal    = $journal; | ||||
|         $this->error      = $error; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -34,14 +34,11 @@ class NewVersionAvailable extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public string $message; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. This event is triggered when a new version is available. | ||||
|      */ | ||||
|     public function __construct(string $message) | ||||
|     public function __construct(public string $message) | ||||
|     { | ||||
|         Log::debug(__METHOD__); | ||||
|         $this->message = $message; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,11 +33,8 @@ class UserGroupChangedDefaultCurrency extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public UserGroup $userGroup; | ||||
| 
 | ||||
|     public function __construct(UserGroup $userGroup) | ||||
|     public function __construct(public UserGroup $userGroup) | ||||
|     { | ||||
|         Log::debug('User group changed default currency.'); | ||||
|         $this->userGroup = $userGroup; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -35,15 +35,8 @@ class RegisteredUser extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public OwnerNotifiable $owner; | ||||
|     public User            $user; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. This event is triggered when a new user registers. | ||||
|      */ | ||||
|     public function __construct(OwnerNotifiable $owner, User $user) | ||||
|     { | ||||
|         $this->user  = $user; | ||||
|         $this->owner = $owner; | ||||
|     } | ||||
|     public function __construct(public OwnerNotifiable $owner, public User $user) {} | ||||
| } | ||||
|   | ||||
| @@ -39,17 +39,12 @@ class RequestedReportOnJournals | ||||
|     use InteractsWithSockets; | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public Collection $groups; | ||||
|     public int        $userId; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      */ | ||||
|     public function __construct(int $userId, Collection $groups) | ||||
|     public function __construct(public int $userId, public Collection $groups) | ||||
|     { | ||||
|         app('log')->debug('In event RequestedReportOnJournals.'); | ||||
|         $this->userId = $userId; | ||||
|         $this->groups = $groups; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|   | ||||
| @@ -34,14 +34,9 @@ class RequestedVersionCheckStatus extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public User $user; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new event instance. This event is triggered when Firefly III wants to know | ||||
|      * what the deal is with the version checker. | ||||
|      */ | ||||
|     public function __construct(User $user) | ||||
|     { | ||||
|         $this->user = $user; | ||||
|     } | ||||
|     public function __construct(public User $user) {} | ||||
| } | ||||
|   | ||||
| @@ -33,14 +33,12 @@ class MFABackupFewLeft extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
| 
 | ||||
|     public int  $count; | ||||
|     public User $user; | ||||
| 
 | ||||
|     public function __construct(null|Authenticatable|User $user, int $count) | ||||
|     public function __construct(null|Authenticatable|User $user, public int $count) | ||||
|     { | ||||
|         if ($user instanceof User) { | ||||
|             $this->user = $user; | ||||
|         } | ||||
|         $this->count = $count; | ||||
|     } | ||||
| } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user