mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 18:54:58 +00:00 
			
		
		
		
	Compare commits
	
		
			221 Commits
		
	
	
		
			develop-20
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2297589dca | ||
|  | 6ada5fa560 | ||
|  | 8f6eefb5e7 | ||
|  | b36a50381b | ||
|  | 51f84b3060 | ||
|  | 72132a19b0 | ||
|  | 065d165211 | ||
|  | 01695b3342 | ||
|  | 3bec106840 | ||
|  | fb01c36be1 | ||
|  | 26d851e69e | ||
|  | 28c18c046b | ||
|  | 318cef7e3b | ||
|  | e8dc8f25be | ||
|  | 10ccc30240 | ||
|  | 5adc877d5e | ||
|  | 30923afb2b | ||
|  | 4eb6813b43 | ||
|  | 7521a31619 | ||
|  | fc05beb452 | ||
|  | 1103428a83 | ||
|  | d06d521bf0 | ||
|  | 8f64f1c0eb | ||
|  | d11c232171 | ||
|  | 93c73248de | ||
|  | 5bed081ab9 | ||
|  | c5188c503e | ||
|  | 98ffcac7b6 | ||
|  | df1e81d611 | ||
|  | 9711170b08 | ||
|  | e43264bdce | ||
|  | e0643bed7a | ||
|  | 7f0eb3b064 | ||
|  | f38e510526 | ||
|  | 25f99b23b2 | ||
|  | 44281fc8a0 | ||
|  | eed3902cb7 | ||
|  | 94a3bb0443 | ||
|  | 8dcc36880e | ||
|  | 695bb31894 | ||
|  | f8ded66869 | ||
|  | 8e4bdbc584 | ||
|  | f7b14b01bc | ||
|  | 705b9bf0f2 | ||
|  | f0226dbc54 | ||
|  | 1b1dfb0d7b | ||
|  | 8ed5092a76 | ||
|  | d609821be6 | ||
|  | cd0201074c | ||
|  | 1d8feec7bc | ||
|  | d941472c84 | ||
|  | 674a118fac | ||
|  | 1334d793f6 | ||
|  | 60354c0202 | ||
|  | 22081d3f0a | ||
|  | 4b3f8fc78d | ||
|  | 4bd1aab86d | ||
|  | 60362cb60c | ||
|  | 27f740bf98 | ||
|  | 5e15747a5b | ||
|  | 8a6eaad2bb | ||
|  | 5ab52d9f66 | ||
|  | 21a327bf08 | ||
|  | 15dd175394 | ||
|  | 3f35305beb | ||
|  | 768d8b1515 | ||
|  | 1c19428a12 | ||
|  | c204533195 | ||
|  | 6d89485792 | ||
|  | 949d818bad | ||
|  | a12e200a0a | ||
|  | b4039b1f13 | ||
|  | 32921e15b1 | ||
|  | 4f7cc7d53b | ||
|  | 0986bfbc34 | ||
|  | 663202bfc6 | ||
|  | 6f63ddf5b0 | ||
|  | a9805b144a | ||
|  | e1b8b9b3ae | ||
|  | d57327fd11 | ||
|  | 15ac69bfad | ||
|  | a5bd28f8d4 | ||
|  | b2516ca1b4 | ||
|  | 053b46ae63 | ||
|  | 6e836aceec | ||
|  | 0e8bcd2e79 | ||
|  | bd1f8b2497 | ||
|  | 19dfcf7139 | ||
|  | ef7a3287bb | ||
|  | 2900049498 | ||
|  | 04d1e8fd59 | ||
|  | 9d2f57e40a | ||
|  | ae366341cc | ||
|  | 3766128cb8 | ||
|  | 950c60d55c | ||
|  | 4b2807de48 | ||
|  | 649736cb31 | ||
|  | 6a121a8a78 | ||
|  | f69b9ac9da | ||
|  | 23d70a2fac | ||
|  | d178ff9de0 | ||
|  | 3ecad3457f | ||
|  | fa6c621968 | ||
|  | df863b6cff | ||
|  | 9316ff3e51 | ||
|  | bfd91f8ee6 | ||
|  | 13e5d25cfe | ||
|  | b13030420b | ||
|  | 44d1e8181c | ||
|  | 63b34c1853 | ||
|  | facd0144cb | ||
|  | 115e3435af | ||
|  | d44cd50768 | ||
|  | 1afcaea4c6 | ||
|  | 2bd1b37717 | ||
|  | 2d37177316 | ||
|  | abb25e2015 | ||
|  | d08d075e30 | ||
|  | b4c67c02a7 | ||
|  | 04fb6a953e | ||
|  | 5dce0bec8e | ||
|  | 481bb3fb0a | ||
|  | b6960dc299 | ||
|  | 73104aae1f | ||
|  | 10a284848b | ||
|  | fd6560bdd0 | ||
|  | 0810f617c7 | ||
|  | c3ffd39450 | ||
|  | 0f69e0d672 | ||
|  | 1aa8ebe57f | ||
|  | 23178614d5 | ||
|  | d2b6829574 | ||
|  | 5602715c96 | ||
|  | 54d0433dd4 | ||
|  | f4bc313d0b | ||
|  | 5617de3a79 | ||
|  | 2d62f0ff06 | ||
|  | 1c79f6b1b6 | ||
|  | bf01153c6b | ||
|  | c43b37baef | ||
|  | d4942efd8e | ||
|  | ea9f635b1a | ||
|  | 7eaa0e16b3 | ||
|  | 1b97d8fd48 | ||
|  | 89a29b9b10 | ||
|  | 2baac1a6d7 | ||
|  | cd296aa9ac | ||
|  | 959d168352 | ||
|  | 6cd60951ba | ||
|  | 3898c0c0ef | ||
|  | fe4d139817 | ||
|  | d95f3ca59f | ||
|  | 7f6c03ce17 | ||
|  | 394d0eabef | ||
|  | a8ae496fda | ||
|  | 1787f4421b | ||
|  | 36351a5dd9 | ||
|  | d009ce31ca | ||
|  | 44eafeeae5 | ||
|  | 21165eb3e0 | ||
|  | 2ef3a33fbf | ||
|  | f74be0402f | ||
|  | a60cb366b2 | ||
|  | 58e2ef187d | ||
|  | ae80fd8578 | ||
|  | c17f2efca6 | ||
|  | 4a185639b9 | ||
|  | dae7e7d507 | ||
|  | e33e3cc40f | ||
|  | 36ec1daf3a | ||
|  | 50aff9cfb6 | ||
|  | 058a0f9fb2 | ||
|  | 0c955efa8b | ||
|  | a62916a63d | ||
|  | af7a4b5d3d | ||
|  | 2ae3929dd6 | ||
|  | ebd30f4861 | ||
|  | afc9ea08f3 | ||
|  | 78f9f7e2dd | ||
|  | c44b827922 | ||
|  | fb30f7ec8f | ||
|  | e878d5ce07 | ||
|  | f727a38b69 | ||
|  | c11a5384da | ||
|  | ed92cbd4b8 | ||
|  | a9ea32772f | ||
|  | 92f5cca65b | ||
|  | 57b064f590 | ||
|  | 9729434926 | ||
|  | 9d9dffee74 | ||
|  | b3f374f4ea | ||
|  | 50e07d422f | ||
|  | 631ed4956a | ||
|  | 0eca1c8d03 | ||
|  | e38e4574ad | ||
|  | be2d3f3637 | ||
|  | 0e3d779e24 | ||
|  | 4d25336d87 | ||
|  | 74f76a2835 | ||
|  | 84560a6f44 | ||
|  | 6fde693e7a | ||
|  | 2e46d9ba33 | ||
|  | e36f8deb08 | ||
|  | 1631b422f1 | ||
|  | b58d809063 | ||
|  | 9e34314dbc | ||
|  | e4aa218b5f | ||
|  | 31722477d4 | ||
|  | ec82105433 | ||
|  | 146e164f04 | ||
|  | 7d37c93988 | ||
|  | 73dffacd9a | ||
|  | d37304fa68 | ||
|  | 62f4da6063 | ||
|  | 760da08ab7 | ||
|  | e68c4d4408 | ||
|  | 46a200aa1f | ||
|  | c422039335 | ||
|  | 5971d155ef | ||
|  | 9e373a9b0d | ||
|  | 4fb61646b4 | 
| @@ -61,6 +61,7 @@ return $config->setRules( | ||||
|         'comment_to_phpdoc'             => false, // breaks phpstan lines in combination with PHPStorm.
 | ||||
|         'type_declaration_spaces'       => false, | ||||
|         'cast_spaces'                   => false, | ||||
|         'phpdoc_to_comment' => false, // do not overrule single line comment style, breaks phpstan.
 | ||||
| 
 | ||||
|         // complex rules
 | ||||
|         'array_syntax'                  => ['syntax' => 'short'], | ||||
|   | ||||
							
								
								
									
										104
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										104
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -406,16 +406,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "friendsofphp/php-cs-fixer", | ||||
|             "version": "v3.66.0", | ||||
|             "version": "v3.68.5", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", | ||||
|                 "reference": "5f5f2a142ff36b93c41885bca29cc5f861c013e6" | ||||
|                 "reference": "7bedb718b633355272428c60736dc97fb96daf27" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/5f5f2a142ff36b93c41885bca29cc5f861c013e6", | ||||
|                 "reference": "5f5f2a142ff36b93c41885bca29cc5f861c013e6", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7bedb718b633355272428c60736dc97fb96daf27", | ||||
|                 "reference": "7bedb718b633355272428c60736dc97fb96daf27", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -432,17 +432,17 @@ | ||||
|                 "react/promise": "^2.0 || ^3.0", | ||||
|                 "react/socket": "^1.0", | ||||
|                 "react/stream": "^1.0", | ||||
|                 "sebastian/diff": "^4.0 || ^5.0 || ^6.0", | ||||
|                 "symfony/console": "^5.4 || ^6.0 || ^7.0", | ||||
|                 "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", | ||||
|                 "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", | ||||
|                 "symfony/finder": "^5.4 || ^6.0 || ^7.0", | ||||
|                 "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", | ||||
|                 "symfony/polyfill-mbstring": "^1.28", | ||||
|                 "symfony/polyfill-php80": "^1.28", | ||||
|                 "symfony/polyfill-php81": "^1.28", | ||||
|                 "symfony/process": "^5.4 || ^6.0 || ^7.0 <7.2", | ||||
|                 "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" | ||||
|                 "sebastian/diff": "^4.0 || ^5.1 || ^6.0", | ||||
|                 "symfony/console": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/finder": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/polyfill-mbstring": "^1.31", | ||||
|                 "symfony/polyfill-php80": "^1.31", | ||||
|                 "symfony/polyfill-php81": "^1.31", | ||||
|                 "symfony/process": "^5.4 || ^6.4 || ^7.2", | ||||
|                 "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "facile-it/paraunit": "^1.3.1 || ^2.4", | ||||
| @@ -454,9 +454,9 @@ | ||||
|                 "php-cs-fixer/accessible-object": "^1.1", | ||||
|                 "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", | ||||
|                 "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", | ||||
|                 "phpunit/phpunit": "^9.6.21 || ^10.5.38 || ^11.4.3", | ||||
|                 "symfony/var-dumper": "^5.4.47 || ^6.4.15 || ^7.1.8", | ||||
|                 "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.1.6" | ||||
|                 "phpunit/phpunit": "^9.6.22 || ^10.5.40 || ^11.5.2", | ||||
|                 "symfony/var-dumper": "^5.4.48 || ^6.4.15 || ^7.2.0", | ||||
|                 "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.2.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "ext-dom": "For handling output formats in XML", | ||||
| @@ -497,7 +497,7 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.66.0" | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.5" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -505,7 +505,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-12-29T13:46:23+00:00" | ||||
|             "time": "2025-01-30T17:00:50+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "psr/container", | ||||
| @@ -734,33 +734,33 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "react/child-process", | ||||
|             "version": "v0.6.5", | ||||
|             "version": "v0.6.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/reactphp/child-process.git", | ||||
|                 "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" | ||||
|                 "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", | ||||
|                 "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", | ||||
|                 "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", | ||||
|                 "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "evenement/evenement": "^3.0 || ^2.0 || ^1.0", | ||||
|                 "php": ">=5.3.0", | ||||
|                 "react/event-loop": "^1.2", | ||||
|                 "react/stream": "^1.2" | ||||
|                 "react/stream": "^1.4" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", | ||||
|                 "react/socket": "^1.8", | ||||
|                 "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", | ||||
|                 "react/socket": "^1.16", | ||||
|                 "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "autoload": { | ||||
|                 "psr-4": { | ||||
|                     "React\\ChildProcess\\": "src" | ||||
|                     "React\\ChildProcess\\": "src/" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
| @@ -797,19 +797,15 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/reactphp/child-process/issues", | ||||
|                 "source": "https://github.com/reactphp/child-process/tree/v0.6.5" | ||||
|                 "source": "https://github.com/reactphp/child-process/tree/v0.6.6" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
|                     "url": "https://github.com/WyriHaximus", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/clue", | ||||
|                     "type": "github" | ||||
|                     "url": "https://opencollective.com/reactphp", | ||||
|                     "type": "open_collective" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2022-09-16T13:41:56+00:00" | ||||
|             "time": "2025-01-01T16:37:48+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "react/dns", | ||||
| @@ -1641,16 +1637,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/finder", | ||||
|             "version": "v7.2.0", | ||||
|             "version": "v7.2.2", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/finder.git", | ||||
|                 "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" | ||||
|                 "reference": "87a71856f2f56e4100373e92529eed3171695cfb" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", | ||||
|                 "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", | ||||
|                 "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", | ||||
|                 "reference": "87a71856f2f56e4100373e92529eed3171695cfb", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1685,7 +1681,7 @@ | ||||
|             "description": "Finds files and directories via an intuitive fluent interface", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/finder/tree/v7.2.0" | ||||
|                 "source": "https://github.com/symfony/finder/tree/v7.2.2" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1701,7 +1697,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-10-23T06:56:12+00:00" | ||||
|             "time": "2024-12-30T19:00:17+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/options-resolver", | ||||
| @@ -2246,16 +2242,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/process", | ||||
|             "version": "v7.1.8", | ||||
|             "version": "v7.2.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/process.git", | ||||
|                 "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892" | ||||
|                 "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/process/zipball/42783370fda6e538771f7c7a36e9fa2ee3a84892", | ||||
|                 "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892", | ||||
|                 "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", | ||||
|                 "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2287,7 +2283,7 @@ | ||||
|             "description": "Executes commands in sub-processes", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/process/tree/v7.1.8" | ||||
|                 "source": "https://github.com/symfony/process/tree/v7.2.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2303,7 +2299,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-11-06T14:23:19+00:00" | ||||
|             "time": "2024-11-06T14:24:19+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/service-contracts", | ||||
| @@ -2390,16 +2386,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/stopwatch", | ||||
|             "version": "v7.2.0", | ||||
|             "version": "v7.2.2", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/stopwatch.git", | ||||
|                 "reference": "696f418b0d722a4225e1c3d95489d262971ca924" | ||||
|                 "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/stopwatch/zipball/696f418b0d722a4225e1c3d95489d262971ca924", | ||||
|                 "reference": "696f418b0d722a4225e1c3d95489d262971ca924", | ||||
|                 "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", | ||||
|                 "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2432,7 +2428,7 @@ | ||||
|             "description": "Provides a way to profile code", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/stopwatch/tree/v7.2.0" | ||||
|                 "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2448,7 +2444,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-09-25T14:21:43+00:00" | ||||
|             "time": "2024-12-18T14:28:33+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/string", | ||||
|   | ||||
| @@ -28,7 +28,7 @@ composer update --quiet | ||||
| rm -f .php-cs-fixer.cache | ||||
| PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \ | ||||
|     --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \ | ||||
|     --format=txt \ | ||||
|     --format=txt -v \ | ||||
|     --allow-risky=yes | ||||
|  | ||||
| EXIT_CODE=$? | ||||
|   | ||||
| @@ -1,61 +1,36 @@ | ||||
| parameters: | ||||
|   scanFiles: | ||||
|     - ../_ide_helper_models.php | ||||
|   universalObjectCratesClasses: | ||||
|     - Illuminate\Database\Eloquent\Model | ||||
|   # TODO: slowly remove these parameters and fix the issues found. | ||||
|   reportUnmatchedIgnoredErrors: false | ||||
|   ignoreErrors: | ||||
|   # TODO: slowly remove these exceptions and fix the issues found. | ||||
|     - '#Dynamic call to static method#' # all the Laravel ORM things depend on this. | ||||
|     - '#Control structures using switch should not be used.#' # switch is fine in some cases. | ||||
|     - '#with no value type specified in iterable type array#' # remove this rule when all other issues are solved. | ||||
|     - '#has no value type specified in iterable type array#' # remove this rule when all other issues are solved. | ||||
|     - '#is not allowed to extend#' | ||||
|     - '#does not specify its types#' | ||||
|     - '#switch is forbidden to use#' | ||||
|     - '#is neither abstract nor final#' | ||||
|     - '#on left side of \?\?\= always exists and is not nullable#' | ||||
|     - '#has a nullable return type declaration#' # perhaps throw errors instead? | ||||
|     - '#with a nullable type declaration#' # decide what action should be if param is null. | ||||
|     - '#with null as default value#' | ||||
|     - | ||||
|         message: '#Constructor in [a-zA-Z0-9\\_]+ has parameter \$[a-zA-Z0-9\\_]+ with default value#' | ||||
|         paths: | ||||
|             - ../app/Exceptions/IntervalException.php | ||||
|             - ../app/Support/Navigation.php | ||||
|     - | ||||
|         message: '#but containers should not be injected#' | ||||
|         paths: | ||||
|             - ../app/Support/Authentication/RemoteUserGuard.php | ||||
|     - | ||||
|         message: '#Function compact\(\) should not be used#' # too useful in template rendering. | ||||
|         paths: | ||||
|             - ../app/Generator/Report/Account/MonthReportGenerator.php | ||||
|             - ../app/Generator/Report/Audit/MonthReportGenerator.php | ||||
|             - ../app/Generator/Report/Budget/MonthReportGenerator.php | ||||
|             - ../app/Generator/Report/Category/MonthReportGenerator.php | ||||
|             - ../app/Generator/Report/Standard/MonthReportGenerator.php | ||||
|             - ../app/Generator/Report/Standard/MultiYearReportGenerator.php | ||||
|             - ../app/Generator/Report/Standard/YearReportGenerator.php | ||||
|             - ../app/Generator/Report/Tag/MonthReportGenerator.php | ||||
|             - ../app/Http/Controllers/Account/*.php | ||||
|             - ../app/Http/Controllers/Admin/*.php | ||||
|             - ../app/Http/Controllers/*.php | ||||
|             - ../app/Support/ExpandedForm.php | ||||
|             - ../app/Support/Form/AccountForm.php | ||||
|             - ../app/Support/Form/CurrencyForm.php | ||||
|             - ../app/Support/Form/FormSupport.php | ||||
|     - | ||||
|         message: '#Either catch a more specific exception#' | ||||
|         paths: | ||||
|             - ../app/Support/Form/FormSupport.php | ||||
|     - ../_ide_helper | ||||
|   paths: | ||||
|     - ../app | ||||
|     - ../database | ||||
|     - ../routes | ||||
|     - ../config | ||||
|     - ../bootstrap/app.php | ||||
|   universalObjectCratesClasses: | ||||
|     - Illuminate\Database\Eloquent\Model | ||||
|   # TODO: slowly remove these parameters and fix the issues found. | ||||
|   reportUnmatchedIgnoredErrors: true | ||||
|   ignoreErrors: | ||||
|   # TODO: slowly remove these exceptions and fix the issues found. | ||||
|     - '#Dynamic call to static method#' # all the Laravel ORM things depend on this. | ||||
|     - identifier: varTag.nativeType | ||||
|     - identifier: varTag.type | ||||
|     - | ||||
|         identifier: larastan.noEnvCallsOutsideOfConfig | ||||
|         path: ../app/Console/Commands/System/CreatesDatabase.php | ||||
|     - identifier: missingType.iterableValue # not interesting enough to fix. | ||||
|     - identifier: missingType.generics # not interesting enough to fix. | ||||
|     - "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#" | ||||
|     - '#expects view-string, string given#' | ||||
|     - '#expects view-string\|null, string given#' | ||||
|  | ||||
|     # phpstan can't handle this so we ignore them. | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#' | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#' | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#' | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#' | ||||
|  | ||||
|   # The level 8 is the highest level. original was 5 | ||||
|   # 7 is more than enough, higher just leaves NULL things. | ||||
|   | ||||
| @@ -325,6 +325,12 @@ USE_RUNNING_BALANCE=false | ||||
| # | ||||
| FIREFLY_III_LAYOUT=v1 | ||||
|  | ||||
| # | ||||
| # Which Query Parser implementation to use for the search rngine and rules | ||||
| # 'new' is experimental, 'legacy' is the classic one | ||||
| # | ||||
| QUERY_PARSER_IMPLEMENTATION=legacy | ||||
|  | ||||
| # | ||||
| # Please make sure this URL matches the external URL of your Firefly III installation. | ||||
| # It is used to validate specific requests and to generate URLs in emails. | ||||
|   | ||||
							
								
								
									
										17
									
								
								.github/label-actions.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/label-actions.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,19 @@ | ||||
| # Configuration for Label Actions - https://github.com/dessant/label-actions | ||||
|  | ||||
| # The `feature` label is added to issues | ||||
| fixed: | ||||
|   issues: | ||||
|     # Post a comment, `{issue-author}` is an optional placeholder | ||||
|     comment: | | ||||
|       Hi there! | ||||
|  | ||||
|       This is an automatic reply. `Share and enjoy` | ||||
|  | ||||
|       This issue has been marked as fixed. Thanks for reporting! A new version will be released in due time. Unfortunately, [I cannot give an estimate](https://docs.firefly-iii.org/references/faq/firefly-iii/general/#when-will-you-release-version-the-next-version), but [the roadmap](https://roadmap.firefly-iii.org/) is available for your reading pleasure. | ||||
|  | ||||
|       There is no need to close the issue. It will be closed automatically. | ||||
|  | ||||
|       Thank you for your contributions. | ||||
| feature: | ||||
|   issues: | ||||
|     # Post a comment, `{issue-author}` is an optional placeholder | ||||
| @@ -10,7 +23,7 @@ feature: | ||||
|  | ||||
|       This is an automatic reply. `Share and enjoy` | ||||
|  | ||||
|       This issue has been marked as a feature request. The requested (new) feature will become a part of Firefly III or the data importer in due course. | ||||
|       This issue has been marked as a feature request. | ||||
|  | ||||
|       If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates. | ||||
|  | ||||
| @@ -41,7 +54,7 @@ enhancement: | ||||
|  | ||||
|       This is an automatic reply. `Share and enjoy` | ||||
|  | ||||
|       This issue has been marked as an enhancement. The requested enhancement to an existing feature will become a part of Firefly III or the data importer in due course. | ||||
|       This issue has been marked as an enhancement. | ||||
|  | ||||
|       If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates. | ||||
|  | ||||
|   | ||||
							
								
								
									
										53
									
								
								.github/mergify.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								.github/mergify.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,56 +8,3 @@ pull_request_rules: | ||||
|       close: | ||||
|         message: Please do not open PR's on the `main` branch, but on the `develop` | ||||
|           branch only. Thank you! | ||||
|   - name: No translations | ||||
|     conditions: | ||||
|       - -author~=^dependabot(|-preview)\[bot\]$ | ||||
|       - base=develop | ||||
|       - or: | ||||
|           - files~=^resources/lang/bg_BG | ||||
|           - files~=^resources/lang/ca_ES | ||||
|           - files~=^resources/lang/cs_CZ | ||||
|           - files~=^resources/lang/da_DK | ||||
|           - files~=^resources/lang/de_DE | ||||
|           - files~=^resources/lang/el_GR | ||||
|           - files~=^resources/lang/en_GB | ||||
|           - files~=^resources/lang/es_ES | ||||
|           - files~=^resources/lang/et_EE | ||||
|           - files~=^resources/lang/fa_IR | ||||
|           - files~=^resources/lang/fi_FI | ||||
|           - files~=^resources/lang/fr_FR | ||||
|           - files~=^resources/lang/he_IL | ||||
|           - files~=^resources/lang/hu_HU | ||||
|           - files~=^resources/lang/id_ID | ||||
|           - files~=^resources/lang/is_IS | ||||
|           - files~=^resources/lang/it_IT | ||||
|           - files~=^resources/lang/ja_JP | ||||
|           - files~=^resources/lang/ko_KR | ||||
|           - files~=^resources/lang/lt_LT | ||||
|           - files~=^resources/lang/nb_NO | ||||
|           - files~=^resources/lang/nl_NL | ||||
|           - files~=^resources/lang/pl_PL | ||||
|           - files~=^resources/lang/pt_BR | ||||
|           - files~=^resources/lang/pt_PT | ||||
|           - files~=^resources/lang/ro_RO | ||||
|           - files~=^resources/lang/ru_RU | ||||
|           - files~=^resources/lang/si_LK | ||||
|           - files~=^resources/lang/sk_SK | ||||
|           - files~=^resources/lang/sl_SI | ||||
|           - files~=^resources/lang/sr_CS | ||||
|           - files~=^resources/lang/sv_SE | ||||
|           - files~=^resources/lang/th_TH | ||||
|           - files~=^resources/lang/tlh_AA | ||||
|           - files~=^resources/lang/tr_TR | ||||
|           - files~=^resources/lang/uk_UA | ||||
|           - files~=^resources/lang/vi_VN | ||||
|           - files~=^resources/lang/zh_CN | ||||
|           - files~=^resources/lang/zh_TW | ||||
|     actions: | ||||
|       comment: | ||||
|         message: > | ||||
|           Please do not submit translated strings in your PR. If you need new | ||||
|           sentences to be translated, add them to the `en_US` language strings. | ||||
|           New or changed translations for other languages can be submitted at | ||||
|           https://crowdin.com/project/firefly-iii | ||||
|  | ||||
|           Thank you! | ||||
|   | ||||
							
								
								
									
										82
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										82
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -58,15 +58,6 @@ jobs: | ||||
|           GITHUB_TOKEN: ${{ github.token }} | ||||
|           CROWDIN_PROJECT_NR: ${{ secrets.CROWDIN_PROJECT_NR }} | ||||
|           CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }} | ||||
|       - name: Cleanup translations | ||||
|         id: cleanup-transactions | ||||
|         uses: JC5/firefly-iii-dev@main | ||||
|         with: | ||||
|           action: 'ff3:crowdin-warning' | ||||
|           output: '' | ||||
|         env: | ||||
|           FIREFLY_III_ROOT: /github/workspace | ||||
|           GH_TOKEN: '' | ||||
|       - name: Cleanup changelog | ||||
|         id: cleanup-changelog | ||||
|         uses: JC5/firefly-iii-dev@main | ||||
| @@ -168,7 +159,7 @@ jobs: | ||||
|  | ||||
|           # if this is a develop build, slightly different variable names. | ||||
|           if [[ "develop" == "$version" ]]; then | ||||
|             [[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0; | ||||
|             #[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0; | ||||
|             releaseName=$version-$(date +'%Y%m%d') | ||||
|             originalName=$releaseName | ||||
|             zipName=FireflyIII-develop.zip | ||||
| @@ -177,7 +168,7 @@ jobs: | ||||
|  | ||||
|           # if this is a branch build, also slightly different variable names. | ||||
|           if [[ "$version" == branch* ]]; then | ||||
|             [[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0; | ||||
|             #[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0; | ||||
|             # branch builds overrule develop | ||||
|             releaseName=$version-$(date +'%Y%m%d') | ||||
|             originalName=$releaseName | ||||
| @@ -229,7 +220,7 @@ jobs: | ||||
|           # describe the development release. | ||||
|           if [[ "develop" == "$version" ]]; then | ||||
|             echo 'Develop release.' | ||||
|             rm output.txt | ||||
|             rm -f output.txt | ||||
|             touch output.txt | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt | ||||
| @@ -244,7 +235,7 @@ jobs: | ||||
|           # describe a branch release | ||||
|           if [[ "$version" == branch* ]]; then | ||||
|             echo 'Branch release.' | ||||
|             rm output.txt | ||||
|             rm -f output.txt | ||||
|             touch output.txt | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
| @@ -257,9 +248,45 @@ jobs: | ||||
|             echo ":warning: Please be careful with this branch pre-release, as it may not work as expected." >> output.txt | ||||
|           fi | ||||
|           # describe the main release | ||||
|           if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]]; then | ||||
|             sudo chown -R runner:docker output.txt | ||||
|           if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then | ||||
|             echo 'Main release.' | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt | ||||
|             echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt | ||||
|             echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|  | ||||
|           fi | ||||
|  | ||||
|           # describe alpha release | ||||
|           if [[ "$version" == *alpha* ]]; then | ||||
|             echo 'ALPHA release.' | ||||
|             rm -f output.txt | ||||
|             touch output.txt | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt | ||||
|             echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt | ||||
|             echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|  | ||||
|           fi | ||||
|  | ||||
|           # describe beta release | ||||
|           if [[ "$version" == *beta* ]]; then | ||||
|             echo 'BETA release.' | ||||
|             rm -f output.txt | ||||
|             touch output.txt | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
| @@ -278,6 +305,7 @@ jobs: | ||||
|             git push origin $releaseName | ||||
|             gh release create $releaseName -p --verify-tag \ | ||||
|               -t "Development release for $(date +'%Y-%m-%d')" \ | ||||
|               --latest=false \ | ||||
|               -F output.txt | ||||
|           fi | ||||
|  | ||||
| @@ -291,6 +319,7 @@ jobs: | ||||
|             git push origin $releaseName | ||||
|             gh release create $releaseName -p --verify-tag \ | ||||
|               -t "Branch release for $(date +'%Y-%m-%d')" \ | ||||
|               --latest=false \ | ||||
|               -F output.txt | ||||
|           fi | ||||
|  | ||||
| @@ -316,7 +345,18 @@ jobs: | ||||
|             echo 'MAIN (real) release' | ||||
|             git tag -a $releaseName -m "Here be changelog" | ||||
|             git push origin $releaseName | ||||
|  | ||||
|             # do not tag as latest when alpha or beta. | ||||
|             if [[ "$version" == *alpha* ]] || [[ "$version" == *beta* ]]; then | ||||
|               echo 'Mark alpha or beta as NOT the latest.' | ||||
|               gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag --latest=false | ||||
|             fi | ||||
|  | ||||
|             # tag as latest when NOT alpha or beta. | ||||
|             if [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then | ||||
|               echo 'Mark prod as the latest.' | ||||
|               gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag | ||||
|             fi | ||||
|  | ||||
|             # add archive files to release | ||||
|             gh release upload $releaseName $zipName | ||||
| @@ -336,12 +376,12 @@ jobs: | ||||
|             gh release upload $releaseName HEAD.txt | ||||
|  | ||||
|             # remove all temporary files | ||||
|             rm output.txt | ||||
|             rm HEAD.txt | ||||
|             rm $zipName | ||||
|             rm $zipName.sha256 | ||||
|             rm $tarName | ||||
|             rm $tarName.sha256 | ||||
|             rm -f output.txt | ||||
|             rm -f HEAD.txt | ||||
|             rm -f $zipName | ||||
|             rm -f $zipName.sha256 | ||||
|             rm -f $tarName | ||||
|             rm -f $tarName.sha256 | ||||
|  | ||||
|             # merge main back into develop | ||||
|             git checkout develop | ||||
|   | ||||
							
								
								
									
										6
									
								
								.github/workflows/sonarcloud.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/sonarcloud.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ on: | ||||
|       - develop | ||||
| env: | ||||
|   DB_CONNECTION: sqlite | ||||
|   APP_KEY: UfpBqqeXx7zpNodsC6yjYQcRfDdm4Bxh | ||||
|   APP_KEY: TestTestTestTestTestTestTestTest | ||||
| jobs: | ||||
|   sonarcloud: | ||||
|     name: SonarCloud | ||||
| @@ -46,7 +46,9 @@ jobs: | ||||
|         run: composer install --prefer-dist --no-interaction --no-progress --no-scripts | ||||
|  | ||||
|       - name: "Create database file" | ||||
|         run: touch storage/database/database.sqlite | ||||
|         run: | | ||||
|           touch storage/database/database.sqlite | ||||
|           wget -q https://github.com/firefly-iii/test-fixtures/raw/refs/heads/main/test-database.sqlite -O storage/database/database.sqlite | ||||
|  | ||||
|       - name: "Upgrades the database to the latest version" | ||||
|         run: php artisan firefly-iii:upgrade-database | ||||
|   | ||||
| @@ -3,7 +3,12 @@ | ||||
| Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated. | ||||
| Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution. | ||||
| 
 | ||||
| ## 2025 | ||||
| - SoftBrix | ||||
| 
 | ||||
| ## 2024 | ||||
| - Sobuno | ||||
| - TasneemTantawy | ||||
| - Antônio Franco | ||||
| - yparitcher | ||||
| - Jhon Pedroza | ||||
|   | ||||
| @@ -29,7 +29,6 @@ use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| @@ -42,6 +41,8 @@ use Illuminate\Http\JsonResponse; | ||||
| 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']; | ||||
| 
 | ||||
|     /** @var array<int, string> */ | ||||
|     private array                      $balanceTypes; | ||||
| @@ -82,15 +83,18 @@ class AccountController extends Controller | ||||
|         $return = []; | ||||
|         $result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit')); | ||||
| 
 | ||||
|         // set date to end-of-day for account balance.
 | ||||
|         $date->endOfDay(); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($result as $account) { | ||||
|             $nameWithBalance = $account->name; | ||||
|             $currency        = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency; | ||||
| 
 | ||||
|             $currency        = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency; | ||||
|             $useCurrency     = $currency; | ||||
|             if (in_array($account->accountType->type, $this->balanceTypes, true)) { | ||||
|                 $balance         = Steam::finalAccountBalance($account, $date); | ||||
|                 $key             = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance'; | ||||
|                 $useCurrency     = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? $this->defaultCurrency : $currency; | ||||
|                 $key             = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance'; | ||||
|                 $useCurrency     = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? $this->nativeCurrency : $currency; | ||||
|                 $amount          = $balance[$key] ?? '0'; | ||||
|                 $nameWithBalance = sprintf( | ||||
|                     '%s (%s)', | ||||
| @@ -116,7 +120,7 @@ class AccountController extends Controller | ||||
|         usort( | ||||
|             $return, | ||||
|             static function (array $left, array $right) { | ||||
|                 $order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE]; | ||||
|                 $order = [AccountTypeEnum::ASSET->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::EXPENSE->value]; | ||||
|                 $posA  = (int) array_search($left['type'], $order, true); | ||||
|                 $posB  = (int) array_search($right['type'], $order, true); | ||||
| 
 | ||||
| @@ -124,6 +128,6 @@ class AccountController extends Controller | ||||
|             } | ||||
|         ); | ||||
| 
 | ||||
|         return response()->json($return); | ||||
|         return response()->api($return); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -74,6 +74,6 @@ class BillController extends Controller | ||||
|             } | ||||
|         ); | ||||
| 
 | ||||
|         return response()->json($filtered->toArray()); | ||||
|         return response()->api($filtered->toArray()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,6 +73,6 @@ class BudgetController extends Controller | ||||
|             } | ||||
|         ); | ||||
| 
 | ||||
|         return response()->json($filtered); | ||||
|         return response()->api($filtered->toArray()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,6 +73,6 @@ class CategoryController extends Controller | ||||
|             } | ||||
|         ); | ||||
| 
 | ||||
