mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Compare commits
	
		
			410 Commits
		
	
	
		
			v6.3.0
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | dbc0210304 | ||
|  | a709e224d4 | ||
|  | 83f3eddf44 | ||
|  | 7cfc4c2671 | ||
|  | 1c6055cb2d | ||
|  | 4f4576e458 | ||
|  | 84d3bcbb37 | ||
|  | c91c87d646 | ||
|  | e09b6034f7 | ||
|  | ad67bb80f3 | ||
|  | a88d0de34d | ||
|  | ecf498cc81 | ||
|  | 569f553d26 | ||
|  | 7d45bc46b8 | ||
|  | 08553fcfb2 | ||
|  | 58c76bee94 | ||
|  | 3fa1b6dd27 | ||
|  | 63aa8adab7 | ||
|  | 70b8ea0acb | ||
|  | d800a01e33 | ||
|  | 52f3ec7d3d | ||
|  | d4978a09ee | ||
|  | 77095276e2 | ||
|  | b77a8591dc | ||
|  | 132d7d9ff8 | ||
|  | a981e2c5cb | ||
|  | 77b88b7758 | ||
|  | b9894eea57 | ||
|  | 469319a240 | ||
|  | 5a55593e34 | ||
|  | 8979e5ad5a | ||
|  | 3ab65c27ac | ||
|  | a3cac6fd0f | ||
|  | 1acb5d8681 | ||
|  | f24cdc7897 | ||
|  | a2b611253b | ||
|  | 252459c29b | ||
|  | 3582baf9f7 | ||
|  | b03ecab035 | ||
|  | 547a4e9dbb | ||
|  | 62e33a51bd | ||
|  | 8b0ee7e20a | ||
|  | 0e0ec89b26 | ||
|  | ec08485c2b | ||
|  | d91d30c8f0 | ||
|  | 634a43c361 | ||
|  | f2f86e1139 | ||
|  | a1c870c962 | ||
|  | 98be3a1414 | ||
|  | e3c3a0a84b | ||
|  | b254074867 | ||
|  | f21a5b3000 | ||
|  | 6029fe2e84 | ||
|  | 651e11ed1c | ||
|  | 5ba29cdacd | ||
|  | f948cc95b4 | ||
|  | 11e721c6c9 | ||
|  | 4bc77b2707 | ||
|  | 6639309935 | ||
|  | 52e08bb9eb | ||
|  | 435ca994cf | ||
|  | b29c35864c | ||
|  | 2ddc012549 | ||
|  | 22c88383ad | ||
|  | 9593f1b44e | ||
|  | 22f67be0b5 | ||
|  | 0e1633b52b | ||
|  | 0070e000b6 | ||
|  | c525a18263 | ||
|  | 68fbd8d5f4 | ||
|  | 0724c005cf | ||
|  | e662275400 | ||
|  | def2dd77ab | ||
|  | 36e87f3383 | ||
|  | e420752991 | ||
|  | c541cf48c3 | ||
|  | 521db984ab | ||
|  | b2b3c3f135 | ||
|  | b0033cf9ed | ||
|  | 50279d623c | ||
|  | 6341743cf9 | ||
|  | 072212c112 | ||
|  | 362705ec71 | ||
|  | 6ce926e7d2 | ||
|  | 1652c3af72 | ||
|  | 012172b0b5 | ||
|  | 957bc00847 | ||
|  | 7f827fb277 | ||
|  | 8e700944fd | ||
|  | 037a128942 | ||
|  | ca364dc877 | ||
|  | e55af7186c | ||
|  | 354bbebbee | ||
|  | a70fab1e87 | ||
|  | b9c93091cd | ||
|  | 4349f8f303 | ||
|  | 5088e20f25 | ||
|  | 3f81aa7403 | ||
|  | 8885d1dbeb | ||
|  | a6ba75d528 | ||
|  | 667cbb1332 | ||
|  | d1bae875f7 | ||
|  | c5cf529413 | ||
|  | 62b9f2785f | ||
|  | 3b85f87502 | ||
|  | 87d3d14504 | ||
|  | 5637573fd0 | ||
|  | 48255ae6ee | ||
|  | ea02986170 | ||
|  | f4fbc15ac6 | ||
|  | a02c4b42a4 | ||
|  | 1ff47441ce | ||
|  | 2cc8568077 | ||
|  | 408687ec6b | ||
|  | 308abffb0b | ||
|  | 6743b3fe83 | ||
|  | ac0113e445 | ||
|  | 0f0a28c3d9 | ||
|  | 79f2d70211 | ||
|  | 8a06c0f7ec | ||
|  | c54da62005 | ||
|  | e5923202af | ||
|  | eb6f78406e | ||
|  | d61f87f649 | ||
|  | 33dcce7525 | ||
|  | b1d86c3a37 | ||
|  | 822dee6e70 | ||
|  | f6dac83777 | ||
|  | d3c557ca22 | ||
|  | 853a99852e | ||
|  | 8f24ac4fcd | ||
|  | 8b09cfb8c9 | ||
|  | 18ae950d2e | ||
|  | 69dfbda847 | ||
|  | 4ec2fcdb8a | ||
|  | 08879d31ba | ||
|  | 66d09450d3 | ||
|  | 74f7c07a76 | ||
|  | ae3d0a3e49 | ||
|  | 61e8d7d7a2 | ||
|  | 62c5440605 | ||
|  | 0aa90b9453 | ||
|  | 855bc2f8e7 | ||
|  | d8f05492c3 | ||
|  | 4a264f34fa | ||
|  | 5a1413e758 | ||
|  | 84dbeeb0ce | ||
|  | d868dc0945 | ||
|  | beecf9c229 | ||
|  | e39ba46398 | ||
|  | e6b6a3cee5 | ||
|  | b5483f6ad3 | ||
|  | a751218d53 | ||
|  | 2af5e6eeef | ||
|  | 013c43f9f2 | ||
|  | 7e08a1f33c | ||
|  | e592b56d7a | ||
|  | a2479f71fe | ||
|  | 7d3b993b98 | ||
|  | 90623101a3 | ||
|  | e2eca79b25 | ||
|  | 8c0ee8f024 | ||
|  | 69cae3ae55 | ||
|  | 8a06298385 | ||
|  | acc3c294d8 | ||
|  | dbf7dba421 | ||
|  | 65813f290d | ||
|  | 3491fbb99d | ||
|  | cb6b3d5f85 | ||
|  | 956d4e09c3 | ||
|  | 6a7c35e7bc | ||
|  | 090aecb5f5 | ||
|  | b653d63d3d | ||
|  | 258dbf4a98 | ||
|  | 53335077ff | ||
|  | ecfb3e2f95 | ||
|  | f512e6724e | ||
|  | de9efb0727 | ||
|  | 9075fa8ac8 | ||
|  | 768bd892c8 | ||
|  | 9d9483e20f | ||
|  | 935453796e | ||
|  | c2d3f5da16 | ||
|  | 9e6f9d16e4 | ||
|  | fad016f92f | ||
|  | 30df6684cb | ||
|  | 4aa911420a | ||
|  | 19555a7046 | ||
|  | e5c409a8fc | ||
|  | 3adf3d2fdb | ||
|  | 0923d5a23e | ||
|  | 76b8cdc385 | ||
|  | 0a27da83eb | ||
|  | 17d6e2be85 | ||
|  | 7381f3eba9 | ||
|  | 7f2ef1b8e1 | ||
|  | 9dccae2402 | ||
|  | 073afd5b6e | ||
|  | 4167d85be2 | ||
|  | ee28d1307d | ||
|  | 7562215666 | ||
|  | 0203b918e9 | ||
|  | ae7c664418 | ||
|  | f13e0991fb | ||
|  | deae94b658 | ||
|  | c38c752520 | ||
|  | 28e7df2527 | ||
|  | cb0b42e44b | ||
|  | a3674c4dfe | ||
|  | 27480561ee | ||
|  | 6ea7152423 | ||
|  | dab95f7a86 | ||
|  | adf34805a8 | ||
|  | 93e926465f | ||
|  | 5b0be91f93 | ||
|  | 01e7b604da | ||
|  | 974a550d22 | ||
|  | 58d175444b | ||
|  | 29d8861e96 | ||
|  | eb832c750f | ||
|  | 134770644a | ||
|  | a9f21c9371 | ||
|  | 781947beeb | ||
|  | 9760cd2f97 | ||
|  | d317e9ec32 | ||
|  | 534f7fcadb | ||
|  | fb3f7a1d4b | ||
|  | bf2c3e3561 | ||
|  | b670f81dcd | ||
|  | 7aac1cdf67 | ||
|  | fa0ac8a16c | ||
|  | 0990b1f0b4 | ||
|  | c1922670c8 | ||
|  | 81cd89d66f | ||
|  | f5c202543c | ||
|  | 034f437c6b | ||
|  | 8550ba6138 | ||
|  | a51501025b | ||
|  | a9d26e4586 | ||
|  | 949691935f | ||
|  | 4835b05304 | ||
|  | cce5a73dd2 | ||
|  | 3152f635dd | ||
|  | 12e8651017 | ||
|  | f88286c848 | ||
|  | 39cf0533d9 | ||
|  | 6d82887960 | ||
|  | 262f1bae34 | ||
|  | 75dfdcc220 | ||
|  | c3a3bdf525 | ||
|  | 602df95f3c | ||
|  | 296a64e284 | ||
|  | b87b99a755 | ||
|  | bf53f5d6b7 | ||
|  | bcbb868acc | ||
|  | b3a9e6569e | ||
|  | f174f124ef | ||
|  | 8745377f31 | ||
|  | cf76e93f31 | ||
|  | 19e36f6f6e | ||
|  | 2a7bb6f048 | ||
|  | 536eacbc0c | ||
|  | af78158d0b | ||
|  | fb97910a34 | ||
|  | 66b4d14129 | ||
|  | fd53047dbc | ||
|  | 5f6fc1bab4 | ||
|  | cd0b64bd24 | ||
|  | 91b26bce0e | ||
|  | 26a8bd921d | ||
|  | ad77d55c16 | ||
|  | 445a383dd0 | ||
|  | 1666af939e | ||
|  | 35447f5eee | ||
|  | 7c6fcb5731 | ||
|  | fabd9bf765 | ||
|  | 6352d26633 | ||
|  | ebef145bd6 | ||
|  | acc89eb5f9 | ||
|  | 6523596415 | ||
|  | b6c2d23116 | ||
|  | 2a123354f9 | ||
|  | 1e7ea4b76c | ||
|  | d959526eb3 | ||
|  | 8846ee9091 | ||
|  | 6eb8d0fc8c | ||
|  | 1b0e16b6a5 | ||
|  | 2e4df28288 | ||
|  | f3b7a3015d | ||
|  | 5de5e08b1d | ||
|  | 0a116cd04c | ||
|  | fd32a692c1 | ||
|  | 1ac762aba8 | ||
|  | 315dc532b6 | ||
|  | e19ed1be15 | ||
|  | cbb0621fd9 | ||
|  | 049cbab861 | ||
|  | 28b620fb5c | ||
|  | c183f91ff6 | ||
|  | 172efae41c | ||
|  | 756e857ba0 | ||
|  | 1cde7aab0c | ||
|  | 2d67eece5d | ||
|  | b1f79c4c0f | ||
|  | 33bd2ceae8 | ||
|  | e68850f192 | ||
|  | 450ac7e6ee | ||
|  | 91f52b5dbc | ||
|  | eed2405d76 | ||
|  | c956df7790 | ||
|  | 0fdccec6a8 | ||
|  | 8ded54d7a8 | ||
|  | bb1b4ca5ca | ||
|  | e90d60113b | ||
|  | d95dada0e0 | ||
|  | 8722456595 | ||
|  | b5ad226451 | ||
|  | ddb0e66651 | ||
|  | e802899608 | ||
|  | 0894d3bf42 | ||
|  | 80bcfd3bcd | ||
|  | 8c410f42bd | ||
|  | 7a1021dffc | ||
|  | 63883c9a84 | ||
|  | 50d7f9d1ec | ||
|  | ebc7ea0eb6 | ||
|  | b905efd0aa | ||
|  | 93085599b7 | ||
|  | 8a8bbaf827 | ||
|  | 96a66b894a | ||
|  | 1ba641c279 | ||
|  | 6c5ddfcb8a | ||
|  | 65ddc246dc | ||
|  | e4aff5ff4c | ||
|  | dfece91541 | ||
|  | 6ddda13c3a | ||
|  | 46219c4678 | ||
|  | a1595d0647 | ||
|  | 4ee9f9bb27 | ||
|  | bcaa0bddea | ||
|  | 01cce49070 | ||
|  | 293be04d40 | ||
|  | 44a00ec8eb | ||
|  | d84e772945 | ||
|  | b475f6c51d | ||
|  | 2712662510 | ||
|  | 1f2eeba862 | ||
|  | 46a60134f4 | ||
|  | f3f7820816 | ||
|  | a57f8076b2 | ||
|  | 517afa2273 | ||
|  | 2142b23aec | ||
|  | 1bec43b111 | ||
|  | d2978a5ee8 | ||
|  | 39b61c71e8 | ||
|  | fa2c964790 | ||
|  | 134aeb3a46 | ||
|  | 6f6e1a4ff4 | ||
|  | b743bf3d9e | ||
|  | 84ee6f16c9 | ||
|  | 9fe39e42b3 | ||
|  | 4013c7e316 | ||
|  | 0b76747531 | ||
|  | 3129756b37 | ||
|  | b0df383004 | ||
|  | 9c5b1df86c | ||
|  | 5854e24775 | ||
|  | 3f873422f2 | ||
|  | f898990773 | ||
|  | a5759ab1c6 | ||
|  | 9bd6417e02 | ||
|  | cd12a10214 | ||
|  | ee8cb62e04 | ||
|  | 87ee95a852 | ||
|  | 10f8436885 | ||
|  | 6955846a1c | ||
|  | 11d2f8d471 | ||
|  | 99347ffff1 | ||
|  | 3ddc11a905 | ||
|  | 0a48c0c20f | ||
|  | 8bc764d6ef | ||
|  | 4b4f568558 | ||
|  | d42117281a | ||
|  | d68ed5a713 | ||
|  | 2f6f36c3f0 | ||
|  | 984aa02e35 | ||
|  | cdadc7d533 | ||
|  | 4d59955cc5 | ||
|  | fc547ba59a | ||
|  | 1b2ded3167 | ||
|  | dcf20a472a | ||
|  | 7bd528defe | ||
|  | 9e6d123165 | ||
|  | c592f51c83 | ||
|  | fbb6f30366 | ||
|  | 4546c721fb | ||
|  | 3a659c9a81 | ||
|  | e28a988eb3 | ||
|  | a29742fe1f | ||
|  | dd06838eec | ||
|  | 5eb828bff8 | ||
|  | c7f3701053 | ||
|  | ab6799442c | ||
|  | 1fe9bf7d76 | ||
|  | bd14797da6 | ||
|  | 93b4e6a8d0 | ||
|  | 5566671971 | ||
|  | defcc7a00c | ||
|  | 5183de634b | ||
|  | 7771b0311c | 
							
								
								
									
										290
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										290
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -151,16 +151,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "composer/semver", | ||||
|             "version": "3.4.3", | ||||
|             "version": "3.4.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/composer/semver.git", | ||||
|                 "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" | ||||
|                 "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", | ||||
|                 "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", | ||||
|                 "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", | ||||
|                 "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -212,7 +212,7 @@ | ||||
|             "support": { | ||||
|                 "irc": "ircs://irc.libera.chat:6697/composer", | ||||
|                 "issues": "https://github.com/composer/semver/issues", | ||||
|                 "source": "https://github.com/composer/semver/tree/3.4.3" | ||||
|                 "source": "https://github.com/composer/semver/tree/3.4.4" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -222,13 +222,9 @@ | ||||
|                 { | ||||
|                     "url": "https://github.com/composer", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/composer/composer", | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-09-19T14:15:21+00:00" | ||||
|             "time": "2025-08-20T19:15:30+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "composer/xdebug-handler", | ||||
| @@ -406,16 +402,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "friendsofphp/php-cs-fixer", | ||||
|             "version": "v3.86.0", | ||||
|             "version": "v3.88.2", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", | ||||
|                 "reference": "4a952bd19dc97879b0620f495552ef09b55f7d36" | ||||
|                 "reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4a952bd19dc97879b0620f495552ef09b55f7d36", | ||||
|                 "reference": "4a952bd19dc97879b0620f495552ef09b55f7d36", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a8d15584bafb0f0d9d938827840060fd4a3ebc99", | ||||
|                 "reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -426,39 +422,38 @@ | ||||
|                 "ext-hash": "*", | ||||
|                 "ext-json": "*", | ||||
|                 "ext-tokenizer": "*", | ||||
|                 "fidry/cpu-core-counter": "^1.2", | ||||
|                 "fidry/cpu-core-counter": "^1.3", | ||||
|                 "php": "^7.4 || ^8.0", | ||||
|                 "react/child-process": "^0.6.6", | ||||
|                 "react/event-loop": "^1.5", | ||||
|                 "react/promise": "^3.2", | ||||
|                 "react/promise": "^3.3", | ||||
|                 "react/socket": "^1.16", | ||||
|                 "react/stream": "^1.4", | ||||
|                 "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", | ||||
|                 "symfony/console": "^5.4.47 || ^6.4.13 || ^7.0", | ||||
|                 "symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0", | ||||
|                 "symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0", | ||||
|                 "symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0", | ||||
|                 "symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0", | ||||
|                 "symfony/polyfill-mbstring": "^1.32", | ||||
|                 "symfony/polyfill-php80": "^1.32", | ||||
|                 "symfony/polyfill-php81": "^1.32", | ||||
|                 "symfony/process": "^5.4.47 || ^6.4.20 || ^7.2", | ||||
|                 "symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0" | ||||
|                 "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0", | ||||
|                 "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0", | ||||
|                 "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0", | ||||
|                 "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0", | ||||
|                 "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0", | ||||
|                 "symfony/polyfill-mbstring": "^1.33", | ||||
|                 "symfony/polyfill-php80": "^1.33", | ||||
|                 "symfony/polyfill-php81": "^1.33", | ||||
|                 "symfony/polyfill-php84": "^1.33", | ||||
|                 "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2", | ||||
|                 "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "facile-it/paraunit": "^1.3.1 || ^2.6", | ||||
|                 "infection/infection": "^0.29.14", | ||||
|                 "justinrainbow/json-schema": "^5.3 || ^6.4", | ||||
|                 "facile-it/paraunit": "^1.3.1 || ^2.7", | ||||
|                 "infection/infection": "^0.31.0", | ||||
|                 "justinrainbow/json-schema": "^6.5", | ||||
|                 "keradus/cli-executor": "^2.2", | ||||
|                 "mikey179/vfsstream": "^1.6.12", | ||||
|                 "php-coveralls/php-coveralls": "^2.8", | ||||
|                 "php-cs-fixer/accessible-object": "^1.1", | ||||
|                 "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", | ||||
|                 "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", | ||||
|                 "phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25", | ||||
|                 "symfony/polyfill-php84": "^1.32", | ||||
|                 "symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1", | ||||
|                 "symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1" | ||||
|                 "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", | ||||
|                 "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2", | ||||
|                 "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "ext-dom": "For handling output formats in XML", | ||||
| @@ -499,7 +494,7 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.86.0" | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.2" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -507,7 +502,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-08-13T22:36:21+00:00" | ||||
|             "time": "2025-09-27T00:24:15+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "psr/container", | ||||
| @@ -959,23 +954,23 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "react/promise", | ||||
|             "version": "v3.2.0", | ||||
|             "version": "v3.3.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/reactphp/promise.git", | ||||
|                 "reference": "8a164643313c71354582dc850b42b33fa12a4b63" | ||||
|                 "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", | ||||
|                 "reference": "8a164643313c71354582dc850b42b33fa12a4b63", | ||||
|                 "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", | ||||
|                 "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=7.1.0" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "phpstan/phpstan": "1.10.39 || 1.4.10", | ||||
|                 "phpstan/phpstan": "1.12.28 || 1.4.10", | ||||
|                 "phpunit/phpunit": "^9.6 || ^7.5" | ||||
|             }, | ||||
|             "type": "library", | ||||
| @@ -1020,7 +1015,7 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/reactphp/promise/issues", | ||||
|                 "source": "https://github.com/reactphp/promise/tree/v3.2.0" | ||||
|                 "source": "https://github.com/reactphp/promise/tree/v3.3.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1028,7 +1023,7 @@ | ||||
|                     "type": "open_collective" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-05-24T10:39:05+00:00" | ||||
|             "time": "2025-08-19T18:57:03+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "react/socket", | ||||
| @@ -1257,16 +1252,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/console", | ||||
|             "version": "v7.3.2", | ||||
|             "version": "v7.3.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/console.git", | ||||
|                 "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1" | ||||
|                 "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1", | ||||
|                 "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1", | ||||
|                 "url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", | ||||
|                 "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1331,7 +1326,7 @@ | ||||
|                 "terminal" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/console/tree/v7.3.2" | ||||
|                 "source": "https://github.com/symfony/console/tree/v7.3.4" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1351,7 +1346,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-07-30T17:13:41+00:00" | ||||
|             "time": "2025-09-22T15:31:00+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/deprecation-contracts", | ||||
| @@ -1422,16 +1417,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/event-dispatcher", | ||||
|             "version": "v7.3.0", | ||||
|             "version": "v7.3.3", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/event-dispatcher.git", | ||||
|                 "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" | ||||
|                 "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", | ||||
|                 "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", | ||||
|                 "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", | ||||
|                 "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1482,7 +1477,7 @@ | ||||
|             "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" | ||||
|                 "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1493,12 +1488,16 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-04-22T09:11:45+00:00" | ||||
|             "time": "2025-08-13T11:49:31+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/event-dispatcher-contracts", | ||||
| @@ -1716,16 +1715,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/options-resolver", | ||||
|             "version": "v7.3.2", | ||||
|             "version": "v7.3.3", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/options-resolver.git", | ||||
|                 "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37" | ||||
|                 "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37", | ||||
|                 "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37", | ||||
|                 "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d", | ||||
|                 "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1763,7 +1762,7 @@ | ||||
|                 "options" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/options-resolver/tree/v7.3.2" | ||||
|                 "source": "https://github.com/symfony/options-resolver/tree/v7.3.3" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1783,11 +1782,11 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-07-15T11:36:08+00:00" | ||||
|             "time": "2025-08-05T10:16:07+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-ctype", | ||||
|             "version": "v1.32.0", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-ctype.git", | ||||
| @@ -1846,7 +1845,7 @@ | ||||
|                 "portable" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1857,6 +1856,10 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
| @@ -1866,16 +1869,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-intl-grapheme", | ||||
|             "version": "v1.32.0", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-intl-grapheme.git", | ||||
|                 "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" | ||||
|                 "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", | ||||
|                 "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", | ||||
|                 "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1924,7 +1927,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1935,16 +1938,20 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-09-09T11:45:10+00:00" | ||||
|             "time": "2025-06-27T09:58:17+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-intl-normalizer", | ||||
|             "version": "v1.32.0", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-intl-normalizer.git", | ||||
| @@ -2005,7 +2012,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2016,6 +2023,10 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
| @@ -2025,7 +2036,7 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-mbstring", | ||||
|             "version": "v1.32.0", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-mbstring.git", | ||||
| @@ -2086,7 +2097,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2097,6 +2108,10 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
| @@ -2106,7 +2121,7 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-php80", | ||||
|             "version": "v1.32.0", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-php80.git", | ||||
| @@ -2166,7 +2181,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2177,6 +2192,10 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
| @@ -2186,7 +2205,7 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/polyfill-php81", | ||||
|             "version": "v1.32.0", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/polyfill-php81.git", | ||||
| @@ -2242,7 +2261,7 @@ | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-php81/tree/v1.32.0" | ||||
|                 "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2253,6 +2272,10 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
| @@ -2261,17 +2284,97 @@ | ||||
|             "time": "2024-09-09T11:45:10+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/process", | ||||
|             "version": "v7.3.0", | ||||
|             "name": "symfony/polyfill-php84", | ||||
|             "version": "v1.33.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/process.git", | ||||
|                 "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" | ||||
|                 "url": "https://github.com/symfony/polyfill-php84.git", | ||||
|                 "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", | ||||
|                 "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", | ||||
|                 "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", | ||||
|                 "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=7.2" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "thanks": { | ||||
|                     "url": "https://github.com/symfony/polyfill", | ||||
|                     "name": "symfony/polyfill" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "files": [ | ||||
|                     "bootstrap.php" | ||||
|                 ], | ||||
|                 "psr-4": { | ||||
|                     "Symfony\\Polyfill\\Php84\\": "" | ||||
|                 }, | ||||
|                 "classmap": [ | ||||
|                     "Resources/stubs" | ||||
|                 ] | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Nicolas Grekas", | ||||
|                     "email": "p@tchwork.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Symfony Community", | ||||
|                     "homepage": "https://symfony.com/contributors" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "keywords": [ | ||||
|                 "compatibility", | ||||
|                 "polyfill", | ||||
|                 "portable", | ||||
|                 "shim" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
|                     "url": "https://symfony.com/sponsor", | ||||
|                     "type": "custom" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-06-24T13:30:11+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/process", | ||||
|             "version": "v7.3.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/process.git", | ||||
|                 "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", | ||||
|                 "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2303,7 +2406,7 @@ | ||||
|             "description": "Executes commands in sub-processes", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/process/tree/v7.3.0" | ||||
|                 "source": "https://github.com/symfony/process/tree/v7.3.4" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2314,12 +2417,16 @@ | ||||
|                     "url": "https://github.com/fabpot", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://github.com/nicolas-grekas", | ||||
|                     "type": "github" | ||||
|                 }, | ||||
|                 { | ||||
|                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-04-17T09:11:12+00:00" | ||||
|             "time": "2025-09-11T10:12:26+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/service-contracts", | ||||
| @@ -2468,16 +2575,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/string", | ||||
|             "version": "v7.3.2", | ||||
|             "version": "v7.3.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/string.git", | ||||
|                 "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca" | ||||
|                 "reference": "f96476035142921000338bad71e5247fbc138872" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca", | ||||
|                 "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca", | ||||
|                 "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", | ||||
|                 "reference": "f96476035142921000338bad71e5247fbc138872", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2492,7 +2599,6 @@ | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "symfony/emoji": "^7.1", | ||||
|                 "symfony/error-handler": "^6.4|^7.0", | ||||
|                 "symfony/http-client": "^6.4|^7.0", | ||||
|                 "symfony/intl": "^6.4|^7.0", | ||||
|                 "symfony/translation-contracts": "^2.5|^3.0", | ||||
| @@ -2535,7 +2641,7 @@ | ||||
|                 "utf8" | ||||
|             ], | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/string/tree/v7.3.2" | ||||
|                 "source": "https://github.com/symfony/string/tree/v7.3.4" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2555,7 +2661,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-07-10T08:47:49+00:00" | ||||
|             "time": "2025-09-11T14:36:48+00:00" | ||||
|         } | ||||
|     ], | ||||
|     "packages-dev": [], | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| parameters: | ||||
|   scanFiles: | ||||
|     - ../_ide_helper.php | ||||
|   paths: | ||||
|     - ../app | ||||
|     - ../database | ||||
| @@ -9,30 +7,26 @@ parameters: | ||||
|     - ../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 | ||||
|     # all errors below I will never fix. | ||||
|     - '#expects view-string\|null, string given#' | ||||
|     - '#expects view-string, string given#' | ||||
|     - "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#" | ||||
|     - identifier: missingType.generics # not interesting enough to fix. | ||||
|     - | ||||
|         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#' | ||||
|     - identifier: varTag.type # needs a custom extension for every repository, not gonna happen. | ||||
|     - '#Dynamic call to static method Illuminate#' | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' # is custom scope | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#' # is custom scope | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#' # is to allow soft delete | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#' # is a custom scope | ||||
|     - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#' # is to allow soft delete | ||||
|  | ||||
|   # The level 8 is the highest level. original was 5 | ||||
|   # 7 is more than enough, higher just leaves NULL things. | ||||
|   level: 7 | ||||
|   level: 6 | ||||
|  | ||||
|   | ||||
| @@ -314,8 +314,9 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
|  | ||||
| # | ||||
| # Disable or enable the running balance column data | ||||
| # Please disable this. It's a very experimental feature. | ||||
| # Disable or enable the running balance column data. | ||||
| # If you enable this, please also run "php artisan firefly-iii:correct-database" | ||||
| # This will take some time the first run. | ||||
| # | ||||
| USE_RUNNING_BALANCE=false | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								.github/label-actions.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/label-actions.yml
									
									
									
									
										vendored
									
									
								
							| @@ -25,7 +25,7 @@ feature: | ||||
