mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Compare commits
	
		
			161 Commits
		
	
	
		
			develop-20
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 422a23e700 | ||
|  | 8c2672cdf8 | ||
|  | 764e49985b | ||
|  | 84251f8f10 | ||
|  | 8b4740d28c | ||
|  | 0845e265c2 | ||
|  | b4455a3802 | ||
|  | 8d12d47691 | ||
|  | 3dc01b0d5c | ||
|  | b442645280 | ||
|  | eda2b5f822 | ||
|  | d9593db5e2 | ||
|  | 56bac9fc97 | ||
|  | b93cfc5de2 | ||
|  | d41f5b1090 | ||
|  | 40322813c9 | ||
|  | 4a98927e32 | ||
|  | 193e529803 | ||
|  | fbf20ef2c2 | ||
|  | 54de829c8a | ||
|  | 131b987561 | ||
|  | dce6754c62 | ||
|  | f4bca90080 | ||
|  | b2960b1ed9 | ||
|  | 33f87bce23 | ||
|  | 23aa45609b | ||
|  | b098952f82 | ||
|  | 68c3e14b0c | ||
|  | 19d08137a5 | ||
|  | 73776e7869 | ||
|  | bf04ca12c1 | ||
|  | a4637debe9 | ||
|  | 48c1b525be | ||
|  | 56470bfbba | ||
|  | 0f732ca874 | ||
|  | e452ba938d | ||
|  | 9921c5a925 | ||
|  | 58fab75681 | ||
|  | 54990308f6 | ||
|  | f95758ff47 | ||
|  | 8d830e178f | ||
|  | 334a521ca1 | ||
|  | 12629a1955 | ||
|  | 2e3669a32f | ||
|  | ea337607c4 | ||
|  | f7f317a3b2 | ||
|  | adbf6defe5 | ||
|  | e0709f2975 | ||
|  | 30007b05cb | ||
|  | 13fc7f0d8d | ||
|  | 7c85138115 | ||
|  | 2c25f65f7f | ||
|  | 7eaba962e8 | ||
|  | 7c38393cde | ||
|  | 153fd2ae74 | ||
|  | c0204c810c | ||
|  | 944c107e26 | ||
|  | 18e05c06fd | ||
|  | fb79dbf17c | ||
|  | 31a8163c61 | ||
|  | 8bcd729250 | ||
|  | 80c4e69528 | ||
|  | 7f6d8fdb87 | ||
|  | c8e301326e | ||
|  | 4820ef6580 | ||
|  | 4cb775cf4b | ||
|  | c371662c51 | ||
|  | ffaa164aa5 | ||
|  | 344bfbe059 | ||
|  | 6c38b87ec5 | ||
|  | dfcd5d79be | ||
|  | 07631eea28 | ||
|  | 26c4fe36cc | ||
|  | 90fc4b44f2 | ||
|  | f755dd2d48 | ||
|  | d2647f96e7 | ||
|  | 9f94ec067a | ||
|  | a795755618 | ||
|  | 8457a1c881 | ||
|  | fc9429bf3e | ||
|  | b6e8b66035 | ||
|  | 7504b21c3e | ||
|  | b7dad8166d | ||
|  | 2da1b43c37 | ||
|  | a606315884 | ||
|  | 295feedd77 | ||
|  | d3b2748c8f | ||
|  | 1b4655fd70 | ||
|  | 05f67ef584 | ||
|  | 04ab7ba07d | ||
|  | 5806323970 | ||
|  | ee260a3df7 | ||
|  | 7cb41fb333 | ||
|  | d38adbfdc2 | ||
|  | e6a6766ef1 | ||
|  | a1e596491c | ||
|  | 9c920908a6 | ||
|  | 0014bffeb8 | ||
|  | 63c17f99b2 | ||
|  | ec1e0e2807 | ||
|  | 2f16419a7b | ||
|  | 02c13859e7 | ||
|  | 57ec9b8e36 | ||
|  | 41ad35880d | ||
|  | 3aa946e028 | ||
|  | 53e46895aa | ||
|  | c61389037d | ||
|  | 6172d60e00 | ||
|  | f909f1d9ff | ||
|  | 55018ca046 | ||
|  | 19c746a865 | ||
|  | 503d2aa786 | ||
|  | 70d83ab501 | ||
|  | edab602bb7 | ||
|  | f9bcc4b1fa | ||
|  | f3fe86167c | ||
|  | 2189fb46a2 | ||
|  | 7ff4178c8b | ||
|  | fffd695ef8 | ||
|  | ee592de035 | ||
|  | 7394e50ae2 | ||
|  | f42fcff04a | ||
|  | 4eb3ce7c14 | ||
|  | a977c567ce | ||
|  | 785bd7e905 | ||
|  | df19f699d4 | ||
|  | 5e6e932e7e | ||
|  | 5bc397f01a | ||
|  | 42209e367f | ||
|  | d53b1670d3 | ||
|  | a6d450ba18 | ||
|  | e8c1a95128 | ||
|  | edb201f210 | ||
|  | fe57367a8c | ||
|  | 134194a95b | ||
|  | 41c0e6fe2d | ||
|  | c07914e733 | ||
|  | 52e2302f4f | ||
|  | 0a6b34b4f2 | ||
|  | 1e06b4dd0b | ||
|  | 5701f95e0b | ||
|  | 60d3572d37 | ||
|  | ffa6e6a571 | ||
|  | d6453cd735 | ||
|  | fd79f9df44 | ||
|  | 4587340293 | ||
|  | 90bfdc7573 | ||
|  | eca12f661f | ||
|  | f85878b843 | ||
|  | 6499b5eaab | ||
|  | 7e4fece63d | ||
|  | 512eddf8be | ||
|  | f0fa93a811 | ||
|  | 3c8de21709 | ||
|  | 81173e8340 | ||
|  | 35a8fa5f02 | ||
|  | 443036936d | ||
|  | ac88007593 | ||
|  | cabedf39b2 | ||
|  | 5d3806fcd4 | ||
|  | 71fb5fe077 | 
							
								
								
									
										72
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										72
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -406,16 +406,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "friendsofphp/php-cs-fixer", | ||||
|             "version": "v3.68.5", | ||||
|             "version": "v3.70.2", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", | ||||
|                 "reference": "7bedb718b633355272428c60736dc97fb96daf27" | ||||
|                 "reference": "1ca468270efbb75ce0c7566a79cca8ea2888584d" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7bedb718b633355272428c60736dc97fb96daf27", | ||||
|                 "reference": "7bedb718b633355272428c60736dc97fb96daf27", | ||||
|                 "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1ca468270efbb75ce0c7566a79cca8ea2888584d", | ||||
|                 "reference": "1ca468270efbb75ce0c7566a79cca8ea2888584d", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -432,7 +432,7 @@ | ||||
|                 "react/promise": "^2.0 || ^3.0", | ||||
|                 "react/socket": "^1.0", | ||||
|                 "react/stream": "^1.0", | ||||
|                 "sebastian/diff": "^4.0 || ^5.1 || ^6.0", | ||||
|                 "sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0", | ||||
|                 "symfony/console": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", | ||||
|                 "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", | ||||
| @@ -445,18 +445,18 @@ | ||||
|                 "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "facile-it/paraunit": "^1.3.1 || ^2.4", | ||||
|                 "infection/infection": "^0.29.8", | ||||
|                 "facile-it/paraunit": "^1.3.1 || ^2.5", | ||||
|                 "infection/infection": "^0.29.10", | ||||
|                 "justinrainbow/json-schema": "^5.3 || ^6.0", | ||||
|                 "keradus/cli-executor": "^2.1", | ||||
|                 "mikey179/vfsstream": "^1.6.12", | ||||
|                 "php-coveralls/php-coveralls": "^2.7", | ||||
|                 "php-cs-fixer/accessible-object": "^1.1", | ||||
|                 "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", | ||||
|                 "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", | ||||
|                 "phpunit/phpunit": "^9.6.22 || ^10.5.40 || ^11.5.2", | ||||
|                 "symfony/var-dumper": "^5.4.48 || ^6.4.15 || ^7.2.0", | ||||
|                 "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.2.0" | ||||
|                 "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", | ||||
|                 "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", | ||||
|                 "phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.7", | ||||
|                 "symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.0", | ||||
|                 "symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "ext-dom": "For handling output formats in XML", | ||||
| @@ -497,7 +497,7 @@ | ||||
|             ], | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.5" | ||||
|                 "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.70.2" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -505,7 +505,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2025-01-30T17:00:50+00:00" | ||||
|             "time": "2025-03-03T21:07:23+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "psr/container", | ||||
| @@ -1188,29 +1188,29 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "sebastian/diff", | ||||
|             "version": "6.0.2", | ||||
|             "version": "7.0.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/diff.git", | ||||
|                 "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" | ||||
|                 "reference": "7ab1ea946c012266ca32390913653d844ecd085f" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", | ||||
|                 "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", | ||||
|                 "reference": "7ab1ea946c012266ca32390913653d844ecd085f", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=8.2" | ||||
|                 "php": ">=8.3" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "phpunit/phpunit": "^11.0", | ||||
|                 "symfony/process": "^4.2 || ^5" | ||||
|                 "phpunit/phpunit": "^12.0", | ||||
|                 "symfony/process": "^7.2" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-main": "6.0-dev" | ||||
|                     "dev-main": "7.0-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -1243,7 +1243,7 @@ | ||||
|             "support": { | ||||
|                 "issues": "https://github.com/sebastianbergmann/diff/issues", | ||||
|                 "security": "https://github.com/sebastianbergmann/diff/security/policy", | ||||
|                 "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" | ||||
|                 "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -1251,7 +1251,7 @@ | ||||
|                     "type": "github" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-07-03T04:53:05+00:00" | ||||
|             "time": "2025-02-07T04:55:46+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/console", | ||||
| @@ -2242,16 +2242,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/process", | ||||
|             "version": "v7.2.0", | ||||
|             "version": "v7.2.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/process.git", | ||||
|                 "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" | ||||
|                 "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", | ||||
|                 "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", | ||||
|                 "url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", | ||||
|                 "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2283,7 +2283,7 @@ | ||||
|             "description": "Executes commands in sub-processes", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/process/tree/v7.2.0" | ||||
|                 "source": "https://github.com/symfony/process/tree/v7.2.4" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2299,7 +2299,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-11-06T14:24:19+00:00" | ||||
|             "time": "2025-02-05T08:33:46+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/service-contracts", | ||||
| @@ -2386,16 +2386,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/stopwatch", | ||||
|             "version": "v7.2.2", | ||||
|             "version": "v7.2.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/symfony/stopwatch.git", | ||||
|                 "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" | ||||
|                 "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", | ||||
|                 "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", | ||||
|                 "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", | ||||
|                 "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -2428,7 +2428,7 @@ | ||||
|             "description": "Provides a way to profile code", | ||||
|             "homepage": "https://symfony.com", | ||||
|             "support": { | ||||
|                 "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" | ||||
|                 "source": "https://github.com/symfony/stopwatch/tree/v7.2.4" | ||||
|             }, | ||||
|             "funding": [ | ||||
|                 { | ||||
| @@ -2444,7 +2444,7 @@ | ||||
|                     "type": "tidelift" | ||||
|                 } | ||||
|             ], | ||||
|             "time": "2024-12-18T14:28:33+00:00" | ||||
|             "time": "2025-02-24T10:49:57+00:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/string", | ||||
|   | ||||
| @@ -19,7 +19,7 @@ SITE_OWNER=mail@example.com | ||||
| APP_KEY=SomeRandomStringOf32CharsExactly | ||||
|  | ||||
| # Firefly III will launch using this language (for new users and unauthenticated visitors) | ||||
| # For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/main/resources/lang | ||||
| # For a list of available languages: https://github.com/firefly-iii/firefly-iii/blob/main/config/firefly.php#L123 | ||||
| # | ||||
| # If text is still in English, remember that not everything may have been translated. | ||||
| DEFAULT_LANGUAGE=en_US | ||||
| @@ -189,7 +189,7 @@ SEND_REPORT_JOURNALS=true | ||||
| ENABLE_EXTERNAL_MAP=false | ||||
|  | ||||
| # | ||||
| # Enable or disable exchange rate conversion. This function isn't used yet by Firefly III | ||||
| # Enable or disable exchange rate conversion. | ||||
| # | ||||
| ENABLE_EXCHANGE_RATES=false | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/closed-issues.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/closed-issues.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ jobs: | ||||
|   command_and_close: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: aws-actions/closed-issue-message@v1 | ||||
|       - uses: aws-actions/closed-issue-message@v2 | ||||
|         with: | ||||
|           message: | | ||||
|             Hi there! This is an automatic reply. `Share and enjoy` | ||||
|   | ||||
							
								
								
									
										12
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -204,9 +204,9 @@ jobs: | ||||
|  | ||||
|           # zip and tar everything | ||||
|           echo 'Zip and tar...' | ||||
|           zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" | ||||
|           zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" "*Procfile*" "*crowdin.yml*" "*sonar-project.properties*" | ||||
|           touch $tarName | ||||
|           tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' -czf $tarName . | ||||
|           tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' --exclude='./Procfile' --exclude='../crowdin.yml' --exclude='./sonar-project.properties' -czf $tarName . | ||||
|  | ||||
|           # add sha256 sum | ||||
|           echo 'Sha sum ...' | ||||
| @@ -225,7 +225,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt | ||||
|             echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt | ||||
| @@ -240,7 +240,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "" >> output.txt | ||||
|             echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt | ||||
|             echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt | ||||
| @@ -268,7 +268,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
| @@ -286,7 +286,7 @@ jobs: | ||||
|             sudo chown -R runner:docker output.txt | ||||
|             echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt | ||||
|             echo '' >> output.txt | ||||
|             echo '### Instructions' >> output.txt | ||||
|             echo '' >> output.txt | ||||
|   | ||||
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -14,7 +14,16 @@ public/build | ||||
| # ignore v1 build files | ||||
| resources/assets/v1/node_modules | ||||
| resources/assets/v1/build | ||||
| public/v1/js/app.js* | ||||
| public/v1/js/app_vue.js* | ||||
| public/v1/js/create* | ||||
| public/v1/js/edit* | ||||
| public/v1/js/profile* | ||||
| public/v1/js/administrations | ||||
| public/v1/js/exchange-rates | ||||
| public/v1/js/webhooks | ||||
|  | ||||
| # ignore v2 build files | ||||
| resources/assets/v2/node_modules | ||||
| resources/assets/v2/build | ||||
| public/v2/i18n | ||||
|   | ||||
| @@ -4,6 +4,8 @@ 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 | ||||
| - Lompi | ||||
| - Jose Diaz-Gonzalez | ||||
| - SoftBrix | ||||
| 
 | ||||
| ## 2024 | ||||
|   | ||||
| @@ -34,6 +34,7 @@ use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountController | ||||
| @@ -83,7 +84,7 @@ class AccountController extends Controller | ||||
|         $return = []; | ||||
|         $result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit')); | ||||
| 
 | ||||
|         // set date to end-of-day for account balance.
 | ||||
|         // set date to subday + end-of-day for account balance. so it is at $date 23:59:59
 | ||||
|         $date->endOfDay(); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
| @@ -92,6 +93,8 @@ class AccountController extends Controller | ||||
|             $currency        = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency; | ||||
|             $useCurrency     = $currency; | ||||
|             if (in_array($account->accountType->type, $this->balanceTypes, true)) { | ||||
|                 // this one is correct.
 | ||||
|                 Log::debug(sprintf('accounts: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); | ||||
|                 $balance         = Steam::finalAccountBalance($account, $date); | ||||
|                 $key             = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance'; | ||||
|                 $useCurrency     = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? $this->nativeCurrency : $currency; | ||||
| @@ -113,6 +116,11 @@ class AccountController extends Controller | ||||
|                 'currency_code'                   => $useCurrency->code, | ||||
|                 'currency_symbol'                 => $useCurrency->symbol, | ||||
|                 'currency_decimal_places'         => $useCurrency->decimal_places, | ||||
|                 'account_currency_id'             => (string) $currency->id, | ||||
|                 'account_currency_name'           => $currency->name, | ||||
|                 'account_currency_code'           => $currency->code, | ||||
|                 'account_currency_symbol'         => $currency->symbol, | ||||
|                 'account_currency_decimal_places' => $currency->decimal_places, | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; | ||||
| @@ -41,6 +42,8 @@ class TransactionController extends Controller | ||||
|     private TransactionGroupRepositoryInterface $groupRepository; | ||||
|     private JournalRepositoryInterface          $repository; | ||||
| 
 | ||||
|     protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; | ||||
| 
 | ||||
|     /** | ||||
|      * TransactionController constructor. | ||||
|      */ | ||||
| @@ -51,10 +54,12 @@ class TransactionController extends Controller | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user                  = auth()->user(); | ||||
|                 $userGroup             = $this->validateUserGroup($request); | ||||
|                 $this->repository      = app(JournalRepositoryInterface::class); | ||||
|                 $this->groupRepository = app(TransactionGroupRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|                 $this->groupRepository->setUser($user); | ||||
|                 $this->groupRepository->setUserGroup($userGroup); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; | ||||
| use FireflyIII\Transformers\V2\AbstractTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| @@ -59,6 +60,7 @@ abstract class Controller extends BaseController | ||||
|     use AuthorizesRequests; | ||||
|     use DispatchesJobs; | ||||
|     use ValidatesRequests; | ||||
|     use ValidatesUserGroupTrait; | ||||
| 
 | ||||
|     protected const string CONTENT_TYPE      = 'application/vnd.api+json'; | ||||
|     protected const string JSON_CONTENT_TYPE = 'application/json'; | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\Transformers\PiggyBankTransformer; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| @@ -165,13 +166,17 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.accounts.transactions', [$account->id]).$this->buildParams()); | ||||
|         $groups      = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $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($groups, $transformer, 'transactions'); | ||||
|         $resource     = new FractalCollection($transactions, $transformer, 'transactions'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|   | ||||
| @@ -29,7 +29,9 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| 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; | ||||
| @@ -88,9 +90,17 @@ class ShowController extends Controller | ||||
|         $count       = $collection->count(); | ||||
| 
 | ||||
|         // continue sort:
 | ||||
| 
 | ||||
|         $accounts    = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $accounts    = $enrichment->enrich($accounts); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator   = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.accounts.index').$this->buildParams()); | ||||
| @@ -118,6 +128,16 @@ class ShowController extends Controller | ||||
|         $account->refresh(); | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $account     = $enrichment->enrichSingle($account); | ||||
| 
 | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -27,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\Account; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\Account\StoreRequest; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use League\Fractal\Resource\Item; | ||||
| 
 | ||||
| @@ -69,6 +71,15 @@ class StoreController extends Controller | ||||
|         $account     = $this->repository->store($data); | ||||
|         $manager     = $this->getManager(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $account     = $enrichment->enrichSingle($account); | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\Account\UpdateRequest; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use League\Fractal\Resource\Item; | ||||
| 
 | ||||
| @@ -73,6 +75,15 @@ class UpdateController extends Controller | ||||
|         $account->refresh(); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin        = auth()->user(); | ||||
|         $enrichment   = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $account      = $enrichment->enrichSingle($account); | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer  = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\Transformers\RuleTransformer; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| @@ -176,7 +177,11 @@ class ListController extends Controller | ||||
|         // get paginator.
 | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]).$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -32,6 +32,7 @@ use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\Transformers\BudgetLimitTransformer; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| @@ -172,7 +173,11 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]).$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
| @@ -232,7 +237,11 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.budgets.without-budget').$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -84,7 +85,11 @@ class ListController extends Controller | ||||
|         $collector->setTypes($types); | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]).$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| @@ -139,7 +140,11 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.categories.transactions', [$category->id]).$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -28,9 +28,11 @@ 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; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\Transformers\PiggyBankEventTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| @@ -75,17 +77,26 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $collection  = $piggyBank->accounts; | ||||
|         $count       = $collection->count(); | ||||
|         $events      = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $accounts    = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $accounts    = $enrichment->enrich($accounts); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator   = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator   = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams()); | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         $resource    = new FractalCollection($events, $transformer, 'accounts'); | ||||
|         $resource    = new FractalCollection($accounts, $transformer, 'accounts'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -110,7 +111,11 @@ class ListController extends Controller | ||||
| 
 | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.transactions.index').$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Models\Rule\TestRequest; | ||||
| use FireflyIII\Api\V1\Requests\Models\Rule\TriggerRequest; | ||||
| use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Repositories\Rule\RuleRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\TransactionRules\Engine\RuleEngineInterface; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| @@ -94,6 +95,11 @@ class TriggerController extends Controller | ||||
|         $transactions = $ruleEngine->find(); | ||||
|         $count        = $transactions->count(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($rule->user); | ||||
|         $transactions = $enrichment->enrich($transactions); | ||||
| 
 | ||||
|         $paginator    = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.rules.test', [$rule->id]).$this->buildParams()); | ||||
| 
 | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Api\V1\Requests\Models\RuleGroup\TriggerRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\TransactionRules\Engine\RuleEngineInterface; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| @@ -100,6 +101,11 @@ class TriggerController extends Controller | ||||
|         $transactions = $ruleEngine->find(); | ||||
|         $count        = $transactions->count(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($group->user); | ||||
|         $transactions = $enrichment->enrich($transactions); | ||||
| 
 | ||||
|         $paginator    = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.rule-groups.test', [$group->id]).$this->buildParams()); | ||||
| 
 | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| @@ -141,7 +142,12 @@ class ListController extends Controller | ||||
|         } | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.tags.transactions', [$tag->id]).$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -85,7 +86,11 @@ class ShowController extends Controller | ||||
|         } | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.transactions.index').$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
| @@ -137,6 +142,11 @@ class ShowController extends Controller | ||||
|             throw new NotFoundHttpException(); | ||||
|         } | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment    = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $selectedGroup = $enrichment->enrichSingle($selectedGroup); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer   = app(TransactionGroupTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Models\Transaction; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Models\Transaction\StoreRequest; | ||||
| use FireflyIII\Enums\UserRoleEnum; | ||||
| use FireflyIII\Events\StoredTransactionGroup; | ||||
| use FireflyIII\Exceptions\DuplicateTransactionException; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| @@ -33,10 +34,12 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; | ||||
| use FireflyIII\Rules\IsDuplicateTransaction; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Support\Facades\Validator; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use League\Fractal\Resource\Item; | ||||
| 
 | ||||
| @@ -49,6 +52,8 @@ class StoreController extends Controller | ||||
| 
 | ||||
|     private TransactionGroupRepositoryInterface $groupRepository; | ||||
| 
 | ||||
|     protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS]; | ||||
| 
 | ||||