|         return response()->json($filtered); | ||||
|         return response()->api($filtered->toArray()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -77,7 +77,7 @@ class CurrencyController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($result); | ||||
|         return response()->api($result); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -103,6 +103,6 @@ class CurrencyController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($result); | ||||
|         return response()->api($result); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -75,6 +75,6 @@ class ObjectGroupController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($return); | ||||
|         return response()->api($return); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -87,7 +87,7 @@ class PiggyBankController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($response); | ||||
|         return response()->api($response); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -124,6 +124,6 @@ class PiggyBankController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($response); | ||||
|         return response()->api($response); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,6 +73,6 @@ class RecurrenceController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($response); | ||||
|         return response()->api($response); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -72,6 +72,6 @@ class RuleController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($response); | ||||
|         return response()->api($response); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -72,6 +72,6 @@ class RuleGroupController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($response); | ||||
|         return response()->api($response); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -75,6 +75,6 @@ class TagController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($array); | ||||
|         return response()->api($array); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -84,7 +84,7 @@ class TransactionController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($array); | ||||
|         return response()->api($array); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -122,6 +122,6 @@ class TransactionController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($array); | ||||
|         return response()->api($array); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -72,6 +72,6 @@ class TransactionTypeController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($array); | ||||
|         return response()->api($array); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -32,6 +32,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Api\ApiSupport; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -80,6 +81,10 @@ class AccountController extends Controller | ||||
|         /** @var Carbon $end */ | ||||
|         $end        = $dates['end']; | ||||
| 
 | ||||
|         // set dates to end of day + start of day:
 | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         // user's preferences
 | ||||
|         $defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray(); | ||||
| 
 | ||||
| @@ -97,8 +102,8 @@ class AccountController extends Controller | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $currency     = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency; | ||||
|             $field        = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance'; | ||||
|             $currency     = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency; | ||||
|             $field        = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance'; | ||||
|             $currentSet   = [ | ||||
|                 'label'                   => $account->name, | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
| @@ -113,7 +118,7 @@ class AccountController extends Controller | ||||
|             ]; | ||||
|             // TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
 | ||||
|             $currentStart = clone $start; | ||||
|             $range        = app('steam')->finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative); | ||||
|             $range        = Steam::finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative); | ||||
|             $previous     = array_values($range)[0][$field]; | ||||
|             while ($currentStart <= $end) { | ||||
|                 $format                        = $currentStart->format('Y-m-d'); | ||||
|   | ||||
| @@ -25,18 +25,25 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use Carbon\Exceptions\InvalidDateException; | ||||
| use Carbon\Exceptions\InvalidFormatException; | ||||
| use FireflyIII\Exceptions\BadHttpHeaderException; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Transformers\V2\AbstractTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||||
| 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; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Symfony\Component\HttpFoundation\Exception\BadRequestException; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| @@ -44,8 +51,8 @@ use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| /** | ||||
|  * Class Controller. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||
|  * @SuppressWarnings("PHPMD.CouplingBetweenObjects") | ||||
|  * @SuppressWarnings("PHPMD.NumberOfChildren") | ||||
|  */ | ||||
| abstract class Controller extends BaseController | ||||
| { | ||||
| @@ -54,12 +61,14 @@ abstract class Controller extends BaseController | ||||
|     use ValidatesRequests; | ||||
| 
 | ||||
|     protected const string CONTENT_TYPE      = 'application/vnd.api+json'; | ||||
|     protected const string JSON_CONTENT_TYPE = 'application/json'; | ||||
| 
 | ||||
|     /** @var array<int, string> */ | ||||
|     protected array        $allowedSort; | ||||
|     protected ParameterBag $parameters; | ||||
|     protected bool        $convertToNative   = false; | ||||
|     protected TransactionCurrency $defaultCurrency; | ||||
|     protected array $accepts                 = ['application/json', 'application/vnd.api+json']; | ||||
|     protected TransactionCurrency $nativeCurrency; | ||||
| 
 | ||||
|     /** | ||||
|      * Controller constructor. | ||||
| @@ -74,11 +83,17 @@ abstract class Controller extends BaseController | ||||
|                 if (auth()->check()) { | ||||
|                     $language              = Steam::getLanguage(); | ||||
|                     $this->convertToNative = Amount::convertToNative(); | ||||
|                     $this->defaultCurrency = Amount::getDefaultCurrency(); | ||||
|                     $this->nativeCurrency  = Amount::getNativeCurrency(); | ||||
|                     app()->setLocale($language); | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 // filter down what this endpoint accepts.
 | ||||
|                 if (!$request->accepts($this->accepts)) { | ||||
|                     throw new BadHttpHeaderException(sprintf('Sorry, Accept header "%s" is not something this endpoint can provide.', $request->header('Accept'))); | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
| @@ -116,7 +131,7 @@ abstract class Controller extends BaseController | ||||
|             if (null !== $date) { | ||||
|                 try { | ||||
|                     $obj = Carbon::parse((string) $date); | ||||
|                 } catch (InvalidDateException|InvalidFormatException $e) { | ||||
|                 } catch (InvalidFormatException $e) { | ||||
|                     // don't care
 | ||||
|                     app('log')->warning( | ||||
|                         sprintf( | ||||
| @@ -142,7 +157,15 @@ abstract class Controller extends BaseController | ||||
|                 $value = null; | ||||
|             } | ||||
|             if (null !== $value) { | ||||
|                 $bag->set($integer, (int) $value); | ||||
|                 $value = (int) $value; | ||||
|                 if ($value < 1) { | ||||
|                     $value = 1; | ||||
|                 } | ||||
|                 if ($value > 2 ** 16) { | ||||
|                     $value = 2 ** 16; | ||||
|                 } | ||||
| 
 | ||||
|                 $bag->set($integer, $value); | ||||
|             } | ||||
|             if (null === $value | ||||
|                 && 'limit' === $integer // @phpstan-ignore-line
 | ||||
| @@ -224,4 +247,45 @@ abstract class Controller extends BaseController | ||||
| 
 | ||||
|         return $manager; | ||||
|     } | ||||
| 
 | ||||
|     final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array | ||||
|     { | ||||
|         $manager  = new Manager(); | ||||
|         $baseUrl  = sprintf('%s/api/v1/', request()->getSchemeAndHttpHost()); | ||||
| 
 | ||||
|         // TODO add stuff to path?
 | ||||
| 
 | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
| 
 | ||||
|         $objects  = $paginator->getCollection(); | ||||
| 
 | ||||
|         // the transformer, at this point, needs to collect information that ALL items in the collection
 | ||||
|         // require, like meta-data and stuff like that, and save it for later.
 | ||||
|         $objects  = $transformer->collectMetaData($objects); | ||||
|         $paginator->setCollection($objects); | ||||
| 
 | ||||
|         $resource = new FractalCollection($objects, $transformer, $key); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| 
 | ||||
|         return $manager->createData($resource)->toArray(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns a JSON API object and returns it. | ||||
|      * | ||||
|      * @param array<int, mixed>|Model $object | ||||
|      */ | ||||
|     final protected function jsonApiObject(string $key, array|Model $object, AbstractTransformer $transformer): array | ||||
|     { | ||||
|         // create some objects:
 | ||||
|         $manager  = new Manager(); | ||||
|         $baseUrl  = sprintf('%s/api/v1', request()->getSchemeAndHttpHost()); | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
| 
 | ||||
|         $transformer->collectMetaData(new Collection([$object])); | ||||
| 
 | ||||
|         $resource = new Item($object, $transformer, $key); | ||||
| 
 | ||||
|         return $manager->createData($resource)->toArray(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -59,7 +59,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function accounts(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -100,7 +100,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function bills(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -115,7 +115,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function budgets(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -130,7 +130,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function categories(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -145,7 +145,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function piggyBanks(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -160,7 +160,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function recurring(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -175,7 +175,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function rules(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
| @@ -190,7 +190,7 @@ class ExportController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function tags(ExportRequest $request): LaravelResponse | ||||
|     { | ||||
|   | ||||
| @@ -70,7 +70,7 @@ class BillController extends Controller | ||||
|         $start           = $request->getStart(); | ||||
|         $end             = $request->getEnd(); | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
|         $response        = []; | ||||
| 
 | ||||
|         // get all bills:
 | ||||
| @@ -133,7 +133,7 @@ class BillController extends Controller | ||||
|         $start           = $request->getStart(); | ||||
|         $end             = $request->getEnd(); | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
|         $response        = []; | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | ||||
|   | ||||
| @@ -48,7 +48,7 @@ class PeriodController extends Controller | ||||
|         $end             = $request->getEnd(); | ||||
|         $response        = []; | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type)
 | ||||
|         $collector       = app(GroupCollectorInterface::class); | ||||
|   | ||||
| @@ -69,7 +69,7 @@ class TagController extends Controller | ||||
|         $end             = $request->getEnd(); | ||||
|         $response        = []; | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | ||||
|         $collector       = app(GroupCollectorInterface::class); | ||||
|   | ||||
| @@ -47,7 +47,7 @@ class PeriodController extends Controller | ||||
|         $end             = $request->getEnd(); | ||||
|         $response        = []; | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type)
 | ||||
|         $collector       = app(GroupCollectorInterface::class); | ||||
|   | ||||
| @@ -69,7 +69,7 @@ class TagController extends Controller | ||||
|         $end             = $request->getEnd(); | ||||
|         $response        = []; | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | ||||
|         $collector       = app(GroupCollectorInterface::class); | ||||
|   | ||||
| @@ -26,8 +26,8 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Transfer; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| @@ -47,11 +47,11 @@ class PeriodController extends Controller | ||||
|         $end             = $request->getEnd(); | ||||
|         $response        = []; | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type)
 | ||||
|         $collector       = app(GroupCollectorInterface::class); | ||||
|         $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $genericSet      = $collector->getExtractedJournals(); | ||||
|         foreach ($genericSet as $journal) { | ||||
|             // currency
 | ||||
|   | ||||
| @@ -26,8 +26,8 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Transfer; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -67,12 +67,12 @@ class TagController extends Controller | ||||
|         $end             = $request->getEnd(); | ||||
|         $response        = []; | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
| 
 | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | ||||
|         $collector       = app(GroupCollectorInterface::class); | ||||
|         $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $collector->withoutTags(); | ||||
| 
 | ||||
|         $genericSet      = $collector->getExtractedJournals(); | ||||
| @@ -128,7 +128,7 @@ class TagController extends Controller | ||||
| 
 | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | ||||
|         $collector  = app(GroupCollectorInterface::class); | ||||
|         $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $collector->setTags($tags); | ||||
|         $genericSet = $collector->getExtractedJournals(); | ||||
| 
 | ||||
|   | ||||
| @@ -25,6 +25,7 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Budget; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Budget; | ||||
| @@ -208,6 +209,8 @@ class ListController extends Controller | ||||
|         $collector    = app(GroupCollectorInterface::class); | ||||
|         $collector | ||||
|             ->setUser($admin) | ||||
|             // withdrawals only
 | ||||
|             ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]) | ||||
|             // filter on budget.
 | ||||
|             ->withoutBudget() | ||||
|             // all info needed for the API:
 | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class ShowController extends Controller | ||||
|      * | ||||
|      * Display a listing of the budget limits for this budget. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function indexAll(SameDateRequest $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| 
 | ||||
| /* | ||||
|  * DestroyController.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,10 +22,13 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Api\V2\Request\Model\ExchangeRate\DestroyRequest; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\DestroyRequest; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Exceptions\ValidationException; | ||||
| use FireflyIII\Models\CurrencyExchangeRate; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| @@ -36,6 +39,8 @@ class DestroyController extends Controller | ||||
| { | ||||
|     use ValidatesUserGroupTrait; | ||||
| 
 | ||||
|     protected array $acceptedRoles   = [UserRoleEnum::OWNER]; | ||||
| 
 | ||||
|     public const string RESOURCE_KEY = 'exchange-rates'; | ||||
| 
 | ||||
|     private ExchangeRateRepositoryInterface $repository; | ||||
| @@ -56,6 +61,9 @@ class DestroyController extends Controller | ||||
|     public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse | ||||
|     { | ||||
|         $date = $request->getDate(); | ||||
|         if (null === $date) { | ||||
|             throw new ValidationException('Date is required'); | ||||
|         } | ||||
|         $rate = $this->repository->getSpecificRateOnDate($from, $to, $date); | ||||
|         if (null === $rate) { | ||||
|             throw new NotFoundHttpException(); | ||||
| @@ -64,4 +72,11 @@ class DestroyController extends Controller | ||||
| 
 | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
| 
 | ||||
|     public function destroySingle(CurrencyExchangeRate $exchangeRate): JsonResponse | ||||
|     { | ||||
|         $this->repository->deleteRate($exchangeRate); | ||||
| 
 | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
| } | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * ShowController.php | ||||
|  * Copyright (c) 2023 james@firefly-iii.org | ||||
|  * IndexController.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -17,16 +17,17 @@ | ||||
|  * 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/>. | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| use FireflyIII\Transformers\V2\ExchangeRateTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| 
 | ||||
| @@ -37,7 +38,7 @@ class IndexController extends Controller | ||||
| { | ||||
|     use ValidatesUserGroupTrait; | ||||
| 
 | ||||
|     public const string RESOURCE_KEY = 'exchange-rates'; | ||||
|     public const string RESOURCE_KEY = 'currency_exchange_rates'; | ||||
| 
 | ||||
|     private ExchangeRateRepositoryInterface $repository; | ||||
| 
 | ||||
| @@ -56,14 +57,11 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|         $piggies     = $this->repository->getAll(); | ||||
|         $entries     = $this->repository->getAll(); | ||||
|         $pageSize    = $this->parameters->get('limit'); | ||||
|         $count       = $piggies->count(); | ||||
|         $piggies     = $piggies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $paginator   = new LengthAwarePaginator($piggies, $count, $pageSize, $this->parameters->get('page')); | ||||
| 
 | ||||
|         var_dump('here we are'); | ||||
| 
 | ||||
|         $count       = $entries->count(); | ||||
|         $entries     = $entries->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $paginator   = new LengthAwarePaginator($entries, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $transformer = new ExchangeRateTransformer(); | ||||
|         $transformer->setParameters($this->parameters); // give params to transformer
 | ||||
| 
 | ||||
| @@ -2,7 +2,7 @@ | ||||
| 
 | ||||
| /* | ||||
|  * ShowController.php | ||||
|  * Copyright (c) 2023 james@firefly-iii.org | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -17,14 +17,15 @@ | ||||
|  * 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/>. | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Models\CurrencyExchangeRate; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| @@ -73,4 +74,15 @@ class ShowController extends Controller | ||||
|             ->header('Content-Type', self::CONTENT_TYPE) | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
|     public function showSingle(CurrencyExchangeRate $exchangeRate): JsonResponse | ||||
|     { | ||||
|         $transformer = new ExchangeRateTransformer(); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         return response() | ||||
|             ->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer)) | ||||
|             ->header('Content-Type', self::CONTENT_TYPE) | ||||
|         ; | ||||
|     } | ||||
| } | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * DestroyController.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * StoreController.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,10 +22,10 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreRequest; | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Api\V2\Request\Model\ExchangeRate\StoreRequest; | ||||
| use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| use FireflyIII\Transformers\V2\ExchangeRateTransformer; | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * DestroyController.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * UpdateController.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,10 +22,10 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\UpdateRequest; | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Api\V2\Request\Model\ExchangeRate\UpdateRequest; | ||||
| use FireflyIII\Models\CurrencyExchangeRate; | ||||
| use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| @@ -37,7 +37,7 @@ class ExpressionController extends Controller | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/validateExpression
 | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function validateExpression(ValidateExpressionRequest $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -88,21 +88,21 @@ class StoreController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $transactionGroup = $this->groupRepository->store($data); | ||||
|         } catch (DuplicateTransactionException $e) { // @phpstan-ignore-line
 | ||||
|         } catch (DuplicateTransactionException $e) { | ||||
|             app('log')->warning('Caught a duplicate transaction. Return error message.'); | ||||
|             $validator = \Validator::make( | ||||
|                 ['transactions' => [['description' => $e->getMessage()]]], | ||||
|                 ['transactions.0.description' => new IsDuplicateTransaction()] | ||||
|             ); | ||||
| 
 | ||||
|             throw new ValidationException($validator); // @phpstan-ignore-line
 | ||||
|         } catch (FireflyException $e) { // @phpstan-ignore-line
 | ||||
|             throw new ValidationException($validator); | ||||
|         } catch (FireflyException $e) { | ||||
|             app('log')->warning('Caught an exception. Return error message.'); | ||||
|             app('log')->error($e->getMessage()); | ||||
|             $message   = sprintf('Internal exception: %s', $e->getMessage()); | ||||
|             $validator = \Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]); | ||||
| 
 | ||||
|             throw new ValidationException($validator); // @phpstan-ignore-line
 | ||||
|             throw new ValidationException($validator); | ||||
|         } | ||||
|         app('preferences')->mark(); | ||||
|         $applyRules    = $data['apply_rules'] ?? true; | ||||
|   | ||||
| @@ -72,13 +72,6 @@ class UpdateController extends Controller | ||||
|     { | ||||
|         app('log')->debug('Now in update routine for transaction group'); | ||||
|         $data             = $request->getAll(); | ||||
| 
 | ||||
|         // Fixes 8750.
 | ||||
|         $transactions     = $data['transactions'] ?? []; | ||||
|         foreach ($transactions as $index => $info) { | ||||
|             unset($data['transactions'][$index]['type']); | ||||
|         } | ||||
| 
 | ||||
|         $transactionGroup = $this->groupRepository->update($transactionGroup, $data); | ||||
|         $manager          = $this->getManager(); | ||||
| 
 | ||||
|   | ||||
| @@ -236,10 +236,10 @@ class ListController extends Controller | ||||
|         // get list of budgets. Count it and split it.
 | ||||
|         /** @var RecurringRepositoryInterface $recurringRepos */ | ||||
|         $recurringRepos = app(RecurringRepositoryInterface::class); | ||||
|         $unfiltered     = $recurringRepos->getAll(); | ||||
|         $unfiltered     = $recurringRepos->get(); | ||||
| 
 | ||||
|         // filter selection
 | ||||
|         $collection     = $unfiltered->filter( // @phpstan-ignore-line
 | ||||
|         $collection     = $unfiltered->filter( | ||||
|             static function (Recurrence $recurrence) use ($currency) {  // @phpstan-ignore-line
 | ||||
|                 /** @var RecurrenceTransaction $transaction */ | ||||
|                 foreach ($recurrence->recurrenceTransactions as $transaction) { | ||||
| @@ -286,7 +286,7 @@ class ListController extends Controller | ||||
|         $ruleRepos   = app(RuleRepositoryInterface::class); | ||||
|         $unfiltered  = $ruleRepos->getAll(); | ||||
| 
 | ||||
|         $collection  = $unfiltered->filter( // @phpstan-ignore-line
 | ||||
|         $collection  = $unfiltered->filter( | ||||
|             static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
 | ||||
|                 /** @var RuleTrigger $trigger */ | ||||
|                 foreach ($rule->ruleTriggers as $trigger) { | ||||
|   | ||||
| @@ -107,7 +107,7 @@ class ShowController extends Controller | ||||
|         /** @var User $user */ | ||||
|         $user        = auth()->user(); | ||||
|         $manager     = $this->getManager(); | ||||
|         $this->parameters->set('defaultCurrency', $this->defaultCurrency); | ||||
|         $this->parameters->set('nativeCurrency', $this->nativeCurrency); | ||||
| 
 | ||||
|         // update fields with user info.
 | ||||
|         $currency->refreshForUser($user); | ||||
| @@ -123,7 +123,7 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/getDefaultCurrency
 | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/getNativeCurrency
 | ||||
|      * | ||||
|      * Show a currency. | ||||
|      * | ||||
| @@ -134,7 +134,7 @@ class ShowController extends Controller | ||||
|         /** @var User $user */ | ||||
|         $user        = auth()->user(); | ||||
|         $manager     = $this->getManager(); | ||||
|         $currency    = $this->defaultCurrency; | ||||
|         $currency    = $this->nativeCurrency; | ||||
| 
 | ||||
|         // update fields with user info.
 | ||||
|         $currency->refreshForUser($user); | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class UpdateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/defaultCurrency
 | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/nativeCurrency
 | ||||
|      * | ||||
|      * Make the currency a default currency. | ||||
|      * | ||||
|   | ||||
							
								
								
									
										71
									
								
								app/Api/V1/Controllers/Models/UserGroup/IndexController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								app/Api/V1/Controllers/Models/UserGroup/IndexController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * IndexController.php | ||||
|  * Copyright (c) 2024 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); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\UserGroup; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Data\DateRequest; | ||||
| use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; | ||||
| use FireflyIII\Transformers\UserGroupTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| 
 | ||||
| class IndexController extends Controller | ||||
| { | ||||
|     public const string RESOURCE_KEY = 'user_groups'; | ||||
| 
 | ||||
|     private UserGroupRepositoryInterface $repository; | ||||
| 
 | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $this->repository = app(UserGroupRepositoryInterface::class); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public function index(DateRequest $request): JsonResponse | ||||
|     { | ||||
|         $administrations = $this->repository->get(); | ||||
|         $pageSize        = $this->parameters->get('limit'); | ||||
|         $count           = $administrations->count(); | ||||
|         $administrations = $administrations->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $paginator       = new LengthAwarePaginator($administrations, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $transformer     = new UserGroupTransformer(); | ||||
| 
 | ||||
|         $transformer->setParameters($this->parameters); // give params to transformer
 | ||||
| 
 | ||||
|         return response() | ||||
|             ->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer)) | ||||
|             ->header('Content-Type', self::CONTENT_TYPE) | ||||
|         ; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										64
									
								
								app/Api/V1/Controllers/Models/UserGroup/ShowController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								app/Api/V1/Controllers/Models/UserGroup/ShowController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * ShowController.php | ||||
|  * 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/>. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\UserGroup; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; | ||||
| use FireflyIII\Transformers\UserGroupTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| /** | ||||
|  * Class ShowController | ||||
|  */ | ||||
| class ShowController extends Controller | ||||
| { | ||||
|     public const string RESOURCE_KEY = 'user_groups'; | ||||
|     private WebhookRepositoryInterface $repository; | ||||
| 
 | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $this->repository = app(WebhookRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public function show(UserGroup $userGroup): JsonResponse | ||||
|     { | ||||
|         $transformer = new UserGroupTransformer(); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         return response() | ||||
|             ->api($this->jsonApiObject(self::RESOURCE_KEY, $userGroup, $transformer)) | ||||
|             ->header('Content-Type', self::CONTENT_TYPE) | ||||
|         ; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										71
									
								
								app/Api/V1/Controllers/Models/UserGroup/UpdateController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								app/Api/V1/Controllers/Models/UserGroup/UpdateController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * UpdateController.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); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\UserGroup; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\UserGroup\UpdateRequest; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; | ||||
| use FireflyIII\Transformers\UserGroupTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| class UpdateController extends Controller | ||||
| { | ||||
|     public const string RESOURCE_KEY = 'user_groups'; | ||||
| 
 | ||||
|     private UserGroupRepositoryInterface $repository; | ||||
| 
 | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $this->repository = app(UserGroupRepositoryInterface::class); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public function update(UpdateRequest $request, UserGroup $userGroup): JsonResponse | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__)); | ||||
|         $data        = $request->getData(); | ||||
|         $userGroup   = $this->repository->update($userGroup, $data); | ||||
|         $userGroup->refresh(); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         $transformer = new UserGroupTransformer(); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         return response() | ||||
|             ->api($this->jsonApiObject(self::RESOURCE_KEY, $userGroup, $transformer)) | ||||
|             ->header('Content-Type', self::CONTENT_TYPE) | ||||
|         ; | ||||
|     } | ||||
| } | ||||
| @@ -124,7 +124,7 @@ class BasicController extends Controller | ||||
|     { | ||||
|         // some config settings
 | ||||
|         $convertToNative = Amount::convertToNative(); | ||||
|         $default         = Amount::getDefaultCurrency(); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
|         // prep some arrays:
 | ||||
|         $incomes         = []; | ||||
|         $expenses        = []; | ||||
|   | ||||
| @@ -58,7 +58,7 @@ class AboutController extends Controller | ||||
|                            'driver'      => $currentDriver, | ||||
|                        ]; | ||||
| 
 | ||||
|         return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); | ||||
|         return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|   | ||||
| @@ -86,7 +86,7 @@ class ConfigurationController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($return); | ||||
|         return response()->api($return); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -142,7 +142,7 @@ class ConfigurationController extends Controller | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); | ||||
|         return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -173,6 +173,6 @@ class ConfigurationController extends Controller | ||||
|             'editable' => true, | ||||
|         ]; | ||||
| 
 | ||||
|         return response()->json(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); | ||||
|         return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -52,8 +52,8 @@ class CronController extends Controller | ||||
|         if (true === config('cer.download_enabled')) { | ||||
|             $return['exchange_rates'] = $this->exchangeRatesCronJob($config['force'], $config['date']); | ||||
|         } | ||||
|         $return['bill_warnings']          = $this->billWarningCronJob($config['force'], $config['date']); | ||||
|         $return['bill_notifications']     = $this->billWarningCronJob($config['force'], $config['date']); | ||||
| 
 | ||||
|         return response()->json($return); | ||||
|         return response()->api($return); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -32,7 +32,6 @@ use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Transformers\PreferenceTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| @@ -86,7 +85,7 @@ class PreferencesController extends Controller | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|         if ('currencyPreference' === $preference->name) { | ||||
|             throw new FireflyException('Please use api/v1/currencies/default instead.'); | ||||
|             throw new FireflyException('Please use api/v1/currencies/native instead.'); | ||||
|         } | ||||
| 
 | ||||
|         /** @var PreferenceTransformer $transformer */ | ||||
| @@ -98,34 +97,6 @@ class PreferencesController extends Controller | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO This endpoint is not documented. | ||||
|      * | ||||
|      * Return a single preference by name. | ||||
|      * | ||||
|      * @param Collection<int, Preference> $collection | ||||
|      */ | ||||
|     public function showList(Collection $collection): JsonResponse | ||||
|     { | ||||
|         $manager     = $this->getManager(); | ||||
|         $count       = $collection->count(); | ||||
|         $pageSize    = $this->parameters->get('limit'); | ||||
|         $preferences = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator   = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.preferences.show-list').$this->buildParams()); | ||||
| 
 | ||||
|         /** @var PreferenceTransformer $transformer */ | ||||
|         $transformer = app(PreferenceTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         $resource    = new FractalCollection($preferences, $transformer, self::RESOURCE_KEY); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/storePreference
 | ||||
| @@ -161,7 +132,7 @@ class PreferencesController extends Controller | ||||
|     public function update(PreferenceUpdateRequest $request, Preference $preference): JsonResponse | ||||
|     { | ||||
|         if ('currencyPreference' === $preference->name) { | ||||
|             throw new FireflyException('Please use api/v1/currencies/default instead.'); | ||||
|             throw new FireflyException('Please use api/v1/currencies/native instead.'); | ||||
|         } | ||||
| 
 | ||||
|         $manager     = $this->getManager(); | ||||
|   | ||||
| @@ -24,7 +24,7 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Autocomplete; | ||||
| 
 | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| @@ -46,7 +46,7 @@ class AutocompleteRequest extends FormRequest | ||||
|         } | ||||
| 
 | ||||
|         // remove 'initial balance' from allowed types. its internal
 | ||||
|         $array = array_diff($array, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION]); | ||||
|         $array = array_diff($array, [AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::RECONCILIATION->value]); | ||||
| 
 | ||||
|         return [ | ||||
|             'types' => $array, | ||||
| @@ -58,6 +58,7 @@ class AutocompleteRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'date' => 'date|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -24,7 +24,7 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Data; | ||||
| 
 | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Exceptions\ValidationException; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| @@ -49,12 +49,13 @@ class DateRequest extends FormRequest | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
|         if ($start->diffInYears($end, true) > 5) { | ||||
|             throw new FireflyException('Date range out of range.'); | ||||
|             throw new ValidationException('Date range out of range.'); | ||||
|         } | ||||
| 
 | ||||
|         return [ | ||||
|             'start' => $start, | ||||
|             'end'   => $end, | ||||
|             'date'  => $this->getCarbonDate('date'), | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
| @@ -64,8 +65,9 @@ class DateRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start' => 'required|date', | ||||
|             'end'   => 'required|date|after:start', | ||||
|             'date'  => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'start' => 'date|after:1900-01-01|before:2099-12-31|before:end|required_with:end', | ||||
|             'end'   => 'date|after:1900-01-01|before:2099-12-31|after:start|required_with:start', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -24,7 +24,7 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Data\Export; | ||||
| 
 | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| @@ -55,7 +55,7 @@ class ExportRequest extends FormRequest | ||||
|             $accountId = (int) $part; | ||||
|             if (0 !== $accountId) { | ||||
|                 $account = $repository->find($accountId); | ||||
|                 if (null !== $account && AccountType::ASSET === $account->accountType->type) { | ||||
|                 if (null !== $account && AccountTypeEnum::ASSET->value === $account->accountType->type) { | ||||
|                     $accounts->push($account); | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -25,8 +25,8 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Requests\Insight; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| @@ -70,7 +70,7 @@ class GenericRequest extends FormRequest | ||||
|         /** @var Account $account */ | ||||
|         foreach ($this->accounts as $account) { | ||||
|             $type = $account->accountType->type; | ||||
|             if (in_array($type, [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true)) { | ||||
|             if (in_array($type, [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], true)) { | ||||
|                 $return->push($account); | ||||
|             } | ||||
|         } | ||||
| @@ -191,7 +191,7 @@ class GenericRequest extends FormRequest | ||||
|         /** @var Account $account */ | ||||
|         foreach ($this->accounts as $account) { | ||||
|             $type = $account->accountType->type; | ||||
|             if (AccountType::EXPENSE === $type) { | ||||
|             if (AccountTypeEnum::EXPENSE->value === $type) { | ||||
|                 $return->push($account); | ||||
|             } | ||||
|         } | ||||
| @@ -207,7 +207,7 @@ class GenericRequest extends FormRequest | ||||
|         /** @var Account $account */ | ||||
|         foreach ($this->accounts as $account) { | ||||
|             $type = $account->accountType->type; | ||||
|             if (AccountType::REVENUE === $type) { | ||||
|             if (AccountTypeEnum::REVENUE->value === $type) { | ||||
|                 $return->push($account); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Account; | ||||
| 
 | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Location; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Rules\IsBoolean; | ||||
| use FireflyIII\Rules\UniqueAccountNumber; | ||||
| use FireflyIII\Rules\UniqueIban; | ||||
| @@ -33,6 +34,8 @@ use FireflyIII\Support\Request\AppendsLocationData; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Validation\Validator; | ||||
| 
 | ||||
| /** | ||||
|  * Class UpdateRequest | ||||
| @@ -112,4 +115,36 @@ class UpdateRequest extends FormRequest | ||||
| 
 | ||||
|         return Location::requestRules($rules); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Configure the validator instance with special rules for after the basic validation rules. | ||||
|      */ | ||||
|     public function withValidator(Validator $validator): void | ||||
|     { | ||||
|         $validator->after( | ||||
|             function (Validator $validator): void { | ||||
|                 // validate start before end only if both are there.
 | ||||
|                 $data       = $validator->getData(); | ||||
| 
 | ||||
|                 /** @var Account $account */ | ||||
|                 $account    = $this->route()->parameter('account'); | ||||
| 
 | ||||
|                 /** @var AccountRepositoryInterface $repository */ | ||||
|                 $repository = app(AccountRepositoryInterface::class); | ||||
|                 $currency   = $repository->getAccountCurrency($account); | ||||
| 
 | ||||
|                 // how many piggies are attached?
 | ||||
|                 $piggyBanks = $account->piggyBanks()->count(); | ||||
|                 if ($piggyBanks > 0 && array_key_exists('currency_code', $data) && $data['currency_code'] !== $currency->code) { | ||||
|                     $validator->errors()->add('currency_code', (string) trans('validation.piggy_no_change_currency')); | ||||
|                 } | ||||
|                 if ($piggyBanks > 0 && array_key_exists('currency_id', $data) && (int) $data['currency_id'] !== $currency->id) { | ||||
|                     $validator->errors()->add('currency_id', (string) trans('validation.piggy_no_change_currency')); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -66,8 +66,8 @@ class Request extends FormRequest | ||||
|             'currency_id'   => 'numeric|exists:transaction_currencies,id', | ||||
|             'currency_code' => 'min:3|max:51|exists:transaction_currencies,code', | ||||
|             'amount'        => ['nullable', new IsValidPositiveAmount()], | ||||
|             'start'         => 'date', | ||||
|             'end'           => 'date', | ||||
|             'start'         => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'           => 'date|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -78,9 +78,9 @@ class StoreRequest extends FormRequest | ||||
|             'amount_max'     => ['required', new IsValidPositiveAmount()], | ||||
|             'currency_id'    => 'numeric|exists:transaction_currencies,id', | ||||
|             'currency_code'  => 'min:3|max:51|exists:transaction_currencies,code', | ||||
|             'date'           => 'date|required', | ||||
|             'end_date'       => 'nullable|date|after:date', | ||||
|             'extension_date' => 'nullable|date|after:date', | ||||
|             'date'           => 'date|required|after:1900-01-01|before:2099-12-31', | ||||
|             'end_date'       => 'nullable|date|after:date|after:1900-01-01|before:2099-12-31', | ||||
|             'extension_date' => 'nullable|date|after:date|after:1900-01-01|before:2099-12-31', | ||||
|             'repeat_freq'    => 'in:weekly,monthly,quarterly,half-year,yearly|required', | ||||
|             'skip'           => 'min:0|max:31|numeric', | ||||
|             'active'         => [new IsBoolean()], | ||||
| @@ -96,15 +96,39 @@ class StoreRequest extends FormRequest | ||||
|         $validator->after( | ||||
|             static function (Validator $validator): void { | ||||
|                 $data   = $validator->getData(); | ||||
|                 $min  = (string) ($data['amount_min'] ?? '0'); | ||||
|                 $max  = (string) ($data['amount_max'] ?? '0'); | ||||
|                 $min    = $data['amount_min'] ?? '0'; | ||||
|                 $max    = $data['amount_max'] ?? '0'; | ||||
| 
 | ||||
|                 if (1 === bccomp($min, $max)) { | ||||
|                 if (is_array($min) || is_array($max)) { | ||||
|                     $validator->errors()->add('amount_min', (string) trans('validation.generic_invalid')); | ||||
|                     $validator->errors()->add('amount_max', (string) trans('validation.generic_invalid')); | ||||
|                     $min = '0'; | ||||
|                     $max = '0'; | ||||
|                 } | ||||
|                 $result = false; | ||||
| 
 | ||||
|                 try { | ||||
|                     $result = bccomp($min, $max); | ||||
|                 } catch (\ValueError $e) { | ||||
|                     Log::error($e->getMessage()); | ||||
|                     $validator->errors()->add('amount_min', (string) trans('validation.generic_invalid')); | ||||
|                     $validator->errors()->add('amount_max', (string) trans('validation.generic_invalid')); | ||||
|                 } | ||||
| 
 | ||||
|                 if (1 === $result) { | ||||
|                     $validator->errors()->add('amount_min', (string) trans('validation.amount_min_over_max')); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|         if ($validator->fails()) { | ||||
|         $failed = false; | ||||
| 
 | ||||
|         try { | ||||
|             $failed = $validator->fails(); | ||||
|         } catch (\TypeError $e) { | ||||
|             Log::error($e->getMessage()); | ||||
|             $failed = false; | ||||
|         } | ||||
|         if ($failed) { | ||||
|             Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -81,9 +81,9 @@ class UpdateRequest extends FormRequest | ||||
|             'amount_max'     => ['nullable', new IsValidPositiveAmount()], | ||||
|             'currency_id'    => 'numeric|exists:transaction_currencies,id', | ||||
|             'currency_code'  => 'min:3|max:51|exists:transaction_currencies,code', | ||||
|             'date'           => 'date', | ||||
|             'end_date'       => 'date|after:date', | ||||
|             'extension_date' => 'date|after:date', | ||||
|             'date'           => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end_date'       => 'date|after:date|after:1900-01-01|before:2099-12-31', | ||||
|             'extension_date' => 'date|after:date|after:1900-01-01|before:2099-12-31', | ||||
|             'repeat_freq'    => 'in:weekly,monthly,quarterly,half-year,yearly', | ||||
|             'skip'           => 'min:0|max:31|numeric', | ||||
|             'active'         => [new IsBoolean()], | ||||
|   | ||||
| @@ -67,8 +67,8 @@ class UpdateRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start'         => 'date', | ||||
|             'end'           => 'date', | ||||
|             'start'         => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'           => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'amount'        => ['nullable', new IsValidPositiveAmount()], | ||||
|             'currency_id'   => 'numeric|exists:transaction_currencies,id', | ||||
|             'currency_code' => 'min:3|max:51|exists:transaction_currencies,code', | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| 
 | ||||
| /* | ||||
|  * DestroyRequest.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,7 +22,7 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Request\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| @@ -34,7 +34,7 @@ class DestroyRequest extends FormRequest | ||||
|     use ChecksLogin; | ||||
|     use ConvertsDataTypes; | ||||
| 
 | ||||
|     public function getDate(): Carbon | ||||
|     public function getDate(): ?Carbon | ||||
|     { | ||||
|         return $this->getCarbonDate('date'); | ||||
|     } | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * DestroyRequest.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * StoreRequest.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,7 +22,7 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Request\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * DestroyRequest.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * UpdateRequest.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,7 +22,7 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Request\Model\ExchangeRate; | ||||
| namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| @@ -154,7 +154,7 @@ class UpdateRequest extends FormRequest | ||||
|         return [ | ||||
|             'title'                                => sprintf('min:1|max:255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id), | ||||
|             'description'                          => 'min:1|max:32768', | ||||
|             'first_date'                           => 'date', | ||||
|             'first_date'                           => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'apply_rules'                          => [new IsBoolean()], | ||||
|             'active'                               => [new IsBoolean()], | ||||
|             'repeat_until'                         => 'nullable|date', | ||||
|   | ||||
| @@ -71,8 +71,8 @@ class TestRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start'      => 'date', | ||||
|             'end'        => 'date|after_or_equal:start', | ||||
|             'start'      => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'        => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31', | ||||
|             'accounts'   => '', | ||||
|             'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts', | ||||
|         ]; | ||||
|   | ||||
| @@ -65,8 +65,8 @@ class TriggerRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start'      => 'date', | ||||
|             'end'        => 'date|after_or_equal:start', | ||||
|             'start'      => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'        => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31', | ||||
|             'accounts'   => '', | ||||
|             'accounts.*' => 'exists:accounts,id|belongsToUser:accounts', | ||||
|         ]; | ||||
|   | ||||
| @@ -65,8 +65,8 @@ class TestRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start'      => 'date', | ||||
|             'end'        => 'date|after_or_equal:start', | ||||
|             'start'      => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'        => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31', | ||||
|             'accounts'   => '', | ||||
|             'accounts.*' => 'exists:accounts,id|belongsToUser:accounts', | ||||
|         ]; | ||||
|   | ||||
| @@ -69,8 +69,8 @@ class TriggerRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start' => 'date', | ||||
|             'end'   => 'date|after_or_equal:start', | ||||
|             'start' => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'   => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -62,7 +62,7 @@ class StoreRequest extends FormRequest | ||||
|         $rules = [ | ||||
|             'tag'         => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024', | ||||
|             'description' => 'min:1|nullable|max:32768', | ||||
|             'date'        => 'date|nullable', | ||||
|             'date'        => 'date|nullable|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
| 
 | ||||
|         return Location::requestRules($rules); | ||||
|   | ||||
| @@ -63,11 +63,10 @@ class UpdateRequest extends FormRequest | ||||
|     { | ||||
|         /** @var Tag $tag */ | ||||
|         $tag   = $this->route()->parameter('tagOrId'); | ||||
|         // TODO check if uniqueObjectForUser is obsolete
 | ||||
|         $rules = [ | ||||
|             'tag'         => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id, | ||||
|             'description' => 'min:1|nullable|max:32768', | ||||
|             'date'        => 'date|nullable', | ||||
|             'date'        => 'date|nullable|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
| 
 | ||||
|         return Location::requestRules($rules); | ||||
|   | ||||
| @@ -24,6 +24,7 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Models\Transaction; | ||||
| 
 | ||||
| use FireflyIII\Models\Location; | ||||
| use FireflyIII\Rules\BelongsUser; | ||||
| use FireflyIII\Rules\IsBoolean; | ||||
| use FireflyIII\Rules\IsDateOrTime; | ||||
| @@ -89,6 +90,11 @@ class StoreRequest extends FormRequest | ||||
|                 'currency_id'             => $this->integerFromValue((string) $object['currency_id']), | ||||
|                 'currency_code'           => $this->clearString((string) $object['currency_code']), | ||||
| 
 | ||||
|                 // location
 | ||||
|                 'latitude'                => $this->floatFromValue((string) $object['latitude']), | ||||
|                 'longitude'               => $this->floatFromValue((string) $object['longitude']), | ||||
|                 'zoom_level'              => $this->integerFromValue((string) $object['zoom_level']), | ||||
| 
 | ||||
|                 // foreign currency info:
 | ||||
|                 'foreign_currency_id'     => $this->integerFromValue((string) $object['foreign_currency_id']), | ||||
|                 'foreign_currency_code'   => $this->clearString((string) $object['foreign_currency_code']), | ||||
| @@ -171,6 +177,7 @@ class StoreRequest extends FormRequest | ||||
|     { | ||||
|         app('log')->debug('Collect rules of TransactionStoreRequest'); | ||||
|         $validProtocols = config('firefly.valid_url_protocols'); | ||||
|         $locationRules  = Location::requestRules([]); | ||||
| 
 | ||||
|         return [ | ||||
|             // basic fields for group:
 | ||||
| @@ -178,6 +185,11 @@ class StoreRequest extends FormRequest | ||||
|             'error_if_duplicate_hash'              => [new IsBoolean()], | ||||
|             'apply_rules'                          => [new IsBoolean()], | ||||
| 
 | ||||
|             // location rules
 | ||||
|             'transactions.*.latitude'              => $locationRules['latitude'], | ||||
|             'transactions.*.longitude'             => $locationRules['longitude'], | ||||
|             'transactions.*.zoom_level'            => $locationRules['zoom_level'], | ||||
| 
 | ||||
|             // transaction rules (in array for splits):
 | ||||
|             'transactions.*.type'                  => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation', | ||||
|             'transactions.*.date'                  => ['required', new IsDateOrTime()], | ||||
|   | ||||
							
								
								
									
										65
									
								
								app/Api/V1/Requests/Models/UserGroup/UpdateRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/Api/V1/Requests/Models/UserGroup/UpdateRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * UpdateRequest.php | ||||
|  * 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/>. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Models\UserGroup; | ||||
| 
 | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| 
 | ||||
| /** | ||||
|  * Class UpdateRequest | ||||
|  */ | ||||
| class UpdateRequest extends FormRequest | ||||
| { | ||||
|     use ChecksLogin; | ||||
|     use ConvertsDataTypes; | ||||
| 
 | ||||
|     public function getData(): array | ||||
|     { | ||||
|         $fields = [ | ||||
|             'title'                => ['title', 'convertString'], | ||||
|             'native_currency_id'   => ['native_currency_id', 'convertInteger'], | ||||
|             'native_currency_code' => ['native_currency_code', 'convertString'], | ||||
|         ]; | ||||
| 
 | ||||
|         return $this->getAllData($fields); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Rules for this request. | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         /** @var UserGroup $userGroup */ | ||||
|         $userGroup = $this->route()->parameter('userGroup'); | ||||
| 
 | ||||
|         return [ | ||||
|             'title'                => ['required', 'min:1', 'max:255'], | ||||
|             'native_currency_id'   => 'exists:transaction_currencies,id', | ||||
|             'native_currency_code' => 'exists:transaction_currencies,code', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
| @@ -57,6 +57,10 @@ class CronRequest extends FormRequest | ||||
|         if ($this->has('date')) { | ||||
|             $data['date'] = $this->getCarbonDate('date'); | ||||
|         } | ||||
|         // catch NULL.
 | ||||
|         if (null === $data['date']) { | ||||
|             $data['date'] = today(config('app.timezone')); | ||||
|         } | ||||
| 
 | ||||
|         return $data; | ||||
|     } | ||||
| @@ -68,7 +72,7 @@ class CronRequest extends FormRequest | ||||
|     { | ||||
|         return [ | ||||
|             'force' => 'in:true,false', | ||||
|             'date'  => 'date', | ||||
|             'date'  => 'nullable|date|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -55,7 +55,7 @@ class AccountController extends Controller | ||||
|                 $userGroup        = $this->validateUserGroup($request); | ||||
|                 $this->repository = app(AccountRepositoryInterface::class); | ||||
|                 $this->repository->setUserGroup($userGroup); | ||||
|                 $this->default    = app('amount')->getDefaultCurrency(); | ||||
|                 $this->default    = app('amount')->getNativeCurrency(); | ||||
|                 $this->converter  = app(ExchangeRateConverter::class); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Chart\ChartData; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Api\CleansChartData; | ||||
| use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| @@ -57,7 +58,7 @@ class AccountController extends Controller | ||||
|                 $this->repository = app(AccountRepositoryInterface::class); | ||||
|                 $this->repository->setUserGroup($this->validateUserGroup($request)); | ||||
|                 $this->chartData  = new ChartData(); | ||||
|                 $this->default    = app('amount')->getDefaultCurrency(); | ||||
|                 $this->default    = app('amount')->getNativeCurrency(); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -118,7 +119,7 @@ class AccountController extends Controller | ||||
|             'native_entries'                 => [], | ||||
|         ]; | ||||
|         $currentStart   = clone $params['start']; | ||||
|         $range          = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative); | ||||
|         $range          = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative); | ||||
| 
 | ||||
|         $previous       = array_values($range)[0]['balance']; | ||||
|         $previousNative = array_values($range)[0]['native_balance']; | ||||
|   | ||||
| @@ -62,7 +62,7 @@ class BalanceController extends Controller | ||||
|                 $this->repository->setUserGroup($userGroup); | ||||
|                 $this->collector->setUserGroup($userGroup); | ||||
|                 $this->chartData  = new ChartData(); | ||||
|                 // $this->default    = app('amount')->getDefaultCurrency();
 | ||||
|                 // $this->default    = app('amount')->getNativeCurrency();
 | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -87,7 +87,7 @@ class BalanceController extends Controller | ||||
| 
 | ||||
|         // prepare for currency conversion and data collection:
 | ||||
|         /** @var TransactionCurrency $default */ | ||||
|         $default         = app('amount')->getDefaultCurrency(); | ||||
|         $default         = app('amount')->getNativeCurrency(); | ||||
| 
 | ||||
|         // get journals for entire period:
 | ||||
| 
 | ||||
|   | ||||
| @@ -63,7 +63,7 @@ class BudgetController extends Controller | ||||
|                 $this->repository    = app(BudgetRepositoryInterface::class); | ||||
|                 $this->blRepository  = app(BudgetLimitRepositoryInterface::class); | ||||
|                 $this->opsRepository = app(OperationsRepositoryInterface::class); | ||||
|                 $this->currency      = app('amount')->getDefaultCurrency(); | ||||
|                 $this->currency      = app('amount')->getNativeCurrency(); | ||||
|                 $userGroup           = $this->validateUserGroup($request); | ||||
|                 $this->repository->setUserGroup($userGroup); | ||||
|                 $this->opsRepository->setUserGroup($userGroup); | ||||
|   | ||||
| @@ -27,10 +27,10 @@ namespace FireflyIII\Api\V2\Controllers\Chart; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Api\V2\Request\Generic\DateRequest; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\CleansChartData; | ||||
| @@ -70,7 +70,7 @@ class CategoryController extends Controller | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function dashboard(DateRequest $request): JsonResponse | ||||
|     { | ||||
| @@ -81,8 +81,8 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end        = $this->parameters->get('end'); | ||||
|         $accounts   = $this->accountRepos->getAccountsByType([AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::ASSET, AccountType::DEFAULT]); | ||||
|         $default    = app('amount')->getDefaultCurrency(); | ||||
|         $accounts   = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]); | ||||
|         $default    = app('amount')->getNativeCurrency(); | ||||
|         $converter  = new ExchangeRateConverter(); | ||||
|         $currencies = []; | ||||
|         $return     = []; | ||||
|   | ||||
| @@ -47,8 +47,8 @@ use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| /** | ||||
|  * Class Controller | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||
|  * @SuppressWarnings("PHPMD.CouplingBetweenObjects") | ||||
|  * @SuppressWarnings("PHPMD.NumberOfChildren") | ||||
|  */ | ||||
| class Controller extends BaseController | ||||
| { | ||||
| @@ -74,7 +74,7 @@ class Controller extends BaseController | ||||
|      * TODO duplicate from V1 controller | ||||
|      * Method to grab all parameters from the URL. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @SuppressWarnings("PHPMD.NPathComplexity") | ||||
|      */ | ||||
|     private function getParameters(): ParameterBag | ||||
|     { | ||||
|   | ||||
| @@ -58,7 +58,7 @@ class SumController extends Controller | ||||
|      * | ||||
|      * TODO see autocomplete/accountcontroller for list. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function paid(DateRequest $request): JsonResponse | ||||
|     { | ||||
| @@ -74,7 +74,7 @@ class SumController extends Controller | ||||
|      * | ||||
|      * TODO see autocomplete/accountcontroller for list. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function unpaid(DateRequest $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -80,21 +80,21 @@ class StoreController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $transactionGroup = $this->groupRepository->store($data); | ||||
|         } catch (DuplicateTransactionException $e) { // @phpstan-ignore-line
 | ||||
|         } catch (DuplicateTransactionException $e) { | ||||
|             app('log')->warning('Caught a duplicate transaction. Return error message.'); | ||||
|             $validator = Validator::make( | ||||
|                 ['transactions' => [['description' => $e->getMessage()]]], | ||||
|                 ['transactions.0.description' => new IsDuplicateTransaction()] | ||||
|             ); | ||||
| 
 | ||||
|             throw new ValidationException($validator); // @phpstan-ignore-line
 | ||||
|         } catch (FireflyException $e) { // @phpstan-ignore-line
 | ||||
|             throw new ValidationException($validator); | ||||
|         } catch (FireflyException $e) { | ||||
|             app('log')->warning('Caught an exception. Return error message.'); | ||||
|             app('log')->error($e->getMessage()); | ||||
|             $message   = sprintf('Internal exception: %s', $e->getMessage()); | ||||
|             $validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]); | ||||
| 
 | ||||
|             throw new ValidationException($validator); // @phpstan-ignore-line
 | ||||
|             throw new ValidationException($validator); | ||||
|         } | ||||
|         app('preferences')->mark(); | ||||
|         $applyRules         = $data['apply_rules'] ?? true; | ||||
|   | ||||
| @@ -66,7 +66,7 @@ class ShowController extends Controller | ||||
|             $default = 1 === $group->pivot->group_default; | ||||
|         } | ||||
|         $currency->userGroupEnabled = $enabled; | ||||
|         $currency->userGroupDefault = $default; | ||||
|         $currency->userGroupNative  = $default; | ||||
| 
 | ||||
| 
 | ||||
|         $transformer                = new CurrencyTransformer(); | ||||
|   | ||||
| @@ -27,12 +27,12 @@ namespace FireflyIII\Api\V2\Controllers\Summary; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Api\V2\Request\Generic\DateRequest; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Helpers\Report\NetWorthInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface; | ||||
| @@ -94,7 +94,7 @@ class BasicController extends Controller | ||||
|      * | ||||
|      * @throws \Exception | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function basic(DateRequest $request): JsonResponse | ||||
|     { | ||||
| @@ -118,7 +118,7 @@ class BasicController extends Controller | ||||
|     private function getBalanceInformation(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $object    = new SummaryBalanceGrouped(); | ||||
|         $default   = app('amount')->getDefaultCurrency(); | ||||
|         $default   = app('amount')->getNativeCurrency(); | ||||
| 
 | ||||
|         $object->setDefault($default); | ||||
| 
 | ||||
| @@ -222,7 +222,7 @@ class BasicController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * @SuppressWarnings("PHPMD.ExcessiveMethodLength") | ||||
|      */ | ||||
|     private function getLeftToSpendInfo(Carbon $start, Carbon $end): array | ||||
|     { | ||||
| @@ -233,7 +233,7 @@ class BasicController extends Controller | ||||
|         $available    = $this->abRepository->getAvailableBudgetWithCurrency($start, $end); | ||||
|         $budgets      = $this->budgetRepository->getActiveBudgets(); | ||||
|         $spent        = $this->opsRepository->listExpenses($start, $end, null, $budgets); | ||||
|         $default      = app('amount')->getDefaultCurrency(); | ||||
|         $default      = app('amount')->getNativeCurrency(); | ||||
|         $currencies   = []; | ||||
|         $converter    = new ExchangeRateConverter(); | ||||
| 
 | ||||
| @@ -353,7 +353,7 @@ class BasicController extends Controller | ||||
|         $netWorthHelper = app(NetWorthInterface::class); | ||||
|         $netWorthHelper->setUserGroup($userGroup); | ||||
|         $allAccounts    = $this->accountRepository->getActiveAccountsByType( | ||||
|             [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT] | ||||
|             [AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value] | ||||
|         ); | ||||
| 
 | ||||
|         // filter list on preference of being included.
 | ||||
|   | ||||
| @@ -26,9 +26,9 @@ namespace FireflyIII\Api\V2\Controllers\Summary; | ||||
| 
 | ||||
| use FireflyIII\Api\V2\Controllers\Controller; | ||||
| use FireflyIII\Api\V2\Request\Generic\SingleDateRequest; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Helpers\Report\NetWorthInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -67,7 +67,7 @@ class NetWorthController extends Controller | ||||
|     public function get(SingleDateRequest $request): JsonResponse | ||||
|     { | ||||
|         $date     = $request->getDate(); | ||||
|         $accounts = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]); | ||||
|         $accounts = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value]); | ||||
| 
 | ||||
|         // filter list on preference of being included.
 | ||||
|         $filtered = $accounts->filter( | ||||
|   | ||||
| @@ -24,9 +24,8 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Request\Autocomplete; | ||||
| 
 | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| use FireflyIII\Support\Http\Api\ParsesQueryFilters; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| @@ -39,7 +38,6 @@ class AutocompleteRequest extends FormRequest | ||||
|     use AccountFilter; | ||||
|     use ChecksLogin; | ||||
|     use ConvertsDataTypes; | ||||
|     use ParsesQueryFilters; | ||||
| 
 | ||||
|     /** | ||||
|      * Loops over all possible query parameters (these are shared over ALL auto complete requests) | ||||
| @@ -67,7 +65,7 @@ class AutocompleteRequest extends FormRequest | ||||
|         } | ||||
| 
 | ||||
|         // remove 'initial balance' from allowed types. its internal
 | ||||
|         $array['account_types'] = array_diff($array['account_types'], [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION, AccountType::CREDITCARD]); | ||||
|         $array['account_types'] = array_diff($array['account_types'], [AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::CREDITCARD->value]); | ||||
|         $array['account_types'] = $this->getAccountTypeParameter($array['account_types']); | ||||
| 
 | ||||
|         return $array; | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V2\Request\Chart; | ||||
| 
 | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Support\Http\Api\ParsesQueryFilters; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| @@ -40,7 +39,6 @@ class ChartRequest extends FormRequest | ||||
| { | ||||
|     use ChecksLogin; | ||||
|     use ConvertsDataTypes; | ||||
|     use ParsesQueryFilters; | ||||
|     use ValidatesUserGroupTrait; | ||||
| 
 | ||||
|     protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; | ||||
|   | ||||
| @@ -109,8 +109,8 @@ class InfiniteListRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start'     => 'date', | ||||
|             'end'       => 'date|after:start', | ||||
|             'start'     => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'       => 'date|after:start|after:1900-01-01|before:2099-12-31', | ||||
|             'start_row' => 'integer|min:0|max:4294967296', | ||||
|             'end_row'   => 'integer|min:0|max:4294967296|gt:start_row', | ||||
|         ]; | ||||
|   | ||||
| @@ -84,8 +84,8 @@ class ListRequest extends FormRequest | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'start' => 'date', | ||||
|             'end'   => 'date|after:start', | ||||
|             'start' => 'date|after:1900-01-01|before:2099-12-31', | ||||
|             'end'   => 'date|after:start|after:1900-01-01|before:2099-12-31', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,26 @@ | ||||
| <?php | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  * SeparateTimezoneCaster.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); | ||||
| 
 | ||||
| namespace FireflyIII\Casts; | ||||
|   | ||||
| @@ -55,34 +55,24 @@ class ConvertsDatesToUTC extends Command | ||||
| { | ||||
|     use ShowsFriendlyMessages; | ||||
| 
 | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $description = 'Convert stored dates to UTC.'; | ||||
| 
 | ||||
|     /** | ||||
|      * The name and signature of the console command. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $signature   = 'correction:convert-to-utc'; | ||||
| 
 | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle(): int | ||||
|     { | ||||
|         $this->friendlyWarning('Please do not use this command.'); | ||||
|         $this->friendlyWarning('Please do not use this command right now.'); | ||||
| 
 | ||||
|         return 0; | ||||
|         // this variable is ALWAYS en_US.
 | ||||
|         // stops phpstan complaining about dead code.
 | ||||
|         if ('en_US' === config('app.fallback_locale')) { | ||||
|             return Command::SUCCESS; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * @var string $model | ||||
|          * @var array  $fields | ||||
|          */ | ||||
|         foreach (AddTimezonesToDates::$models as $model => $fields) { | ||||
|         foreach (CorrectsTimezoneInformation::$models as $model => $fields) { | ||||
|             $this->ConvertModeltoUTC($model, $fields); | ||||
|         } | ||||
|         // tell the system we are now in UTC mode.
 | ||||
| @@ -122,10 +112,10 @@ class ConvertsDatesToUTC extends Command | ||||
|         $items->each( | ||||
|             function ($item) use ($field, $timezoneField): void { | ||||
|                 /** @var Carbon $date */ | ||||
|                 $date                   = Carbon::parse($item->{$field}, $item->{$timezoneField}); | ||||
|                 $date                   = Carbon::parse($item->{$field}, $item->{$timezoneField}); // @phpstan-ignore-line
 | ||||
|                 $date->setTimezone('UTC'); | ||||
|                 $item->{$field}         = $date->format('Y-m-d H:i:s'); | ||||
|                 $item->{$timezoneField} = 'UTC'; | ||||
|                 $item->{$field}         = $date->format('Y-m-d H:i:s'); // @phpstan-ignore-line
 | ||||
|                 $item->{$timezoneField} = 'UTC';                        // @phpstan-ignore-line
 | ||||
|                 $item->save(); | ||||
|             } | ||||
|         ); | ||||
|   | ||||
| @@ -26,9 +26,9 @@ namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Factory\AccountFactory; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| @@ -111,6 +111,8 @@ class CorrectsAccountTypes extends Command | ||||
|             $this->friendlyLine(sprintf('Found %d journals that need to be fixed.', $resultSet->count())); | ||||
|             foreach ($resultSet as $entry) { | ||||
|                 app('log')->debug(sprintf('Now fixing journal #%d', $entry->id)); | ||||
| 
 | ||||
|                 /** @var null|TransactionJournal $journal */ | ||||
|                 $journal = TransactionJournal::find($entry->id); | ||||
|                 if (null !== $journal) { | ||||
|                     $this->inspectJournal($journal); | ||||
| @@ -245,18 +247,18 @@ class CorrectsAccountTypes extends Command | ||||
| 
 | ||||
|     private function shouldBeTransfer(string $transactionType, string $sourceType, string $destinationType): bool | ||||
|     { | ||||
|         return TransactionType::TRANSFER === $transactionType && AccountType::ASSET === $sourceType && $this->isLiability($destinationType); | ||||
|         return TransactionTypeEnum::TRANSFER->value === $transactionType && AccountTypeEnum::ASSET->value === $sourceType && $this->isLiability($destinationType); | ||||
|     } | ||||
| 
 | ||||
|     private function isLiability(string $destinationType): bool | ||||
|     { | ||||
|         return AccountType::LOAN === $destinationType || AccountType::DEBT === $destinationType || AccountType::MORTGAGE === $destinationType; | ||||
|         return AccountTypeEnum::LOAN->value === $destinationType || AccountTypeEnum::DEBT->value === $destinationType || AccountTypeEnum::MORTGAGE->value === $destinationType; | ||||
|     } | ||||
| 
 | ||||
|     private function makeTransfer(TransactionJournal $journal): void | ||||
|     { | ||||
|         // from an asset to a liability should be a withdrawal:
 | ||||
|         $withdrawal = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); | ||||
|         $withdrawal = TransactionType::whereType(TransactionTypeEnum::WITHDRAWAL->value)->first(); | ||||
|         $journal->transactionType()->associate($withdrawal); | ||||
|         $journal->save(); | ||||
|         $message    = sprintf('Converted transaction #%d from a transfer to a withdrawal.', $journal->id); | ||||
| @@ -268,13 +270,13 @@ class CorrectsAccountTypes extends Command | ||||
| 
 | ||||
|     private function shouldBeDeposit(string $transactionType, string $sourceType, string $destinationType): bool | ||||
|     { | ||||
|         return TransactionType::TRANSFER === $transactionType && $this->isLiability($sourceType) && AccountType::ASSET === $destinationType; | ||||
|         return TransactionTypeEnum::TRANSFER->value === $transactionType && $this->isLiability($sourceType) && AccountTypeEnum::ASSET->value === $destinationType; | ||||
|     } | ||||
| 
 | ||||
|     private function makeDeposit(TransactionJournal $journal): void | ||||
|     { | ||||
|         // from a liability to an asset should be a deposit.
 | ||||
|         $deposit = TransactionType::whereType(TransactionType::DEPOSIT)->first(); | ||||
|         $deposit = TransactionType::whereType(TransactionTypeEnum::DEPOSIT->value)->first(); | ||||
|         $journal->transactionType()->associate($deposit); | ||||
|         $journal->save(); | ||||
|         $message = sprintf('Converted transaction #%d from a transfer to a deposit.', $journal->id); | ||||
| @@ -286,7 +288,7 @@ class CorrectsAccountTypes extends Command | ||||
| 
 | ||||
|     private function shouldGoToExpenseAccount(string $transactionType, string $sourceType, string $destinationType): bool | ||||
|     { | ||||
|         return TransactionType::WITHDRAWAL === $transactionType && AccountType::ASSET === $sourceType && AccountType::REVENUE === $destinationType; | ||||
|         return TransactionTypeEnum::WITHDRAWAL->value === $transactionType && AccountTypeEnum::ASSET->value === $sourceType && AccountTypeEnum::REVENUE->value === $destinationType; | ||||
|     } | ||||
| 
 | ||||
|     private function makeExpenseDestination(TransactionJournal $journal, Transaction $destination): void | ||||
| @@ -294,7 +296,7 @@ class CorrectsAccountTypes extends Command | ||||
|         // withdrawals with a revenue account as destination instead of an expense account.
 | ||||
|         $this->factory->setUser($journal->user); | ||||
|         $oldDest = $destination->account; | ||||
|         $result  = $this->factory->findOrCreate($destination->account->name, AccountType::EXPENSE); | ||||
|         $result  = $this->factory->findOrCreate($destination->account->name, AccountTypeEnum::EXPENSE->value); | ||||
|         $destination->account()->associate($result); | ||||
|         $destination->save(); | ||||
|         $message = sprintf( | ||||
| @@ -312,7 +314,7 @@ class CorrectsAccountTypes extends Command | ||||
| 
 | ||||
|     private function shouldComeFromRevenueAccount(string $transactionType, string $sourceType, string $destinationType): bool | ||||
|     { | ||||
|         return TransactionType::DEPOSIT === $transactionType && AccountType::EXPENSE === $sourceType && AccountType::ASSET === $destinationType; | ||||
|         return TransactionTypeEnum::DEPOSIT->value === $transactionType && AccountTypeEnum::EXPENSE->value === $sourceType && AccountTypeEnum::ASSET->value === $destinationType; | ||||
|     } | ||||
| 
 | ||||
|     private function makeRevenueSource(TransactionJournal $journal, Transaction $source): void | ||||
| @@ -320,7 +322,7 @@ class CorrectsAccountTypes extends Command | ||||
|         // deposits with an expense account as source instead of a revenue account.
 | ||||
|         // find revenue account.
 | ||||
|         $this->factory->setUser($journal->user); | ||||
|         $result    = $this->factory->findOrCreate($source->account->name, AccountType::REVENUE); | ||||
|         $result    = $this->factory->findOrCreate($source->account->name, AccountTypeEnum::REVENUE->value); | ||||
|         $oldSource = $source->account; | ||||
|         $source->account()->associate($result); | ||||
|         $source->save(); | ||||
|   | ||||
| @@ -63,7 +63,7 @@ class CorrectsCurrencies extends Command | ||||
|         $repos           = app(CurrencyRepositoryInterface::class); | ||||
| 
 | ||||
|         // first check if the user has any default currency (not necessarily the case, so can be forced).
 | ||||
|         $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($userGroup); | ||||
|         $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($userGroup); | ||||
| 
 | ||||
|         Log::debug(sprintf('Now correcting currencies for user group #%d', $userGroup->id)); | ||||
|         $found           = [$defaultCurrency->id]; | ||||
|   | ||||
| @@ -25,7 +25,7 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
| @@ -73,7 +73,7 @@ class CorrectsFrontpageAccounts extends Command | ||||
|                 $accountIdInt = (int) $accountId; | ||||
|                 $account      = $repository->find($accountIdInt); | ||||
|                 if (null !== $account | ||||
|                     && in_array($account->accountType->type, [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true) | ||||
|                     && in_array($account->accountType->type, [AccountTypeEnum::ASSET->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value], true) | ||||
|                     && true === $account->active) { | ||||
|                     $fixed[] = $account->id; | ||||
|                 } | ||||
|   | ||||
| @@ -25,8 +25,8 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Collection; | ||||
| 
 | ||||
| @@ -78,14 +78,14 @@ class CorrectsIbans extends Command | ||||
|                 continue; | ||||
|             } | ||||
|             $type   = $account->accountType->type; | ||||
|             if (in_array($type, [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true)) { | ||||
|             if (in_array($type, [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], true)) { | ||||
|                 $type = 'liabilities'; | ||||
|             } | ||||
|             if (array_key_exists($iban, $set[$userId])) { | ||||
|                 // iban already in use! two exceptions exist:
 | ||||
|                 if ( | ||||
|                     !(AccountType::EXPENSE === $set[$userId][$iban] && AccountType::REVENUE === $type) // allowed combination
 | ||||
|                     && !(AccountType::REVENUE === $set[$userId][$iban] && AccountType::EXPENSE === $type) // also allowed combination.
 | ||||
|                     !(AccountTypeEnum::EXPENSE->value === $set[$userId][$iban] && AccountTypeEnum::REVENUE->value === $type) // allowed combination
 | ||||
|                     && !(AccountTypeEnum::REVENUE->value === $set[$userId][$iban] && AccountTypeEnum::EXPENSE->value === $type) // also allowed combination.
 | ||||
|                 ) { | ||||
|                     $this->friendlyWarning( | ||||
|                         sprintf( | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <?php | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| /* | ||||
|  * RecalculateNativeAmounts.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * CorrectsNativeAmounts.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -21,6 +21,8 @@ declare(strict_types=1); | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| @@ -59,7 +61,7 @@ class CorrectsNativeAmounts extends Command | ||||
|      */ | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if (!config('cer.enabled')) { | ||||
|         if (false === config('cer.enabled')) { | ||||
|             $this->friendlyInfo('This command will not run because currency exchange rates are disabled.'); | ||||
| 
 | ||||
|             return 0; | ||||
| @@ -86,7 +88,7 @@ class CorrectsNativeAmounts extends Command | ||||
| 
 | ||||
|         // do a check with the group's currency so we can skip some stuff.
 | ||||
|         Preferences::mark(); | ||||
|         $currency = app('amount')->getDefaultCurrencyByUserGroup($userGroup); | ||||
|         $currency = app('amount')->getNativeCurrencyByUserGroup($userGroup); | ||||
| 
 | ||||
|         $this->recalculatePiggyBanks($userGroup, $currency); | ||||
|         $this->recalculateBudgets($userGroup, $currency); | ||||
| @@ -100,7 +102,14 @@ class CorrectsNativeAmounts extends Command | ||||
|     { | ||||
|         $set = $userGroup->accounts()->where(function (EloquentBuilder $q): void { | ||||
|             $q->whereNotNull('virtual_balance'); | ||||
| 
 | ||||
|             // this needs a different piece of code for postgres.
 | ||||
|             if ('pgsql' === config('database.default')) { | ||||
|                 $q->orWhere(DB::raw('CAST(virtual_balance AS TEXT)'), '!=', ''); | ||||
|             } | ||||
|             if ('pgsql' !== config('database.default')) { | ||||
|                 $q->orWhere('virtual_balance', '!=', ''); | ||||
|             } | ||||
|         })->get(); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
| @@ -144,7 +153,7 @@ class CorrectsNativeAmounts extends Command | ||||
|     { | ||||
|         $set = $piggyBank->piggyBankEvents()->get(); | ||||
|         $set->each( | ||||
|             static function (PiggyBankEvent $event): void { | ||||
|             static function (PiggyBankEvent $event): void { // @phpstan-ignore-line
 | ||||
|                 $event->touch(); | ||||
|             } | ||||
|         ); | ||||
| @@ -216,7 +225,6 @@ class CorrectsNativeAmounts extends Command | ||||
|         $set                              = DB::table('transactions') | ||||
|             ->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|             ->where('transaction_journals.user_group_id', $userGroup->id) | ||||
| 
 | ||||
|             ->where(function (DatabaseBuilder $q1) use ($currency): void { | ||||
|                 $q1->where(function (DatabaseBuilder $q2) use ($currency): void { | ||||
|                     $q2->whereNot('transactions.transaction_currency_id', $currency->id)->whereNull('transactions.foreign_currency_id'); | ||||
| @@ -234,8 +242,9 @@ class CorrectsNativeAmounts extends Command | ||||
|         TransactionObserver::$recalculate = false; | ||||
|         foreach ($set as $item) { | ||||
|             // here we are.
 | ||||
|             /** @var null|Transaction $transaction */ | ||||
|             $transaction = Transaction::find($item->id); | ||||
|             $transaction->touch(); | ||||
|             $transaction?->touch(); | ||||
|         } | ||||
|         TransactionObserver::$recalculate = true; | ||||
|         Log::debug(sprintf('Recalculated %d transactions.', $set->count())); | ||||
|   | ||||
| @@ -25,12 +25,12 @@ 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\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Collection; | ||||
| @@ -65,10 +65,10 @@ class CorrectsOpeningBalanceCurrencies extends Command | ||||
| 
 | ||||
|     private function getJournals(): Collection | ||||
|     { | ||||
|         // @var Collection
 | ||||
|         /** @var Collection */ | ||||
|         return TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|             ->whereNull('transaction_journals.deleted_at') | ||||
|             ->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*']) | ||||
|             ->where('transaction_types.type', TransactionTypeEnum::OPENING_BALANCE->value)->get(['transaction_journals.*']) | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
| @@ -96,7 +96,7 @@ class CorrectsOpeningBalanceCurrencies extends Command | ||||
|         foreach ($transactions as $transaction) { | ||||
|             /** @var null|Account $account */ | ||||
|             $account = $transaction->account()->first(); | ||||
|             if (null !== $account && AccountType::INITIAL_BALANCE !== $account->accountType()->first()->type) { | ||||
|             if (null !== $account && AccountTypeEnum::INITIAL_BALANCE->value !== $account->accountType()->first()->type) { | ||||
|                 return $account; | ||||
|             } | ||||
|         } | ||||
| @@ -132,6 +132,6 @@ class CorrectsOpeningBalanceCurrencies extends Command | ||||
|         $repos = app(AccountRepositoryInterface::class); | ||||
|         $repos->setUser($account->user); | ||||
| 
 | ||||
|         return $repos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->userGroup); | ||||
|         return $repos->getAccountCurrency($account) ?? app('amount')->getNativeCurrencyByUserGroup($account->userGroup); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <?php | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| /* | ||||
|  * MigratePreferences.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * CorrectsPreferences.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -21,6 +21,8 @@ declare(strict_types=1); | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Models\Preference; | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user