|  | ||||
|       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. | ||||
|       If you come across this issue, please be aware there is NO need to reply with "+1" or "I need this too" or "any updates?" 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. | ||||
|  | ||||
|       Thank you for your contributions. | ||||
|  | ||||
| @@ -39,7 +39,7 @@ epic: | ||||
|  | ||||
|       This issue has been marked as an epic. In epics, large amounts of works are collected that will be part of a major new feature. If you have more ideas that could be a part of this epic, feel free to reply. | ||||
|  | ||||
|       *However*, 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. | ||||
|       *However*, please be aware there is NO need to reply with "+1" or "I need this too" or "any updates?" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. | ||||
|  | ||||
|       If you are merely interested in this epic's progress, you can subscribe to this issue to get updates. | ||||
|  | ||||
| @@ -56,7 +56,7 @@ enhancement: | ||||
|  | ||||
|       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. | ||||
|       If you come across this issue, please be aware there is NO need to reply with "+1" or "I need this too" or "any updates?" 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. | ||||
|  | ||||
|       Thank you for your contributions. | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/release-notes/alpha.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/release-notes/alpha.md
									
									
									
									
										vendored
									
									
								
							| @@ -16,6 +16,10 @@ Alpha releases are created to test new features and fixes before they are includ | ||||
| 
 | ||||