|     /** | ||||
|      * TransactionController constructor. | ||||
|      */ | ||||
| @@ -59,9 +64,11 @@ class StoreController extends Controller | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin                 = auth()->user(); | ||||
|                 $userGroup             = $this->validateUserGroup($request); | ||||
| 
 | ||||
|                 $this->groupRepository = app(TransactionGroupRepositoryInterface::class); | ||||
|                 $this->groupRepository->setUser($admin); | ||||
|                 $this->groupRepository->setUserGroup($userGroup); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -80,27 +87,24 @@ class StoreController extends Controller | ||||
|     { | ||||
|         app('log')->debug('Now in API StoreController::store()'); | ||||
|         $data               = $request->getAll(); | ||||
|         $data['user']  = auth()->user()->id; | ||||
|         $data['user']       = auth()->user(); | ||||
|         $data['user_group'] = $this->userGroup; | ||||
| 
 | ||||
|         Log::channel('audit') | ||||
|             ->info('Store new transaction over API.', $data) | ||||
|         ; | ||||
| 
 | ||||
|         Log::channel('audit')->info('Store new transaction over API.', $data); | ||||
| 
 | ||||
|         try { | ||||
|             $transactionGroup = $this->groupRepository->store($data); | ||||
|         } catch (DuplicateTransactionException $e) { | ||||
|             app('log')->warning('Caught a duplicate transaction. Return error message.'); | ||||
|             $validator = \Validator::make( | ||||
|                 ['transactions' => [['description' => $e->getMessage()]]], | ||||
|                 ['transactions.0.description' => new IsDuplicateTransaction()] | ||||
|             ); | ||||
|             $validator = Validator::make(['transactions' => [['description' => $e->getMessage()]]], ['transactions.0.description' => new IsDuplicateTransaction()]); | ||||
| 
 | ||||
|             throw new ValidationException($validator); | ||||
|         } catch (FireflyException $e) { | ||||
|             app('log')->warning('Caught an exception. Return error message.'); | ||||
|             app('log')->error($e->getMessage()); | ||||
|             $message   = sprintf('Internal exception: %s', $e->getMessage()); | ||||
|             $validator = \Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]); | ||||
|             $validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]); | ||||
| 
 | ||||
|             throw new ValidationException($validator); | ||||
|         } | ||||
| @@ -119,6 +123,7 @@ class StoreController extends Controller | ||||
|         $collector          = app(GroupCollectorInterface::class); | ||||
|         $collector | ||||
|             ->setUser($admin) | ||||
|             ->setUserGroup($this->userGroup) | ||||
|             // filter on transaction group.
 | ||||
|             ->setTransactionGroup($transactionGroup) | ||||
|             // all info needed for the API:
 | ||||
| @@ -130,6 +135,11 @@ class StoreController extends Controller | ||||
|             throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.'); | ||||
|         } | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment         = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $selectedGroup      = $enrichment->enrichSingle($selectedGroup); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer        = app(TransactionGroupTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Events\UpdatedTransactionGroup; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -99,6 +100,11 @@ class UpdateController extends Controller | ||||
|             throw new NotFoundHttpException(); | ||||
|         } | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment       = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $selectedGroup    = $enrichment->enrichSingle($selectedGroup); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer      = app(TransactionGroupTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -42,6 +42,8 @@ use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; | ||||
| use FireflyIII\Repositories\Rule\RuleRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\Transformers\AvailableBudgetTransformer; | ||||
| use FireflyIII\Transformers\BillTransformer; | ||||
| @@ -100,6 +102,15 @@ class ListController extends Controller | ||||
|         $count             = $collection->count(); | ||||
|         $accounts          = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin             = auth()->user(); | ||||
|         $enrichment        = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $accounts          = $enrichment->enrich($accounts); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator         = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]).$this->buildParams()); | ||||
| @@ -360,7 +371,11 @@ class ListController extends Controller | ||||
|         } | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]).$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\LinkType; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\TransactionFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -109,7 +110,11 @@ class ListController extends Controller | ||||
|         } | ||||
|         $paginator    = $collector->getPaginatedGroups(); | ||||
|         $paginator->setPath(route('api.v1.transactions.index').$this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $transactions = $enrichment->enrich($paginator->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -26,8 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Search; | ||||
| 
 | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Support\Http\Api\AccountFilter; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Support\Search\AccountSearch; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Http\Response; | ||||
| @@ -81,6 +83,15 @@ class AccountController extends Controller | ||||
| 
 | ||||
|         $accounts    = $search->search(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin       = auth()->user(); | ||||
|         $enrichment  = new AccountEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->nativeCurrency); | ||||
|         $accounts    = $enrichment->enrich($accounts); | ||||
| 
 | ||||
|         /** @var AccountTransformer $transformer */ | ||||
|         $transformer = app(AccountTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
|   | ||||
| @@ -26,6 +26,7 @@ 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; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| @@ -57,7 +58,11 @@ class TransactionController extends Controller | ||||
|         $parameters   = ['search' => $fullQuery]; | ||||
|         $url          = route('api.v1.search.transactions').'?'.http_build_query($parameters); | ||||
|         $groups->setPath($url); | ||||
|         $transactions = $groups->getCollection(); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         $enrichment   = new TransactionGroupEnrichment(); | ||||
|         $enrichment->setUser(auth()->user()); | ||||
|         $transactions = $enrichment->enrich($groups->getCollection()); | ||||
| 
 | ||||
|         /** @var TransactionGroupTransformer $transformer */ | ||||
|         $transformer  = app(TransactionGroupTransformer::class); | ||||
|   | ||||
| @@ -102,7 +102,7 @@ class BasicController extends Controller | ||||
|         $balanceData  = $this->getBalanceInformation($start, $end); | ||||
|         $billData     = $this->getBillInformation($start, $end); | ||||
|         $spentData    = $this->getLeftToSpendInfo($start, $end); | ||||
|         $netWorthData = $this->getNetWorthInfo($start, $end); | ||||
|         $netWorthData = $this->getNetWorthInfo($end); | ||||
|         //                $balanceData  = [];
 | ||||
|         //                $billData     = [];
 | ||||
|         //                $spentData    = [];
 | ||||
| @@ -185,8 +185,8 @@ class BasicController extends Controller | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false), | ||||
|                 'local_icon'              => 'balance-scale', | ||||
|                 'sub_title'               => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false). | ||||
|                                              ' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false), | ||||
|                 'sub_title'               => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false) | ||||
|                                              .' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false), | ||||
|             ]; | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('spent-in-%s', $currency->code), | ||||
| @@ -213,6 +213,47 @@ class BasicController extends Controller | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|         } | ||||
|         if (0 === count($return)) { | ||||
|             $currency = $this->nativeCurrency; | ||||
|             // create objects for big array.
 | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('balance-in-%s', $currency->code), | ||||
|                 'title'                   => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_code'           => $currency->code, | ||||
|                 'currency_symbol'         => $currency->symbol, | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatAnything($currency, '0', false), | ||||
|                 'local_icon'              => 'balance-scale', | ||||
|                 'sub_title'               => app('amount')->formatAnything($currency, '0', false) | ||||
|                     .' + '.app('amount')->formatAnything($currency, '0', false), | ||||
|             ]; | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('spent-in-%s', $currency->code), | ||||
|                 'title'                   => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_code'           => $currency->code, | ||||
|                 'currency_symbol'         => $currency->symbol, | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatAnything($currency, '0', false), | ||||
|                 'local_icon'              => 'balance-scale', | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('earned-in-%s', $currency->code), | ||||
|                 'title'                   => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_code'           => $currency->code, | ||||
|                 'currency_symbol'         => $currency->symbol, | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatAnything($currency, '0', false), | ||||
|                 'local_icon'              => 'balance-scale', | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| @@ -268,6 +309,37 @@ class BasicController extends Controller | ||||
|         } | ||||
|         app('log')->debug(sprintf('Done with getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-'))); | ||||
| 
 | ||||
|         if (0 === count($return)) { | ||||
|             $currency = $this->nativeCurrency; | ||||
|             unset($info, $amount); | ||||
| 
 | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('bills-paid-in-%s', $currency->code), | ||||
|                 'title'                   => trans('firefly.box_bill_paid_in_currency', ['currency' => $currency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_code'           => $currency->code, | ||||
|                 'currency_symbol'         => $currency->symbol, | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatFlat($currency->symbol, $currency->decimal_places, '0', false), | ||||
|                 'local_icon'              => 'check', | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('bills-unpaid-in-%s', $currency->code), | ||||
|                 'title'                   => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $currency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_code'           => $currency->code, | ||||
|                 'currency_symbol'         => $currency->symbol, | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatFlat($currency->symbol, $currency->decimal_places, '0', false), | ||||
|                 'local_icon'              => 'calendar-o', | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
| @@ -315,22 +387,37 @@ class BasicController extends Controller | ||||
|                 ), | ||||
|             ]; | ||||
|         } | ||||
|         if (0 === count($return)) { | ||||
|             $currency = $this->nativeCurrency; | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('left-to-spend-in-%s', $currency->code), | ||||
|                 'title'                   => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $currency->id, | ||||
|                 'currency_code'           => $currency->code, | ||||
|                 'currency_symbol'         => $currency->symbol, | ||||
|                 'currency_decimal_places' => $currency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatFlat($currency->symbol, $currency->decimal_places, '0', false), | ||||
|                 'local_icon'              => 'money', | ||||
|                 'sub_title'               => app('amount')->formatFlat( | ||||
|                     $currency->symbol, | ||||
|                     $currency->decimal_places, | ||||
|                     '0', | ||||
|                     false | ||||
|                 ), | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     private function getNetWorthInfo(Carbon $start, Carbon $end): array | ||||
|     private function getNetWorthInfo(Carbon $end): array | ||||
|     { | ||||
|         Log::debug('getNetWorthInfo'); | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user           = auth()->user(); | ||||
|         $date           = now(config('app.timezone')); | ||||
|         // start and end in the future? use $end
 | ||||
|         if ($this->notInDateRange($date, $start, $end)) { | ||||
|             /** @var Carbon $date */ | ||||
|             $date = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         } | ||||
|         Log::debug(sprintf('getNetWorthInfo up until "%s".', $end->format('Y-m-d H:i:s'))); | ||||
| 
 | ||||
|         /** @var NetWorthInterface $netWorthHelper */ | ||||
|         $netWorthHelper = app(NetWorthInterface::class); | ||||
| @@ -346,7 +433,7 @@ class BasicController extends Controller | ||||
|             } | ||||
|         ); | ||||
| 
 | ||||