| The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/). | ||||
| 
 | ||||
| ## Develop with Firefly III | ||||
| 
 | ||||
| Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III. | ||||
| 
 | ||||
| ## Support Firefly III | ||||
| 
 | ||||
| Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration. | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/release-notes/beta.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/release-notes/beta.md
									
									
									
									
										vendored
									
									
								
							| @@ -16,6 +16,10 @@ Alpha releases are created to test new features and fixes before they are includ | ||||
| 
 | ||||
| The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/). | ||||
| 
 | ||||
| ## Develop with Firefly III | ||||
| 
 | ||||
| Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III. | ||||
| 
 | ||||
| ## Support Firefly III | ||||
| 
 | ||||
| Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration. | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/release-notes/branch.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/release-notes/branch.md
									
									
									
									
										vendored
									
									
								
							| @@ -16,6 +16,10 @@ There is no changelog for this release, as it is not final. However, [changelog. | ||||
| 
 | ||||
| The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/). | ||||
| 
 | ||||
| ## Develop with Firefly III | ||||
| 
 | ||||
| Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III. | ||||
| 
 | ||||
| ## Support Firefly III | ||||
| 
 | ||||
| Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration. | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/release-notes/develop.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/release-notes/develop.md
									
									
									
									
										vendored
									
									
								
							| @@ -16,6 +16,10 @@ The changelog for this release may not be up-to-date, so it is not included. How | ||||
| 
 | ||||
| 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/). | ||||
| 
 | ||||
| ## Develop with Firefly III | ||||
| 
 | ||||
| Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III. | ||||
| 
 | ||||
| ## Support Firefly III | ||||
| 
 | ||||
| Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration. | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/release-notes/release.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/release-notes/release.md
									
									
									
									
										vendored
									
									
								
							| @@ -11,6 +11,10 @@ Welcome to release %version of Firefly III. It contains the latest fixes, transl | ||||
| 
 | ||||
| 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/). | ||||
| 
 | ||||
| ## Develop with Firefly III | ||||
| 
 | ||||
| Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III. | ||||
| 
 | ||||
| ## Support Firefly III | ||||
| 
 | ||||
| Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration. | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,7 @@ jobs: | ||||
|     timeout-minutes: 10 | ||||
|     steps: | ||||
|       - name: Prune cancelled/skipped runs | ||||
|         uses: actions/github-script@v7 | ||||
|         uses: actions/github-script@v8 | ||||
|         with: | ||||
|           github-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|           script: | | ||||
| @@ -45,7 +45,7 @@ jobs: | ||||
|             } | ||||
|  | ||||
|       - name: Prune runs older than 3 days | ||||
|         uses: actions/github-script@v7 | ||||
|         uses: actions/github-script@v8 | ||||
|         with: | ||||
|           github-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|           script: | | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/depsreview.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/depsreview.yml
									
									
									
									
										vendored
									
									
								
							| @@ -9,7 +9,7 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: 'Checkout repository' | ||||
|         uses: actions/checkout@v4 | ||||
|         uses: actions/checkout@v5 | ||||
|         with: | ||||
|           fetch-depth: 0 | ||||
|       - name: 'Dependency review' | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/lock.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/lock.yml
									
									
									
									
										vendored
									
									
								
							| @@ -21,7 +21,7 @@ jobs: | ||||
|       discussions: write | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: JC5/lock-threads@v6.0.2 | ||||
|       - uses: JC5/lock-threads@v6.0.6 | ||||
|         with: | ||||
|           issue-inactive-days: 21 | ||||
|           pr-inactive-days: 21 | ||||
|   | ||||
							
								
								
									
										20
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -50,7 +50,7 @@ jobs: | ||||
|           git pull | ||||
|           echo "Current branch is $(git branch --show-current)" | ||||
|         env: | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|       - name: Configure Git | ||||
|         run: | | ||||
|           # do some configuration | ||||
| @@ -118,7 +118,7 @@ jobs: | ||||
|         env: | ||||
|           FIREFLY_III_ROOT: /github/workspace | ||||
|           GH_TOKEN: "" | ||||
|           FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|       - name: Generate JSON v1 | ||||
|         id: json-v1 | ||||
|         uses: JC5/firefly-iii-dev@main | ||||
| @@ -221,7 +221,7 @@ jobs: | ||||
|           echo "tarName=$tarName" >> "$GITHUB_ENV" | ||||
|           echo "BRANCH_NAME=$BRANCH_NAME" >> "$GITHUB_ENV" | ||||
|         env: | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|       - name: Commit all changes | ||||
|         run: | | ||||
|           # add all content, except output.txt (this contains the changelog and/or the download instructions) | ||||
| @@ -232,12 +232,12 @@ jobs: | ||||
|           git commit -m "🤖 Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true | ||||
|           git push | ||||
|         env: | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|       - name: Generate release description | ||||
|         id: release-description | ||||
|         uses: JC5/firefly-iii-dev@main | ||||
|         with: | ||||
|           action: "ff3:generate-release-notes firefly-iii ${{ github.event.inputs.version }}" | ||||
|           action: "ff3:generate-release-notes firefly-iii ${{ inputs.version || 'develop' }}" | ||||
|           output: 'output' | ||||
|         env: | ||||
|           FIREFLY_III_ROOT: /github/workspace | ||||
| @@ -250,7 +250,7 @@ jobs: | ||||
|             fi | ||||
|  | ||||
|           echo "Merge all changes from $BRANCH_NAME back into '$MERGE_INTO' using a PR" | ||||
|           PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 Created by GitHub action') | ||||
|           PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 This PR was created automatically by a GitHub action to merge the changed files into this branch. It will be merged automatically. `Share and enjoy`') | ||||
|           echo "PR URL is '$PR_URL'" | ||||
|           IFS='/' read -ra parts <<< "$PR_URL" | ||||
|           PR_NR=$(printf %s\\n "${parts[@]:(-1)}") | ||||
| @@ -272,7 +272,7 @@ jobs: | ||||
|  | ||||
|             echo "Also merge everything into main since this is a release." | ||||
|             echo 'create PR' | ||||
|             PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body "🤖 Created by GitHub action") | ||||
|             PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body '🤖 This PR was created automatically by a GitHub action to merge the changed files into this branch. It will be merged automatically. `Share and enjoy`') | ||||
|             echo "PR URL is '$PR_URL'" | ||||
|  | ||||
|             IFS='/' read -ra parts <<< "$PR_URL" | ||||
| @@ -291,7 +291,7 @@ jobs: | ||||
|           echo "DONE!" | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|       - name: Create archives | ||||
|         run: | | ||||
|           echo "Create zip file $zipName" | ||||
| @@ -375,7 +375,7 @@ jobs: | ||||
|           fi | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|       - name: Upload artifacts | ||||
|         run: | | ||||
|           # add zip file to release. | ||||
| @@ -411,4 +411,4 @@ jobs: | ||||
|           rm -f $tarName.sha256 | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }} | ||||
|           version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }} | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,7 @@ jobs: | ||||
|       actions: write | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/stale@v9 | ||||
|       - uses: actions/stale@v10 | ||||
|         with: | ||||
|           repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||
|           stale-issue-message: | | ||||
|   | ||||
| @@ -4,8 +4,10 @@ Over time, many people have contributed to Firefly III. Their efforts are not al | ||||
| 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 | ||||
| - jreyesr | ||||
| - codearena-bot | ||||
| - Nicky De Maeyer | ||||
| - Denis Iskandarov | ||||
| - = | ||||
| - Lompi | ||||
| - Jose Diaz-Gonzalez | ||||
| - SoftBrix | ||||
|   | ||||
| @@ -84,13 +84,13 @@ class AccountController extends Controller | ||||
|         $data        = $request->getData(); | ||||
|         $types       = $data['types']; | ||||
|         $query       = $data['query']; | ||||
|         $date        = $data['date'] ?? today(config('app.timezone')); | ||||
|         $date        = $data['date']; | ||||
|         $return      = []; | ||||
|         $timer       = Timer::getInstance(); | ||||
|         $timer->start(sprintf('AC accounts "%s"', $query)); | ||||
|         $result      = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit')); | ||||
| 
 | ||||
|         // set date to subday + end-of-day for account balance. so it is at $date 23:59:59
 | ||||
|         // set date to end-of-day for account balance. so it is at $date 23:59:59
 | ||||
|         $date->endOfDay(); | ||||
| 
 | ||||
|         $allBalances = Steam::accountsBalancesOptimized($result, $date, $this->primaryCurrency, $this->convertToPrimary); | ||||
| @@ -114,6 +114,7 @@ class AccountController extends Controller | ||||
|                 'id'                              => (string) $account->id, | ||||
|                 'name'                            => $account->name, | ||||
|                 'name_with_balance'               => $nameWithBalance, | ||||
|                 'active'                          => $account->active, | ||||
|                 'type'                            => $account->accountType->type, | ||||
|                 'currency_id'                     => (string) $useCurrency->id, | ||||
|                 'currency_name'                   => $useCurrency->name, | ||||
|   | ||||
| @@ -67,8 +67,9 @@ class BudgetController extends Controller | ||||
|         $result   = $this->repository->searchBudget($data['query'], $this->parameters->get('limit')); | ||||
|         $filtered = $result->map( | ||||
|             static fn (Budget $item) => [ | ||||
|                 'id'   => (string) $item->id, | ||||
|                 'name' => $item->name, | ||||
|                 'id'     => (string) $item->id, | ||||
|                 'name'   => $item->name, | ||||
|                 'active' => $item->active, | ||||
|             ] | ||||
|         ); | ||||
| 
 | ||||