|         $netWorthSet    = $netWorthHelper->byAccounts($filtered, $date); | ||||
|         $netWorthSet    = $netWorthHelper->byAccounts($filtered, $end); | ||||
|         $return         = []; | ||||
|         foreach ($netWorthSet as $key => $data) { | ||||
|             if ('native' === $key) { | ||||
| @@ -370,6 +457,22 @@ class BasicController extends Controller | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|         } | ||||
|         if (0 === count($return)) { | ||||
|             $return[] = [ | ||||
|                 'key'                     => sprintf('net-worth-in-%s', $this->nativeCurrency->code), | ||||
|                 'title'                   => trans('firefly.box_net_worth_in_currency', ['currency' => $this->nativeCurrency->symbol]), | ||||
|                 'monetary_value'          => '0', | ||||
|                 'currency_id'             => (string) $this->nativeCurrency->id, | ||||
|                 'currency_code'           => $this->nativeCurrency->code, | ||||
|                 'currency_symbol'         => $this->nativeCurrency->symbol, | ||||
|                 'currency_decimal_places' => $this->nativeCurrency->decimal_places, | ||||
|                 'value_parsed'            => app('amount')->formatFlat($this->nativeCurrency->symbol, $this->nativeCurrency->decimal_places, '0', false), | ||||
|                 'local_icon'              => 'line-chart', | ||||
|                 'sub_title'               => '', | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         Log::debug('End of getNetWorthInfo'); | ||||
| 
 | ||||
|         return $return; | ||||
|   | ||||
| @@ -27,6 +27,7 @@ namespace FireflyIII\Api\V1\Controllers\System; | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Transformers\UserTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use League\Fractal\Resource\Item; | ||||
| 
 | ||||
| /** | ||||
| @@ -48,7 +49,7 @@ class AboutController extends Controller | ||||
|         $replace       = ['\~', '# ']; | ||||
|         $phpVersion    = str_replace($search, $replace, PHP_VERSION); | ||||
|         $phpOs         = str_replace($search, $replace, PHP_OS); | ||||
|         $currentDriver = \DB::getDriverName(); | ||||
|         $currentDriver = DB::getDriverName(); | ||||
|         $data | ||||
|                        = [ | ||||
|                            'version'     => config('firefly.version'), | ||||
|   | ||||
| @@ -49,9 +49,9 @@ class DestroyRequest extends FormRequest | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'. | ||||
|                  ',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'. | ||||
|                  ',not_assets_liabilities'; | ||||
|         $valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups' | ||||
|                  .',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers' | ||||
|                  .',not_assets_liabilities'; | ||||
| 
 | ||||
|         return [ | ||||
|             'objects' => sprintf('required|max:255|min:1|string|in:%s', $valid), | ||||
|   | ||||
| @@ -65,25 +65,6 @@ class StoreRequest extends FormRequest | ||||
|         return $data; | ||||
|     } | ||||
| 
 | ||||
|     private function parseAccounts(mixed $array): array | ||||
|     { | ||||
|         if (!is_array($array)) { | ||||
|             return []; | ||||
|         } | ||||
|         $return = []; | ||||
|         foreach ($array as $entry) { | ||||
|             if (!is_array($entry)) { | ||||
|                 continue; | ||||
|             } | ||||
|             $return[] = [ | ||||
|                 'account_id'     => $this->integerFromValue((string) ($entry['account_id'] ?? '0')), | ||||
|                 'current_amount' => $this->clearString((string) ($entry['current_amount'] ?? '0')), | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      */ | ||||
|   | ||||
| @@ -25,8 +25,8 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Requests\Models\PiggyBank; | ||||
| 
 | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Rules\IsAssetAccountId; | ||||
| use FireflyIII\Rules\IsValidPositiveAmount; | ||||
| use FireflyIII\Rules\IsValidZeroOrMoreAmount; | ||||
| use FireflyIII\Rules\LessThanPiggyTarget; | ||||
| use FireflyIII\Support\Request\ChecksLogin; | ||||
| use FireflyIII\Support\Request\ConvertsDataTypes; | ||||
| @@ -47,18 +47,21 @@ class UpdateRequest extends FormRequest | ||||
|     { | ||||
|         $fields             = [ | ||||
|             'name'                      => ['name', 'convertString'], | ||||
|             'account_id'         => ['account_id', 'convertInteger'], | ||||
|             'targetamount'       => ['target_amount', 'convertString'], | ||||
|             'current_amount'     => ['current_amount', 'convertString'], | ||||
|             'startdate'          => ['start_date', 'convertDateTime'], | ||||
|             'targetdate'         => ['target_date', 'convertDateTime'], | ||||
|             'target_amount'             => ['target_amount', 'convertString'], | ||||
|             'start_date'                => ['start_date', 'convertDateTime'], | ||||
|             'target_date'               => ['target_date', 'convertDateTime'], | ||||
|             'notes'                     => ['notes', 'stringWithNewlines'], | ||||
|             'order'                     => ['order', 'convertInteger'], | ||||
|             'object_group_title'        => ['object_group_title', 'convertString'], | ||||
|             'object_group_id'           => ['object_group_id', 'convertInteger'], | ||||
|             'transaction_currency_code' => ['transaction_currency_code', 'convertString'], | ||||
|             'transaction_currency_id'   => ['transaction_currency_id', 'convertInteger'], | ||||
|         ]; | ||||
| 
 | ||||
|         return $this->getAllData($fields); | ||||
|         $result             = $this->getAllData($fields); | ||||
|         $result['accounts'] = $this->parseAccounts($this->get('accounts')); | ||||
| 
 | ||||
|         return $result; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -72,11 +75,18 @@ class UpdateRequest extends FormRequest | ||||
|         return [ | ||||
|             'name'                      => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id, | ||||
|             'current_amount'            => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()], | ||||
|             'target_amount'  => ['nullable', new IsValidPositiveAmount()], | ||||
|             'target_amount'             => ['nullable', new IsValidZeroOrMoreAmount()], | ||||
|             'start_date'                => 'date|nullable', | ||||
|             'target_date'               => 'date|nullable|after:start_date', | ||||
|             'notes'                     => 'max:65000', | ||||
|             'account_id'     => ['belongsToUser:accounts', new IsAssetAccountId()], | ||||
|             'accounts'                  => 'required', | ||||
|             'accounts.*'                => 'array|required', | ||||
|             'accounts.*.account_id'     => ['required', 'numeric', 'belongsToUser:accounts,id'], | ||||
|             'accounts.*.current_amount' => ['numeric', new IsValidZeroOrMoreAmount()], | ||||
|             'object_group_id'           => 'numeric|belongsToUser:object_groups,id', | ||||
|             'object_group_title'        => ['min:1', 'max:255'], | ||||
|             'transaction_currency_id'   => 'exists:transaction_currencies,id|nullable', | ||||
|             'transaction_currency_code' => 'exists:transaction_currencies,code|nullable', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -65,7 +65,7 @@ class TestRequest extends FormRequest | ||||
| 
 | ||||
|     private function getAccounts(): array | ||||
|     { | ||||
|         return $this->get('accounts'); | ||||
|         return $this->get('accounts') ?? []; | ||||
|     } | ||||
| 
 | ||||
|     public function rules(): array | ||||
|   | ||||
| @@ -59,7 +59,7 @@ class TestRequest extends FormRequest | ||||
| 
 | ||||
|     private function getAccounts(): array | ||||
|     { | ||||
|         return $this->get('accounts'); | ||||
|         return $this->get('accounts') ?? []; | ||||
|     } | ||||
| 
 | ||||
|     public function rules(): array | ||||
|   | ||||
| @@ -73,6 +73,7 @@ class StoreController extends Controller | ||||
|         $userGroup          = $request->getUserGroup(); | ||||
|         $data['user_group'] = $userGroup; | ||||
| 
 | ||||
| 
 | ||||
|         // overrule user group and see where we end up.
 | ||||
|         // what happens when we refer to a budget that is not in this user group?
 | ||||
| 
 | ||||
|   | ||||
| @@ -21,25 +21,6 @@ | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| /* | ||||
|  * ConvertDatesToUTC.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
|   | ||||
| @@ -25,6 +25,7 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use FireflyIII\Enums\TransactionTypeEnum; | ||||
| use FireflyIII\Models\AutoBudget; | ||||
| use FireflyIII\Models\AvailableBudget; | ||||
| use FireflyIII\Models\Bill; | ||||
| @@ -33,8 +34,14 @@ use FireflyIII\Models\CurrencyExchangeRate; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\RecurrenceTransaction; | ||||
| use FireflyIII\Models\RuleTrigger; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| class CorrectsAmounts extends Command | ||||
| { | ||||
| @@ -45,6 +52,8 @@ class CorrectsAmounts extends Command | ||||
| 
 | ||||
|     public function handle(): int | ||||
|     { | ||||
|         // transfers must not have foreign currency info if both accounts have the same currency.
 | ||||
|         $this->correctTransfers(); | ||||
|         // auto budgets must be positive
 | ||||
|         $this->fixAutoBudgets(); | ||||
|         // available budgets must be positive
 | ||||
| @@ -62,6 +71,7 @@ class CorrectsAmounts extends Command | ||||
|         // rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
 | ||||
|         $this->fixRuleTriggers(); | ||||
| 
 | ||||
| 
 | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
| @@ -182,4 +192,63 @@ class CorrectsAmounts extends Command | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     private function correctTransfers(): void | ||||
|     { | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $type       = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first(); | ||||
|         $journals   = TransactionJournal::where('transaction_type_id', $type->id)->get(); | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $repository->setUser($journal->user); | ||||
|             $native         = Amount::getNativeCurrencyByUserGroup($journal->userGroup); | ||||
| 
 | ||||
|             /** @var null|Transaction $source */ | ||||
|             $source         = $journal->transactions()->where('amount', '<', 0)->first(); | ||||
| 
 | ||||
|             /** @var null|Transaction $destination */ | ||||
|             $destination    = $journal->transactions()->where('amount', '>', 0)->first(); | ||||
|             if (null === $source || null === $destination) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) { | ||||
|                 continue; | ||||
|             } | ||||
|             $sourceAccount  = $source->account; | ||||
|             $destAccount    = $destination->account; | ||||
|             if (null === $sourceAccount || null === $destAccount) { | ||||
|                 continue; | ||||
|             } | ||||
|             $sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native; | ||||
|             $destCurrency   = $repository->getAccountCurrency($destAccount) ?? $native; | ||||
| 
 | ||||
|             if ($sourceCurrency->id === $destCurrency->id) { | ||||
|                 Log::debug('Both accounts have the same currency. Removing foreign currency info.'); | ||||
|                 $source->foreign_currency_id      = null; | ||||
|                 $source->foreign_amount           = null; | ||||
|                 $source->save(); | ||||
|                 $destination->foreign_currency_id = null; | ||||
|                 $destination->foreign_amount      = null; | ||||
|                 $destination->save(); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             // validate source
 | ||||
|             if ($destCurrency->id !== $source->foreign_currency_id) { | ||||
|                 Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code)); | ||||
|                 $source->foreign_currency_id = $destCurrency->id; | ||||
|                 $source->save(); | ||||
|             } | ||||
| 
 | ||||
|             // validate destination:
 | ||||
|             if ($sourceCurrency->id !== $destination->foreign_currency_id) { | ||||
|                 Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code)); | ||||
|                 $destination->foreign_currency_id = $sourceCurrency->id; | ||||
|                 $destination->save(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Handlers\Events\UpdatedGroupEventHandler; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| 
 | ||||
| class CorrectsGroupAccounts extends Command | ||||
| { | ||||
| @@ -45,7 +46,7 @@ class CorrectsGroupAccounts extends Command | ||||
|     { | ||||
|         $groups  = []; | ||||
|         $res     = TransactionJournal::groupBy('transaction_group_id') | ||||
|             ->get(['transaction_group_id', \DB::raw('COUNT(transaction_group_id) as the_count')])// @phpstan-ignore-line
 | ||||
|             ->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')])// @phpstan-ignore-line
 | ||||
|         ; | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|   | ||||
| @@ -33,6 +33,7 @@ use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\CurrencyExchangeRate; | ||||
| use FireflyIII\Models\ObjectGroup; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| @@ -89,6 +90,7 @@ class CorrectsGroupInformation extends Command | ||||
|             Category::class, | ||||
|             ObjectGroup::class, | ||||
|             CurrencyExchangeRate::class, | ||||
|             Preference::class, | ||||
|             Recurrence::class, | ||||
|             RuleGroup::class, | ||||
|             Rule::class, | ||||
|   | ||||
| @@ -21,25 +21,6 @@ | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| /* | ||||
|  * AddTimezonesToDates.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| namespace FireflyIII\Console\Commands\Correction; | ||||
| 
 | ||||
|   | ||||
| @@ -30,6 +30,7 @@ use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Support\Models\AccountBalanceCalculator; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| class CorrectsUnevenAmount extends Command | ||||
| @@ -118,10 +119,10 @@ class CorrectsUnevenAmount extends Command | ||||
| 
 | ||||
|     private function fixUnevenAmounts(): void | ||||
|     { | ||||
|         $journals = \DB::table('transactions') | ||||
|         $journals = DB::table('transactions') | ||||
|             ->groupBy('transaction_journal_id') | ||||
|             ->whereNull('deleted_at') | ||||
|             ->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])  // @phpstan-ignore-line
 | ||||
|             ->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')])  // @phpstan-ignore-line
 | ||||
|         ; | ||||
| 
 | ||||
|         /** @var \stdClass $entry */ | ||||
| @@ -262,7 +263,7 @@ class CorrectsUnevenAmount extends Command | ||||
|     private function matchCurrencies(): void | ||||
|     { | ||||
|         $journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', 'transactions.transaction_journal_id') | ||||
|             ->where('transactions.transaction_currency_id', '!=', \DB::raw('transaction_journals.transaction_currency_id')) | ||||
|             ->where('transactions.transaction_currency_id', '!=', DB::raw('transaction_journals.transaction_currency_id')) | ||||
|             ->get(['transaction_journals.*']) | ||||
|         ; | ||||
| 
 | ||||
|   | ||||
| @@ -29,6 +29,7 @@ use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Database\QueryException; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| 
 | ||||
| class RemovesEmptyJournals extends Command | ||||
| { | ||||
| @@ -56,7 +57,7 @@ class RemovesEmptyJournals extends Command | ||||
|     { | ||||
|         $set   = Transaction::whereNull('deleted_at') | ||||
|             ->groupBy('transactions.transaction_journal_id') | ||||
|             ->get([\DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']) // @phpstan-ignore-line
 | ||||
|             ->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']) // @phpstan-ignore-line
 | ||||
|         ; | ||||
|         $total = 0; | ||||
| 
 | ||||
|   | ||||
| @@ -57,7 +57,7 @@ class ExportsData extends Command | ||||
|     {--export-tags : Create a file with all your tags and some meta data.} | ||||
|     {--export-recurring : Create a file with all your recurring transactions and some meta data.} | ||||
|     {--export-rules : Create a file with all your rules and some meta data.} | ||||
|     {--export-bills : Create a file with all your bills and some meta data.} | ||||
|     {--export-subscriptions : Create a file with all your subscriptions and some meta data.} | ||||
|     {--export-piggies : Create a file with all your piggy banks and some meta data.} | ||||
|     {--force : Force overwriting of previous exports if found.}'; | ||||
|     private AccountRepositoryInterface $accountRepository; | ||||
| @@ -157,7 +157,7 @@ class ExportsData extends Command | ||||
|                 'tags'         => $this->option('export-tags'), | ||||
|                 'recurring'    => $this->option('export-recurring'), | ||||
|                 'rules'        => $this->option('export-rules'), | ||||
|                 'bills'        => $this->option('export-bills'), | ||||
|                 'bills'        => $this->option('export-subscriptions'), | ||||
|                 'piggies'      => $this->option('export-piggies'), | ||||
|             ], | ||||
|             'start'     => $start, | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use FireflyIII\Support\Cronjobs\AutoBudgetCronjob; | ||||
| use FireflyIII\Support\Cronjobs\BillWarningCronjob; | ||||
| use FireflyIII\Support\Cronjobs\ExchangeRatesCronjob; | ||||
| use FireflyIII\Support\Cronjobs\RecurringCronjob; | ||||
| use FireflyIII\Support\Cronjobs\UpdateCheckCronjob; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| @@ -43,6 +44,7 @@ class Cron extends Command | ||||
|     protected $signature   = 'firefly-iii:cron | ||||
|         {--F|force : Force the cron job(s) to execute.} | ||||
|         {--date= : Set the date in YYYY-MM-DD to make Firefly III think that\'s the current date.} | ||||
|         {--check-version : Check if there is a new Firefly III version. Other tasks will be skipped unless also requested.} | ||||
|         {--download-cer : Download exchange rates. Other tasks will be skipped unless also requested.} | ||||
|         {--create-recurring : Create recurring transactions. Other tasks will be skipped unless also requested.} | ||||
|         {--create-auto-budgets : Create auto budgets. Other tasks will be skipped unless also requested.} | ||||
| @@ -51,7 +53,11 @@ class Cron extends Command | ||||
| 
 | ||||
|     public function handle(): int | ||||
|     { | ||||
|         $doAll = !$this->option('download-cer') && !$this->option('create-recurring') && !$this->option('create-auto-budgets') && !$this->option('send-bill-warnings'); | ||||
|         $doAll = !$this->option('download-cer') | ||||
|                  && !$this->option('create-recurring') | ||||
|                  && !$this->option('create-auto-budgets') | ||||
|                  && !$this->option('send-bill-warnings') | ||||
|                  && !$this->option('check-version'); | ||||
|         $date  = null; | ||||
| 
 | ||||
|         try { | ||||
| @@ -72,6 +78,17 @@ class Cron extends Command | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // check for new version
 | ||||
|         if ($doAll || $this->option('check-version')) { | ||||
|             try { | ||||
|                 $this->checkForUpdates($force); | ||||
|             } catch (FireflyException $e) { | ||||
|                 app('log')->error($e->getMessage()); | ||||
|                 app('log')->error($e->getTraceAsString()); | ||||
|                 $this->friendlyError($e->getMessage()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Fire recurring transaction cron job.
 | ||||
|         if ($doAll || $this->option('create-recurring')) { | ||||
|             try { | ||||
| @@ -204,4 +221,21 @@ class Cron extends Command | ||||
|             $this->friendlyPositive(sprintf('"Send bill warnings" cron ran with success: %s', $autoBudget->message)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private function checkForUpdates(bool $force): void | ||||
|     { | ||||
|         $updateCheck = new UpdateCheckCronjob(); | ||||
|         $updateCheck->setForce($force); | ||||
|         $updateCheck->fire(); | ||||
| 
 | ||||
|         if ($updateCheck->jobErrored) { | ||||
|             $this->friendlyError(sprintf('Error in "update check" cron: %s', $updateCheck->message)); | ||||
|         } | ||||
|         if ($updateCheck->jobFired) { | ||||
|             $this->friendlyInfo(sprintf('"Update check" cron fired: %s', $updateCheck->message)); | ||||
|         } | ||||
|         if ($updateCheck->jobSucceeded) { | ||||
|             $this->friendlyPositive(sprintf('"Update check" cron ran with success: %s', $updateCheck->message)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Preference; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| 
 | ||||
| class RemovesDatabaseDecryption extends Command | ||||
| { | ||||
| @@ -101,7 +102,7 @@ class RemovesDatabaseDecryption extends Command | ||||
| 
 | ||||
|     private function decryptField(string $table, string $field): void | ||||
|     { | ||||
|         $rows = \DB::table($table)->get(['id', $field]); | ||||
|         $rows = DB::table($table)->get(['id', $field]); | ||||
| 
 | ||||
|         /** @var \stdClass $row */ | ||||
|         foreach ($rows as $row) { | ||||
| @@ -135,7 +136,7 @@ class RemovesDatabaseDecryption extends Command | ||||
|         } | ||||
| 
 | ||||
|         if ($value !== $original) { | ||||
|             \DB::table($table)->where('id', $id)->update([$field => $value]); | ||||
|             DB::table($table)->where('id', $id)->update([$field => $value]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace FireflyIII\Console\Commands\Upgrade; | ||||
| 
 | ||||
| use FireflyIII\Console\Commands\ShowsFriendlyMessages; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| 
 | ||||
| class RepairsPostgresSequences extends Command | ||||
| { | ||||
| @@ -40,7 +41,7 @@ class RepairsPostgresSequences extends Command | ||||
|      */ | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if ('pgsql' !== \DB::connection()->getName()) { | ||||
|         if ('pgsql' !== DB::connection()->getName()) { | ||||
|             return 0; | ||||
|         } | ||||
|         $this->friendlyLine('Going to verify PostgreSQL table sequences.'); | ||||
| @@ -49,8 +50,8 @@ class RepairsPostgresSequences extends Command | ||||
|         foreach ($tablesToCheck as $tableToCheck) { | ||||
|             $this->friendlyLine(sprintf('Checking the next id sequence for table "%s".', $tableToCheck)); | ||||
| 
 | ||||
|             $highestId = \DB::table($tableToCheck)->select(\DB::raw('MAX(id)'))->first(); | ||||
|             $nextId    = \DB::table($tableToCheck)->select(\DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first(); | ||||
|             $highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first(); | ||||
|             $nextId    = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first(); | ||||
|             if (null === $nextId) { | ||||
|                 $this->friendlyInfo(sprintf('nextval is NULL for table "%s", go to next table.', $tableToCheck)); | ||||
| 
 | ||||
| @@ -58,9 +59,9 @@ class RepairsPostgresSequences extends Command | ||||
|             } | ||||
| 
 | ||||
|             if ($nextId->nextval < $highestId->max) { // @phpstan-ignore-line
 | ||||
|                 \DB::select(sprintf('SELECT setval(\'%s_id_seq\', %d)', $tableToCheck, $highestId->max)); | ||||
|                 $highestId = \DB::table($tableToCheck)->select(\DB::raw('MAX(id)'))->first(); | ||||
|                 $nextId    = \DB::table($tableToCheck)->select(\DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first(); | ||||
|                 DB::select(sprintf('SELECT setval(\'%s_id_seq\', %d)', $tableToCheck, $highestId->max)); | ||||
|                 $highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first(); | ||||
|                 $nextId    = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first(); | ||||
|                 if ($nextId->nextval > $highestId->max) { // @phpstan-ignore-line
 | ||||
|                     $this->friendlyInfo(sprintf('Table "%s" autoincrement corrected.', $tableToCheck)); | ||||
|                 } | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| 
 | ||||
| class UpgradesJournalMetaData extends Command | ||||
| { | ||||
| @@ -86,8 +87,8 @@ class UpgradesJournalMetaData extends Command | ||||
|         $this->migrateCategories(); | ||||
| 
 | ||||
|         // empty tables
 | ||||
|         \DB::table('budget_transaction')->delete(); | ||||
|         \DB::table('category_transaction')->delete(); | ||||
|         DB::table('budget_transaction')->delete(); | ||||
|         DB::table('category_transaction')->delete(); | ||||
|     } | ||||
| 
 | ||||
|     private function migrateBudgets(): void | ||||
| @@ -108,12 +109,12 @@ class UpgradesJournalMetaData extends Command | ||||
| 
 | ||||
|     private function getIdsForBudgets(): array | ||||
|     { | ||||
|         $transactions = \DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray(); | ||||
|         $transactions = DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray(); | ||||
|         $array        = []; | ||||
|         $chunks       = array_chunk($transactions, 500); | ||||
| 
 | ||||
|         foreach ($chunks as $chunk) { | ||||
|             $set   = \DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray(); | ||||
|             $set   = DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray(); | ||||
|             $array = array_merge($array, $set); | ||||
|         } | ||||
| 
 | ||||
| @@ -171,12 +172,12 @@ class UpgradesJournalMetaData extends Command | ||||
| 
 | ||||
|     private function getIdsForCategories(): array | ||||
|     { | ||||
|         $transactions = \DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray(); | ||||
|         $transactions = DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray(); | ||||
|         $array        = []; | ||||
|         $chunks       = array_chunk($transactions, 500); | ||||
| 
 | ||||
|         foreach ($chunks as $chunk) { | ||||
|             $set   = \DB::table('transactions') | ||||
|             $set   = DB::table('transactions') | ||||
|                 ->whereIn('transactions.id', $chunk) | ||||
|                 ->pluck('transaction_journal_id')->toArray() | ||||
|             ; | ||||
|   | ||||
| @@ -35,6 +35,7 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Services\Internal\Destroy\JournalDestroyService; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| 
 | ||||
| class UpgradesToGroups extends Command | ||||
| { | ||||
| @@ -237,7 +238,8 @@ class UpgradesToGroups extends Command | ||||
|         return [ | ||||
|             'type'                => strtolower($journal->transactionType->type), | ||||
|             'date'                => $journal->date, | ||||
|             'user'                => $journal->user_id, | ||||
|             'user'                => $journal->user, | ||||
|             'user_group'          => $journal->user->userGroup, | ||||
|             'currency_id'         => $transaction->transaction_currency_id, | ||||
|             'foreign_currency_id' => $transaction->foreign_currency_id, | ||||
|             'amount'              => $transaction->amount, | ||||
| @@ -364,7 +366,7 @@ class UpgradesToGroups extends Command | ||||
| 
 | ||||
|     private function giveGroup(array $array): void | ||||
|     { | ||||
|         $groupId = \DB::table('transaction_groups')->insertGetId( | ||||
|         $groupId = DB::table('transaction_groups')->insertGetId( | ||||
|             [ | ||||
|                 'created_at' => date('Y-m-d H:i:s'), | ||||
|                 'updated_at' => date('Y-m-d H:i:s'), | ||||
| @@ -372,7 +374,7 @@ class UpgradesToGroups extends Command | ||||
|                 'user_id'    => $array['user_id'], | ||||
|             ] | ||||
|         ); | ||||
|         \DB::table('transaction_journals')->where('id', $array['id'])->update(['transaction_group_id' => $groupId]); | ||||
|         DB::table('transaction_journals')->where('id', $array['id'])->update(['transaction_group_id' => $groupId]); | ||||
|         ++$this->count; | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -129,6 +129,11 @@ class GracefulNotFoundHandler extends ExceptionHandler | ||||
| 
 | ||||
|                 return redirect(route('rules.index')); | ||||
| 
 | ||||
|             case 'rule-groups.edit': | ||||
|                 $request->session()->reflash(); | ||||
| 
 | ||||
|                 return redirect(route('rules.index')); | ||||
| 
 | ||||
|             case 'transactions.mass.edit': | ||||
|             case 'transactions.mass.delete': | ||||
|             case 'transactions.bulk.edit': | ||||
|   | ||||
| @@ -48,8 +48,8 @@ class BillFactory | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__), $data); | ||||
|         $factory          = app(TransactionCurrencyFactory::class); | ||||
|         $currency         = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null)) ?? | ||||
|                     app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); | ||||
|         $currency         = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null)) | ||||
|                     ?? app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); | ||||
| 
 | ||||
|         try { | ||||
|             $skip   = array_key_exists('skip', $data) ? $data['skip'] : 0; | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace FireflyIII\Factory; | ||||
| 
 | ||||
| use FireflyIII\Models\Location; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\User; | ||||
| 
 | ||||
| /** | ||||
| @@ -34,6 +35,7 @@ use FireflyIII\User; | ||||
| class TagFactory | ||||
| { | ||||
|     private User $user; | ||||
|     private UserGroup $userGroup; | ||||
| 
 | ||||
|     public function findOrCreate(string $tag): ?Tag | ||||
|     { | ||||
| @@ -74,7 +76,7 @@ class TagFactory | ||||
|         $longitude = 0.0 === (float) $data['longitude'] ? null : (float) $data['longitude']; // intentional float
 | ||||
|         $array     = [ | ||||
|             'user_id'       => $this->user->id, | ||||
|             'user_group_id' => $this->user->user_group_id, | ||||
|             'user_group_id' => $this->userGroup->id, | ||||
|             'tag'           => trim($data['tag']), | ||||
|             'tagMode'       => 'nothing', | ||||
|             'date'          => $data['date'], | ||||
| @@ -102,5 +104,11 @@ class TagFactory | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user      = $user; | ||||
|         $this->userGroup = $user->userGroup; | ||||
|     } | ||||
| 
 | ||||
|     public function setUserGroup(UserGroup $userGroup): void | ||||
|     { | ||||
|         $this->userGroup = $userGroup; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -31,7 +31,6 @@ use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Rules\UniqueIban; | ||||
| use FireflyIII\Services\Internal\Update\AccountUpdateService; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Database\QueryException; | ||||
| 
 | ||||
| /** | ||||
| @@ -216,12 +215,4 @@ class TransactionFactory | ||||
|     { | ||||
|         $this->reconciled = $reconciled; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @SuppressWarnings("PHPMD.UnusedFormalParameter") | ||||
|      */ | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         // empty function.
 | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -27,6 +27,7 @@ namespace FireflyIII\Factory; | ||||
| use FireflyIII\Exceptions\DuplicateTransactionException; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\User; | ||||
| 
 | ||||
| /** | ||||
| @@ -36,6 +37,7 @@ class TransactionGroupFactory | ||||
| { | ||||
|     private TransactionJournalFactory $journalFactory; | ||||
|     private User                      $user; | ||||
|     private UserGroup $userGroup; | ||||
| 
 | ||||
|     /** | ||||
|      * TransactionGroupFactory constructor. | ||||
| @@ -54,7 +56,8 @@ class TransactionGroupFactory | ||||
|     public function create(array $data): TransactionGroup | ||||
|     { | ||||
|         app('log')->debug('Now in TransactionGroupFactory::create()'); | ||||
|         $this->journalFactory->setUser($this->user); | ||||
|         $this->journalFactory->setUser($data['user']); | ||||
|         $this->journalFactory->setUserGroup($data['user_group']); | ||||
|         $this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false); | ||||
| 
 | ||||
|         try { | ||||
| @@ -76,7 +79,7 @@ class TransactionGroupFactory | ||||
| 
 | ||||
|         $group        = new TransactionGroup(); | ||||
|         $group->user()->associate($this->user); | ||||
|         $group->userGroup()->associate($data['user_group'] ?? $this->user->userGroup); | ||||
|         $group->userGroup()->associate($this->userGroup); | ||||
|         $group->title = $title; | ||||
|         $group->save(); | ||||
| 
 | ||||
| @@ -91,5 +94,11 @@ class TransactionGroupFactory | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user      = $user; | ||||
|         $this->userGroup = $user->userGroup; | ||||
|     } | ||||
| 
 | ||||
|     public function setUserGroup(UserGroup $userGroup): void | ||||
|     { | ||||
|         $this->userGroup = $userGroup; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -34,6 +34,7 @@ use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionJournalMeta; | ||||
| use FireflyIII\Models\UserGroup; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| @@ -69,6 +70,7 @@ class TransactionJournalFactory | ||||
|     private PiggyBankRepositoryInterface       $piggyRepository; | ||||
|     private TransactionTypeRepositoryInterface $typeRepository; | ||||
|     private User                               $user; | ||||
|     private UserGroup $userGroup; | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor. | ||||
| @@ -176,7 +178,6 @@ class TransactionJournalFactory | ||||
|         if (true === FireflyConfig::get('utc', false)->data) { | ||||
|             $carbon->setTimezone('UTC'); | ||||
|         } | ||||
|         // $carbon->setTimezone('UTC');
 | ||||
| 
 | ||||
|         try { | ||||
|             // validate source and destination using a new Validator.
 | ||||
| @@ -228,7 +229,7 @@ class TransactionJournalFactory | ||||
|         $journal               = TransactionJournal::create( | ||||
|             [ | ||||
|                 'user_id'                 => $this->user->id, | ||||
|                 'user_group_id'           => $this->user->user_group_id, | ||||
|                 'user_group_id'           => $this->userGroup->id, | ||||
|                 'transaction_type_id'     => $type->id, | ||||
|                 'bill_id'                 => $billId, | ||||
|                 'transaction_currency_id' => $currency->id, | ||||
| @@ -244,7 +245,6 @@ class TransactionJournalFactory | ||||
| 
 | ||||
|         /** Create two transactions. */ | ||||
|         $transactionFactory    = app(TransactionFactory::class); | ||||
|         $transactionFactory->setUser($this->user); | ||||
|         $transactionFactory->setJournal($journal); | ||||
|         $transactionFactory->setAccount($sourceAccount); | ||||
|         $transactionFactory->setCurrency($currency); | ||||
| @@ -263,7 +263,6 @@ class TransactionJournalFactory | ||||
| 
 | ||||
|         /** @var TransactionFactory $transactionFactory */ | ||||
|         $transactionFactory    = app(TransactionFactory::class); | ||||
|         $transactionFactory->setUser($this->user); | ||||
|         $transactionFactory->setJournal($journal); | ||||
|         $transactionFactory->setAccount($destinationAccount); | ||||
|         $transactionFactory->setAccountInformation($destInfo); | ||||
| @@ -405,6 +404,7 @@ class TransactionJournalFactory | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user      = $user; | ||||
|         $this->userGroup = $user->userGroup; | ||||
|         $this->currencyRepository->setUser($this->user); | ||||
|         $this->tagFactory->setUser($user); | ||||
|         $this->billRepository->setUser($this->user); | ||||
| @@ -414,6 +414,18 @@ class TransactionJournalFactory | ||||
|         $this->accountRepository->setUser($this->user); | ||||
|     } | ||||
| 
 | ||||
|     public function setUserGroup(UserGroup $userGroup): void | ||||
|     { | ||||
|         $this->userGroup = $userGroup; | ||||
|         $this->currencyRepository->setUserGroup($userGroup); | ||||
|         $this->tagFactory->setUserGroup($userGroup); | ||||
|         $this->billRepository->setUserGroup($userGroup); | ||||
|         $this->budgetRepository->setUserGroup($userGroup); | ||||
|         $this->categoryRepository->setUserGroup($userGroup); | ||||
|         $this->piggyRepository->setUserGroup($userGroup); | ||||
|         $this->accountRepository->setUserGroup($userGroup); | ||||
|     } | ||||
| 
 | ||||
|     private function reconciliationSanityCheck(?Account $sourceAccount, ?Account $destinationAccount): array | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in %s', __METHOD__)); | ||||
|   | ||||
| @@ -33,6 +33,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
|  * Class MonthReportGenerator. | ||||
| @@ -52,10 +53,9 @@ class MonthReportGenerator implements ReportGeneratorInterface | ||||
|     { | ||||
|         $auditData   = []; | ||||
|         $dayBefore   = clone $this->start; | ||||
|         $dayBefore->subDay(); | ||||
| 
 | ||||
|         // move to end of day
 | ||||
|         $dayBefore->endOfDay(); | ||||
|         // set date to subday + end-of-day for account balance. so it is at $date 23:59:59
 | ||||
|         $dayBefore->subDay()->endOfDay(); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($this->accounts as $account) { | ||||
| @@ -136,6 +136,8 @@ class MonthReportGenerator implements ReportGeneratorInterface | ||||
|         ; | ||||
|         $journals          = $collector->getExtractedJournals(); | ||||
|         $journals          = array_reverse($journals, true); | ||||
|         // this call is correct.
 | ||||
|         Log::debug(sprintf('getAuditReport: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); | ||||
|         $dayBeforeBalance  = Steam::finalAccountBalance($account, $date); | ||||
|         $startBalance      = $dayBeforeBalance['balance']; | ||||
|         $defaultCurrency   = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); | ||||
| @@ -170,6 +172,8 @@ class MonthReportGenerator implements ReportGeneratorInterface | ||||
|             $journals[$index]['invoice_date']   = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date'); | ||||
|         } | ||||
|         $locale            = app('steam')->getLocale(); | ||||
|         // call is correct.
 | ||||
|         Log::debug(sprintf('getAuditReport end: Call finalAccountBalance with date/time "%s"', $this->end->toIso8601String())); | ||||
| 
 | ||||
|         return [ | ||||
|             'journals'         => $journals, | ||||
|   | ||||
| @@ -38,10 +38,17 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class StoredGroupEventHandler | ||||
| { | ||||
|     public function runAllHandlers(StoredTransactionGroup $event): void | ||||
|     { | ||||
|         $this->processRules($event); | ||||
|         $this->recalculateCredit($event); | ||||
|         $this->triggerWebhooks($event); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This method grabs all the users rules and processes them. | ||||
|      */ | ||||
|     public function processRules(StoredTransactionGroup $storedGroupEvent): void | ||||
|     private function processRules(StoredTransactionGroup $storedGroupEvent): void | ||||
|     { | ||||
|         if (false === $storedGroupEvent->applyRules) { | ||||
|             app('log')->info(sprintf('Will not run rules on group #%d', $storedGroupEvent->transactionGroup->id)); | ||||
| @@ -76,7 +83,7 @@ class StoredGroupEventHandler | ||||
|         $newRuleEngine->fire(); | ||||
|     } | ||||
| 
 | ||||
|     public function recalculateCredit(StoredTransactionGroup $event): void | ||||
|     private function recalculateCredit(StoredTransactionGroup $event): void | ||||
|     { | ||||
|         $group  = $event->transactionGroup; | ||||
| 
 | ||||
| @@ -89,7 +96,7 @@ class StoredGroupEventHandler | ||||
|     /** | ||||
|      * This method processes all webhooks that respond to the "stored transaction group" trigger (100) | ||||
|      */ | ||||
|     public function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void | ||||
|     private function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void | ||||
|     { | ||||
|         app('log')->debug(__METHOD__); | ||||
|         $group  = $storedGroupEvent->transactionGroup; | ||||
|   | ||||
| @@ -41,10 +41,19 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class UpdatedGroupEventHandler | ||||
| { | ||||
|     public function runAllHandlers(UpdatedTransactionGroup $event): void | ||||
|     { | ||||
|         $this->unifyAccounts($event); | ||||
|         $this->processRules($event); | ||||
|         $this->recalculateCredit($event); | ||||
|         $this->triggerWebhooks($event); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This method will check all the rules when a journal is updated. | ||||
|      */ | ||||
|     public function processRules(UpdatedTransactionGroup $updatedGroupEvent): void | ||||
|     private function processRules(UpdatedTransactionGroup $updatedGroupEvent): void | ||||
|     { | ||||
|         if (false === $updatedGroupEvent->applyRules) { | ||||
|             app('log')->info(sprintf('Will not run rules on group #%d', $updatedGroupEvent->transactionGroup->id)); | ||||
| @@ -76,7 +85,7 @@ class UpdatedGroupEventHandler | ||||
|         $newRuleEngine->fire(); | ||||
|     } | ||||
| 
 | ||||
|     public function recalculateCredit(UpdatedTransactionGroup $event): void | ||||
|     private function recalculateCredit(UpdatedTransactionGroup $event): void | ||||
|     { | ||||
|         $group  = $event->transactionGroup; | ||||
| 
 | ||||
| @@ -86,7 +95,7 @@ class UpdatedGroupEventHandler | ||||
|         $object->recalculate(); | ||||
|     } | ||||
| 
 | ||||
|     public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void | ||||
|     private function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void | ||||
|     { | ||||
|         app('log')->debug(__METHOD__); | ||||
|         $group  = $updatedGroupEvent->transactionGroup; | ||||
|   | ||||
| @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Update\UpdateTrait; | ||||
| use FireflyIII\Models\Configuration; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
|  * Class VersionCheckEventHandler | ||||
| @@ -45,13 +46,13 @@ class VersionCheckEventHandler | ||||
|      */ | ||||
|     public function checkForUpdates(RequestedVersionCheckStatus $event): void | ||||
|     { | ||||
|         app('log')->debug('Now in checkForUpdates()'); | ||||
|         Log::debug('Now in checkForUpdates()'); | ||||
| 
 | ||||
|         // should not check for updates:
 | ||||
|         $permission    = app('fireflyconfig')->get('permission_update_check', -1); | ||||
|         $value         = (int) $permission->data; | ||||
|         if (1 !== $value) { | ||||
|             app('log')->debug('Update check is not enabled.'); | ||||
|             Log::debug('Update check is not enabled.'); | ||||
|             $this->warnToCheckForUpdates($event); | ||||
| 
 | ||||
|             return; | ||||
| @@ -61,7 +62,7 @@ class VersionCheckEventHandler | ||||
|         $repository    = app(UserRepositoryInterface::class); | ||||
|         $user          = $event->user; | ||||
|         if (!$repository->hasRole($user, 'owner')) { | ||||
|             app('log')->debug('User is not admin, done.'); | ||||
|             Log::debug('User is not admin, done.'); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| @@ -70,14 +71,14 @@ class VersionCheckEventHandler | ||||
|         $lastCheckTime = app('fireflyconfig')->get('last_update_check', time()); | ||||
|         $now           = time(); | ||||
|         $diff          = $now - $lastCheckTime->data; | ||||
|         app('log')->debug(sprintf('Last check time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff)); | ||||
|         Log::debug(sprintf('Last check time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff)); | ||||
|         if ($diff < 604800) { | ||||
|             app('log')->debug(sprintf('Checked for updates less than a week ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data))); | ||||
|             Log::debug(sprintf('Checked for updates less than a week ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data))); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
|         // last check time was more than a week ago.
 | ||||
|         app('log')->debug('Have not checked for a new version in a week!'); | ||||
|         Log::debug('Have not checked for a new version in a week!'); | ||||
|         $release       = $this->getLatestRelease(); | ||||
| 
 | ||||
|         session()->flash($release['level'], $release['message']); | ||||
| @@ -93,7 +94,7 @@ class VersionCheckEventHandler | ||||
|         $repository    = app(UserRepositoryInterface::class); | ||||
|         $user          = $event->user; | ||||
|         if (!$repository->hasRole($user, 'owner')) { | ||||
|             app('log')->debug('User is not admin, done.'); | ||||
|             Log::debug('User is not admin, done.'); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| @@ -102,14 +103,14 @@ class VersionCheckEventHandler | ||||
|         $lastCheckTime = app('fireflyconfig')->get('last_update_warning', time()); | ||||
|         $now           = time(); | ||||
|         $diff          = $now - $lastCheckTime->data; | ||||
|         app('log')->debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff)); | ||||
|         Log::debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff)); | ||||
|         if ($diff < 604800 * 4) { | ||||
|             app('log')->debug(sprintf('Warned about updates less than four weeks ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data))); | ||||
|             Log::debug(sprintf('Warned about updates less than four weeks ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data))); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
|         // last check time was more than a week ago.
 | ||||
|         app('log')->debug('Have warned about a new version in four weeks!'); | ||||
|         Log::debug('Have warned about a new version in four weeks!'); | ||||
| 
 | ||||
|         session()->flash('info', (string) trans('firefly.disabled_but_check')); | ||||
|         app('fireflyconfig')->set('last_update_warning', time()); | ||||
|   | ||||
| @@ -25,10 +25,15 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
| @@ -70,19 +75,31 @@ class AccountObserver | ||||
|      */ | ||||
|     public function deleting(Account $account): void | ||||
|     { | ||||
|         //        app('log')->debug('Observe "deleting" of an account.');
 | ||||
|         $account->accountMeta()->delete(); | ||||
|         app('log')->debug('Observe "deleting" of an account.'); | ||||
| 
 | ||||
|         /** @var PiggyBank $piggy */ | ||||
|         foreach ($account->piggyBanks()->get() as $piggy) { | ||||
|             $piggy->accounts()->detach($account); | ||||
|         } | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($account->user); | ||||
| 
 | ||||
|         DB::table('account_piggy_bank')->where('account_id', $account->id)->delete(); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($account->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
|         foreach ($account->transactions()->get() as $transaction) { | ||||
|             $transaction->delete(); | ||||
| 
 | ||||
|         $journalIds = Transaction::where('account_id', $account->id)->get(['transactions.transaction_journal_id'])->pluck('transaction_journal_id')->toArray(); | ||||
|         $groupIds   = TransactionJournal::whereIn('id', $journalIds)->get(['transaction_journals.transaction_group_id'])->pluck('transaction_group_id')->toArray(); | ||||
|         if (count($journalIds) > 0) { | ||||
|             Transaction::whereIn('transaction_journal_id', $journalIds)->delete(); | ||||
|             TransactionJournal::whereIn('id', $journalIds)->delete(); | ||||
|         } | ||||
|         if (count($groupIds) > 0) { | ||||
|             TransactionGroup::whereIn('id', $groupIds)->delete(); | ||||
|         } | ||||
| 
 | ||||
|         Log::debug(sprintf('Delete %d journal(s)', count($journalIds))); | ||||
|         Log::debug(sprintf('Delete %d group(s)', count($groupIds))); | ||||
| 
 | ||||
|         $account->notes()->delete(); | ||||
|         $account->locations()->delete(); | ||||
|     } | ||||
|   | ||||
| @@ -23,7 +23,9 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| @@ -41,9 +43,13 @@ class BillObserver | ||||
| 
 | ||||
|     public function deleting(Bill $bill): void | ||||
|     { | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($bill->user); | ||||
| 
 | ||||
|         //        app('log')->debug('Observe "deleting" of a bill.');
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($bill->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
|         $bill->notes()->delete(); | ||||
|     } | ||||
|   | ||||
| @@ -23,8 +23,10 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class BudgetObserver | ||||
| @@ -34,8 +36,13 @@ class BudgetObserver | ||||
|     public function deleting(Budget $budget): void | ||||
|     { | ||||
|         app('log')->debug('Observe "deleting" of a budget.'); | ||||
| 
 | ||||
|         $repository   = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($budget->user); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($budget->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
|         $budgetLimits = $budget->budgetlimits()->get(); | ||||
| 
 | ||||
|   | ||||
| @@ -23,7 +23,9 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class CategoryObserver | ||||
| @@ -33,8 +35,13 @@ class CategoryObserver | ||||
|     public function deleting(Category $category): void | ||||
|     { | ||||
|         app('log')->debug('Observe "deleting" of a category.'); | ||||
| 
 | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($category->user); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($category->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
|         $category->notes()->delete(); | ||||
|     } | ||||
|   | ||||
| @@ -24,7 +24,9 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| @@ -46,8 +48,12 @@ class PiggyBankObserver | ||||
|     { | ||||
|         app('log')->debug('Observe "deleting" of a piggy bank.'); | ||||
| 
 | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($piggyBank->accounts()->first()->user); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($piggyBank->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
| 
 | ||||
|         $piggyBank->piggyBankEvents()->delete(); | ||||
|   | ||||
| @@ -23,7 +23,9 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class RecurrenceObserver | ||||
| @@ -33,8 +35,13 @@ class RecurrenceObserver | ||||
|     public function deleting(Recurrence $recurrence): void | ||||
|     { | ||||
|         app('log')->debug('Observe "deleting" of a recurrence.'); | ||||
| 
 | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($recurrence->user); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($recurrence->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
| 
 | ||||
|         $recurrence->recurrenceRepetitions()->delete(); | ||||
|   | ||||
| @@ -23,7 +23,9 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class TagObserver | ||||
| @@ -34,8 +36,12 @@ class TagObserver | ||||
|     { | ||||
|         app('log')->debug('Observe "deleting" of a tag.'); | ||||
| 
 | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($tag->user); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($tag->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
| 
 | ||||
|         $tag->locations()->delete(); | ||||
|   | ||||
| @@ -23,7 +23,9 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Handlers\Observer; | ||||
| 
 | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class TransactionJournalObserver | ||||
| @@ -34,14 +36,20 @@ class TransactionJournalObserver | ||||
|     { | ||||
|         app('log')->debug('Observe "deleting" of a transaction journal.'); | ||||
| 
 | ||||
|         $repository = app(AttachmentRepositoryInterface::class); | ||||
|         $repository->setUser($transactionJournal->user); | ||||
| 
 | ||||
| 
 | ||||
|         // to make sure the listener doesn't get back to use and loop
 | ||||
|         TransactionJournal::withoutEvents(static function () use ($transactionJournal): void { | ||||
|             foreach ($transactionJournal->transactions()->get() as $transaction) { | ||||
|                 $transaction->delete(); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($transactionJournal->attachments()->get() as $attachment) { | ||||
|             $attachment->delete(); | ||||
|             $repository->destroy($attachment); | ||||
|         } | ||||
|         $transactionJournal->locations()->delete(); | ||||
|         $transactionJournal->sourceJournalLinks()->delete(); | ||||
|   | ||||
| @@ -258,7 +258,12 @@ trait AccountCollection | ||||
|                 if (null === $account) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 $balance   = Steam::finalAccountBalance($account, $transaction['date']); | ||||
|                 // the balance must be found BEFORE the transaction date.
 | ||||
|                 // so sub one second. This is not perfect, but works well enough.
 | ||||
|                 $date      = clone $transaction['date']; | ||||
|                 $date->subSecond(); | ||||
|                 Log::debug(sprintf('accountBalanceIs: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); | ||||
|                 $balance   = Steam::finalAccountBalance($account, $date); | ||||
|                 $result    = bccomp($balance['balance'], $value); | ||||
|                 Log::debug(sprintf('"%s" vs "%s" is %d', $balance['balance'], $value, $result)); | ||||
| 
 | ||||
|   | ||||
| @@ -167,6 +167,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'external_id'); | ||||
|         $this->query->where('journal_meta.data', '!=', sprintf('%s', json_encode($externalId))); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -405,6 +406,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->whereLike('journal_meta.data', sprintf('%%%s%%', $internalReference)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -417,6 +419,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->whereNotLike('journal_meta.data', sprintf('%%%s%%', $internalReference)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -429,6 +432,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->whereNotLike('journal_meta.data', sprintf('%%%s"', $internalReference)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -441,6 +445,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->whereLike('journal_meta.data', sprintf('"%s%%', $internalReference)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -453,6 +458,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->whereLike('journal_meta.data', sprintf('%%%s"', $internalReference)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -465,6 +471,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->whereLike('journal_meta.data', sprintf('"%s%%', $internalReference)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -697,6 +704,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'external_id'); | ||||
|         $this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($externalId))); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -706,6 +714,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'external_url'); | ||||
|         $this->query->where('journal_meta.data', '=', json_encode($url)); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -718,6 +727,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'internal_reference'); | ||||
|         $this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($internalReference))); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -727,6 +737,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'recurrence_id'); | ||||
|         $this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($recurringId))); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -862,6 +873,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'external_id'); | ||||
|         $this->query->whereNotNull('journal_meta.data'); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -871,6 +883,7 @@ trait MetaCollection | ||||
|         $this->joinMetaDataTables(); | ||||
|         $this->query->where('journal_meta.name', '=', 'external_url'); | ||||
|         $this->query->whereNotNull('journal_meta.data'); | ||||
|         $this->query->whereNull('journal_meta.deleted_at'); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| @@ -915,10 +928,13 @@ trait MetaCollection | ||||
|             $q1->where(static function (Builder $q2): void { | ||||
|                 $q2->where('journal_meta.name', '=', 'external_id'); | ||||
|                 $q2->whereNull('journal_meta.data'); | ||||
|                 $q2->whereNull('journal_meta.deleted_at'); | ||||
|             })->orWhere(static function (Builder $q3): void { | ||||
|                 $q3->where('journal_meta.name', '!=', 'external_id'); | ||||
|                 $q3->whereNull('journal_meta.deleted_at'); | ||||
|             })->orWhere(static function (Builder $q4): void { | ||||
|                 $q4->whereNull('journal_meta.name'); | ||||
|                 $q4->whereNull('journal_meta.deleted_at'); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
| @@ -933,10 +949,13 @@ trait MetaCollection | ||||
|             $q1->where(static function (Builder $q2): void { | ||||
|                 $q2->where('journal_meta.name', '=', 'external_url'); | ||||
|                 $q2->whereNull('journal_meta.data'); | ||||
|                 $q2->whereNull('journal_meta.deleted_at'); | ||||
|             })->orWhere(static function (Builder $q3): void { | ||||
|                 $q3->where('journal_meta.name', '!=', 'external_url'); | ||||
|                 $q3->whereNull('journal_meta.deleted_at'); | ||||
|             })->orWhere(static function (Builder $q4): void { | ||||
|                 $q4->whereNull('journal_meta.name'); | ||||
|                 $q4->whereNull('journal_meta.deleted_at'); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|   | ||||
| @@ -79,6 +79,7 @@ class NetWorth implements NetWorthInterface | ||||
|         Log::debug(sprintf('Now in byAccounts("%s", "%s")', $ids, $date->format('Y-m-d H:i:s'))); | ||||
|         $default         = Amount::getNativeCurrency(); | ||||
|         $netWorth        = []; | ||||
|         Log::debug(sprintf('NetWorth: finalAccountsBalance("%s")', $date->format('Y-m-d H:i:s'))); | ||||
|         $balances        = Steam::finalAccountsBalance($accounts, $date); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
| @@ -159,6 +160,7 @@ class NetWorth implements NetWorthInterface | ||||
|          */ | ||||
|         $accounts = $this->getAccounts(); | ||||
|         $return   = []; | ||||
|         Log::debug(sprintf('SumNetWorth: finalAccountsBalance("%s")', $date->format('Y-m-d H:i:s'))); | ||||
|         $balances = Steam::finalAccountsBalance($accounts, $date); | ||||
|         foreach ($accounts as $account) { | ||||
|             $currency                     = $this->getRepository()->getAccountCurrency($account); | ||||
|   | ||||
| @@ -33,6 +33,7 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
| @@ -90,9 +91,11 @@ class IndexController extends Controller | ||||
|         $start->subDay(); | ||||
| 
 | ||||
|         $ids           = $accounts->pluck('id')->toArray(); | ||||
|         $startBalances = app('steam')->finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = app('steam')->finalAccountsBalance($accounts, $end); | ||||
|         $activities    = app('steam')->getLastActivities($ids); | ||||
|         Log::debug(sprintf('inactive start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); | ||||
|         Log::debug(sprintf('inactive end: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s'))); | ||||
|         $startBalances = Steam::finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = Steam::finalAccountsBalance($accounts, $end); | ||||
|         $activities    = Steam::getLastActivities($ids); | ||||
| 
 | ||||
| 
 | ||||
|         $accounts->each( | ||||
| @@ -102,7 +105,7 @@ class IndexController extends Controller | ||||
|                 $account->startBalances     = Steam::filterAccountBalance($startBalances[$account->id] ?? [], $account, $this->convertToNative, $currency); | ||||
|                 $account->endBalances       = Steam::filterAccountBalance($endBalances[$account->id] ?? [], $account, $this->convertToNative, $currency); | ||||
|                 $account->differences       = $this->subtract($account->startBalances, $account->endBalances); | ||||
|                 $account->interest          = app('steam')->bcround($this->repository->getMetaValue($account, 'interest'), 4); | ||||
|                 $account->interest          = Steam::bcround($this->repository->getMetaValue($account, 'interest'), 4); | ||||
|                 $account->interestPeriod    = (string) trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period'))); | ||||
|                 $account->accountTypeString = (string) trans(sprintf('firefly.account_type_%s', $account->accountType->type)); | ||||
|                 $account->current_debt      = '0'; | ||||
| @@ -153,9 +156,11 @@ class IndexController extends Controller | ||||
|         $start->subDay(); | ||||
| 
 | ||||
|         $ids           = $accounts->pluck('id')->toArray(); | ||||
|         $startBalances = app('steam')->finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = app('steam')->finalAccountsBalance($accounts, $end); | ||||
|         $activities    = app('steam')->getLastActivities($ids); | ||||
|         Log::debug(sprintf('index start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); | ||||
|         Log::debug(sprintf('index end: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s'))); | ||||
|         $startBalances = Steam::finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = Steam::finalAccountsBalance($accounts, $end); | ||||
|         $activities    = Steam::getLastActivities($ids); | ||||
| 
 | ||||
| 
 | ||||
|         $accounts->each( | ||||
| @@ -168,7 +173,7 @@ class IndexController extends Controller | ||||
|                 $account->endBalances         = Steam::filterAccountBalance($endBalances[$account->id] ?? [], $account, $this->convertToNative, $currency); | ||||
|                 $account->differences         = $this->subtract($account->startBalances, $account->endBalances); | ||||
|                 $account->lastActivityDate    = $this->isInArrayDate($activities, $account->id); | ||||
|                 $account->interest            = app('steam')->bcround($interest, 4); | ||||
|                 $account->interest            = Steam::bcround($interest, 4); | ||||
|                 $account->interestPeriod      = (string) trans( | ||||
|                     sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')) | ||||
|                 ); | ||||
|   | ||||
| @@ -39,6 +39,7 @@ use FireflyIII\User; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
| @@ -113,6 +114,10 @@ class ReconcileController extends Controller | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         $startDate       = clone $start; | ||||
|         $startDate->subDay()->endOfDay(); // this is correct, subday endofday ends at 23:59:59
 | ||||
|         // both are validated and are correct.
 | ||||
|         Log::debug(sprintf('reconcile: Call finalAccountBalance with date/time "%s"', $startDate->toIso8601String())); | ||||
|         Log::debug(sprintf('reconcile2: Call finalAccountBalance with date/time "%s"', $end->toIso8601String())); | ||||
|         $startBalance    = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); | ||||
|         $endBalance      = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); | ||||
|         $subTitleIcon    = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type)); | ||||
| @@ -220,11 +225,13 @@ class ReconcileController extends Controller | ||||
|             ] | ||||
|         ); | ||||
|         $submission     = [ | ||||
|             'user'         => auth()->user()->id, | ||||
|             'user'               => auth()->user(), | ||||
|             'user_group'         => auth()->user()->userGroup, | ||||
|             'group_title'        => null, | ||||
|             'transactions'       => [ | ||||
|                 [ | ||||
|                     'user'                => auth()->user()->id, | ||||
|                     'user'                => auth()->user(), | ||||
|                     'user_group'          => auth()->user()->userGroup, | ||||
|                     'type'                => strtolower(TransactionTypeEnum::RECONCILIATION->value), | ||||
|                     'date'                => $end, | ||||
|                     'order'               => 0, | ||||
|   | ||||
| @@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Controllers\PeriodOverview; | ||||
| @@ -37,6 +38,7 @@ use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
| @@ -79,6 +81,7 @@ class ShowController extends Controller | ||||
|      *                                              */ | ||||
|     public function show(Request $request, Account $account, ?Carbon $start = null, ?Carbon $end = null) | ||||
|     { | ||||
| 
 | ||||
|         $objectType       = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type)); | ||||
| 
 | ||||
|         if (!$this->isEditableAccount($account)) { | ||||
| @@ -120,12 +123,7 @@ class ShowController extends Controller | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector        = app(GroupCollectorInterface::class); | ||||
|         $collector | ||||
|             ->setAccounts(new Collection([$account])) | ||||
|             ->setLimit($pageSize) | ||||
|             ->setPage($page)->withAccountInformation()->withCategoryInformation() | ||||
|             ->setRange($start, $end) | ||||
|         ; | ||||
|         $collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation()->setRange($start, $end); | ||||
| 
 | ||||
|         // this search will not include transaction groups where this asset account (or liability)
 | ||||
|         // is just part of ONE of the journals. To force this:
 | ||||
| @@ -135,7 +133,14 @@ class ShowController extends Controller | ||||
| 
 | ||||
|         $groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')])); | ||||
|         $showAll          = false; | ||||
|         $balances         = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $end), $account, $this->convertToNative, $accountCurrency); | ||||
|         // correct
 | ||||
|         $now              = today()->endOfDay(); | ||||
|         if ($now->gt($end) || $now->lt($start)) { | ||||
|             $now = $end; | ||||
|         } | ||||
| 
 | ||||
|         Log::debug(sprintf('show: Call finalAccountBalance with date/time "%s"', $now->toIso8601String())); | ||||
|         $balances         = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $now), $account, $this->convertToNative, $accountCurrency); | ||||
| 
 | ||||
|         return view( | ||||
|             'accounts.show', | ||||
| @@ -200,6 +205,8 @@ class ShowController extends Controller | ||||
|         $groups->setPath(route('accounts.show.all', [$account->id])); | ||||
|         $chartUrl        = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]); | ||||
|         $showAll         = true; | ||||
|         // correct
 | ||||
|         Log::debug(sprintf('showAll: Call finalAccountBalance with date/time "%s"', $end->toIso8601String())); | ||||
|         $balances        = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $end), $account, $this->convertToNative, $accountCurrency); | ||||
| 
 | ||||
|         return view( | ||||
|   | ||||
| @@ -41,6 +41,7 @@ use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Http\Response; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| 
 | ||||
| @@ -223,7 +224,7 @@ class LoginController extends Controller | ||||
|     { | ||||
|         Log::channel('audit')->info('Show login form (1.1).'); | ||||
| 
 | ||||
|         $count             = \DB::table('users')->count(); | ||||
|         $count             = DB::table('users')->count(); | ||||
|         $guard             = config('auth.defaults.guard'); | ||||
|         $title             = (string) trans('firefly.login_page_title'); | ||||
| 
 | ||||
|   | ||||
| @@ -35,6 +35,7 @@ use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\Facades\Steam; | ||||
| use FireflyIII\Support\Http\Controllers\AugumentData; | ||||
| use FireflyIII\Support\Http\Controllers\ChartGeneration; | ||||
| @@ -108,8 +109,10 @@ class AccountController extends Controller | ||||
|         $accountNames  = $this->extractNames($accounts); | ||||
| 
 | ||||
|         // grab all balances
 | ||||
|         $startBalances = app('steam')->finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = app('steam')->finalAccountsBalance($accounts, $end); | ||||
|         Log::debug(sprintf('expenseAccounts: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); | ||||
|         Log::debug(sprintf('expenseAccounts: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s'))); | ||||
|         $startBalances = Steam::finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = Steam::finalAccountsBalance($accounts, $end); | ||||
| 
 | ||||
|         // loop the accounts, then check for balance and currency info.
 | ||||
|         foreach ($accounts as $account) { | ||||
| @@ -138,6 +141,7 @@ class AccountController extends Controller | ||||
|                 } | ||||
|                 // Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
 | ||||
|                 $searchCode   = $this->convertToNative ? $this->defaultCurrency->code : $key; | ||||
|                 $searchCode   = 'balance' === $searchCode || 'native_balance' === $searchCode ? $this->defaultCurrency->code : $searchCode; | ||||
|                 // Log::debug(sprintf('Search code is %s', $searchCode));
 | ||||
|                 // see if there is an accompanying start amount.
 | ||||
|                 // grab the difference and find the currency.
 | ||||
| @@ -333,7 +337,7 @@ class AccountController extends Controller | ||||
|         $start          = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
|         $end            = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $defaultSet     = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray(); | ||||
|         Log::debug('Default set is ', $defaultSet); | ||||
|         // Log::debug('Default set is ', $defaultSet);
 | ||||
|         $frontpage      = app('preferences')->get('frontpageAccounts', $defaultSet); | ||||
|         $frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data; | ||||
|         Log::debug('Frontpage preference set is ', $frontpageArray); | ||||
| @@ -343,6 +347,9 @@ class AccountController extends Controller | ||||
|         } | ||||
|         $accounts       = $repository->getAccountsById($frontpageArray); | ||||
| 
 | ||||
|         // move to end of day for $end.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         return response()->json($this->accountBalanceChart($accounts, $start, $end)); | ||||
|     } | ||||
| 
 | ||||
| @@ -417,8 +424,8 @@ class AccountController extends Controller | ||||
|     { | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
|         // TODO not sure if these date ranges will work as expected.
 | ||||
|         Log::debug(sprintf('Now in period("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); | ||||
|         $chartData       = []; | ||||
|         $cache           = new CacheProperties(); | ||||
|         $cache->addProperty('chart.account.period'); | ||||
|         $cache->addProperty($start); | ||||
| @@ -426,13 +433,13 @@ class AccountController extends Controller | ||||
|         $cache->addProperty($this->convertToNative); | ||||
|         $cache->addProperty($account->id); | ||||
|         if ($cache->has()) { | ||||
|             // return response()->json($cache->get());
 | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         // collect and filter balances for the entire period.
 | ||||
|         $step            = $this->calculateStep($start, $end); | ||||
|         Log::debug(sprintf('Step is %s', $step)); | ||||
|         $locale          = app('steam')->getLocale(); | ||||
|         $locale          = Steam::getLocale(); | ||||
|         $return          = []; | ||||
| 
 | ||||
|         // fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
 | ||||
| @@ -447,7 +454,7 @@ class AccountController extends Controller | ||||
|         $range           = Steam::filterAccountBalances($range, $account, $this->convertToNative, $accountCurrency); | ||||
| 
 | ||||
|         // temp, get end balance.
 | ||||
|         Log::debug('temp get end balance'); | ||||
|         Log::debug(sprintf('period: Call finalAccountBalance with date/time "%s"', $end->toIso8601String())); | ||||
|         Steam::finalAccountBalance($account, $end); | ||||
|         Log::debug('END temp get end balance done'); | ||||
| 
 | ||||
| @@ -500,7 +507,7 @@ class AccountController extends Controller | ||||
|         $chartData       = []; | ||||
| 
 | ||||
|         foreach ($return as $key => $info) { | ||||
|             if (3 === strlen($key)) { | ||||
|             if ('balance' !== $key && 'native_balance' !== $key) { | ||||
|                 // assume it's a currency:
 | ||||
|                 $setCurrency             = $this->currencyRepository->findByCode($key); | ||||
|                 $info['currency_symbol'] = $setCurrency->symbol; | ||||
| @@ -570,8 +577,10 @@ class AccountController extends Controller | ||||
|         $accountNames  = $this->extractNames($accounts); | ||||
| 
 | ||||
|         // grab all balances
 | ||||
|         $startBalances = app('steam')->finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = app('steam')->finalAccountsBalance($accounts, $end); | ||||
|         Log::debug(sprintf('revAccounts: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); | ||||
|         Log::debug(sprintf('revAccounts: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s'))); | ||||
|         $startBalances = Steam::finalAccountsBalance($accounts, $start); | ||||
|         $endBalances   = Steam::finalAccountsBalance($accounts, $end); | ||||
| 
 | ||||
| 
 | ||||
|         // loop the accounts, then check for balance and currency info.
 | ||||
| @@ -601,6 +610,7 @@ class AccountController extends Controller | ||||
|                 } | ||||
|                 // Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
 | ||||
|                 $searchCode   = $this->convertToNative ? $this->defaultCurrency->code : $key; | ||||
|                 $searchCode   = 'balance' === $searchCode || 'native_balance' === $searchCode ? $this->defaultCurrency->code : $searchCode; | ||||
|                 // Log::debug(sprintf('Search code is %s', $searchCode));
 | ||||
|                 // see if there is an accompanying start amount.
 | ||||
|                 // grab the difference and find the currency.
 | ||||
|   | ||||
| @@ -168,15 +168,14 @@ class BudgetController extends Controller | ||||
|         } | ||||
|         $locale                                 = app('steam')->getLocale(); | ||||
|         $entries                                = []; | ||||
|         $amount                                 = $budgetLimit->amount; | ||||
|         $amount                                 = $budgetLimit->amount ?? '0'; | ||||
|         $budgetCollection                       = new Collection([$budget]); | ||||
|         $currency                               = $budgetLimit->transactionCurrency; | ||||
|         if ($this->convertToNative) { | ||||
|             $amount   = $budgetLimit->native_amount; | ||||
|             $amount   = $budgetLimit->native_amount ?? '0'; | ||||
|             $currency = $this->defaultCurrency; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         while ($start <= $end) { | ||||
|             $current          = clone $start; | ||||
|             $expenses         = $this->opsRepository->sumExpenses($current, $current, null, $budgetCollection, $budgetLimit->transactionCurrency); | ||||
|   | ||||
| @@ -100,7 +100,10 @@ class ReportController extends Controller | ||||
| 
 | ||||
|         while ($current < $end) { | ||||
|             // get balances by date, grouped by currency.
 | ||||
|             $result = $helper->byAccounts($filtered, $current); | ||||
|             $balanceCurrent = clone $current; | ||||
|             $balanceCurrent->subDay()->endOfDay(); // go to correct moment.
 | ||||
|             Log::debug(sprintf('Call byAccounts("%s")', $balanceCurrent->format('Y-m-d H:i:s'))); | ||||
|             $result         = $helper->byAccounts($filtered, $balanceCurrent); | ||||
| 
 | ||||
|             // loop result, add to array.
 | ||||
|             /** @var array $netWorthItem */ | ||||
|   | ||||
| @@ -42,6 +42,7 @@ use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Facades\Artisan; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\Support\Facades\Route; | ||||
| use Illuminate\View\View; | ||||
| @@ -259,7 +260,7 @@ class DebugController extends Controller | ||||
|         $system = $this->getSystemInformation(); | ||||
|         $docker = $this->getBuildInfo(); | ||||
|         $app    = $this->getAppInfo(); | ||||
|         $user   = $this->getuserInfo(); | ||||
|         $user   = $this->getUserInfo(); | ||||
| 
 | ||||
|         return (string) view('partials.debug-table', compact('system', 'docker', 'app', 'user')); | ||||
|     } | ||||
| @@ -268,8 +269,8 @@ class DebugController extends Controller | ||||
|     { | ||||
|         $maxFileSize   = Steam::phpBytes((string) ini_get('upload_max_filesize')); | ||||
|         $maxPostSize   = Steam::phpBytes((string) ini_get('post_max_size')); | ||||
|         $drivers       = \DB::availableDrivers(); | ||||
|         $currentDriver = \DB::getDriverName(); | ||||
|         $drivers       = DB::availableDrivers(); | ||||
|         $currentDriver = DB::getDriverName(); | ||||
| 
 | ||||
|         return [ | ||||
|             'db_version'      => app('fireflyconfig')->get('db_version', 1)->data, | ||||
|   | ||||
| @@ -189,21 +189,29 @@ class ReconcileController extends Controller | ||||
|         if ($end->lt($start)) { | ||||
|             [$end, $start] = [$start, $end]; | ||||
|         } | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); | ||||
|         $end->endOfDay(); | ||||
|         $startDate      = clone $start; | ||||
|         $startDate->subDay(); | ||||
| 
 | ||||
|         $currency       = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency; | ||||
|         // correct
 | ||||
|         Log::debug(sprintf('transactions: Call finalAccountBalance with date/time "%s"', $startDate->toIso8601String())); | ||||
|         Log::debug(sprintf('transactions2: Call finalAccountBalance with date/time "%s"', $end->toIso8601String())); | ||||
|         $startBalance   = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); | ||||
|         $endBalance     = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); | ||||
| 
 | ||||
|         // get the transactions
 | ||||
|         $selectionStart = clone $start; | ||||
|         $selectionStart->startOfDay(); | ||||
|         $selectionStart->subDays(3); | ||||
|         $selectionEnd   = clone $end; | ||||
|         $selectionEnd->endOfDay(); | ||||
|         $selectionEnd->addDays(3); | ||||
| 
 | ||||
|         // to make sure the bar is in the right place:
 | ||||
|         $start->startOfDay(); | ||||
| 
 | ||||
|         // grab transactions:
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector      = app(GroupCollectorInterface::class); | ||||
|   | ||||
| @@ -31,6 +31,7 @@ use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\Transformers\PiggyBankTransformer; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| @@ -87,13 +88,13 @@ class IndexController extends Controller | ||||
|         $end        = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
| 
 | ||||
|         // transform piggies using the transformer:
 | ||||
|         $parameters         = new ParameterBag(); | ||||
|         $parameters->set('end', $end); | ||||
|         // $parameters         = new ParameterBag();
 | ||||
|         // $parameters->set('end', $end);
 | ||||
| 
 | ||||
| 
 | ||||
|         /** @var AccountTransformer $accountTransformer */ | ||||
|         $accountTransformer = app(AccountTransformer::class); | ||||
|         $accountTransformer->setParameters($parameters); | ||||
|         // /** @var AccountTransformer $accountTransformer */
 | ||||
|         // $accountTransformer = app(AccountTransformer::class);
 | ||||
|         // $accountTransformer->setParameters($parameters);
 | ||||
| 
 | ||||
|         // data
 | ||||
|         $piggyBanks = $this->groupPiggyBanks($collection); | ||||
| @@ -144,6 +145,11 @@ class IndexController extends Controller | ||||
|         $accountTransformer = app(AccountTransformer::class); | ||||
|         $accountTransformer->setParameters($parameters); | ||||
| 
 | ||||
|         // enrich each account.
 | ||||
|         $enrichment         = new AccountEnrichment(); | ||||
|         $enrichment->setUser(auth()->user()); | ||||
|         $enrichment->setConvertToNative($this->convertToNative); | ||||
|         $enrichment->setNative($this->defaultCurrency); | ||||
|         $return             = []; | ||||
| 
 | ||||
|         /** @var PiggyBank $piggy */ | ||||
| @@ -152,6 +158,7 @@ class IndexController extends Controller | ||||
| 
 | ||||
|             /** @var Account $account */ | ||||
|             foreach ($accounts as $account) { | ||||
|                 $account   = $enrichment->enrichSingle($account); | ||||
|                 $array     = $accountTransformer->transform($account); | ||||
|                 $accountId = (int) $array['id']; | ||||
|                 if (!array_key_exists($accountId, $return)) { | ||||
|   | ||||
							
								
								
									
										29
									
								
								app/Http/Controllers/Preferences/NotificationsController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Http/Controllers/Preferences/NotificationsController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * NotificationsController.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\Http\Controllers\Preferences; | ||||
| 
 | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| 
 | ||||
| class NotificationsController extends Controller {} | ||||
| @@ -42,6 +42,7 @@ use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\View\View; | ||||
| use Laravel\Passport\ClientRepository; | ||||
| 
 | ||||
| @@ -139,7 +140,7 @@ class ProfileController extends Controller | ||||
|         /** @var User $user */ | ||||
|         $user           = auth()->user(); | ||||
|         $isInternalAuth = $this->internalAuth; | ||||
|         $count          = \DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count(); | ||||
|         $count          = DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count(); | ||||
|         $subTitle       = $user->email; | ||||
|         $userId         = $user->id; | ||||
|         $enabled2FA     = null !== $user->mfa_secret; | ||||
|   | ||||
| @@ -83,7 +83,7 @@ class ReportController extends Controller | ||||
|             return view('error')->with('message', (string) trans('firefly.end_after_start_date')); | ||||
|         } | ||||
|         $this->repository->cleanupBudgets(); | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); // end of day so the final balance is at the end of that day.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         app('view')->share( | ||||
| @@ -116,7 +116,7 @@ class ReportController extends Controller | ||||
|             return view('error')->with('message', (string) trans('firefly.end_after_start_date')); | ||||
|         } | ||||
|         $this->repository->cleanupBudgets(); | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); // end of day so the final balance is at the end of that day.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         app('view')->share( | ||||
| @@ -150,7 +150,7 @@ class ReportController extends Controller | ||||
|             return view('error')->with('message', (string) trans('firefly.end_after_start_date')); | ||||
|         } | ||||
|         $this->repository->cleanupBudgets(); | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); // end of day so the final balance is at the end of that day.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         app('view')->share( | ||||
| @@ -185,7 +185,7 @@ class ReportController extends Controller | ||||
|         } | ||||
| 
 | ||||
|         $this->repository->cleanupBudgets(); | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); // end of day so the final balance is at the end of that day.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         app('view')->share( | ||||
| @@ -219,7 +219,7 @@ class ReportController extends Controller | ||||
|         } | ||||
| 
 | ||||
|         $this->repository->cleanupBudgets(); | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); // end of day so the final balance is at the end of that day.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         app('view')->share( | ||||
| @@ -377,7 +377,7 @@ class ReportController extends Controller | ||||
|             return view('error')->with('message', (string) trans('firefly.end_after_start_date')); | ||||
|         } | ||||
|         $this->repository->cleanupBudgets(); | ||||
|         $start->startOfDay(); | ||||
|         $start->endOfDay(); // end of day so the final balance is at the end of that day.
 | ||||
|         $end->endOfDay(); | ||||
| 
 | ||||
|         app('view')->share( | ||||
|   | ||||
| @@ -43,6 +43,7 @@ use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
| @@ -223,7 +224,9 @@ class ConvertController extends Controller | ||||
|         // group accounts:
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accountList as $account) { | ||||
|             $balance                     = Steam::finalAccountBalance($account, today()->endOfDay())['balance']; | ||||
|             $date                        = today()->endOfDay(); | ||||
|             Log::debug(sprintf('getLiabilities: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); | ||||
|             $balance                     = Steam::finalAccountBalance($account, $date)['balance']; | ||||
|             $currency                    = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency; | ||||
|             $role                        = 'l_'.$account->accountType->type; | ||||
|             $key                         = (string) trans('firefly.opt_group_'.$role); | ||||
| @@ -245,7 +248,9 @@ class ConvertController extends Controller | ||||
|         // group accounts:
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accountList as $account) { | ||||
|             $balance                     = Steam::finalAccountBalance($account, today()->endOfDay())['balance']; | ||||
|             $date                        = today()->endOfDay(); | ||||
|             Log::debug(sprintf('getAssetAccounts: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); | ||||
|             $balance                     = Steam::finalAccountBalance($account, $date)['balance']; | ||||
|             $currency                    = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency; | ||||
|             $role                        = (string) $this->accountRepository->getMetaValue($account, 'account_role'); | ||||
|             if ('' === $role) { | ||||
|   | ||||
| @@ -141,8 +141,8 @@ class MassController extends Controller | ||||
|         // reverse amounts
 | ||||
|         foreach ($journals as $index => $journal) { | ||||
|             $journals[$index]['amount']         = app('steam')->bcround(app('steam')->positive($journal['amount']), $journal['currency_decimal_places']); | ||||
|             $journals[$index]['foreign_amount'] = null === $journal['foreign_amount'] ? | ||||
|                 null : app('steam')->positive($journal['foreign_amount']); | ||||
|             $journals[$index]['foreign_amount'] = null === $journal['foreign_amount'] | ||||
|                 ? null : app('steam')->positive($journal['foreign_amount']); | ||||
|         } | ||||
| 
 | ||||
|         $this->rememberPreviousUrl('transactions.mass-edit.url'); | ||||
|   | ||||
| @@ -103,7 +103,7 @@ class ShowController extends Controller | ||||
| 
 | ||||
|         foreach (array_keys($groupArray['transactions']) as $index) { | ||||
|             $groupArray['transactions'][$index]['tags'] = $this->repository->getTagObjects( | ||||
|                 $groupArray['transactions'][$index]['transaction_journal_id'] | ||||
|                 (int) $groupArray['transactions'][$index]['transaction_journal_id'] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Support\System\OAuthKeys; | ||||
| use Illuminate\Database\QueryException; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
| @@ -83,7 +84,7 @@ class Installer | ||||
|         // Log::debug('Now in routine hasNoTables()');
 | ||||
| 
 | ||||
|         try { | ||||
|             \DB::table('users')->count(); | ||||
|             DB::table('users')->count(); | ||||
|         } catch (QueryException $e) { | ||||
|             $message = $e->getMessage(); | ||||
|             Log::error(sprintf('Error message trying to access users-table: %s', $message)); | ||||
|   | ||||
| @@ -33,11 +33,11 @@ class TrustProxies extends Middleware | ||||
| { | ||||
|     // After...
 | ||||
|     protected $headers | ||||
|         = Request::HEADER_X_FORWARDED_FOR | | ||||
|         Request::HEADER_X_FORWARDED_HOST | | ||||
|         Request::HEADER_X_FORWARDED_PORT | | ||||
|         Request::HEADER_X_FORWARDED_PROTO | | ||||
|         Request::HEADER_X_FORWARDED_AWS_ELB; | ||||
|         = Request::HEADER_X_FORWARDED_FOR | ||||
|         | Request::HEADER_X_FORWARDED_HOST | ||||
|         | Request::HEADER_X_FORWARDED_PORT | ||||
|         | Request::HEADER_X_FORWARDED_PROTO | ||||
|         | Request::HEADER_X_FORWARDED_AWS_ELB; | ||||
| 
 | ||||
|     /** | ||||
|      * TrustProxies constructor. | ||||
|   | ||||
| @@ -74,7 +74,7 @@ class TagFormRequest extends FormRequest | ||||
|             'tag'         => $tagRule, | ||||
|             'id'          => $idRule, | ||||
|             'description' => 'max:32768|min:1|nullable', | ||||
|             'date'        => 'date|nullable', | ||||
|             'date'        => 'date|nullable|after:1984-09-17', | ||||
|         ]; | ||||
| 
 | ||||
|         return Location::requestRules($rules); | ||||
|   | ||||
| @@ -380,7 +380,8 @@ class CreateRecurringTransactions implements ShouldQueue | ||||
|         } | ||||
| 
 | ||||
|         $array                      = [ | ||||
|             'user'         => $recurrence->user_id, | ||||
|             'user'               => $recurrence->user, | ||||
|             'user_group'         => $recurrence->user->userGroup, | ||||
|             'group_title'        => $groupTitle, | ||||
|             'transactions'       => $this->getTransactionData($recurrence, $repetition, $date), | ||||
|         ]; | ||||
| @@ -419,11 +420,10 @@ class CreateRecurringTransactions implements ShouldQueue | ||||
|         /** @var RecurrenceTransaction $transaction */ | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             $single   = [ | ||||
|                 'type'                  => null === $transaction?->transactionType?->type ? | ||||
|                     strtolower($recurrence->transactionType->type) : | ||||
|                     strtolower($transaction->transactionType->type), | ||||
|                 'type'                  => null === $transaction?->transactionType?->type ? strtolower($recurrence->transactionType->type) : strtolower($transaction->transactionType->type), // @phpstan-ignore-line
 | ||||
|                 'date'                  => $date, | ||||
|                 'user'                  => $recurrence->user_id, | ||||
|                 'user'                  => $recurrence->user, | ||||
|                 'user_group'            => $recurrence->user->userGroup, | ||||
|                 'currency_id'           => $transaction->transaction_currency_id, | ||||
|                 'currency_code'         => null, | ||||
|                 'description'           => $transaction->description, | ||||
|   | ||||
| @@ -51,6 +51,7 @@ class Account extends Model | ||||
|             'created_at'                   => 'datetime', | ||||
|             'updated_at'                   => 'datetime', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|             'deleted_at'                   => 'datetime', | ||||
|             'active'                       => 'boolean', | ||||
|             'encrypted'                    => 'boolean', | ||||
|   | ||||
| @@ -46,9 +46,11 @@ class Attachment extends Model | ||||
|             'updated_at'                   => 'datetime', | ||||
|             'deleted_at'                   => 'datetime', | ||||
|             'uploaded'                     => 'boolean', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|         ]; | ||||
| 
 | ||||
|     protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded']; | ||||
|     protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'user_group_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded']; | ||||
| 
 | ||||
|     /** | ||||
|      * Route binder. Converts the key in the URL to the specified object (or throw 404). | ||||
|   | ||||
| @@ -49,6 +49,8 @@ class AvailableBudget extends Model | ||||
|             'transaction_currency_id'      => 'int', | ||||
|             'amount'                       => 'string', | ||||
|             'native_amount'                => 'string', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|         ]; | ||||
| 
 | ||||
|     protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date', 'start_date_tz', 'end_date_tz', 'native_amount']; | ||||
|   | ||||
| @@ -48,9 +48,11 @@ class Budget extends Model | ||||
|             'deleted_at'                   => 'datetime', | ||||
|             'active'                       => 'boolean', | ||||
|             'encrypted'                    => 'boolean', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|         ]; | ||||
| 
 | ||||
|     protected $fillable = ['user_id', 'name', 'active', 'order', 'user_group_id']; | ||||
|     protected $fillable = ['user_id', 'user_group_id', 'name', 'active', 'order', 'user_group_id']; | ||||
| 
 | ||||
|     protected $hidden   = ['encrypted']; | ||||
| 
 | ||||
|   | ||||
| @@ -46,6 +46,8 @@ class Category extends Model | ||||
|             'updated_at'                   => 'datetime', | ||||
|             'deleted_at'                   => 'datetime', | ||||
|             'encrypted'                    => 'boolean', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|         ]; | ||||
| 
 | ||||
|     protected $fillable = ['user_id', 'user_group_id', 'name']; | ||||
|   | ||||
| @@ -42,9 +42,10 @@ class CurrencyExchangeRate extends Model | ||||
|                         = [ | ||||
|             'created_at'                   => 'datetime', | ||||
|             'updated_at'                   => 'datetime', | ||||
|             'user_id'          => 'int', | ||||
|             'from_currency_id' => 'int', | ||||
|             'to_currency_id'   => 'int', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|             'from_currency_id'             => 'integer', | ||||
|             'to_currency_id'               => 'integer', | ||||
|             'date'                         => SeparateTimezoneCaster::class, | ||||
|             'rate'                         => 'string', | ||||
|             'user_rate'                    => 'string', | ||||
|   | ||||
| @@ -36,6 +36,13 @@ class GroupMembership extends Model | ||||
|     use ReturnsIntegerIdTrait; | ||||
|     use ReturnsIntegerUserIdTrait; | ||||
| 
 | ||||
|     protected $casts    = [ | ||||
|         'created_at'                   => 'datetime', | ||||
|         'updated_at'                   => 'datetime', | ||||
|         'user_id'                      => 'integer', | ||||
|         'user_group_id'                => 'integer', | ||||
|     ]; | ||||
| 
 | ||||
|     protected $fillable = ['user_id', 'user_group_id', 'user_role_id']; | ||||
| 
 | ||||
|     public function user(): BelongsTo | ||||
|   | ||||
| @@ -41,8 +41,10 @@ class InvitedUser extends Model | ||||
|                         = [ | ||||
|             'expires'                      => SeparateTimezoneCaster::class, | ||||
|             'redeemed'                     => 'boolean', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|         ]; | ||||
|     protected $fillable = ['user_id', 'email', 'invite_code', 'expires', 'expires_tz', 'redeemed']; | ||||
|     protected $fillable = ['user_group_id', 'user_id', 'email', 'invite_code', 'expires', 'expires_tz', 'redeemed']; | ||||
| 
 | ||||
|     /** | ||||
|      * Route binder. Converts the key in the URL to the specified object (or throw 404). | ||||
|   | ||||
| @@ -43,6 +43,7 @@ class ObjectGroup extends Model | ||||
|             'created_at'                   => 'datetime', | ||||
|             'updated_at'                   => 'datetime', | ||||
|             'user_id'                      => 'integer', | ||||
|             'user_group_id'                => 'integer', | ||||
|             'deleted_at'                   => 'datetime', | ||||
|         ]; | ||||
|     protected $fillable = ['title', 'order', 'user_id', 'user_group_id']; | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user