|   | ||||
| @@ -28,8 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| /** | ||||
| @@ -96,6 +98,7 @@ class PiggyBankController extends Controller | ||||
| 
 | ||||
|         /** @var PiggyBank $piggy */ | ||||
|         foreach ($piggies as $piggy) { | ||||
|             /** @var TransactionCurrency $currency */ | ||||
|             $currency      = $piggy->transactionCurrency; | ||||
|             $currentAmount = $this->piggyRepository->getCurrentAmount($piggy); | ||||
|             $objectGroup   = $piggy->objectGroups()->first(); | ||||
| @@ -105,8 +108,8 @@ class PiggyBankController extends Controller | ||||
|                 'name_with_balance'       => sprintf( | ||||
|                     '%s (%s / %s)', | ||||
|                     $piggy->name, | ||||
|                     app('amount')->formatAnything($currency, $currentAmount, false), | ||||
|                     app('amount')->formatAnything($currency, $piggy->target_amount, false), | ||||
|                     Amount::formatAnything($currency, $currentAmount, false), | ||||
|                     Amount::formatAnything($currency, $piggy->target_amount, false), | ||||
|                 ), | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_name'           => $currency->name, | ||||
|   | ||||
| @@ -69,6 +69,7 @@ class RecurrenceController extends Controller | ||||
|                 'id'          => (string) $recurrence->id, | ||||
|                 'name'        => $recurrence->title, | ||||
|                 'description' => $recurrence->description, | ||||
|                 'active'      => $recurrence->active, | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -37,7 +37,7 @@ use Illuminate\Http\JsonResponse; | ||||
| class RuleController extends Controller | ||||
| { | ||||
|     private RuleRepositoryInterface $repository; | ||||
|     protected array $acceptedRoles = [UserRoleEnum::READ_RULES]; | ||||
|     protected array                 $acceptedRoles = [UserRoleEnum::READ_RULES]; | ||||
| 
 | ||||
|     /** | ||||
|      * RuleController constructor. | ||||
| @@ -66,9 +66,10 @@ class RuleController extends Controller | ||||
|         /** @var Rule $rule */ | ||||
|         foreach ($rules as $rule) { | ||||
|             $response[] = [ | ||||
|                 'id'          => (string) $rule->id, | ||||
|                 'id'          => (string)$rule->id, | ||||
|                 'name'        => $rule->title, | ||||
|                 'description' => $rule->description, | ||||
|                 'active'      => $rule->active, | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -69,6 +69,7 @@ class RuleGroupController extends Controller | ||||
|                 'id'          => (string) $group->id, | ||||
|                 'name'        => $group->title, | ||||
|                 'description' => $group->description, | ||||
|                 'active'      => $group->active, | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -24,10 +24,10 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Autocomplete; | ||||
| 
 | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; | ||||
|   | ||||
| @@ -49,8 +49,6 @@ class TransactionTypeController extends Controller | ||||
|             function ($request, $next) { | ||||
|                 $this->validateUserGroup($request); | ||||
|                 $this->repository = app(TransactionTypeRepositoryInterface::class); | ||||
|                 $this->repository->setUser($this->user); | ||||
|                 $this->repository->setUserGroup($this->userGroup); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|   | ||||
| @@ -130,6 +130,7 @@ class AccountController extends Controller | ||||
|             'yAxisID'                 => 0, | ||||
|             'period'                  => '1D', | ||||
|             'entries'                 => [], | ||||
|             'pc_entries'              => [], | ||||
|         ]; | ||||
|         if ($this->convertToPrimary) { | ||||
|             $currentSet['pc_entries']                      = []; | ||||
|   | ||||
| @@ -1,5 +1,26 @@ | ||||
| <?php | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  * BalanceController.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\Chart; | ||||
| @@ -10,9 +31,7 @@ use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Http\Api\AccountBalanceGrouped; | ||||
| use FireflyIII\Support\Http\Api\CleansChartData; | ||||
| use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter; | ||||
|   | ||||
| @@ -31,10 +31,10 @@ use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Http\Api\CleansChartData; | ||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| @@ -55,7 +55,6 @@ class BudgetController extends Controller | ||||
|     protected OperationsRepositoryInterface $opsRepository; | ||||
|     private BudgetLimitRepositoryInterface  $blRepository; | ||||
|     private array                           $currencies = []; | ||||
|     private TransactionCurrency             $currency; | ||||
|     private BudgetRepositoryInterface       $repository; | ||||
| 
 | ||||
|     public function __construct() | ||||
| @@ -115,7 +114,7 @@ class BudgetController extends Controller | ||||
|         // get all limits:
 | ||||
|         $limits     = $this->blRepository->getBudgetLimits($budget, $start, $end); | ||||
|         $rows       = []; | ||||
|         $spent      = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget])); | ||||
|         $spent      = $this->opsRepository->listExpenses($start, $end, null, new Collection()->push($budget)); | ||||
|         $expenses   = $this->processExpenses($budget->id, $spent, $start, $end); | ||||
|         $converter  = new ExchangeRateConverter(); | ||||
|         $currencies = [$this->primaryCurrency->id => $this->primaryCurrency]; | ||||
| @@ -134,9 +133,9 @@ class BudgetController extends Controller | ||||
|             $row['pc_left']      = '0'; | ||||
|             $row['pc_overspent'] = '0'; | ||||
| 
 | ||||
|             if (null !== $limit) { | ||||
|             if ($limit instanceof BudgetLimit) { | ||||
|                 $row['budgeted']  = $limit->amount; | ||||
|                 $row['left']      = bcsub($row['budgeted'], bcmul($row['spent'], '-1')); | ||||
|                 $row['left']      = bcsub((string) $row['budgeted'], bcmul((string) $row['spent'], '-1')); | ||||
|                 $row['overspent'] = bcmul($row['left'], '-1'); | ||||
|                 $row['left']      = 1 === bccomp($row['left'], '0') ? $row['left'] : '0'; | ||||
|                 $row['overspent'] = 1 === bccomp($row['overspent'], '0') ? $row['overspent'] : '0'; | ||||
| @@ -144,7 +143,7 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|             // convert data if necessary.
 | ||||
|             if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) { | ||||
|                 $currencies[$currencyId] ??= TransactionCurrency::find($currencyId); | ||||
|                 $currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId); | ||||
|                 $row['pc_budgeted']  = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']); | ||||
|                 $row['pc_spent']     = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']); | ||||
|                 $row['pc_left']      = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']); | ||||
| @@ -201,18 +200,18 @@ class BudgetController extends Controller | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * When no budget limits are present, the expenses of the whole period are collected and grouped. | ||||
|      * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget])); | ||||
| 
 | ||||
|         return $this->processExpenses($budget->id, $spent, $start, $end); | ||||
|     } | ||||
|     //    /**
 | ||||
|     //     * When no budget limits are present, the expenses of the whole period are collected and grouped.
 | ||||
|     //     * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
 | ||||
|     //     *
 | ||||
|     //     * @throws FireflyException
 | ||||
|     //     */
 | ||||
|     //    private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
 | ||||
|     //    {
 | ||||
|     //        $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection()->push($budget));
 | ||||
|     //
 | ||||
|     //        return $this->processExpenses($budget->id, $spent, $start, $end);
 | ||||
|     //    }
 | ||||
| 
 | ||||
|     /** | ||||
|      * Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return | ||||
| @@ -232,7 +231,7 @@ class BudgetController extends Controller | ||||
|          * @var array $block | ||||
|          */ | ||||
|         foreach ($spent as $currencyId => $block) { | ||||
|             $this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId); | ||||
|             $this->currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId); | ||||
|             $return[$currencyId]           ??= [ | ||||
|                 'currency_id'             => (string)$currencyId, | ||||
|                 'currency_code'           => $block['currency_code'], | ||||
| @@ -251,67 +250,15 @@ class BudgetController extends Controller | ||||
|             // var_dump($return);
 | ||||
|             /** @var array $journal */ | ||||
|             foreach ($currentBudgetArray['transaction_journals'] as $journal) { | ||||
|                 $return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string)$journal['amount']); | ||||
|                 /** @var numeric-string $amount */ | ||||
|                 $amount                       = (string)$journal['amount']; | ||||
|                 $return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $amount); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Function that processes each budget limit (per budget). | ||||
|      * | ||||
|      * If you have a budget limit in EUR, only transactions in EUR will be considered. | ||||
|      * If you have a budget limit in GBP, only transactions in GBP will be considered. | ||||
|      * | ||||
|      * If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function budgetLimits(Budget $budget, Collection $limits): array | ||||
|     { | ||||
|         Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id)); | ||||
|         $data = []; | ||||
| 
 | ||||
|         /** @var BudgetLimit $limit */ | ||||
|         foreach ($limits as $limit) { | ||||
|             $data = array_merge($data, $this->processLimit($budget, $limit)); | ||||
|         } | ||||
| 
 | ||||
|         return $data; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function processLimit(Budget $budget, BudgetLimit $limit): array | ||||
|     { | ||||
|         Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); | ||||
|         $end             = clone $limit->end_date; | ||||
|         $end->endOfDay(); | ||||
|         $spent           = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget])); | ||||
|         $limitCurrencyId = $limit->transaction_currency_id; | ||||
| 
 | ||||
|         /** @var array $entry */ | ||||
|         // only spent the entry where the entry's currency matches the budget limit's currency
 | ||||
|         // so $filtered will only have 1 or 0 entries
 | ||||
|         $filtered        = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId); | ||||
|         $result          = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end); | ||||
|         if (1 === count($result)) { | ||||
|             $compare                              = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent'])); | ||||
|             $result[$limitCurrencyId]['budgeted'] = $limit->amount; | ||||
|             if (1 === $compare) { | ||||
|                 // convert this amount into the primary currency:
 | ||||
|                 $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']); | ||||
|             } | ||||
|             if ($compare <= 0) { | ||||
|                 $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent'])); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $result; | ||||
|     } | ||||
| 
 | ||||
|     private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit | ||||
|     { | ||||
|         $amount    = '0'; | ||||
|   | ||||
| @@ -97,40 +97,41 @@ class CategoryController extends Controller | ||||
|         $collector  = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->withAccountInformation(); | ||||
|         $collector->setXorAccounts($accounts)->withCategoryInformation(); | ||||
|         $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::RECONCILIATION->value]); | ||||
|         $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value]); | ||||
|         $journals   = $collector->getExtractedJournals(); | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             // find journal:
 | ||||
|             $journalCurrencyId                = (int)$journal['currency_id']; | ||||
|             $currency                         = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId); | ||||
|             $currencies[$journalCurrencyId]   = $currency; | ||||
|             $currencyId                       = (int)$currency->id; | ||||
|             $currencyName                     = (string)$currency->name; | ||||
|             $currencyCode                     = (string)$currency->code; | ||||
|             $currencySymbol                   = (string)$currency->symbol; | ||||
|             $currencyDecimalPlaces            = (int)$currency->decimal_places; | ||||
|             $amount                           = Steam::positive($journal['amount']); | ||||
|             $pcAmount                         = null; | ||||
|             $journalCurrencyId              = (int)$journal['currency_id']; | ||||
|             $type                           = $journal['transaction_type_type']; | ||||
|             $currency                       = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId); | ||||
|             $currencies[$journalCurrencyId] = $currency; | ||||
|             $currencyId                     = $currency->id; | ||||
|             $currencyName                   = $currency->name; | ||||
|             $currencyCode                   = $currency->code; | ||||
|             $currencySymbol                 = $currency->symbol; | ||||
|             $currencyDecimalPlaces          = $currency->decimal_places; | ||||
|             $amount                         = Steam::positive((string)$journal['amount']); | ||||
|             $pcAmount                       = null; | ||||
| 
 | ||||
|             // overrule if necessary:
 | ||||
|             if ($this->convertToPrimary && $journalCurrencyId === $this->primaryCurrency->id) { | ||||
|                 $pcAmount = $amount; | ||||
|             } | ||||
|             if ($this->convertToPrimary && $journalCurrencyId !== $this->primaryCurrency->id) { | ||||
|                 $currencyId            = (int)$this->primaryCurrency->id; | ||||
|                 $currencyName          = (string)$this->primaryCurrency->name; | ||||
|                 $currencyCode          = (string)$this->primaryCurrency->code; | ||||
|                 $currencySymbol        = (string)$this->primaryCurrency->symbol; | ||||
|                 $currencyDecimalPlaces = (int)$this->primaryCurrency->decimal_places; | ||||
|                 $currencyId            = $this->primaryCurrency->id; | ||||
|                 $currencyName          = $this->primaryCurrency->name; | ||||
|                 $currencyCode          = $this->primaryCurrency->code; | ||||
|                 $currencySymbol        = $this->primaryCurrency->symbol; | ||||
|                 $currencyDecimalPlaces = $this->primaryCurrency->decimal_places; | ||||
|                 $pcAmount              = $converter->convert($currency, $this->primaryCurrency, $journal['date'], $amount); | ||||
|                 Log::debug(sprintf('Converted %s %s to %s %s', $journal['currency_code'], $amount, $this->primaryCurrency->code, $pcAmount)); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             $categoryName                     = $journal['category_name'] ?? (string)trans('firefly.no_category'); | ||||
|             $key                              = sprintf('%s-%s', $categoryName, $currencyCode); | ||||
|             $categoryName                   = $journal['category_name'] ?? (string)trans('firefly.no_category'); | ||||
|             $key                            = sprintf('%s-%s', $categoryName, $currencyCode); | ||||
|             // create arrays
 | ||||
|             $return[$key] ??= [ | ||||
|                 'label'                           => $categoryName, | ||||
| @@ -140,33 +141,47 @@ class CategoryController extends Controller | ||||
|                 'currency_symbol'                 => $currencySymbol, | ||||
|                 'currency_decimal_places'         => $currencyDecimalPlaces, | ||||
|                 'primary_currency_id'             => (string)$this->primaryCurrency->id, | ||||
|                 'primary_currency_name'           => (string)$this->primaryCurrency->name, | ||||
|                 'primary_currency_code'           => (string)$this->primaryCurrency->code, | ||||
|                 'primary_currency_symbol'         => (string)$this->primaryCurrency->symbol, | ||||
|                 'primary_currency_decimal_places' => (int)$this->primaryCurrency->decimal_places, | ||||
|                 'primary_currency_name'           => $this->primaryCurrency->name, | ||||
|                 'primary_currency_code'           => $this->primaryCurrency->code, | ||||
|                 'primary_currency_symbol'         => $this->primaryCurrency->symbol, | ||||
|                 'primary_currency_decimal_places' => $this->primaryCurrency->decimal_places, | ||||
|                 'period'                          => null, | ||||
|                 'start_date'                      => $start->toAtomString(), | ||||
|                 'end_date'                        => $end->toAtomString(), | ||||
|                 'yAxisID'                         => 0, | ||||
|                 'type'                            => 'bar', | ||||
|                 'entries'                         => [ | ||||
|                     'spent' => '0', | ||||
|                     'spent'  => '0', | ||||
|                     'earned' => '0', | ||||
|                 ], | ||||
|                 'pc_entries'                      => [ | ||||
|                     'spent' => '0', | ||||
|                     'spent'  => '0', | ||||
|                     'earned' => '0', | ||||
|                 ], | ||||
|             ]; | ||||
| 
 | ||||
|             // add monies
 | ||||
|             $return[$key]['entries']['spent'] = bcadd($return[$key]['entries']['spent'], (string)$amount); | ||||
|             if (null !== $pcAmount) { | ||||
|                 $return[$key]['pc_entries']['spent'] = bcadd($return[$key]['pc_entries']['spent'], (string)$pcAmount); | ||||
|             // expenses to spent
 | ||||
|             if (TransactionTypeEnum::WITHDRAWAL->value === $type) { | ||||
|                 $return[$key]['entries']['spent'] = bcadd($return[$key]['entries']['spent'], $amount); | ||||
|                 if (null !== $pcAmount) { | ||||
|                     $return[$key]['pc_entries']['spent'] = bcadd($return[$key]['pc_entries']['spent'], $pcAmount); | ||||
|                 } | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
|             // positive amount = earned
 | ||||
|             if (TransactionTypeEnum::DEPOSIT->value === $type) { | ||||
|                 $return[$key]['entries']['earned'] = bcadd($return[$key]['entries']['earned'], $amount); | ||||
|                 if (null !== $pcAmount) { | ||||
|                     $return[$key]['pc_entries']['earned'] = bcadd($return[$key]['pc_entries']['earned'], $pcAmount); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         $return     = array_values($return); | ||||
| 
 | ||||
|         // order by amount
 | ||||
|         usort($return, static fn (array $a, array $b) => (float)$a['entries']['spent'] < (float)$b['entries']['spent'] ? 1 : -1); | ||||
|         usort($return, static fn (array $a, array $b) => ((float)$a['entries']['spent'] + (float)$a['entries']['earned']) < ((float)$b['entries']['spent'] + (float)$b['entries']['earned']) ? 1 : -1); | ||||
| 
 | ||||
|         return response()->json($this->clean($return)); | ||||
|     } | ||||
|   | ||||
| @@ -27,7 +27,6 @@ namespace FireflyIII\Api\V1\Controllers; | ||||
| use Carbon\Carbon; | ||||
| 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; | ||||
| @@ -66,10 +65,10 @@ abstract class Controller extends BaseController | ||||
|     protected const string JSON_CONTENT_TYPE        = 'application/json'; | ||||
|     protected array $accepts                        = ['application/json', 'application/vnd.api+json']; | ||||
| 
 | ||||
|     /** @var array<int, string> */ | ||||
|     protected array               $allowedSort; | ||||
|     protected bool                $convertToPrimary = false; | ||||
|     protected TransactionCurrency $primaryCurrency; | ||||
| 
 | ||||
|     /** @deprecated use Request classes */ | ||||
|     protected ParameterBag        $parameters; | ||||
| 
 | ||||
|     /** | ||||
| @@ -78,7 +77,6 @@ abstract class Controller extends BaseController | ||||
|     public function __construct() | ||||
|     { | ||||
|         // get global parameters
 | ||||
|         $this->allowedSort = config('firefly.allowed_sort_parameters'); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $this->parameters = $this->getParameters(); | ||||
| @@ -102,18 +100,14 @@ abstract class Controller extends BaseController | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Method to grab all parameters from the URL. | ||||
|      * @deprecated use Request classes | ||||
|      * Method to grab all parameters from the URL | ||||
|      */ | ||||
|     private function getParameters(): ParameterBag | ||||
|     { | ||||
|         $bag      = new ParameterBag(); | ||||
|         $page     = (int)request()->get('page'); | ||||
|         if ($page < 1) { | ||||
|             $page = 1; | ||||
|         } | ||||
|         if ($page > 2 ** 16) { | ||||
|             $page = 2 ** 16; | ||||
|         } | ||||
|         $page     = min(max(1, $page), 2 ** 16); | ||||
|         $bag->set('page', $page); | ||||
| 
 | ||||
|         // some date fields:
 | ||||
| @@ -131,19 +125,15 @@ abstract class Controller extends BaseController | ||||
|             $obj  = null; | ||||
|             if (null !== $date) { | ||||
|                 try { | ||||
|                     $obj = Carbon::parse((string)$date); | ||||
|                     $obj = Carbon::parse((string)$date, config('app.timezone')); | ||||
|                 } catch (InvalidFormatException $e) { | ||||
|                     // don't care
 | ||||
|                     Log::warning( | ||||
|                         sprintf( | ||||
|                             'Ignored invalid date "%s" in API controller parameter check: %s', | ||||
|                             substr((string)$date, 0, 20), | ||||
|                             $e->getMessage() | ||||
|                         ) | ||||
|                     ); | ||||
|                     Log::warning(sprintf('Ignored invalid date "%s" in API controller parameter check: %s', substr((string)$date, 0, 20), $e->getMessage())); | ||||
|                 } | ||||
|             } | ||||
|             $bag->set($field, $obj); | ||||
|             if ($obj instanceof Carbon) { | ||||
|                 $bag->set($field, $obj); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // integer fields:
 | ||||
| @@ -159,13 +149,7 @@ abstract class Controller extends BaseController | ||||
|             } | ||||
|             if (null !== $value) { | ||||
|                 $value = (int)$value; | ||||
|                 if ($value < 1) { | ||||
|                     $value = 1; | ||||
|                 } | ||||
|                 if ($value > 2 ** 16) { | ||||
|                     $value = 2 ** 16; | ||||
|                 } | ||||
| 
 | ||||
|                 $value = min(max(1, $value), 2 ** 16); | ||||
|                 $bag->set($integer, $value); | ||||
|             } | ||||
|             if (null === $value | ||||
| @@ -175,46 +159,14 @@ abstract class Controller extends BaseController | ||||
|                 /** @var User $user */ | ||||
|                 $user     = auth()->user(); | ||||
| 
 | ||||
|                 /** @var Preference $pageSize */ | ||||
|                 $pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data; | ||||
|                 $bag->set($integer, $pageSize); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // sort fields:
 | ||||
|         return $this->getSortParameters($bag); | ||||
|     } | ||||
| 
 | ||||
|     private function getSortParameters(ParameterBag $bag): ParameterBag | ||||
|     { | ||||
|         $sortParameters = []; | ||||
| 
 | ||||
|         try { | ||||
|             $param = (string)request()->query->get('sort'); | ||||
|         } catch (BadRequestException $e) { | ||||
|             Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.'); | ||||
|             Log::error($e->getMessage()); | ||||
|             Log::error($e->getTraceAsString()); | ||||
|             $param = ''; | ||||
|         } | ||||
|         if ('' === $param) { | ||||
|             return $bag; | ||||
|         } | ||||
|         $parts          = explode(',', $param); | ||||
|         foreach ($parts as $part) { | ||||
|             $part      = trim($part); | ||||
|             $direction = 'asc'; | ||||
|             if ('-' === $part[0]) { | ||||
|                 $part      = substr($part, 1); | ||||
|                 $direction = 'desc'; | ||||
|             } | ||||
|             if (in_array($part, $this->allowedSort, true)) { | ||||
|                 $sortParameters[] = [$part, $direction]; | ||||
|             } | ||||
|         } | ||||
|         $bag->set('sort', $sortParameters); | ||||
| 
 | ||||
|         return $bag; | ||||
|         // return $this->getSortParameters($bag);
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -283,8 +235,6 @@ abstract class Controller extends BaseController | ||||
|         $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(); | ||||
|   | ||||
| @@ -61,6 +61,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -100,6 +101,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -112,6 +114,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -124,6 +127,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -136,6 +140,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -148,6 +153,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -160,6 +166,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -172,6 +179,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
| @@ -184,6 +192,7 @@ class ExportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws DatetimeException | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(ExportRequest $request): LaravelResponse | ||||
|   | ||||
| @@ -76,7 +76,7 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|         /** @var Budget $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$budget])); | ||||
|             $expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection()->push($budget)); | ||||
| 
 | ||||
|             /** @var array $expense */ | ||||
|             foreach ($expenses as $expense) { | ||||
|   | ||||
| @@ -76,7 +76,7 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         /** @var Category $category */ | ||||
|         foreach ($categories as $category) { | ||||
|             $expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$category])); | ||||
|             $expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection()->push($category)); | ||||
| 
 | ||||
|             /** @var array $expense */ | ||||
|             foreach ($expenses as $expense) { | ||||
|   | ||||
| @@ -76,7 +76,7 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         /** @var Category $category */ | ||||
|         foreach ($categories as $category) { | ||||
|             $expenses = $this->opsRepository->sumIncome($start, $end, $assetAccounts, new Collection([$category])); | ||||
|             $expenses = $this->opsRepository->sumIncome($start, $end, $assetAccounts, new Collection()->push($category)); | ||||
| 
 | ||||
|             /** @var array $expense */ | ||||
|             foreach ($expenses as $expense) { | ||||
|   | ||||
| @@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| /** | ||||
| @@ -71,7 +72,7 @@ class PeriodController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
 | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| /** | ||||
| @@ -97,7 +98,7 @@ class TagController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; | ||||
| 
 | ||||
|         } | ||||
| @@ -148,7 +149,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $currencyId, | ||||
|                         'currency_code'    => $journal['currency_code'], | ||||
|                     ]; | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], Steam::positive($journal['amount'])); | ||||
|                     $response[$key]['difference_float'] = (float) $response[$key]['difference']; | ||||
|                 } | ||||
| 
 | ||||
| @@ -160,10 +161,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $foreignCurrencyId, | ||||
|                         'currency_code'    => $journal['foreign_currency_code'], | ||||
|                     ]; | ||||
|                     $response[$foreignKey]['difference']       = bcadd( | ||||
|                         (string) $response[$foreignKey]['difference'], | ||||
|                         (string) app('steam')->positive($journal['foreign_amount']) | ||||
|                     ); | ||||
|                     $response[$foreignKey]['difference']       = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount'])); | ||||
|                     $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -76,7 +76,7 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         /** @var Category $category */ | ||||
|         foreach ($categories as $category) { | ||||
|             $expenses = $this->opsRepository->sumTransfers($start, $end, $assetAccounts, new Collection([$category])); | ||||
|             $expenses = $this->opsRepository->sumTransfers($start, $end, $assetAccounts, new Collection()->push($category)); | ||||
| 
 | ||||
|             /** @var array $expense */ | ||||
|             foreach ($expenses as $expense) { | ||||
|   | ||||
| @@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| /** | ||||
| @@ -71,7 +72,7 @@ class PeriodController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; | ||||
| 
 | ||||
|         } | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| 
 | ||||
| /** | ||||
| @@ -95,7 +96,7 @@ class TagController extends Controller | ||||
|                 'currency_id'      => (string) $currencyId, | ||||
|                 'currency_code'    => $currencyCode, | ||||
|             ]; | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); | ||||
|             $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field])); | ||||
|             $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; | ||||
| 
 | ||||
|         } | ||||
| @@ -146,7 +147,7 @@ class TagController extends Controller | ||||
|                         'currency_id'      => (string) $currencyId, | ||||
|                         'currency_code'    => $journal['currency_code'], | ||||
|                     ]; | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference']       = bcadd((string) $response[$key]['difference'], Steam::positive($journal['amount'])); | ||||
|                     $response[$key]['difference_float'] = (float) $response[$key]['difference']; | ||||
|                 } | ||||
| 
 | ||||
| @@ -160,7 +161,7 @@ class TagController extends Controller | ||||
|                     ]; | ||||
|                     $response[$foreignKey]['difference']       = bcadd( | ||||
|                         (string) $response[$foreignKey]['difference'], | ||||
|                         (string) app('steam')->positive($journal['foreign_amount']) | ||||
|                         Steam::positive($journal['foreign_amount']) | ||||
|                     ); | ||||
|                     $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
 | ||||
|                 } | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Account; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| @@ -70,9 +69,6 @@ class ListController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(Account $account): JsonResponse | ||||
|     { | ||||
|         $manager     = $this->getManager(); | ||||
| @@ -96,9 +92,6 @@ class ListController extends Controller | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function piggyBanks(Account $account): JsonResponse | ||||
|     { | ||||
|         // create some objects:
 | ||||
| @@ -135,8 +128,6 @@ class ListController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Show all transaction groups related to the account. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Account $account): JsonResponse | ||||
|     { | ||||
| @@ -152,7 +143,7 @@ class ListController extends Controller | ||||
|         // use new group collector:
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector    = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($admin)->setAccounts(new Collection([$account])) | ||||
|         $collector->setUser($admin)->setAccounts(new Collection()->push($account)) | ||||
|             ->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types) | ||||
|         ; | ||||
| 
 | ||||
|   | ||||
| @@ -25,7 +25,7 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Account; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Api\V1\Requests\Models\Account\ShowRequest; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| @@ -33,7 +33,6 @@ use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| @@ -68,42 +67,49 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     public function index(ShowRequest $request): JsonResponse | ||||
|     { | ||||
|         $manager     = $this->getManager(); | ||||
|         $type        = $request->get('type') ?? 'all'; | ||||
|         $this->parameters->set('type', $type); | ||||
| 
 | ||||
|         // types to get, page size:
 | ||||
|         $types       = $this->mapAccountTypes($this->parameters->get('type')); | ||||
|         $pageSize    = $this->parameters->get('limit'); | ||||
|         [ | ||||
|             'types'  => $types, | ||||
|             'page'   => $page, | ||||
|             'limit'  => $limit, | ||||
|             'offset' => $offset, | ||||
|             'sort'   => $sort, | ||||
|             'start'  => $start, | ||||
|             'end'    => $end, | ||||
|             'date'   => $date, | ||||
|         ] | ||||
|                      = $request->attributes->all(); | ||||
| 
 | ||||
|         // get list of accounts. Count it and split it.
 | ||||
|         $this->repository->resetAccountOrder(); | ||||
|         $collection  = $this->repository->getAccountsByType($types, $this->parameters->get('sort') ?? []); | ||||
|         $collection  = $this->repository->getAccountsByType($types, $sort); | ||||
|         $count       = $collection->count(); | ||||
| 
 | ||||
|         // continue sort:
 | ||||
|         $accounts    = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         // TODO if the user sorts on DB dependent field there must be no slice before enrichment, only after.
 | ||||
|         // TODO still need to figure out how to do this easily.
 | ||||
|         $accounts    = $collection->slice($offset, $limit); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setDate($this->parameters->get('date')); | ||||
|         $enrichment->setSort($sort); | ||||
|         $enrichment->setDate($date); | ||||
|         $enrichment->setStart($start); | ||||
|         $enrichment->setEnd($end); | ||||
|         $enrichment->setUser($admin); | ||||
|         $accounts    = $enrichment->enrich($accounts); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator   = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator   = new LengthAwarePaginator($accounts, $count, $limit, $page); | ||||
|         $paginator->setPath(route('api.v1.accounts.index').$this->buildParams()); | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         $resource    = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| @@ -117,26 +123,28 @@ class ShowController extends Controller | ||||
|      * | ||||
|      * Show single instance. | ||||
|      */ | ||||
|     public function show(Account $account): JsonResponse | ||||
|     public function show(ShowRequest $request, Account $account): JsonResponse | ||||
|     { | ||||
|         // get list of accounts. Count it and split it.
 | ||||
|         $this->repository->resetAccountOrder(); | ||||
|         $account->refresh(); | ||||
|         $manager     = $this->getManager(); | ||||
|         $manager              = $this->getManager(); | ||||
|         [$start, $end, $date] = $request->attributes->all(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setDate($this->parameters->get('date')); | ||||
|         $admin                = auth()->user(); | ||||
|         $enrichment           = new AccountEnrichment(); | ||||
|         $enrichment->setDate($date); | ||||
|         $enrichment->setStart($start); | ||||
|         $enrichment->setEnd($end); | ||||
|         $enrichment->setUser($admin); | ||||
|         $account     = $enrichment->enrichSingle($account); | ||||
|         $account              = $enrichment->enrichSingle($account); | ||||
| 
 | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|         $resource    = new Item($account, $transformer, self::RESOURCE_KEY); | ||||
|         $transformer          = app(AccountTransformer::class); | ||||
|         $resource             = new Item($account, $transformer, self::RESOURCE_KEY); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
|   | ||||
| @@ -119,8 +119,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/listAttachment
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\AvailableBudget; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\AvailableBudget; | ||||
| use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AvailableBudgetEnrichment; | ||||
| @@ -67,8 +66,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/available_budgets/getAvailableBudget
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
| @@ -114,8 +111,8 @@ class ShowController extends Controller | ||||
|     public function show(AvailableBudget $availableBudget): JsonResponse | ||||
|     { | ||||
|         $manager         = $this->getManager(); | ||||
|         $start           = $this->parameters->get('start'); | ||||
|         $end             = $this->parameters->get('end'); | ||||
|         //        $start           = $this->parameters->get('start');
 | ||||
|         //        $end             = $this->parameters->get('end');
 | ||||
| 
 | ||||
|         /** @var AvailableBudgetTransformer $transformer */ | ||||
|         $transformer     = app(AvailableBudgetTransformer::class); | ||||
| @@ -126,8 +123,8 @@ class ShowController extends Controller | ||||
|         $admin           = auth()->user(); | ||||
|         $enrichment      = new AvailableBudgetEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setStart($start); | ||||
|         $enrichment->setEnd($end); | ||||
|         //        $enrichment->setStart($start);
 | ||||
|         //        $enrichment->setEnd($end);
 | ||||
|         $availableBudget = $enrichment->enrichSingle($availableBudget); | ||||
| 
 | ||||
| 
 | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Bill; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| @@ -71,8 +70,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/listAttachmentByBill
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(Bill $bill): JsonResponse | ||||
|     { | ||||
| @@ -102,8 +99,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/listRuleByBill
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function rules(Bill $bill): JsonResponse | ||||
|     { | ||||
| @@ -135,8 +130,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/listTransactionByBill
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Bill $bill): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Bill; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment; | ||||
| @@ -65,8 +64,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/listBill
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -26,7 +26,6 @@ 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; | ||||
| use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; | ||||
| @@ -73,8 +72,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listAttachmentByBudget
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(Budget $budget): JsonResponse | ||||
|     { | ||||
| @@ -104,8 +101,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listBudgetLimitByBudget
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function budgetLimits(Budget $budget): JsonResponse | ||||
|     { | ||||
| @@ -140,8 +135,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionByBudget
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Budget $budget): JsonResponse | ||||
|     { | ||||
| @@ -202,8 +195,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionWithoutBudget
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function withoutBudget(Request $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Budget; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| @@ -69,8 +68,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listBudget
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -67,7 +67,9 @@ class StoreController extends Controller | ||||
|      */ | ||||
|     public function store(StoreRequest $request): JsonResponse | ||||
|     { | ||||
|         $budget      = $this->repository->store($request->getAll()); | ||||
|         $data        = $request->getAll(); | ||||
|         $data['fire_webhooks'] ??= true; | ||||
|         $budget      = $this->repository->store($data); | ||||
|         $budget->refresh(); | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|   | ||||
| @@ -57,15 +57,10 @@ class UpdateController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudget
 | ||||
|      * | ||||
|      * Update a budget. | ||||
|      */ | ||||
|     public function update(UpdateRequest $request, Budget $budget): JsonResponse | ||||
|     { | ||||
|         $data        = $request->getAll(); | ||||
|         $data['fire_webhooks'] ??= true; | ||||
|         $budget      = $this->repository->update($budget, $data); | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\BudgetLimit; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| @@ -49,8 +48,6 @@ class ListController extends Controller | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionByBudgetLimit
 | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -84,6 +84,8 @@ class ShowController extends Controller | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setStart($this->parameters->get('start')); | ||||
|         $enrichment->setEnd($this->parameters->get('end')); | ||||
| 
 | ||||
|         /** @var Budget $budget */ | ||||
|         $budget       = $enrichment->enrichSingle($budget); | ||||
| 
 | ||||
| 
 | ||||
| @@ -96,7 +98,6 @@ class ShowController extends Controller | ||||
|         $paginator    = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]).$this->buildParams()); | ||||
| 
 | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new BudgetLimitEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|   | ||||
| @@ -70,6 +70,7 @@ class StoreController extends Controller | ||||
|         $data               = $request->getAll(); | ||||
|         $data['start_date'] = $data['start']; | ||||
|         $data['end_date']   = $data['end']; | ||||
|         $data['fire_webhooks'] ??= true; | ||||
|         $data['budget_id']  = $budget->id; | ||||
| 
 | ||||
|         $budgetLimit        = $this->blRepository->store($data); | ||||
|   | ||||
| @@ -77,6 +77,7 @@ class UpdateController extends Controller | ||||
|             throw new FireflyException('20028: The budget limit does not belong to the budget.'); | ||||
|         } | ||||
|         $data              = $request->getAll(); | ||||
|         $data['fire_webhooks'] ??= true; | ||||
|         $data['budget_id'] = $budget->id; | ||||
|         $budgetLimit       = $this->blRepository->update($budgetLimit, $data); | ||||
|         $manager           = $this->getManager(); | ||||
| @@ -86,7 +87,7 @@ class UpdateController extends Controller | ||||
|         $admin             = auth()->user(); | ||||
|         $enrichment        = new BudgetLimitEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $budgetLimit       = $enrichment->enrich($budgetLimit); | ||||
|         $budgetLimit       = $enrichment->enrichSingle($budgetLimit); | ||||
| 
 | ||||
|         /** @var BudgetLimitTransformer $transformer */ | ||||
|         $transformer       = app(BudgetLimitTransformer::class); | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Category; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| @@ -68,8 +67,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/listAttachmentByCategory
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(Category $category): JsonResponse | ||||
|     { | ||||
| @@ -99,8 +96,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/listTransactionByCategory
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Category $category): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Category; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\CategoryEnrichment; | ||||
| @@ -65,8 +64,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/listCategory
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -72,7 +72,7 @@ class DestroyController extends Controller | ||||
|     public function destroySingleByDate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse | ||||
|     { | ||||
|         $exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date); | ||||
|         if (null !== $exchangeRate) { | ||||
|         if ($exchangeRate instanceof CurrencyExchangeRate) { | ||||
|             $this->repository->deleteRate($exchangeRate); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -95,7 +95,7 @@ class ShowController extends Controller | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         $exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date); | ||||
|         if (null === $exchangeRate) { | ||||
|         if (!$exchangeRate instanceof CurrencyExchangeRate) { | ||||
|             throw new NotFoundHttpException(); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -33,6 +33,7 @@ use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Models\CurrencyExchangeRate; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| use FireflyIII\Transformers\ExchangeRateTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -69,7 +70,7 @@ class StoreController extends Controller | ||||
|         foreach ($data as $date => $rate) { | ||||
|             $date     = Carbon::createFromFormat('Y-m-d', $date); | ||||
|             $existing = $this->repository->getSpecificRateOnDate($from, $to, $date); | ||||
|             if (null !== $existing) { | ||||
|             if ($existing instanceof CurrencyExchangeRate) { | ||||
|                 // update existing rate.
 | ||||
|                 $existing = $this->repository->updateExchangeRate($existing, $rate); | ||||
|                 $collection->push($existing); | ||||
| @@ -98,12 +99,9 @@ class StoreController extends Controller | ||||
|         $from        = $request->getFromCurrency(); | ||||
|         $collection  = new Collection(); | ||||
|         foreach ($data['rates'] as $key => $rate) { | ||||
|             $to       = TransactionCurrency::where('code', $key)->first(); | ||||
|             if (null === $to) { | ||||
|                 continue; // should not happen.
 | ||||
|             } | ||||
|             $to       = Amount::getTransactionCurrencyByCode($key); | ||||
|             $existing = $this->repository->getSpecificRateOnDate($from, $to, $date); | ||||
|             if (null !== $existing) { | ||||
|             if ($existing instanceof CurrencyExchangeRate) { | ||||
|                 // update existing rate.
 | ||||
|                 $existing = $this->repository->updateExchangeRate($existing, $rate); | ||||
|                 $collection->push($existing); | ||||
|   | ||||
| @@ -74,7 +74,7 @@ class UpdateController extends Controller | ||||
|     public function updateByDate(UpdateRequest $request, TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse | ||||
|     { | ||||
|         $exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date); | ||||
|         if (null === $exchangeRate) { | ||||
|         if (!$exchangeRate instanceof CurrencyExchangeRate) { | ||||
|             throw new NotFoundHttpException(); | ||||
|         } | ||||
|         $date         = $request->getDate(); | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\ObjectGroup; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\ObjectGroup; | ||||
| use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\PiggyBankEnrichment; | ||||
| @@ -68,8 +67,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/listBillByObjectGroup
 | ||||
|      * | ||||
|      * List all bills in this object group | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function bills(ObjectGroup $objectGroup): JsonResponse | ||||
|     { | ||||
| @@ -109,8 +106,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/listPiggyBankByObjectGroup
 | ||||
|      * | ||||
|      * List all piggies under the object group. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function piggyBanks(ObjectGroup $objectGroup): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\PiggyBank; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| @@ -67,8 +66,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAccountByPiggyBank
 | ||||
|      * | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function accounts(PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
| @@ -105,8 +102,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
| @@ -136,8 +131,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listEventByPiggyBank
 | ||||
|      * | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function piggyBankEvents(PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\PiggyBank; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\PiggyBankEnrichment; | ||||
| @@ -65,8 +64,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listPiggyBank
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -68,10 +68,6 @@ class UpdateController extends Controller | ||||
|         $data        = $request->getAll(); | ||||
|         $piggyBank   = $this->repository->update($piggyBank, $data); | ||||
| 
 | ||||
|         if (array_key_exists('current_amount', $data) && '' !== $data['current_amount']) { | ||||
|             $this->repository->setCurrentAmount($piggyBank, $data['current_amount']); | ||||
|         } | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Recurrence; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; | ||||
| @@ -68,8 +67,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/recurrences/listTransactionByRecurrence
 | ||||
|      * | ||||
|      * Show transactions for this recurrence. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Recurrence $recurrence): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Recurrence; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\RecurringEnrichment; | ||||
| @@ -65,8 +64,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/recurrences/listRecurrence
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
							
								
								
									
										124
									
								
								app/Api/V1/Controllers/Models/Recurrence/TriggerController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								app/Api/V1/Controllers/Models/Recurrence/TriggerController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| <?php | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| /* | ||||
|  * TriggerController.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Recurrence; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Generic\SingleDateRequest; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Jobs\CreateRecurringTransactions; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Preferences; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| 
 | ||||
| class TriggerController extends Controller | ||||
| { | ||||
|     private RecurringRepositoryInterface $repository; | ||||
| 
 | ||||
|     /** | ||||
|      * RecurrenceController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $this->repository = app(RecurringRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public function trigger(SingleDateRequest $request, Recurrence $recurrence): JsonResponse | ||||
|     { | ||||
|         // find recurrence occurrence for this date and trigger it.
 | ||||
|         // grab the date from the last time the recurrence fired:
 | ||||
|         $backupDate                 = $recurrence->latest_date; | ||||
|         $date                       = $request->getDate(); | ||||
| 
 | ||||
|         // fire the recurring cron job on the given date, then post-date the created transaction.
 | ||||
|         Log::info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s'))); | ||||
| 
 | ||||
|         /** @var CreateRecurringTransactions $job */ | ||||
|         $job                        = app(CreateRecurringTransactions::class); | ||||
|         $job->setRecurrences(new Collection()->push($recurrence)); | ||||
|         $job->setDate($date); | ||||
|         $job->setForce(false); | ||||
|         $job->handle(); | ||||
|         Log::debug('Done with recurrence.'); | ||||
| 
 | ||||
|         $groups                     = $job->getGroups(); | ||||
|         $this->repository->markGroupsAsNow($groups); | ||||
|         $recurrence->latest_date    = $backupDate; | ||||
|         $recurrence->latest_date_tz = $backupDate?->format('e'); | ||||
|         $recurrence->save(); | ||||
|         Preferences::mark(); | ||||
| 
 | ||||
|         // enrich groups and return them:
 | ||||
| 
 | ||||
|         $paginator                  = new LengthAwarePaginator(new Collection(), 0, 1); | ||||
|         if ($groups->count() > 0) { | ||||
|             /** @var User $admin */ | ||||
|             $admin     = auth()->user(); | ||||
| 
 | ||||
|             // use new group collector:
 | ||||
|             /** @var GroupCollectorInterface $collector */ | ||||
|             $collector = app(GroupCollectorInterface::class); | ||||
|             $collector | ||||
|                 ->setUser($admin) | ||||
|                 ->setIds($groups->pluck('id')->toArray()) | ||||
|                 ->withAPIInformation() | ||||
|             ; | ||||
|             $paginator = $collector->getPaginatedGroups(); | ||||
|         } | ||||
| 
 | ||||
|         $manager                    = $this->getManager(); | ||||
|         $paginator->setPath(route('api.v1.recurrences.trigger', [$recurrence->id]).$this->buildParams()); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $admin                      = auth()->user(); | ||||
|         $enrichment                 = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions               = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer                = app(TransactionGroupTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         $resource                   = new FractalCollection($transactions, $transformer, 'transactions'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| } | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Rule; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Repositories\Rule\RuleRepositoryInterface; | ||||
| use FireflyIII\Transformers\RuleTransformer; | ||||
| @@ -67,8 +66,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/listRule
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -75,7 +75,7 @@ class TriggerController extends Controller | ||||
| 
 | ||||
|         /** @var RuleEngineInterface $ruleEngine */ | ||||
|         $ruleEngine   = app(RuleEngineInterface::class); | ||||
|         $ruleEngine->setRules(new Collection([$rule])); | ||||
|         $ruleEngine->setRules(new Collection()->push($rule)); | ||||
| 
 | ||||
|         // overrule the rule(s) if necessary.
 | ||||
|         if (array_key_exists('start', $parameters) && null !== $parameters['start']) { | ||||
| @@ -129,7 +129,7 @@ class TriggerController extends Controller | ||||
| 
 | ||||
|         /** @var RuleEngineInterface $ruleEngine */ | ||||
|         $ruleEngine = app(RuleEngineInterface::class); | ||||
|         $ruleEngine->setRules(new Collection([$rule])); | ||||
|         $ruleEngine->setRules(new Collection()->push($rule)); | ||||
| 
 | ||||
|         // overrule the rule(s) if necessary.
 | ||||
|         if (array_key_exists('start', $parameters) && null !== $parameters['start']) { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\RuleGroup; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; | ||||
| use FireflyIII\Transformers\RuleTransformer; | ||||
| @@ -64,8 +63,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/listRuleByGroup
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function rules(RuleGroup $group): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\RuleGroup; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; | ||||
| use FireflyIII\Transformers\RuleGroupTransformer; | ||||
| @@ -66,8 +65,6 @@ class ShowController extends Controller | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/listRuleGroup
 | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Tag; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| @@ -71,8 +70,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/listAttachmentByTag
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(Tag $tag): JsonResponse | ||||
|     { | ||||
| @@ -102,8 +99,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/listTransactionByTag
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, Tag $tag): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Tag; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use FireflyIII\Transformers\TagTransformer; | ||||
| @@ -67,8 +66,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/listTag
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Transaction; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Journal\JournalAPIRepositoryInterface; | ||||
| @@ -69,8 +68,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listAttachmentByTransaction
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function attachments(TransactionGroup $transactionGroup): JsonResponse | ||||
|     { | ||||
| @@ -101,8 +98,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listEventByTransaction
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function piggyBankEvents(TransactionGroup $transactionGroup): JsonResponse | ||||
|     { | ||||
| @@ -144,8 +139,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listLinksByJournal
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactionLinks(TransactionJournal $transactionJournal): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\Transaction; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| @@ -52,8 +51,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listTransaction
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency; | ||||
| 
 | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| @@ -32,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| 
 | ||||
| /** | ||||
|   | ||||
| @@ -25,14 +25,11 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Models\RecurrenceTransaction; | ||||
| use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Models\RuleTrigger; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| @@ -73,8 +70,6 @@ class ListController extends Controller | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listAccountByCurrency
 | ||||
|      * Display a list of accounts. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function accounts(Request $request, TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -105,11 +100,18 @@ class ListController extends Controller | ||||
|         $count             = $collection->count(); | ||||
|         $accounts          = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
| 
 | ||||
|         // #11007 go to the end of the previous day.
 | ||||
|         $this->parameters->set('start', $this->parameters->get('start')?->subSecond()); | ||||
|         // #11018 also end of the day.
 | ||||
|         $this->parameters->set('end', $this->parameters->get('end')?->endOfDay()); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin             = auth()->user(); | ||||
|         $enrichment        = new AccountEnrichment(); | ||||
|         $enrichment->setDate($this->parameters->get('date')); | ||||
|         $enrichment->setStart($this->parameters->get('start')); | ||||
|         $enrichment->setEnd($this->parameters->get('end')); | ||||
|         $enrichment->setUser($admin); | ||||
|         $accounts          = $enrichment->enrich($accounts); | ||||
| 
 | ||||
| @@ -131,8 +133,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listAvailableBudgetByCurrency
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function availableBudgets(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -166,8 +166,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listBillByCurrency
 | ||||
|      * | ||||
|      * List all bills | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function bills(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -192,7 +190,7 @@ class ListController extends Controller | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setStart($this->parameters->get('start')); | ||||
|         $enrichment->setEnd($this->parameters->get('end')); | ||||
|         $bills       = $enrichment->enrichSingle($bills); | ||||
|         $bills       = $enrichment->enrich($bills); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator   = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page')); | ||||
| @@ -213,8 +211,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listBudgetLimitByCurrency
 | ||||
|      * | ||||
|      * List all budget limits | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function budgetLimits(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -251,8 +247,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listRecurrenceByCurrency
 | ||||
|      * | ||||
|      * List all recurring transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function recurrences(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -268,7 +262,6 @@ class ListController extends Controller | ||||
|         // filter selection
 | ||||
|         $collection     = $unfiltered->filter( | ||||
|             static function (Recurrence $recurrence) use ($currency) {  // @phpstan-ignore-line
 | ||||
|                 /** @var RecurrenceTransaction $transaction */ | ||||
|                 if (array_any($recurrence->recurrenceTransactions, fn ($transaction) => $transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id)) { | ||||
|                     return $recurrence; | ||||
|                 } | ||||
| @@ -305,8 +298,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listRuleByCurrency
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function rules(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -320,7 +311,6 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $collection  = $unfiltered->filter( | ||||
|             static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
 | ||||
|                 /** @var RuleTrigger $trigger */ | ||||
|                 if (array_any($rule->ruleTriggers, fn ($trigger) => 'currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value)) { | ||||
|                     return $rule; | ||||
|                 } | ||||
| @@ -351,8 +341,6 @@ class ListController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listTransactionByCurrency
 | ||||
|      * | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| @@ -69,8 +68,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listCurrency
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
| @@ -99,8 +96,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/getCurrency
 | ||||
|      * | ||||
|      * Show a currency. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function show(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
| @@ -123,8 +118,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Show a currency. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function showPrimary(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -26,7 +26,6 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\StoreRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| @@ -66,8 +65,6 @@ class StoreController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/storeCurrency
 | ||||
|      * | ||||
|      * Store new currency. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(StoreRequest $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -98,9 +98,6 @@ class UpdateController extends Controller | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function makePrimary(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|         /** @var User $user */ | ||||
| @@ -127,8 +124,6 @@ class UpdateController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/enableCurrency
 | ||||
|      * | ||||
|      * Enable a currency. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function enable(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionLink; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionJournalLink; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| use FireflyIII\Transformers\TransactionLinkTransformer; | ||||
| @@ -69,8 +68,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/listTransactionLink
 | ||||
|      * | ||||
|      * List all transaction links there are. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -24,10 +24,10 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionLink; | ||||
| 
 | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\TransactionLink\StoreRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\LinkType; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| @@ -68,8 +67,6 @@ class ListController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/listTransactionByLinkType
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function transactions(Request $request, LinkType $linkType): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\LinkType; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| @@ -67,8 +66,6 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/listLinkType
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType; | ||||
| 
 | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\StoreRequest; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| @@ -33,6 +32,7 @@ use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Transformers\LinkTypeTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use League\Fractal\Resource\Item; | ||||
| 
 | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType; | ||||
| 
 | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\UpdateRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| @@ -35,6 +34,7 @@ use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Transformers\LinkTypeTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use League\Fractal\Resource\Item; | ||||
| 
 | ||||
|   | ||||
| @@ -25,7 +25,7 @@ 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\Api\V1\Requests\PaginationRequest; | ||||
| use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; | ||||
| use FireflyIII\Transformers\UserGroupTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -52,17 +52,19 @@ class IndexController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public function index(DateRequest $request): JsonResponse | ||||
|     public function index(PaginationRequest $request): JsonResponse | ||||
|     { | ||||
|         $administrations = $this->repository->get(); | ||||
|         $pageSize        = $this->parameters->get('limit'); | ||||
|         [ | ||||
|             'page'   => $page, | ||||
|             'limit'  => $limit, | ||||
|             'offset' => $offset, | ||||
|         ]                = $request->attributes->all(); | ||||
|         $count           = $administrations->count(); | ||||
|         $administrations = $administrations->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $paginator       = new LengthAwarePaginator($administrations, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $administrations = $administrations->slice($offset, $limit); | ||||
|         $paginator       = new LengthAwarePaginator($administrations, $count, $limit, $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) | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Search; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Support\Search\SearchInterface; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| @@ -42,8 +41,6 @@ class TransactionController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchTransactions
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function search(Request $request, SearchInterface $searcher): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -24,10 +24,10 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\Summary; | ||||
| 
 | ||||
| use Exception; | ||||
| use Carbon\Carbon; | ||||
| use Exception; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Data\DateRequest; | ||||
| use FireflyIII\Api\V1\Requests\DateRangeRequest; | ||||
| use FireflyIII\Enums\AccountTypeEnum; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| @@ -94,10 +94,10 @@ class BasicController extends Controller | ||||
|      * | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public function basic(DateRequest $request): JsonResponse | ||||
|     public function basic(DateRangeRequest $request): JsonResponse | ||||
|     { | ||||
|         // parameters for boxes:
 | ||||
|         $dates        = $request->getAll(); | ||||
|         $dates        = $request->attributes->all(); | ||||
|         $start        = $dates['start']; | ||||
|         $end          = $dates['end']; | ||||
|         $code         = $request->get('currency_code'); | ||||
| @@ -481,7 +481,7 @@ class BasicController extends Controller | ||||
|         $currencies = []; | ||||
| 
 | ||||
|         // first, create an entry for each entry in the "available" array.
 | ||||
|         /** @var array $availableBudget */ | ||||
|         /** @var string $availableBudget */ | ||||
|         foreach ($available as $currencyId => $availableBudget) { | ||||
|             $currencies[$currencyId] ??= $this->currencyRepos->find($currencyId); | ||||
|             $return[$currencyId] = [ | ||||
| @@ -589,8 +589,6 @@ class BasicController extends Controller | ||||
| 
 | ||||
|     private function getNetWorthInfo(Carbon $end): array | ||||
|     { | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user           = auth()->user(); | ||||
|         Log::debug(sprintf('getNetWorthInfo up until "%s".', $end->format('Y-m-d H:i:s'))); | ||||
|   | ||||
| @@ -24,15 +24,18 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Controllers\System; | ||||
| 
 | ||||
| use FireflyIII\Support\Facades\FireflyConfig; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\System\UpdateRequest; | ||||
| use FireflyIII\Enums\WebhookDelivery; | ||||
| use FireflyIII\Enums\WebhookResponse; | ||||
| use FireflyIII\Enums\WebhookTrigger; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Support\Binder\EitherConfigKey; | ||||
| use FireflyIII\Support\Facades\FireflyConfig; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| 
 | ||||
| /** | ||||
| @@ -107,8 +110,8 @@ class ConfigurationController extends Controller | ||||
| 
 | ||||
|         return [ | ||||
|             'is_demo_site'            => $isDemoSite?->data, | ||||
|             'permission_update_check' => null === $updateCheck ? null : (int) $updateCheck->data, | ||||
|             'last_update_check'       => null === $lastCheck ? null : (int) $lastCheck->data, | ||||
|             'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, | ||||
|             'last_update_check'       => null === $lastCheck ? null : (int)$lastCheck->data, | ||||
|             'single_user_mode'        => $singleUser?->data, | ||||
|         ]; | ||||
|     } | ||||
| @@ -130,7 +133,6 @@ class ConfigurationController extends Controller | ||||
|      */ | ||||
|     public function show(string $configKey): JsonResponse | ||||
|     { | ||||
|         $data     = []; | ||||
|         $dynamic  = $this->getDynamicConfiguration(); | ||||
|         $shortKey = str_replace('configuration.', '', $configKey); | ||||
|         if (str_starts_with($configKey, 'configuration.')) { | ||||
| @@ -139,15 +141,26 @@ class ConfigurationController extends Controller | ||||
|                 'value'    => $dynamic[$shortKey], | ||||
|                 'editable' => true, | ||||
|             ]; | ||||
| 
 | ||||
|             return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); | ||||
|         } | ||||
|         if (!str_starts_with($configKey, 'configuration.')) { | ||||
|         if (str_starts_with($configKey, 'webhook.')) { | ||||
|             $data = [ | ||||
|                 'title'    => $configKey, | ||||
|                 'value'    => config($configKey), | ||||
|                 'value'    => $this->getWebhookConfiguration($configKey), | ||||
|                 'editable' => false, | ||||
|             ]; | ||||
| 
 | ||||
|             return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); | ||||
|         } | ||||
| 
 | ||||
|         // fallback
 | ||||
|         $data     = [ | ||||
|             'title'    => $configKey, | ||||
|             'value'    => config($shortKey), | ||||
|             'editable' => false, | ||||
|         ]; | ||||
| 
 | ||||
|         return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
| @@ -182,4 +195,39 @@ class ConfigurationController extends Controller | ||||
| 
 | ||||
|         return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
| 
 | ||||
|     private function getWebhookConfiguration(string $configKey): array | ||||
|     { | ||||
|         switch ($configKey) { | ||||
|             case 'webhook.triggers': | ||||
|                 $cases = WebhookTrigger::cases(); | ||||
|                 $data  = []; | ||||
|                 foreach ($cases as $c) { | ||||
|                     $data[$c->name] = $c->value; | ||||
|                 } | ||||
| 
 | ||||
|                 return $data; | ||||
| 
 | ||||
|             case 'webhook.responses': | ||||
|                 $cases = WebhookResponse::cases(); | ||||
|                 $data  = []; | ||||
|                 foreach ($cases as $c) { | ||||
|                     $data[$c->name] = $c->value; | ||||
|                 } | ||||
| 
 | ||||
|                 return $data; | ||||
| 
 | ||||
|             case 'webhook.deliveries': | ||||
|                 $cases = WebhookDelivery::cases(); | ||||
|                 $data  = []; | ||||
|                 foreach ($cases as $c) { | ||||
|                     $data[$c->name] = $c->value; | ||||
|                 } | ||||
| 
 | ||||
|                 return $data; | ||||
| 
 | ||||
|             default: | ||||
|                 throw new FireflyException(sprintf('Unknown webhook configuration key "%s".', $configKey)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -90,8 +90,6 @@ class UserController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/users/listUser
 | ||||
|      * | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -49,8 +49,6 @@ class PreferencesController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/listPreference
 | ||||
|      * | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -62,8 +62,6 @@ class MessageController extends Controller | ||||
|     /** | ||||
|      * This endpoint is documented at: | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/getWebhookMessages
 | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(Webhook $webhook): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -25,13 +25,15 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers\Webhook; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Enums\WebhookTrigger; | ||||
| use FireflyIII\Events\RequestedSendWebhookMessages; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Generator\Webhook\MessageGeneratorInterface; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\Webhook; | ||||
| use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment; | ||||
| use FireflyIII\Transformers\WebhookTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
| @@ -67,8 +69,6 @@ class ShowController extends Controller | ||||
|      * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/listWebhook
 | ||||
|      * | ||||
|      * Display a listing of the webhooks of the user. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
| @@ -89,6 +89,13 @@ class ShowController extends Controller | ||||
|         $paginator   = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.webhooks.index').$this->buildParams()); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new WebhookEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $webhooks    = $enrichment->enrich($webhooks); | ||||
| 
 | ||||
|         /** @var WebhookTransformer $transformer */ | ||||
|         $transformer = app(WebhookTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| @@ -116,6 +123,13 @@ class ShowController extends Controller | ||||
|         Log::channel('audit')->info(sprintf('User views webhook #%d.', $webhook->id)); | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new WebhookEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $webhook     = $enrichment->enrichSingle($webhook); | ||||
| 
 | ||||
|         /** @var WebhookTransformer $transformer */ | ||||
|         $transformer = app(WebhookTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| @@ -141,21 +155,26 @@ class ShowController extends Controller | ||||
|         Log::debug(sprintf('Now in triggerTransaction(%d, %d)', $webhook->id, $group->id)); | ||||
|         Log::channel('audit')->info(sprintf('User triggers webhook #%d on transaction group #%d.', $webhook->id, $group->id)); | ||||
| 
 | ||||
|         /** @var MessageGeneratorInterface $engine */ | ||||
|         $engine = app(MessageGeneratorInterface::class); | ||||
|         $engine->setUser(auth()->user()); | ||||
| 
 | ||||
|         // tell the generator which trigger it should look for
 | ||||
|         $engine->setTrigger($webhook->trigger); | ||||
|         // tell the generator which objects to process
 | ||||
|         $engine->setObjects(new Collection([$group])); | ||||
|         // set the webhook to trigger
 | ||||
|         $engine->setWebhooks(new Collection([$webhook])); | ||||
|         // tell the generator to generate the messages
 | ||||
|         $engine->generateMessages(); | ||||
|         /** @var \FireflyIII\Models\WebhookTrigger $trigger */ | ||||
|         foreach ($webhook->webhookTriggers as $trigger) { | ||||
|             /** @var MessageGeneratorInterface $engine */ | ||||
|             $engine = app(MessageGeneratorInterface::class); | ||||
|             $engine->setUser(auth()->user()); | ||||
| 
 | ||||
|             // tell the generator which trigger it should look for
 | ||||
|             $engine->setTrigger(WebhookTrigger::tryFrom((int)$trigger->key)); | ||||
|             // tell the generator which objects to process
 | ||||
|             $engine->setObjects(new Collection()->push($group)); | ||||
|             // set the webhook to trigger
 | ||||
|             $engine->setWebhooks(new Collection()->push($webhook)); | ||||
|             // tell the generator to generate the messages
 | ||||
|             $engine->generateMessages(); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         // trigger event to send them:
 | ||||
|         Log::debug('send event RequestedSendWebhookMessages'); | ||||
|         Log::debug('send event RequestedSendWebhookMessages from ShowController::triggerTransaction()'); | ||||
|         event(new RequestedSendWebhookMessages()); | ||||
| 
 | ||||
|         return response()->json([], 204); | ||||
|   | ||||
| @@ -27,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Webhook; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\Webhook\CreateRequest; | ||||
| use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment; | ||||
| use FireflyIII\Transformers\WebhookTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use League\Fractal\Resource\Item; | ||||
| @@ -68,6 +70,15 @@ class StoreController extends Controller | ||||
|         } | ||||
| 
 | ||||
|         $webhook     = $this->repository->store($data); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new WebhookEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $webhook     = $enrichment->enrichSingle($webhook); | ||||
| 
 | ||||
| 
 | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|         Log::channel('audit')->info('User stores new webhook', $data); | ||||
|   | ||||
| @@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\Webhook\UpdateRequest; | ||||
| use FireflyIII\Models\Webhook; | ||||
| use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment; | ||||
| use FireflyIII\Transformers\WebhookTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use League\Fractal\Resource\Item; | ||||
| @@ -70,6 +72,15 @@ class UpdateController extends Controller | ||||
|         $webhook     = $this->repository->update($webhook, $data); | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new WebhookEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
| 
 | ||||
|         /** @var Webhook $webhook */ | ||||
|         $webhook     = $enrichment->enrichSingle($webhook); | ||||
| 
 | ||||
|         Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data); | ||||
| 
 | ||||
|         /** @var WebhookTransformer $transformer */ | ||||
|   | ||||
							
								
								
									
										92
									
								
								app/Api/V1/Requests/AggregateFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								app/Api/V1/Requests/AggregateFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * Copyright (c) 2025 https://github.com/ctrl-f5 | ||||
|  * | ||||
|  * 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; | ||||
| 
 | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Validation\Validator; | ||||
| use RuntimeException; | ||||
| 
 | ||||
| abstract class AggregateFormRequest extends ApiRequest | ||||
| { | ||||
|     /** | ||||
|      * @var ApiRequest[] | ||||
|      */ | ||||
|     protected array $requests = []; | ||||
| 
 | ||||
|     /** @return class-string[] */ | ||||
|     abstract protected function getRequests(): array; | ||||
| 
 | ||||
|     public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): void | ||||
|     { | ||||
|         parent::initialize($query, $request, $attributes, $cookies, $files, $server, $content); | ||||
| 
 | ||||
|         // instantiate all subrequests and share current requests' bags with them
 | ||||
|         foreach ($this->getRequests() as $config) { | ||||
|             $requestClass         = is_array($config) ? array_shift($config) : $config; | ||||
| 
 | ||||
|             if (!is_a($requestClass, Request::class, true)) { | ||||
|                 throw new RuntimeException('getRequests() must return class-strings of subclasses of Request'); | ||||
|             } | ||||
| 
 | ||||
|             $instance             = $this->requests[] = new $requestClass(); | ||||
|             $instance->request    = $this->request; | ||||
|             $instance->query      = $this->query; | ||||
|             $instance->attributes = $this->attributes; | ||||
|             $instance->cookies    = $this->cookies; | ||||
|             $instance->files      = $this->files; | ||||
|             $instance->server     = $this->server; | ||||
|             $instance->headers    = $this->headers; | ||||
| 
 | ||||
|             if ($instance instanceof ApiRequest) { | ||||
|                 $instance->handleConfig(is_array($config) ? $config : []); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public function rules(): array | ||||
|     { | ||||
|         // check all subrequests for rules and combine them
 | ||||
|         return array_reduce( | ||||
|             $this->requests, | ||||
|             static fn (array $rules, FormRequest $request) => $rules | ||||
|                 + ( | ||||
|                     method_exists($request, 'rules') | ||||
|                     ? $request->rules() | ||||
|                     : [] | ||||
|                 ), | ||||
|             [], | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public function withValidator(Validator $validator): void | ||||
|     { | ||||
|         // register all subrequests' validators
 | ||||
|         foreach ($this->requests as $request) { | ||||
|             if (method_exists($request, 'withValidator')) { | ||||
|                 $request->withValidator($validator); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * Updated.php | ||||
|  * Copyright (c) 2023 james@firefly-iii.org | ||||
|  * Copyright (c) 2025 https://github.com/ctrl-f5 | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
| @@ -22,18 +21,23 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Events\Model\BudgetLimit; | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
| 
 | ||||
| use FireflyIII\Events\Event; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| 
 | ||||
| /** | ||||
|  * Class Updated | ||||
|  */ | ||||
| class Updated extends Event | ||||
| class ApiRequest extends FormRequest | ||||
| { | ||||
|     use SerializesModels; | ||||
|     use ChecksLogin; | ||||
|     use ConvertsDataTypes; | ||||
| 
 | ||||
|     public function __construct(public BudgetLimit $budgetLimit) {} | ||||
|     protected string $required = ''; | ||||
| 
 | ||||
|     public function handleConfig(array $config): void | ||||
|     { | ||||
|         if (in_array('required', $config, true)) { | ||||
|             $this->required = 'required'; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -48,10 +48,12 @@ class AutocompleteRequest extends FormRequest | ||||
|         // remove 'initial balance' from allowed types. its internal
 | ||||
|         $array = array_diff($array, [AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::RECONCILIATION->value]); | ||||
| 
 | ||||
|         $date  = $this->getCarbonDate('date') ?? today(config('app.timezone')); | ||||
| 
 | ||||
|         return [ | ||||
|             'types' => $array, | ||||
|             'query' => $this->convertString('query'), | ||||
|             'date'  => $this->getCarbonDate('date'), | ||||
|             'date'  => $date->endOfDay(), | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -24,13 +24,13 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Chart; | ||||
| 
 | ||||
| use Illuminate\Contracts\Validation\Validator; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| 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 ChartRequest | ||||
| @@ -64,6 +64,7 @@ class ChartRequest extends FormRequest | ||||
|             'end'         => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start', | ||||
|             'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))), | ||||
|             'period'      => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))), | ||||
|             'accounts'    => 'nullable|array', | ||||
|             'accounts.*'  => 'exists:accounts,id', | ||||
|         ]; | ||||
| 
 | ||||
|   | ||||
| @@ -24,12 +24,12 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Data\Bulk; | ||||
| 
 | ||||
| use Illuminate\Contracts\Validation\Validator; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| 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 MoveTransactionsRequest | ||||
|   | ||||
| @@ -24,8 +24,6 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V1\Requests\Data\Bulk; | ||||
| 
 | ||||
| use Illuminate\Contracts\Validation\Validator; | ||||
| use JsonException; | ||||
| use FireflyIII\Enums\ClauseType; | ||||
| use FireflyIII\Rules\IsValidBulkClause; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| @@ -33,6 +31,8 @@ use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Validation\Validator; | ||||
| use JsonException; | ||||
| 
 | ||||
| use function Safe\json_decode; | ||||
| 
 | ||||
|   | ||||
| @@ -1,73 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * DateRequest.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\Data; | ||||
| 
 | ||||
| use FireflyIII\Exceptions\ValidationException; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
| 
 | ||||
| /** | ||||
|  * Request class for end points that require date parameters. | ||||
|  * | ||||
|  * Class DateRequest | ||||
|  */ | ||||
| class DateRequest extends FormRequest | ||||
| { | ||||
|     use ChecksLogin; | ||||
|     use ConvertsDataTypes; | ||||
| 
 | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $start = $this->getCarbonDate('start'); | ||||
|         $end   = $this->getCarbonDate('end'); | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
|         if ($start->diffInYears($end, true) > 5) { | ||||
|             throw new ValidationException('Date range out of range.'); | ||||
|         } | ||||
| 
 | ||||
|         return [ | ||||
|             'start' => $start, | ||||
|             'end'   => $end, | ||||
|             'date'  => $this->getCarbonDate('date'), | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'date'  => 'date|after:1970-01-02|before:2038-01-17', | ||||
|             'start' => 'date|after:1970-01-02|before:2038-01-17|before:end|required_with:end', | ||||
|             'end'   => 'date|after:1970-01-02|before:2038-01-17|after:start|required_with:start', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user