mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-18 18:44:16 +00:00
Compare commits
189 Commits
v6.3.0
...
a9f21c9371
Author | SHA1 | Date | |
---|---|---|---|
|
a9f21c9371 | ||
|
781947beeb | ||
|
9760cd2f97 | ||
|
d317e9ec32 | ||
|
534f7fcadb | ||
|
fb3f7a1d4b | ||
|
bf2c3e3561 | ||
|
b670f81dcd | ||
|
7aac1cdf67 | ||
|
fa0ac8a16c | ||
|
0990b1f0b4 | ||
|
c1922670c8 | ||
|
81cd89d66f | ||
|
f5c202543c | ||
|
034f437c6b | ||
|
8550ba6138 | ||
|
a51501025b | ||
|
a9d26e4586 | ||
|
949691935f | ||
|
4835b05304 | ||
|
cce5a73dd2 | ||
|
3152f635dd | ||
|
12e8651017 | ||
|
f88286c848 | ||
|
39cf0533d9 | ||
|
6d82887960 | ||
|
262f1bae34 | ||
|
75dfdcc220 | ||
|
c3a3bdf525 | ||
|
602df95f3c | ||
|
296a64e284 | ||
|
b87b99a755 | ||
|
bf53f5d6b7 | ||
|
bcbb868acc | ||
|
b3a9e6569e | ||
|
f174f124ef | ||
|
8745377f31 | ||
|
cf76e93f31 | ||
|
19e36f6f6e | ||
|
2a7bb6f048 | ||
|
536eacbc0c | ||
|
af78158d0b | ||
|
fb97910a34 | ||
|
66b4d14129 | ||
|
fd53047dbc | ||
|
5f6fc1bab4 | ||
|
cd0b64bd24 | ||
|
91b26bce0e | ||
|
26a8bd921d | ||
|
ad77d55c16 | ||
|
445a383dd0 | ||
|
1666af939e | ||
|
35447f5eee | ||
|
7c6fcb5731 | ||
|
fabd9bf765 | ||
|
6352d26633 | ||
|
ebef145bd6 | ||
|
acc89eb5f9 | ||
|
6523596415 | ||
|
b6c2d23116 | ||
|
2a123354f9 | ||
|
1e7ea4b76c | ||
|
d959526eb3 | ||
|
8846ee9091 | ||
|
6eb8d0fc8c | ||
|
1b0e16b6a5 | ||
|
2e4df28288 | ||
|
f3b7a3015d | ||
|
5de5e08b1d | ||
|
0a116cd04c | ||
|
fd32a692c1 | ||
|
1ac762aba8 | ||
|
315dc532b6 | ||
|
e19ed1be15 | ||
|
cbb0621fd9 | ||
|
049cbab861 | ||
|
28b620fb5c | ||
|
c183f91ff6 | ||
|
172efae41c | ||
|
756e857ba0 | ||
|
1cde7aab0c | ||
|
2d67eece5d | ||
|
b1f79c4c0f | ||
|
33bd2ceae8 | ||
|
e68850f192 | ||
|
450ac7e6ee | ||
|
91f52b5dbc | ||
|
eed2405d76 | ||
|
c956df7790 | ||
|
0fdccec6a8 | ||
|
8ded54d7a8 | ||
|
bb1b4ca5ca | ||
|
e90d60113b | ||
|
d95dada0e0 | ||
|
8722456595 | ||
|
b5ad226451 | ||
|
ddb0e66651 | ||
|
e802899608 | ||
|
0894d3bf42 | ||
|
80bcfd3bcd | ||
|
8c410f42bd | ||
|
7a1021dffc | ||
|
63883c9a84 | ||
|
50d7f9d1ec | ||
|
ebc7ea0eb6 | ||
|
b905efd0aa | ||
|
93085599b7 | ||
|
8a8bbaf827 | ||
|
96a66b894a | ||
|
1ba641c279 | ||
|
6c5ddfcb8a | ||
|
65ddc246dc | ||
|
e4aff5ff4c | ||
|
dfece91541 | ||
|
6ddda13c3a | ||
|
46219c4678 | ||
|
a1595d0647 | ||
|
4ee9f9bb27 | ||
|
bcaa0bddea | ||
|
01cce49070 | ||
|
293be04d40 | ||
|
44a00ec8eb | ||
|
d84e772945 | ||
|
b475f6c51d | ||
|
2712662510 | ||
|
1f2eeba862 | ||
|
46a60134f4 | ||
|
f3f7820816 | ||
|
a57f8076b2 | ||
|
517afa2273 | ||
|
2142b23aec | ||
|
1bec43b111 | ||
|
d2978a5ee8 | ||
|
39b61c71e8 | ||
|
fa2c964790 | ||
|
134aeb3a46 | ||
|
6f6e1a4ff4 | ||
|
b743bf3d9e | ||
|
84ee6f16c9 | ||
|
9fe39e42b3 | ||
|
4013c7e316 | ||
|
0b76747531 | ||
|
3129756b37 | ||
|
b0df383004 | ||
|
9c5b1df86c | ||
|
5854e24775 | ||
|
3f873422f2 | ||
|
f898990773 | ||
|
a5759ab1c6 | ||
|
9bd6417e02 | ||
|
cd12a10214 | ||
|
ee8cb62e04 | ||
|
87ee95a852 | ||
|
10f8436885 | ||
|
6955846a1c | ||
|
11d2f8d471 | ||
|
99347ffff1 | ||
|
3ddc11a905 | ||
|
0a48c0c20f | ||
|
8bc764d6ef | ||
|
4b4f568558 | ||
|
d42117281a | ||
|
d68ed5a713 | ||
|
2f6f36c3f0 | ||
|
984aa02e35 | ||
|
cdadc7d533 | ||
|
4d59955cc5 | ||
|
fc547ba59a | ||
|
1b2ded3167 | ||
|
dcf20a472a | ||
|
7bd528defe | ||
|
9e6d123165 | ||
|
c592f51c83 | ||
|
fbb6f30366 | ||
|
4546c721fb | ||
|
3a659c9a81 | ||
|
e28a988eb3 | ||
|
a29742fe1f | ||
|
dd06838eec | ||
|
5eb828bff8 | ||
|
c7f3701053 | ||
|
ab6799442c | ||
|
1fe9bf7d76 | ||
|
bd14797da6 | ||
|
93b4e6a8d0 | ||
|
5566671971 | ||
|
defcc7a00c | ||
|
5183de634b | ||
|
7771b0311c |
203
.ci/php-cs-fixer/composer.lock
generated
203
.ci/php-cs-fixer/composer.lock
generated
@@ -151,16 +151,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
"version": "3.4.3",
|
"version": "3.4.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/semver.git",
|
"url": "https://github.com/composer/semver.git",
|
||||||
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
|
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
|
"url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||||
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
|
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -212,7 +212,7 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
"issues": "https://github.com/composer/semver/issues",
|
"issues": "https://github.com/composer/semver/issues",
|
||||||
"source": "https://github.com/composer/semver/tree/3.4.3"
|
"source": "https://github.com/composer/semver/tree/3.4.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -222,13 +222,9 @@
|
|||||||
{
|
{
|
||||||
"url": "https://github.com/composer",
|
"url": "https://github.com/composer",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-19T14:15:21+00:00"
|
"time": "2025-08-20T19:15:30+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/xdebug-handler",
|
"name": "composer/xdebug-handler",
|
||||||
@@ -406,16 +402,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "friendsofphp/php-cs-fixer",
|
"name": "friendsofphp/php-cs-fixer",
|
||||||
"version": "v3.86.0",
|
"version": "v3.87.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||||
"reference": "4a952bd19dc97879b0620f495552ef09b55f7d36"
|
"reference": "2f5170365e2a422d0c5421f9c8818b2c078105f6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4a952bd19dc97879b0620f495552ef09b55f7d36",
|
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2f5170365e2a422d0c5421f9c8818b2c078105f6",
|
||||||
"reference": "4a952bd19dc97879b0620f495552ef09b55f7d36",
|
"reference": "2f5170365e2a422d0c5421f9c8818b2c078105f6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -426,39 +422,38 @@
|
|||||||
"ext-hash": "*",
|
"ext-hash": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-tokenizer": "*",
|
"ext-tokenizer": "*",
|
||||||
"fidry/cpu-core-counter": "^1.2",
|
"fidry/cpu-core-counter": "^1.3",
|
||||||
"php": "^7.4 || ^8.0",
|
"php": "^7.4 || ^8.0",
|
||||||
"react/child-process": "^0.6.6",
|
"react/child-process": "^0.6.6",
|
||||||
"react/event-loop": "^1.5",
|
"react/event-loop": "^1.5",
|
||||||
"react/promise": "^3.2",
|
"react/promise": "^3.3",
|
||||||
"react/socket": "^1.16",
|
"react/socket": "^1.16",
|
||||||
"react/stream": "^1.4",
|
"react/stream": "^1.4",
|
||||||
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
|
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
|
||||||
"symfony/console": "^5.4.47 || ^6.4.13 || ^7.0",
|
"symfony/console": "^5.4.47 || ^6.4.24 || ^7.0",
|
||||||
"symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0",
|
"symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0",
|
||||||
"symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0",
|
"symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0",
|
||||||
"symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0",
|
"symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0",
|
||||||
"symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0",
|
"symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0",
|
||||||
"symfony/polyfill-mbstring": "^1.32",
|
"symfony/polyfill-mbstring": "^1.33",
|
||||||
"symfony/polyfill-php80": "^1.32",
|
"symfony/polyfill-php80": "^1.33",
|
||||||
"symfony/polyfill-php81": "^1.32",
|
"symfony/polyfill-php81": "^1.33",
|
||||||
"symfony/process": "^5.4.47 || ^6.4.20 || ^7.2",
|
"symfony/process": "^5.4.47 || ^6.4.24 || ^7.2",
|
||||||
"symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0"
|
"symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"facile-it/paraunit": "^1.3.1 || ^2.6",
|
"facile-it/paraunit": "^1.3.1 || ^2.7",
|
||||||
"infection/infection": "^0.29.14",
|
"infection/infection": "^0.29.14",
|
||||||
"justinrainbow/json-schema": "^5.3 || ^6.4",
|
"justinrainbow/json-schema": "^6.5",
|
||||||
"keradus/cli-executor": "^2.2",
|
"keradus/cli-executor": "^2.2",
|
||||||
"mikey179/vfsstream": "^1.6.12",
|
"mikey179/vfsstream": "^1.6.12",
|
||||||
"php-coveralls/php-coveralls": "^2.8",
|
"php-coveralls/php-coveralls": "^2.8",
|
||||||
"php-cs-fixer/accessible-object": "^1.1",
|
|
||||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
||||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
||||||
"phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25",
|
"phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34",
|
||||||
"symfony/polyfill-php84": "^1.32",
|
"symfony/polyfill-php84": "^1.33",
|
||||||
"symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1",
|
"symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2",
|
||||||
"symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1"
|
"symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-dom": "For handling output formats in XML",
|
"ext-dom": "For handling output formats in XML",
|
||||||
@@ -499,7 +494,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.86.0"
|
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.87.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -507,7 +502,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-08-13T22:36:21+00:00"
|
"time": "2025-09-02T15:27:36+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@@ -959,23 +954,23 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "react/promise",
|
"name": "react/promise",
|
||||||
"version": "v3.2.0",
|
"version": "v3.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/reactphp/promise.git",
|
"url": "https://github.com/reactphp/promise.git",
|
||||||
"reference": "8a164643313c71354582dc850b42b33fa12a4b63"
|
"reference": "23444f53a813a3296c1368bb104793ce8d88f04a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63",
|
"url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a",
|
||||||
"reference": "8a164643313c71354582dc850b42b33fa12a4b63",
|
"reference": "23444f53a813a3296c1368bb104793ce8d88f04a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1.0"
|
"php": ">=7.1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "1.10.39 || 1.4.10",
|
"phpstan/phpstan": "1.12.28 || 1.4.10",
|
||||||
"phpunit/phpunit": "^9.6 || ^7.5"
|
"phpunit/phpunit": "^9.6 || ^7.5"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
@@ -1020,7 +1015,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/reactphp/promise/issues",
|
"issues": "https://github.com/reactphp/promise/issues",
|
||||||
"source": "https://github.com/reactphp/promise/tree/v3.2.0"
|
"source": "https://github.com/reactphp/promise/tree/v3.3.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1028,7 +1023,7 @@
|
|||||||
"type": "open_collective"
|
"type": "open_collective"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-05-24T10:39:05+00:00"
|
"time": "2025-08-19T18:57:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "react/socket",
|
"name": "react/socket",
|
||||||
@@ -1257,16 +1252,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v7.3.2",
|
"version": "v7.3.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1"
|
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1",
|
"url": "https://api.github.com/repos/symfony/console/zipball/cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1",
|
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1331,7 +1326,7 @@
|
|||||||
"terminal"
|
"terminal"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v7.3.2"
|
"source": "https://github.com/symfony/console/tree/v7.3.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1351,7 +1346,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-07-30T17:13:41+00:00"
|
"time": "2025-08-25T06:35:40+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
@@ -1422,16 +1417,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher",
|
"name": "symfony/event-dispatcher",
|
||||||
"version": "v7.3.0",
|
"version": "v7.3.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||||
"reference": "497f73ac996a598c92409b44ac43b6690c4f666d"
|
"reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d",
|
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191",
|
||||||
"reference": "497f73ac996a598c92409b44ac43b6690c4f666d",
|
"reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1482,7 +1477,7 @@
|
|||||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0"
|
"source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1493,12 +1488,16 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-04-22T09:11:45+00:00"
|
"time": "2025-08-13T11:49:31+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher-contracts",
|
"name": "symfony/event-dispatcher-contracts",
|
||||||
@@ -1716,16 +1715,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/options-resolver",
|
"name": "symfony/options-resolver",
|
||||||
"version": "v7.3.2",
|
"version": "v7.3.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/options-resolver.git",
|
"url": "https://github.com/symfony/options-resolver.git",
|
||||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37"
|
"reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d",
|
||||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
"reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1763,7 +1762,7 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.2"
|
"source": "https://github.com/symfony/options-resolver/tree/v7.3.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1783,11 +1782,11 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-07-15T11:36:08+00:00"
|
"time": "2025-08-05T10:16:07+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.32.0",
|
"version": "v1.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
@@ -1846,7 +1845,7 @@
|
|||||||
"portable"
|
"portable"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0"
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1857,6 +1856,10 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
@@ -1866,16 +1869,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-grapheme",
|
"name": "symfony/polyfill-intl-grapheme",
|
||||||
"version": "v1.32.0",
|
"version": "v1.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||||
"reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe"
|
"reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70",
|
||||||
"reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
|
"reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1924,7 +1927,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
|
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1935,16 +1938,20 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
"time": "2025-06-27T09:58:17+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-normalizer",
|
"name": "symfony/polyfill-intl-normalizer",
|
||||||
"version": "v1.32.0",
|
"version": "v1.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||||
@@ -2005,7 +2012,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
|
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2016,6 +2023,10 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
@@ -2025,7 +2036,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.32.0",
|
"version": "v1.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
@@ -2086,7 +2097,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0"
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2097,6 +2108,10 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
@@ -2106,7 +2121,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
"version": "v1.32.0",
|
"version": "v1.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||||
@@ -2166,7 +2181,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0"
|
"source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2177,6 +2192,10 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
@@ -2186,7 +2205,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php81",
|
"name": "symfony/polyfill-php81",
|
||||||
"version": "v1.32.0",
|
"version": "v1.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||||
@@ -2242,7 +2261,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.32.0"
|
"source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2253,6 +2272,10 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
@@ -2262,16 +2285,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v7.3.0",
|
"version": "v7.3.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
|
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
|
"url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||||
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
|
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2303,7 +2326,7 @@
|
|||||||
"description": "Executes commands in sub-processes",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v7.3.0"
|
"source": "https://github.com/symfony/process/tree/v7.3.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2314,12 +2337,16 @@
|
|||||||
"url": "https://github.com/fabpot",
|
"url": "https://github.com/fabpot",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-04-17T09:11:12+00:00"
|
"time": "2025-08-18T09:42:54+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
@@ -2468,16 +2495,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/string",
|
"name": "symfony/string",
|
||||||
"version": "v7.3.2",
|
"version": "v7.3.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/string.git",
|
"url": "https://github.com/symfony/string.git",
|
||||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca"
|
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca",
|
"url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca",
|
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2535,7 +2562,7 @@
|
|||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/string/tree/v7.3.2"
|
"source": "https://github.com/symfony/string/tree/v7.3.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2555,7 +2582,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-07-10T08:47:49+00:00"
|
"time": "2025-08-25T06:35:40+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
parameters:
|
parameters:
|
||||||
scanFiles:
|
|
||||||
- ../_ide_helper.php
|
|
||||||
paths:
|
paths:
|
||||||
- ../app
|
- ../app
|
||||||
- ../database
|
- ../database
|
||||||
@@ -9,28 +7,24 @@ parameters:
|
|||||||
- ../bootstrap/app.php
|
- ../bootstrap/app.php
|
||||||
universalObjectCratesClasses:
|
universalObjectCratesClasses:
|
||||||
- Illuminate\Database\Eloquent\Model
|
- Illuminate\Database\Eloquent\Model
|
||||||
# TODO: slowly remove these parameters and fix the issues found.
|
|
||||||
reportUnmatchedIgnoredErrors: true
|
reportUnmatchedIgnoredErrors: true
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
# TODO: slowly remove these exceptions and fix the issues found.
|
# all errors below I will never fix.
|
||||||
- '#Dynamic call to static method#' # all the Laravel ORM things depend on this.
|
- '#expects view-string\|null, string given#'
|
||||||
- identifier: varTag.nativeType
|
- '#expects view-string, string given#'
|
||||||
- identifier: varTag.type
|
- "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
|
||||||
|
- identifier: missingType.generics # not interesting enough to fix.
|
||||||
-
|
-
|
||||||
identifier: larastan.noEnvCallsOutsideOfConfig
|
identifier: larastan.noEnvCallsOutsideOfConfig
|
||||||
path: ../app/Console/Commands/System/CreatesDatabase.php
|
path: ../app/Console/Commands/System/CreatesDatabase.php
|
||||||
- identifier: missingType.iterableValue # not interesting enough to fix.
|
- identifier: missingType.iterableValue # not interesting enough to fix.
|
||||||
- identifier: missingType.generics # not interesting enough to fix.
|
- identifier: varTag.type # needs a custom extension for every repository, not gonna happen.
|
||||||
- "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
|
- '#Dynamic call to static method Illuminate#'
|
||||||
- '#expects view-string, string given#'
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' # is custom scope
|
||||||
- '#expects view-string\|null, string given#'
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#' # is custom scope
|
||||||
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#' # is to allow soft delete
|
||||||
# phpstan can't handle this so we ignore them.
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#' # is a custom scope
|
||||||
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#'
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#' # is to allow soft delete
|
||||||
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#'
|
|
||||||
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#'
|
|
||||||
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#'
|
|
||||||
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#'
|
|
||||||
|
|
||||||
# The level 8 is the highest level. original was 5
|
# The level 8 is the highest level. original was 5
|
||||||
# 7 is more than enough, higher just leaves NULL things.
|
# 7 is more than enough, higher just leaves NULL things.
|
||||||
|
6
.github/label-actions.yml
vendored
6
.github/label-actions.yml
vendored
@@ -25,7 +25,7 @@ feature:
|
|||||||
|
|
||||||
This issue has been marked as a feature request.
|
This issue has been marked as a feature request.
|
||||||
|
|
||||||
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "I need this too" or "any updates?" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ epic:
|
|||||||
|
|
||||||
This issue has been marked as an epic. In epics, large amounts of works are collected that will be part of a major new feature. If you have more ideas that could be a part of this epic, feel free to reply.
|
This issue has been marked as an epic. In epics, large amounts of works are collected that will be part of a major new feature. If you have more ideas that could be a part of this epic, feel free to reply.
|
||||||
|
|
||||||
*However*, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted.
|
*However*, please be aware there is NO need to reply with "+1" or "I need this too" or "any updates?" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted.
|
||||||
|
|
||||||
If you are merely interested in this epic's progress, you can subscribe to this issue to get updates.
|
If you are merely interested in this epic's progress, you can subscribe to this issue to get updates.
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ enhancement:
|
|||||||
|
|
||||||
This issue has been marked as an enhancement.
|
This issue has been marked as an enhancement.
|
||||||
|
|
||||||
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "I need this too" or "any updates?" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
4
.github/release-notes/alpha.md
vendored
4
.github/release-notes/alpha.md
vendored
@@ -16,6 +16,10 @@ Alpha releases are created to test new features and fixes before they are includ
|
|||||||
|
|
||||||
The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
||||||
|
|
||||||
|
## Develop with Firefly III
|
||||||
|
|
||||||
|
Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III.
|
||||||
|
|
||||||
## Support Firefly III
|
## Support Firefly III
|
||||||
|
|
||||||
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
||||||
|
4
.github/release-notes/beta.md
vendored
4
.github/release-notes/beta.md
vendored
@@ -16,6 +16,10 @@ Alpha releases are created to test new features and fixes before they are includ
|
|||||||
|
|
||||||
The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
||||||
|
|
||||||
|
## Develop with Firefly III
|
||||||
|
|
||||||
|
Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III.
|
||||||
|
|
||||||
## Support Firefly III
|
## Support Firefly III
|
||||||
|
|
||||||
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
||||||
|
4
.github/release-notes/branch.md
vendored
4
.github/release-notes/branch.md
vendored
@@ -16,6 +16,10 @@ There is no changelog for this release, as it is not final. However, [changelog.
|
|||||||
|
|
||||||
The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
The release files are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
||||||
|
|
||||||
|
## Develop with Firefly III
|
||||||
|
|
||||||
|
Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III.
|
||||||
|
|
||||||
## Support Firefly III
|
## Support Firefly III
|
||||||
|
|
||||||
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
||||||
|
4
.github/release-notes/develop.md
vendored
4
.github/release-notes/develop.md
vendored
@@ -16,6 +16,10 @@ The changelog for this release may not be up-to-date, so it is not included. How
|
|||||||
|
|
||||||
The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
||||||
|
|
||||||
|
## Develop with Firefly III
|
||||||
|
|
||||||
|
Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III.
|
||||||
|
|
||||||
## Support Firefly III
|
## Support Firefly III
|
||||||
|
|
||||||
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
||||||
|
4
.github/release-notes/release.md
vendored
4
.github/release-notes/release.md
vendored
@@ -11,6 +11,10 @@ Welcome to release %version of Firefly III. It contains the latest fixes, transl
|
|||||||
|
|
||||||
The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/).
|
||||||
|
|
||||||
|
## Develop with Firefly III
|
||||||
|
|
||||||
|
Are you interested in (future) API changes to Firefly III, or other interesting dev-related updates? Sign up to the [Firefly III developer newsletter](https://firefly-iii.kit.com/dev) to receive low-frequency updates about the development of Firefly III.
|
||||||
|
|
||||||
## Support Firefly III
|
## Support Firefly III
|
||||||
|
|
||||||
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. Please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information. Thank you for your consideration.
|
||||||
|
4
.github/workflows/cleanup.yml
vendored
4
.github/workflows/cleanup.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- name: Prune cancelled/skipped runs
|
- name: Prune cancelled/skipped runs
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
- name: Prune runs older than 3 days
|
- name: Prune runs older than 3 days
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
|
2
.github/workflows/depsreview.yml
vendored
2
.github/workflows/depsreview.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout repository'
|
- name: 'Checkout repository'
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: 'Dependency review'
|
- name: 'Dependency review'
|
||||||
|
2
.github/workflows/lock.yml
vendored
2
.github/workflows/lock.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
discussions: write
|
discussions: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: JC5/lock-threads@v6.0.2
|
- uses: JC5/lock-threads@v6.0.6
|
||||||
with:
|
with:
|
||||||
issue-inactive-days: 21
|
issue-inactive-days: 21
|
||||||
pr-inactive-days: 21
|
pr-inactive-days: 21
|
||||||
|
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
|||||||
git pull
|
git pull
|
||||||
echo "Current branch is $(git branch --show-current)"
|
echo "Current branch is $(git branch --show-current)"
|
||||||
env:
|
env:
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
- name: Configure Git
|
- name: Configure Git
|
||||||
run: |
|
run: |
|
||||||
# do some configuration
|
# do some configuration
|
||||||
@@ -118,7 +118,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
FIREFLY_III_ROOT: /github/workspace
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
GH_TOKEN: ""
|
GH_TOKEN: ""
|
||||||
FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
- name: Generate JSON v1
|
- name: Generate JSON v1
|
||||||
id: json-v1
|
id: json-v1
|
||||||
uses: JC5/firefly-iii-dev@main
|
uses: JC5/firefly-iii-dev@main
|
||||||
@@ -221,7 +221,7 @@ jobs:
|
|||||||
echo "tarName=$tarName" >> "$GITHUB_ENV"
|
echo "tarName=$tarName" >> "$GITHUB_ENV"
|
||||||
echo "BRANCH_NAME=$BRANCH_NAME" >> "$GITHUB_ENV"
|
echo "BRANCH_NAME=$BRANCH_NAME" >> "$GITHUB_ENV"
|
||||||
env:
|
env:
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
- name: Commit all changes
|
- name: Commit all changes
|
||||||
run: |
|
run: |
|
||||||
# add all content, except output.txt (this contains the changelog and/or the download instructions)
|
# add all content, except output.txt (this contains the changelog and/or the download instructions)
|
||||||
@@ -232,12 +232,12 @@ jobs:
|
|||||||
git commit -m "🤖 Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
|
git commit -m "🤖 Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
|
||||||
git push
|
git push
|
||||||
env:
|
env:
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
- name: Generate release description
|
- name: Generate release description
|
||||||
id: release-description
|
id: release-description
|
||||||
uses: JC5/firefly-iii-dev@main
|
uses: JC5/firefly-iii-dev@main
|
||||||
with:
|
with:
|
||||||
action: "ff3:generate-release-notes firefly-iii ${{ github.event.inputs.version }}"
|
action: "ff3:generate-release-notes firefly-iii ${{ inputs.version || 'develop' }}"
|
||||||
output: 'output'
|
output: 'output'
|
||||||
env:
|
env:
|
||||||
FIREFLY_III_ROOT: /github/workspace
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
@@ -250,7 +250,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Merge all changes from $BRANCH_NAME back into '$MERGE_INTO' using a PR"
|
echo "Merge all changes from $BRANCH_NAME back into '$MERGE_INTO' using a PR"
|
||||||
PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 Created by GitHub action')
|
PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 This PR was created automatically by a GitHub action to merge the changed files into this branch. It will be merged automatically. `Share and enjoy`')
|
||||||
echo "PR URL is '$PR_URL'"
|
echo "PR URL is '$PR_URL'"
|
||||||
IFS='/' read -ra parts <<< "$PR_URL"
|
IFS='/' read -ra parts <<< "$PR_URL"
|
||||||
PR_NR=$(printf %s\\n "${parts[@]:(-1)}")
|
PR_NR=$(printf %s\\n "${parts[@]:(-1)}")
|
||||||
@@ -272,7 +272,7 @@ jobs:
|
|||||||
|
|
||||||
echo "Also merge everything into main since this is a release."
|
echo "Also merge everything into main since this is a release."
|
||||||
echo 'create PR'
|
echo 'create PR'
|
||||||
PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body "🤖 Created by GitHub action")
|
PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body "🤖 This PR was created automatically by a GitHub action to merge the changed files into this branch. It will be merged automatically. `Share and enjoy`")
|
||||||
echo "PR URL is '$PR_URL'"
|
echo "PR URL is '$PR_URL'"
|
||||||
|
|
||||||
IFS='/' read -ra parts <<< "$PR_URL"
|
IFS='/' read -ra parts <<< "$PR_URL"
|
||||||
@@ -291,7 +291,7 @@ jobs:
|
|||||||
echo "DONE!"
|
echo "DONE!"
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
- name: Create archives
|
- name: Create archives
|
||||||
run: |
|
run: |
|
||||||
echo "Create zip file $zipName"
|
echo "Create zip file $zipName"
|
||||||
@@ -375,7 +375,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
run: |
|
run: |
|
||||||
# add zip file to release.
|
# add zip file to release.
|
||||||
@@ -411,4 +411,4 @@ jobs:
|
|||||||
rm -f $tarName.sha256
|
rm -f $tarName.sha256
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || inputs.version }}
|
||||||
|
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
actions: write
|
actions: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
stale-issue-message: |
|
stale-issue-message: |
|
||||||
|
@@ -114,6 +114,7 @@ class AccountController extends Controller
|
|||||||
'id' => (string) $account->id,
|
'id' => (string) $account->id,
|
||||||
'name' => $account->name,
|
'name' => $account->name,
|
||||||
'name_with_balance' => $nameWithBalance,
|
'name_with_balance' => $nameWithBalance,
|
||||||
|
'active' => $account->active,
|
||||||
'type' => $account->accountType->type,
|
'type' => $account->accountType->type,
|
||||||
'currency_id' => (string) $useCurrency->id,
|
'currency_id' => (string) $useCurrency->id,
|
||||||
'currency_name' => $useCurrency->name,
|
'currency_name' => $useCurrency->name,
|
||||||
|
@@ -67,8 +67,9 @@ class BudgetController extends Controller
|
|||||||
$result = $this->repository->searchBudget($data['query'], $this->parameters->get('limit'));
|
$result = $this->repository->searchBudget($data['query'], $this->parameters->get('limit'));
|
||||||
$filtered = $result->map(
|
$filtered = $result->map(
|
||||||
static fn (Budget $item) => [
|
static fn (Budget $item) => [
|
||||||
'id' => (string) $item->id,
|
'id' => (string) $item->id,
|
||||||
'name' => $item->name,
|
'name' => $item->name,
|
||||||
|
'active' => $item->active,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -69,6 +69,7 @@ class RecurrenceController extends Controller
|
|||||||
'id' => (string) $recurrence->id,
|
'id' => (string) $recurrence->id,
|
||||||
'name' => $recurrence->title,
|
'name' => $recurrence->title,
|
||||||
'description' => $recurrence->description,
|
'description' => $recurrence->description,
|
||||||
|
'active' => $recurrence->active,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,7 +37,7 @@ use Illuminate\Http\JsonResponse;
|
|||||||
class RuleController extends Controller
|
class RuleController extends Controller
|
||||||
{
|
{
|
||||||
private RuleRepositoryInterface $repository;
|
private RuleRepositoryInterface $repository;
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_RULES];
|
protected array $acceptedRoles = [UserRoleEnum::READ_RULES];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RuleController constructor.
|
* RuleController constructor.
|
||||||
@@ -66,9 +66,10 @@ class RuleController extends Controller
|
|||||||
/** @var Rule $rule */
|
/** @var Rule $rule */
|
||||||
foreach ($rules as $rule) {
|
foreach ($rules as $rule) {
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string) $rule->id,
|
'id' => (string)$rule->id,
|
||||||
'name' => $rule->title,
|
'name' => $rule->title,
|
||||||
'description' => $rule->description,
|
'description' => $rule->description,
|
||||||
|
'active' => $rule->active,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -69,6 +69,7 @@ class RuleGroupController extends Controller
|
|||||||
'id' => (string) $group->id,
|
'id' => (string) $group->id,
|
||||||
'name' => $group->title,
|
'name' => $group->title,
|
||||||
'description' => $group->description,
|
'description' => $group->description,
|
||||||
|
'active' => $group->active,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,8 +49,6 @@ class TransactionTypeController extends Controller
|
|||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
$this->validateUserGroup($request);
|
$this->validateUserGroup($request);
|
||||||
$this->repository = app(TransactionTypeRepositoryInterface::class);
|
$this->repository = app(TransactionTypeRepositoryInterface::class);
|
||||||
$this->repository->setUser($this->user);
|
|
||||||
$this->repository->setUserGroup($this->userGroup);
|
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
@@ -130,6 +130,7 @@ class AccountController extends Controller
|
|||||||
'yAxisID' => 0,
|
'yAxisID' => 0,
|
||||||
'period' => '1D',
|
'period' => '1D',
|
||||||
'entries' => [],
|
'entries' => [],
|
||||||
|
'pc_entries' => [],
|
||||||
];
|
];
|
||||||
if ($this->convertToPrimary) {
|
if ($this->convertToPrimary) {
|
||||||
$currentSet['pc_entries'] = [];
|
$currentSet['pc_entries'] = [];
|
||||||
|
@@ -1,5 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BalanceController.php
|
||||||
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Api\V1\Controllers\Chart;
|
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||||
|
@@ -31,10 +31,10 @@ use FireflyIII\Enums\UserRoleEnum;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\BudgetLimit;
|
use FireflyIII\Models\BudgetLimit;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
|
||||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
@@ -55,7 +55,6 @@ class BudgetController extends Controller
|
|||||||
protected OperationsRepositoryInterface $opsRepository;
|
protected OperationsRepositoryInterface $opsRepository;
|
||||||
private BudgetLimitRepositoryInterface $blRepository;
|
private BudgetLimitRepositoryInterface $blRepository;
|
||||||
private array $currencies = [];
|
private array $currencies = [];
|
||||||
private TransactionCurrency $currency;
|
|
||||||
private BudgetRepositoryInterface $repository;
|
private BudgetRepositoryInterface $repository;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
@@ -134,9 +133,9 @@ class BudgetController extends Controller
|
|||||||
$row['pc_left'] = '0';
|
$row['pc_left'] = '0';
|
||||||
$row['pc_overspent'] = '0';
|
$row['pc_overspent'] = '0';
|
||||||
|
|
||||||
if (null !== $limit) {
|
if ($limit instanceof BudgetLimit) {
|
||||||
$row['budgeted'] = $limit->amount;
|
$row['budgeted'] = $limit->amount;
|
||||||
$row['left'] = bcsub($row['budgeted'], bcmul($row['spent'], '-1'));
|
$row['left'] = bcsub((string) $row['budgeted'], bcmul((string) $row['spent'], '-1'));
|
||||||
$row['overspent'] = bcmul($row['left'], '-1');
|
$row['overspent'] = bcmul($row['left'], '-1');
|
||||||
$row['left'] = 1 === bccomp($row['left'], '0') ? $row['left'] : '0';
|
$row['left'] = 1 === bccomp($row['left'], '0') ? $row['left'] : '0';
|
||||||
$row['overspent'] = 1 === bccomp($row['overspent'], '0') ? $row['overspent'] : '0';
|
$row['overspent'] = 1 === bccomp($row['overspent'], '0') ? $row['overspent'] : '0';
|
||||||
@@ -144,7 +143,7 @@ class BudgetController extends Controller
|
|||||||
|
|
||||||
// convert data if necessary.
|
// convert data if necessary.
|
||||||
if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) {
|
if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) {
|
||||||
$currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
|
$currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
|
||||||
$row['pc_budgeted'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']);
|
$row['pc_budgeted'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']);
|
||||||
$row['pc_spent'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']);
|
$row['pc_spent'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']);
|
||||||
$row['pc_left'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']);
|
$row['pc_left'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']);
|
||||||
@@ -201,18 +200,18 @@ class BudgetController extends Controller
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* When no budget limits are present, the expenses of the whole period are collected and grouped.
|
// * When no budget limits are present, the expenses of the whole period are collected and grouped.
|
||||||
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
// * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||||
*
|
// *
|
||||||
* @throws FireflyException
|
// * @throws FireflyException
|
||||||
*/
|
// */
|
||||||
private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
// private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
||||||
{
|
// {
|
||||||
$spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
// $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||||
|
//
|
||||||
return $this->processExpenses($budget->id, $spent, $start, $end);
|
// return $this->processExpenses($budget->id, $spent, $start, $end);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
|
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
|
||||||
@@ -232,7 +231,7 @@ class BudgetController extends Controller
|
|||||||
* @var array $block
|
* @var array $block
|
||||||
*/
|
*/
|
||||||
foreach ($spent as $currencyId => $block) {
|
foreach ($spent as $currencyId => $block) {
|
||||||
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
|
$this->currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
|
||||||
$return[$currencyId] ??= [
|
$return[$currencyId] ??= [
|
||||||
'currency_id' => (string)$currencyId,
|
'currency_id' => (string)$currencyId,
|
||||||
'currency_code' => $block['currency_code'],
|
'currency_code' => $block['currency_code'],
|
||||||
@@ -251,66 +250,68 @@ class BudgetController extends Controller
|
|||||||
// var_dump($return);
|
// var_dump($return);
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
||||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string)$journal['amount']);
|
/** @var numeric-string $amount */
|
||||||
|
$amount = (string)$journal['amount'];
|
||||||
|
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Function that processes each budget limit (per budget).
|
// * Function that processes each budget limit (per budget).
|
||||||
*
|
// *
|
||||||
* If you have a budget limit in EUR, only transactions in EUR will be considered.
|
// * If you have a budget limit in EUR, only transactions in EUR will be considered.
|
||||||
* If you have a budget limit in GBP, only transactions in GBP will be considered.
|
// * If you have a budget limit in GBP, only transactions in GBP will be considered.
|
||||||
*
|
// *
|
||||||
* If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
// * If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
||||||
*
|
// *
|
||||||
* @throws FireflyException
|
// * @throws FireflyException
|
||||||
*/
|
// */
|
||||||
private function budgetLimits(Budget $budget, Collection $limits): array
|
// private function budgetLimits(Budget $budget, Collection $limits): array
|
||||||
{
|
// {
|
||||||
Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
// Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
||||||
$data = [];
|
// $data = [];
|
||||||
|
//
|
||||||
|
// /** @var BudgetLimit $limit */
|
||||||
|
// foreach ($limits as $limit) {
|
||||||
|
// $data = array_merge($data, $this->processLimit($budget, $limit));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return $data;
|
||||||
|
// }
|
||||||
|
|
||||||
/** @var BudgetLimit $limit */
|
// /**
|
||||||
foreach ($limits as $limit) {
|
// * @throws FireflyException
|
||||||
$data = array_merge($data, $this->processLimit($budget, $limit));
|
// */
|
||||||
}
|
// private function processLimit(Budget $budget, BudgetLimit $limit): array
|
||||||
|
// {
|
||||||
return $data;
|
// Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
|
||||||
}
|
// $end = clone $limit->end_date;
|
||||||
|
// $end->endOfDay();
|
||||||
/**
|
// $spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||||
* @throws FireflyException
|
// $limitCurrencyId = $limit->transaction_currency_id;
|
||||||
*/
|
//
|
||||||
private function processLimit(Budget $budget, BudgetLimit $limit): array
|
// /** @var array $entry */
|
||||||
{
|
// // only spent the entry where the entry's currency matches the budget limit's currency
|
||||||
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
|
// // so $filtered will only have 1 or 0 entries
|
||||||
$end = clone $limit->end_date;
|
// $filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId);
|
||||||
$end->endOfDay();
|
// $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||||
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
// if (1 === count($result)) {
|
||||||
$limitCurrencyId = $limit->transaction_currency_id;
|
// $compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||||
|
// $result[$limitCurrencyId]['budgeted'] = $limit->amount;
|
||||||
/** @var array $entry */
|
// if (1 === $compare) {
|
||||||
// only spent the entry where the entry's currency matches the budget limit's currency
|
// // convert this amount into the primary currency:
|
||||||
// so $filtered will only have 1 or 0 entries
|
// $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']);
|
||||||
$filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId);
|
// }
|
||||||
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
// if ($compare <= 0) {
|
||||||
if (1 === count($result)) {
|
// $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
|
||||||
$compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent']));
|
// }
|
||||||
$result[$limitCurrencyId]['budgeted'] = $limit->amount;
|
// }
|
||||||
if (1 === $compare) {
|
//
|
||||||
// convert this amount into the primary currency:
|
// return $result;
|
||||||
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']);
|
// }
|
||||||
}
|
|
||||||
if ($compare <= 0) {
|
|
||||||
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
|
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
|
||||||
{
|
{
|
||||||
|
@@ -97,22 +97,23 @@ class CategoryController extends Controller
|
|||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setRange($start, $end)->withAccountInformation();
|
$collector->setRange($start, $end)->withAccountInformation();
|
||||||
$collector->setXorAccounts($accounts)->withCategoryInformation();
|
$collector->setXorAccounts($accounts)->withCategoryInformation();
|
||||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::RECONCILIATION->value]);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value]);
|
||||||
$journals = $collector->getExtractedJournals();
|
$journals = $collector->getExtractedJournals();
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
// find journal:
|
// find journal:
|
||||||
$journalCurrencyId = (int)$journal['currency_id'];
|
$journalCurrencyId = (int)$journal['currency_id'];
|
||||||
$currency = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId);
|
$type = $journal['transaction_type_type'];
|
||||||
$currencies[$journalCurrencyId] = $currency;
|
$currency = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId);
|
||||||
$currencyId = (int)$currency->id;
|
$currencies[$journalCurrencyId] = $currency;
|
||||||
$currencyName = (string)$currency->name;
|
$currencyId = (int)$currency->id;
|
||||||
$currencyCode = (string)$currency->code;
|
$currencyName = (string)$currency->name;
|
||||||
$currencySymbol = (string)$currency->symbol;
|
$currencyCode = (string)$currency->code;
|
||||||
$currencyDecimalPlaces = (int)$currency->decimal_places;
|
$currencySymbol = (string)$currency->symbol;
|
||||||
$amount = Steam::positive($journal['amount']);
|
$currencyDecimalPlaces = (int)$currency->decimal_places;
|
||||||
$pcAmount = null;
|
$amount = Steam::positive((string)$journal['amount']);
|
||||||
|
$pcAmount = null;
|
||||||
|
|
||||||
// overrule if necessary:
|
// overrule if necessary:
|
||||||
if ($this->convertToPrimary && $journalCurrencyId === $this->primaryCurrency->id) {
|
if ($this->convertToPrimary && $journalCurrencyId === $this->primaryCurrency->id) {
|
||||||
@@ -129,8 +130,8 @@ class CategoryController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$categoryName = $journal['category_name'] ?? (string)trans('firefly.no_category');
|
$categoryName = $journal['category_name'] ?? (string)trans('firefly.no_category');
|
||||||
$key = sprintf('%s-%s', $categoryName, $currencyCode);
|
$key = sprintf('%s-%s', $categoryName, $currencyCode);
|
||||||
// create arrays
|
// create arrays
|
||||||
$return[$key] ??= [
|
$return[$key] ??= [
|
||||||
'label' => $categoryName,
|
'label' => $categoryName,
|
||||||
@@ -150,23 +151,37 @@ class CategoryController extends Controller
|
|||||||
'yAxisID' => 0,
|
'yAxisID' => 0,
|
||||||
'type' => 'bar',
|
'type' => 'bar',
|
||||||
'entries' => [
|
'entries' => [
|
||||||
'spent' => '0',
|
'spent' => '0',
|
||||||
|
'earned' => '0',
|
||||||
],
|
],
|
||||||
'pc_entries' => [
|
'pc_entries' => [
|
||||||
'spent' => '0',
|
'spent' => '0',
|
||||||
|
'earned' => '0',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// add monies
|
// add monies
|
||||||
$return[$key]['entries']['spent'] = bcadd($return[$key]['entries']['spent'], (string)$amount);
|
// expenses to spent
|
||||||
if (null !== $pcAmount) {
|
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||||
$return[$key]['pc_entries']['spent'] = bcadd($return[$key]['pc_entries']['spent'], (string)$pcAmount);
|
$return[$key]['entries']['spent'] = bcadd($return[$key]['entries']['spent'], $amount);
|
||||||
|
if (null !== $pcAmount) {
|
||||||
|
$return[$key]['pc_entries']['spent'] = bcadd($return[$key]['pc_entries']['spent'], $pcAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// positive amount = earned
|
||||||
|
if (TransactionTypeEnum::DEPOSIT->value === $type) {
|
||||||
|
$return[$key]['entries']['earned'] = bcadd($return[$key]['entries']['earned'], $amount);
|
||||||
|
if (null !== $pcAmount) {
|
||||||
|
$return[$key]['pc_entries']['earned'] = bcadd($return[$key]['pc_entries']['earned'], $pcAmount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$return = array_values($return);
|
$return = array_values($return);
|
||||||
|
|
||||||
// order by amount
|
// order by amount
|
||||||
usort($return, static fn (array $a, array $b) => (float)$a['entries']['spent'] < (float)$b['entries']['spent'] ? 1 : -1);
|
usort($return, static fn (array $a, array $b) => ((float)$a['entries']['spent'] + (float)$a['entries']['earned']) < ((float)$b['entries']['spent'] + (float)$b['entries']['earned']) ? 1 : -1);
|
||||||
|
|
||||||
return response()->json($this->clean($return));
|
return response()->json($this->clean($return));
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,6 @@ namespace FireflyIII\Api\V1\Controllers;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Carbon\Exceptions\InvalidFormatException;
|
use Carbon\Exceptions\InvalidFormatException;
|
||||||
use FireflyIII\Exceptions\BadHttpHeaderException;
|
use FireflyIII\Exceptions\BadHttpHeaderException;
|
||||||
use FireflyIII\Models\Preference;
|
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
@@ -66,8 +65,6 @@ abstract class Controller extends BaseController
|
|||||||
protected const string JSON_CONTENT_TYPE = 'application/json';
|
protected const string JSON_CONTENT_TYPE = 'application/json';
|
||||||
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
||||||
|
|
||||||
/** @var array<int, string> */
|
|
||||||
protected array $allowedSort;
|
|
||||||
protected bool $convertToPrimary = false;
|
protected bool $convertToPrimary = false;
|
||||||
protected TransactionCurrency $primaryCurrency;
|
protected TransactionCurrency $primaryCurrency;
|
||||||
protected ParameterBag $parameters;
|
protected ParameterBag $parameters;
|
||||||
@@ -78,7 +75,6 @@ abstract class Controller extends BaseController
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
// get global parameters
|
// get global parameters
|
||||||
$this->allowedSort = config('firefly.allowed_sort_parameters');
|
|
||||||
$this->middleware(
|
$this->middleware(
|
||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
$this->parameters = $this->getParameters();
|
$this->parameters = $this->getParameters();
|
||||||
@@ -108,12 +104,7 @@ abstract class Controller extends BaseController
|
|||||||
{
|
{
|
||||||
$bag = new ParameterBag();
|
$bag = new ParameterBag();
|
||||||
$page = (int)request()->get('page');
|
$page = (int)request()->get('page');
|
||||||
if ($page < 1) {
|
$page = min(max(1, $page), 2 ** 16);
|
||||||
$page = 1;
|
|
||||||
}
|
|
||||||
if ($page > 2 ** 16) {
|
|
||||||
$page = 2 ** 16;
|
|
||||||
}
|
|
||||||
$bag->set('page', $page);
|
$bag->set('page', $page);
|
||||||
|
|
||||||
// some date fields:
|
// some date fields:
|
||||||
@@ -131,19 +122,15 @@ abstract class Controller extends BaseController
|
|||||||
$obj = null;
|
$obj = null;
|
||||||
if (null !== $date) {
|
if (null !== $date) {
|
||||||
try {
|
try {
|
||||||
$obj = Carbon::parse((string)$date);
|
$obj = Carbon::parse((string)$date, config('app.timezone'));
|
||||||
} catch (InvalidFormatException $e) {
|
} catch (InvalidFormatException $e) {
|
||||||
// don't care
|
// don't care
|
||||||
Log::warning(
|
Log::warning(sprintf('Ignored invalid date "%s" in API controller parameter check: %s', substr((string)$date, 0, 20), $e->getMessage()));
|
||||||
sprintf(
|
|
||||||
'Ignored invalid date "%s" in API controller parameter check: %s',
|
|
||||||
substr((string)$date, 0, 20),
|
|
||||||
$e->getMessage()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$bag->set($field, $obj);
|
if ($obj instanceof Carbon) {
|
||||||
|
$bag->set($field, $obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// integer fields:
|
// integer fields:
|
||||||
@@ -159,13 +146,7 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
if (null !== $value) {
|
if (null !== $value) {
|
||||||
$value = (int)$value;
|
$value = (int)$value;
|
||||||
if ($value < 1) {
|
$value = min(max(1, $value), 2 ** 16);
|
||||||
$value = 1;
|
|
||||||
}
|
|
||||||
if ($value > 2 ** 16) {
|
|
||||||
$value = 2 ** 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
$bag->set($integer, $value);
|
$bag->set($integer, $value);
|
||||||
}
|
}
|
||||||
if (null === $value
|
if (null === $value
|
||||||
@@ -175,46 +156,14 @@ abstract class Controller extends BaseController
|
|||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
/** @var Preference $pageSize */
|
|
||||||
$pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data;
|
$pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data;
|
||||||
$bag->set($integer, $pageSize);
|
$bag->set($integer, $pageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort fields:
|
// sort fields:
|
||||||
return $this->getSortParameters($bag);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getSortParameters(ParameterBag $bag): ParameterBag
|
|
||||||
{
|
|
||||||
$sortParameters = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$param = (string)request()->query->get('sort');
|
|
||||||
} catch (BadRequestException $e) {
|
|
||||||
Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.');
|
|
||||||
Log::error($e->getMessage());
|
|
||||||
Log::error($e->getTraceAsString());
|
|
||||||
$param = '';
|
|
||||||
}
|
|
||||||
if ('' === $param) {
|
|
||||||
return $bag;
|
|
||||||
}
|
|
||||||
$parts = explode(',', $param);
|
|
||||||
foreach ($parts as $part) {
|
|
||||||
$part = trim($part);
|
|
||||||
$direction = 'asc';
|
|
||||||
if ('-' === $part[0]) {
|
|
||||||
$part = substr($part, 1);
|
|
||||||
$direction = 'desc';
|
|
||||||
}
|
|
||||||
if (in_array($part, $this->allowedSort, true)) {
|
|
||||||
$sortParameters[] = [$part, $direction];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$bag->set('sort', $sortParameters);
|
|
||||||
|
|
||||||
return $bag;
|
return $bag;
|
||||||
|
// return $this->getSortParameters($bag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
|||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +72,7 @@ class PeriodController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +98,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -148,7 +149,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $journal['currency_code'],
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount']));
|
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], Steam::positive($journal['amount']));
|
||||||
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,10 +161,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $foreignCurrencyId,
|
'currency_id' => (string) $foreignCurrencyId,
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
'currency_code' => $journal['foreign_currency_code'],
|
||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd(
|
$response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
|
||||||
(string) $response[$foreignKey]['difference'],
|
|
||||||
(string) app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
|
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
|||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +72,7 @@ class PeriodController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,7 +96,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -146,7 +147,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $journal['currency_code'],
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount']));
|
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], Steam::positive($journal['amount']));
|
||||||
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ class TagController extends Controller
|
|||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd(
|
$response[$foreignKey]['difference'] = bcadd(
|
||||||
(string) $response[$foreignKey]['difference'],
|
(string) $response[$foreignKey]['difference'],
|
||||||
(string) app('steam')->positive($journal['foreign_amount'])
|
Steam::positive($journal['foreign_amount'])
|
||||||
);
|
);
|
||||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
|
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V1\Controllers\Models\Account;
|
namespace FireflyIII\Api\V1\Controllers\Models\Account;
|
||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V1\Requests\Models\Account\ShowRequest;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
@@ -33,7 +34,6 @@ use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
|||||||
use FireflyIII\Transformers\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
@@ -71,34 +71,38 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(Request $request): JsonResponse
|
public function index(ShowRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$type = $request->get('type') ?? 'all';
|
$params = $request->getParameters();
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $params['type']);
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$types = $this->mapAccountTypes($this->parameters->get('type'));
|
$types = $this->mapAccountTypes($params['type']);
|
||||||
$pageSize = $this->parameters->get('limit');
|
|
||||||
|
|
||||||
// get list of accounts. Count it and split it.
|
// get list of accounts. Count it and split it.
|
||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
$collection = $this->repository->getAccountsByType($types, $this->parameters->get('sort') ?? []);
|
$collection = $this->repository->getAccountsByType($types, $params['sort']);
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
|
|
||||||
// continue sort:
|
// continue sort:
|
||||||
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
// TODO if the user sorts on DB dependent field there must be no slice before enrichment, only after.
|
||||||
|
// TODO still need to figure out how to do this easily.
|
||||||
|
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $params['limit'], $params['limit']);
|
||||||
|
|
||||||
// enrich
|
// enrich
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setSort($params['sort']);
|
||||||
$enrichment->setDate($this->parameters->get('date'));
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
|
$enrichment->setStart($this->parameters->get('start'));
|
||||||
|
$enrichment->setEnd($this->parameters->get('end'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($accounts, $count, $params['limit'], $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
|
$paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
|
||||||
|
|
||||||
/** @var AccountTransformer $transformer */
|
/** @var AccountTransformer $transformer */
|
||||||
@@ -117,7 +121,7 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Show single instance.
|
* Show single instance.
|
||||||
*/
|
*/
|
||||||
public function show(Account $account): JsonResponse
|
public function show(ShowRequest $request, Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
// get list of accounts. Count it and split it.
|
// get list of accounts. Count it and split it.
|
||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
@@ -129,6 +133,8 @@ class ShowController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setDate($this->parameters->get('date'));
|
$enrichment->setDate($this->parameters->get('date'));
|
||||||
|
$enrichment->setStart($this->parameters->get('start'));
|
||||||
|
$enrichment->setEnd($this->parameters->get('end'));
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -114,8 +114,8 @@ class ShowController extends Controller
|
|||||||
public function show(AvailableBudget $availableBudget): JsonResponse
|
public function show(AvailableBudget $availableBudget): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$start = $this->parameters->get('start');
|
// $start = $this->parameters->get('start');
|
||||||
$end = $this->parameters->get('end');
|
// $end = $this->parameters->get('end');
|
||||||
|
|
||||||
/** @var AvailableBudgetTransformer $transformer */
|
/** @var AvailableBudgetTransformer $transformer */
|
||||||
$transformer = app(AvailableBudgetTransformer::class);
|
$transformer = app(AvailableBudgetTransformer::class);
|
||||||
@@ -126,8 +126,8 @@ class ShowController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AvailableBudgetEnrichment();
|
$enrichment = new AvailableBudgetEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setStart($start);
|
// $enrichment->setStart($start);
|
||||||
$enrichment->setEnd($end);
|
// $enrichment->setEnd($end);
|
||||||
$availableBudget = $enrichment->enrichSingle($availableBudget);
|
$availableBudget = $enrichment->enrichSingle($availableBudget);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -84,6 +84,8 @@ class ShowController extends Controller
|
|||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setStart($this->parameters->get('start'));
|
$enrichment->setStart($this->parameters->get('start'));
|
||||||
$enrichment->setEnd($this->parameters->get('end'));
|
$enrichment->setEnd($this->parameters->get('end'));
|
||||||
|
|
||||||
|
/** @var Budget $budget */
|
||||||
$budget = $enrichment->enrichSingle($budget);
|
$budget = $enrichment->enrichSingle($budget);
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +98,6 @@ class ShowController extends Controller
|
|||||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]).$this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]).$this->buildParams());
|
||||||
|
|
||||||
|
|
||||||
// enrich
|
// enrich
|
||||||
$enrichment = new BudgetLimitEnrichment();
|
$enrichment = new BudgetLimitEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
|
@@ -86,7 +86,7 @@ class UpdateController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new BudgetLimitEnrichment();
|
$enrichment = new BudgetLimitEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$budgetLimit = $enrichment->enrich($budgetLimit);
|
$budgetLimit = $enrichment->enrichSingle($budgetLimit);
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
|
@@ -33,6 +33,7 @@ use FireflyIII\Enums\UserRoleEnum;
|
|||||||
use FireflyIII\Models\CurrencyExchangeRate;
|
use FireflyIII\Models\CurrencyExchangeRate;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\ExchangeRateTransformer;
|
use FireflyIII\Transformers\ExchangeRateTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@@ -69,7 +70,7 @@ class StoreController extends Controller
|
|||||||
foreach ($data as $date => $rate) {
|
foreach ($data as $date => $rate) {
|
||||||
$date = Carbon::createFromFormat('Y-m-d', $date);
|
$date = Carbon::createFromFormat('Y-m-d', $date);
|
||||||
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||||
if (null !== $existing) {
|
if ($existing instanceof CurrencyExchangeRate) {
|
||||||
// update existing rate.
|
// update existing rate.
|
||||||
$existing = $this->repository->updateExchangeRate($existing, $rate);
|
$existing = $this->repository->updateExchangeRate($existing, $rate);
|
||||||
$collection->push($existing);
|
$collection->push($existing);
|
||||||
@@ -98,12 +99,9 @@ class StoreController extends Controller
|
|||||||
$from = $request->getFromCurrency();
|
$from = $request->getFromCurrency();
|
||||||
$collection = new Collection();
|
$collection = new Collection();
|
||||||
foreach ($data['rates'] as $key => $rate) {
|
foreach ($data['rates'] as $key => $rate) {
|
||||||
$to = TransactionCurrency::where('code', $key)->first();
|
$to = Amount::getTransactionCurrencyByCode($key);
|
||||||
if (null === $to) {
|
|
||||||
continue; // should not happen.
|
|
||||||
}
|
|
||||||
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||||
if (null !== $existing) {
|
if ($existing instanceof CurrencyExchangeRate) {
|
||||||
// update existing rate.
|
// update existing rate.
|
||||||
$existing = $this->repository->updateExchangeRate($existing, $rate);
|
$existing = $this->repository->updateExchangeRate($existing, $rate);
|
||||||
$collection->push($existing);
|
$collection->push($existing);
|
||||||
|
126
app/Api/V1/Controllers/Models/Recurrence/TriggerController.php
Normal file
126
app/Api/V1/Controllers/Models/Recurrence/TriggerController.php
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/*
|
||||||
|
* TriggerController.php
|
||||||
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Controllers\Models\Recurrence;
|
||||||
|
|
||||||
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V1\Requests\Generic\SingleDateRequest;
|
||||||
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
|
use FireflyIII\Jobs\CreateRecurringTransactions;
|
||||||
|
use FireflyIII\Models\Recurrence;
|
||||||
|
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Preferences;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||||
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
|
|
||||||
|
class TriggerController extends Controller
|
||||||
|
{
|
||||||
|
private RecurringRepositoryInterface $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RecurrenceController constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
$this->repository = app(RecurringRepositoryInterface::class);
|
||||||
|
$this->repository->setUser(auth()->user());
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function trigger(SingleDateRequest $request, Recurrence $recurrence): JsonResponse
|
||||||
|
{
|
||||||
|
// find recurrence occurrence for this date and trigger it.
|
||||||
|
// grab the date from the last time the recurrence fired:
|
||||||
|
$backupDate = $recurrence->latest_date;
|
||||||
|
$date = $request->getDate();
|
||||||
|
|
||||||
|
// fire the recurring cron job on the given date, then post-date the created transaction.
|
||||||
|
Log::info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s')));
|
||||||
|
|
||||||
|
/** @var CreateRecurringTransactions $job */
|
||||||
|
$job = app(CreateRecurringTransactions::class);
|
||||||
|
$job->setRecurrences(new Collection()->push($recurrence));
|
||||||
|
$job->setDate($date);
|
||||||
|
$job->setForce(false);
|
||||||
|
$job->handle();
|
||||||
|
Log::debug('Done with recurrence.');
|
||||||
|
|
||||||
|
$groups = $job->getGroups();
|
||||||
|
$this->repository->markGroupsAsNow($groups);
|
||||||
|
$recurrence->latest_date = $backupDate;
|
||||||
|
$recurrence->latest_date_tz = $backupDate?->format('e');
|
||||||
|
$recurrence->save();
|
||||||
|
Preferences::mark();
|
||||||
|
|
||||||
|
// enrich groups and return them:
|
||||||
|
|
||||||
|
if (0 === $groups->count()) {
|
||||||
|
$paginator = new LengthAwarePaginator(new Collection(), 0, 1);
|
||||||
|
}
|
||||||
|
if ($groups->count() > 0) {
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
|
||||||
|
// use new group collector:
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
$collector
|
||||||
|
->setUser($admin)
|
||||||
|
->setIds($groups->pluck('id')->toArray())
|
||||||
|
->withAPIInformation()
|
||||||
|
;
|
||||||
|
$paginator = $collector->getPaginatedGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
$manager = $this->getManager();
|
||||||
|
$paginator->setPath(route('api.v1.recurrences.trigger', [$recurrence->id]).$this->buildParams());
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new TransactionGroupEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$transactions = $enrichment->enrich($paginator->getCollection());
|
||||||
|
|
||||||
|
/** @var TransactionGroupTransformer $transformer */
|
||||||
|
$transformer = app(TransactionGroupTransformer::class);
|
||||||
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
|
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||||
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
}
|
@@ -30,9 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\RecurrenceTransaction;
|
|
||||||
use FireflyIII\Models\Rule;
|
use FireflyIII\Models\Rule;
|
||||||
use FireflyIII\Models\RuleTrigger;
|
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
@@ -192,7 +190,7 @@ class ListController extends Controller
|
|||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setStart($this->parameters->get('start'));
|
$enrichment->setStart($this->parameters->get('start'));
|
||||||
$enrichment->setEnd($this->parameters->get('end'));
|
$enrichment->setEnd($this->parameters->get('end'));
|
||||||
$bills = $enrichment->enrichSingle($bills);
|
$bills = $enrichment->enrich($bills);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
||||||
@@ -268,7 +266,6 @@ class ListController extends Controller
|
|||||||
// filter selection
|
// filter selection
|
||||||
$collection = $unfiltered->filter(
|
$collection = $unfiltered->filter(
|
||||||
static function (Recurrence $recurrence) use ($currency) { // @phpstan-ignore-line
|
static function (Recurrence $recurrence) use ($currency) { // @phpstan-ignore-line
|
||||||
/** @var RecurrenceTransaction $transaction */
|
|
||||||
if (array_any($recurrence->recurrenceTransactions, fn ($transaction) => $transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id)) {
|
if (array_any($recurrence->recurrenceTransactions, fn ($transaction) => $transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id)) {
|
||||||
return $recurrence;
|
return $recurrence;
|
||||||
}
|
}
|
||||||
@@ -320,7 +317,6 @@ class ListController extends Controller
|
|||||||
|
|
||||||
$collection = $unfiltered->filter(
|
$collection = $unfiltered->filter(
|
||||||
static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
|
static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
|
||||||
/** @var RuleTrigger $trigger */
|
|
||||||
if (array_any($rule->ruleTriggers, fn ($trigger) => 'currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value)) {
|
if (array_any($rule->ruleTriggers, fn ($trigger) => 'currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value)) {
|
||||||
return $rule;
|
return $rule;
|
||||||
}
|
}
|
||||||
|
@@ -481,7 +481,7 @@ class BasicController extends Controller
|
|||||||
$currencies = [];
|
$currencies = [];
|
||||||
|
|
||||||
// first, create an entry for each entry in the "available" array.
|
// first, create an entry for each entry in the "available" array.
|
||||||
/** @var array $availableBudget */
|
/** @var string $availableBudget */
|
||||||
foreach ($available as $currencyId => $availableBudget) {
|
foreach ($available as $currencyId => $availableBudget) {
|
||||||
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||||
$return[$currencyId] = [
|
$return[$currencyId] = [
|
||||||
|
@@ -24,15 +24,18 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Controllers\System;
|
namespace FireflyIII\Api\V1\Controllers\System;
|
||||||
|
|
||||||
use FireflyIII\Support\Facades\FireflyConfig;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\System\UpdateRequest;
|
use FireflyIII\Api\V1\Requests\System\UpdateRequest;
|
||||||
|
use FireflyIII\Enums\WebhookDelivery;
|
||||||
|
use FireflyIII\Enums\WebhookResponse;
|
||||||
|
use FireflyIII\Enums\WebhookTrigger;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
use FireflyIII\Support\Binder\EitherConfigKey;
|
use FireflyIII\Support\Binder\EitherConfigKey;
|
||||||
|
use FireflyIII\Support\Facades\FireflyConfig;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,8 +110,8 @@ class ConfigurationController extends Controller
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'is_demo_site' => $isDemoSite?->data,
|
'is_demo_site' => $isDemoSite?->data,
|
||||||
'permission_update_check' => null === $updateCheck ? null : (int) $updateCheck->data,
|
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
|
||||||
'last_update_check' => null === $lastCheck ? null : (int) $lastCheck->data,
|
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
|
||||||
'single_user_mode' => $singleUser?->data,
|
'single_user_mode' => $singleUser?->data,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -139,15 +142,26 @@ class ConfigurationController extends Controller
|
|||||||
'value' => $dynamic[$shortKey],
|
'value' => $dynamic[$shortKey],
|
||||||
'editable' => true,
|
'editable' => true,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
if (!str_starts_with($configKey, 'configuration.')) {
|
if (str_starts_with($configKey, 'webhook.')) {
|
||||||
$data = [
|
$data = [
|
||||||
'title' => $configKey,
|
'title' => $configKey,
|
||||||
'value' => config($configKey),
|
'value' => $this->getWebhookConfiguration($configKey),
|
||||||
'editable' => false,
|
'editable' => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
$data = [
|
||||||
|
'title' => $configKey,
|
||||||
|
'value' => config($shortKey),
|
||||||
|
'editable' => false,
|
||||||
|
];
|
||||||
|
|
||||||
return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE);
|
return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,4 +196,39 @@ class ConfigurationController extends Controller
|
|||||||
|
|
||||||
return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE);
|
return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getWebhookConfiguration(string $configKey): array
|
||||||
|
{
|
||||||
|
switch ($configKey) {
|
||||||
|
case 'webhook.triggers':
|
||||||
|
$cases = WebhookTrigger::cases();
|
||||||
|
$data = [];
|
||||||
|
foreach ($cases as $c) {
|
||||||
|
$data[$c->name] = $c->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
case 'webhook.responses':
|
||||||
|
$cases = WebhookResponse::cases();
|
||||||
|
$data = [];
|
||||||
|
foreach ($cases as $c) {
|
||||||
|
$data[$c->name] = $c->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
case 'webhook.deliveries':
|
||||||
|
$cases = WebhookDelivery::cases();
|
||||||
|
$data = [];
|
||||||
|
foreach ($cases as $c) {
|
||||||
|
$data[$c->name] = $c->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new FireflyException(sprintf('Unknown webhook configuration key "%s".', $configKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,13 +25,16 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V1\Controllers\Webhook;
|
namespace FireflyIII\Api\V1\Controllers\Webhook;
|
||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
use FireflyIII\Enums\WebhookTrigger;
|
||||||
use FireflyIII\Events\RequestedSendWebhookMessages;
|
use FireflyIII\Events\RequestedSendWebhookMessages;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
|
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Models\Webhook;
|
use FireflyIII\Models\Webhook;
|
||||||
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment;
|
||||||
use FireflyIII\Transformers\WebhookTransformer;
|
use FireflyIII\Transformers\WebhookTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -89,6 +92,13 @@ class ShowController extends Controller
|
|||||||
$paginator = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.webhooks.index').$this->buildParams());
|
$paginator->setPath(route('api.v1.webhooks.index').$this->buildParams());
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new WebhookEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$webhooks = $enrichment->enrich($webhooks);
|
||||||
|
|
||||||
/** @var WebhookTransformer $transformer */
|
/** @var WebhookTransformer $transformer */
|
||||||
$transformer = app(WebhookTransformer::class);
|
$transformer = app(WebhookTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
@@ -116,6 +126,13 @@ class ShowController extends Controller
|
|||||||
Log::channel('audit')->info(sprintf('User views webhook #%d.', $webhook->id));
|
Log::channel('audit')->info(sprintf('User views webhook #%d.', $webhook->id));
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new WebhookEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$webhook = $enrichment->enrichSingle($webhook);
|
||||||
|
|
||||||
/** @var WebhookTransformer $transformer */
|
/** @var WebhookTransformer $transformer */
|
||||||
$transformer = app(WebhookTransformer::class);
|
$transformer = app(WebhookTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
@@ -146,7 +163,7 @@ class ShowController extends Controller
|
|||||||
$engine->setUser(auth()->user());
|
$engine->setUser(auth()->user());
|
||||||
|
|
||||||
// tell the generator which trigger it should look for
|
// tell the generator which trigger it should look for
|
||||||
$engine->setTrigger($webhook->trigger);
|
$engine->setTrigger(WebhookTrigger::tryFrom($webhook->trigger));
|
||||||
// tell the generator which objects to process
|
// tell the generator which objects to process
|
||||||
$engine->setObjects(new Collection([$group]));
|
$engine->setObjects(new Collection([$group]));
|
||||||
// set the webhook to trigger
|
// set the webhook to trigger
|
||||||
@@ -155,7 +172,7 @@ class ShowController extends Controller
|
|||||||
$engine->generateMessages();
|
$engine->generateMessages();
|
||||||
|
|
||||||
// trigger event to send them:
|
// trigger event to send them:
|
||||||
Log::debug('send event RequestedSendWebhookMessages');
|
Log::debug('send event RequestedSendWebhookMessages from ShowController::triggerTransaction()');
|
||||||
event(new RequestedSendWebhookMessages());
|
event(new RequestedSendWebhookMessages());
|
||||||
|
|
||||||
return response()->json([], 204);
|
return response()->json([], 204);
|
||||||
|
@@ -27,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Webhook;
|
|||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Models\Webhook\CreateRequest;
|
use FireflyIII\Api\V1\Requests\Models\Webhook\CreateRequest;
|
||||||
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment;
|
||||||
use FireflyIII\Transformers\WebhookTransformer;
|
use FireflyIII\Transformers\WebhookTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
@@ -68,6 +70,15 @@ class StoreController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$webhook = $this->repository->store($data);
|
$webhook = $this->repository->store($data);
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new WebhookEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$webhook = $enrichment->enrichSingle($webhook);
|
||||||
|
|
||||||
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
Log::channel('audit')->info('User stores new webhook', $data);
|
Log::channel('audit')->info('User stores new webhook', $data);
|
||||||
|
@@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Models\Webhook\UpdateRequest;
|
use FireflyIII\Api\V1\Requests\Models\Webhook\UpdateRequest;
|
||||||
use FireflyIII\Models\Webhook;
|
use FireflyIII\Models\Webhook;
|
||||||
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment;
|
||||||
use FireflyIII\Transformers\WebhookTransformer;
|
use FireflyIII\Transformers\WebhookTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
@@ -70,6 +72,15 @@ class UpdateController extends Controller
|
|||||||
$webhook = $this->repository->update($webhook, $data);
|
$webhook = $this->repository->update($webhook, $data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new WebhookEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
|
||||||
|
/** @var Webhook $webhook */
|
||||||
|
$webhook = $enrichment->enrichSingle($webhook);
|
||||||
|
|
||||||
Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data);
|
Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data);
|
||||||
|
|
||||||
/** @var WebhookTransformer $transformer */
|
/** @var WebhookTransformer $transformer */
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Chart;
|
namespace FireflyIII\Api\V1\Requests\Chart;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
@@ -64,6 +64,7 @@ class ChartRequest extends FormRequest
|
|||||||
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start',
|
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start',
|
||||||
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
|
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
|
||||||
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
||||||
|
'accounts' => 'nullable|array',
|
||||||
'accounts.*' => 'exists:accounts,id',
|
'accounts.*' => 'exists:accounts,id',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Data\Bulk;
|
namespace FireflyIII\Api\V1\Requests\Data\Bulk;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Data\Bulk;
|
namespace FireflyIII\Api\V1\Requests\Data\Bulk;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use FireflyIII\Enums\ClauseType;
|
use FireflyIII\Enums\ClauseType;
|
||||||
use FireflyIII\Rules\IsValidBulkClause;
|
use FireflyIII\Rules\IsValidBulkClause;
|
||||||
|
99
app/Api/V1/Requests/Models/Account/ShowRequest.php
Normal file
99
app/Api/V1/Requests/Models/Account/ShowRequest.php
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/*
|
||||||
|
* ShowRequest.php
|
||||||
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Requests\Models\Account;
|
||||||
|
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use FireflyIII\Rules\IsValidSortInstruction;
|
||||||
|
use FireflyIII\Support\Facades\Preferences;
|
||||||
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ShowRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use AccountFilter;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
public function getParameters(): array
|
||||||
|
{
|
||||||
|
$limit = $this->convertInteger('limit');
|
||||||
|
if (0 === $limit) {
|
||||||
|
// get default for user:
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
$limit = (int)Preferences::getForUser($user, 'listPageSize', 50)->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = $this->convertInteger('page');
|
||||||
|
$page = min(max(1, $page), 2 ** 16);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $this->convertString('type', 'all'),
|
||||||
|
'limit' => $limit,
|
||||||
|
'sort' => $this->convertSortParameters('sort', Account::class),
|
||||||
|
'page' => $page,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
$keys = implode(',', array_keys($this->types));
|
||||||
|
|
||||||
|
return [
|
||||||
|
'date' => 'date',
|
||||||
|
'start' => 'date|present_with:end|before_or_equal:end|before:2038-01-17|after:1970-01-02',
|
||||||
|
'end' => 'date|present_with:start|after_or_equal:start|before:2038-01-17|after:1970-01-02',
|
||||||
|
'sort' => ['nullable', new IsValidSortInstruction(Account::class)],
|
||||||
|
'type' => sprintf('in:%s', $keys),
|
||||||
|
'limit' => 'numeric|min:1|max:131337',
|
||||||
|
'page' => 'numeric|min:1|max:131337',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withValidator(Validator $validator): void
|
||||||
|
{
|
||||||
|
$validator->after(
|
||||||
|
function (Validator $validator): void {
|
||||||
|
if (count($validator->failed()) > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$data = $validator->getData();
|
||||||
|
|
||||||
|
|
||||||
|
if (array_key_exists('date', $data) && array_key_exists('start', $data) && array_key_exists('end', $data)) {
|
||||||
|
// assume valid dates, before we got here.
|
||||||
|
$start = Carbon::parse($data['start'], config('app.timezone'))->startOfDay();
|
||||||
|
$end = Carbon::parse($data['end'], config('app.timezone'))->endOfDay();
|
||||||
|
$date = Carbon::parse($data['date'], config('app.timezone'));
|
||||||
|
if (!$date->between($start, $end)) {
|
||||||
|
$validator->errors()->add('date', (string)trans('validation.between_date'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Account;
|
namespace FireflyIII\Api\V1\Requests\Models\Account;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Location;
|
use FireflyIII\Models\Location;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
|
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Bill;
|
namespace FireflyIII\Api\V1\Requests\Models\Bill;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use ValueError;
|
use ValueError;
|
||||||
use TypeError;
|
use TypeError;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Bill;
|
namespace FireflyIII\Api\V1\Requests\Models\Bill;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Budget;
|
namespace FireflyIII\Api\V1\Requests\Models\Budget;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Budget;
|
namespace FireflyIII\Api\V1\Requests\Models\Budget;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
|
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
@@ -28,7 +28,7 @@ use Carbon\Carbon;
|
|||||||
use Carbon\Exceptions\InvalidFormatException;
|
use Carbon\Exceptions\InvalidFormatException;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class StoreByCurrenciesRequest extends FormRequest
|
class StoreByCurrenciesRequest extends FormRequest
|
||||||
@@ -55,7 +55,7 @@ class StoreByCurrenciesRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$validator->after(
|
$validator->after(
|
||||||
static function (Validator $validator): void {
|
static function (Validator $validator): void {
|
||||||
$data = $validator->getData() ?? [];
|
$data = $validator->getData();
|
||||||
foreach ($data as $date => $rate) {
|
foreach ($data as $date => $rate) {
|
||||||
try {
|
try {
|
||||||
$date = Carbon::createFromFormat('Y-m-d', $date);
|
$date = Carbon::createFromFormat('Y-m-d', $date);
|
||||||
|
@@ -24,10 +24,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
|
namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
|
||||||
|
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class StoreByDateRequest extends FormRequest
|
class StoreByDateRequest extends FormRequest
|
||||||
@@ -35,6 +37,9 @@ class StoreByDateRequest extends FormRequest
|
|||||||
use ChecksLogin;
|
use ChecksLogin;
|
||||||
use ConvertsDataTypes;
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
public function getAll(): array
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@@ -45,11 +50,13 @@ class StoreByDateRequest extends FormRequest
|
|||||||
|
|
||||||
public function getFromCurrency(): TransactionCurrency
|
public function getFromCurrency(): TransactionCurrency
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('code', $this->get('from'))->first();
|
return Amount::getTransactionCurrencyByCode((string)$this->get('from'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The rules that the incoming request must be matched against.
|
* The rules that the incoming request must be matched against.
|
||||||
|
*
|
||||||
|
* @return array<string, string>
|
||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
@@ -79,8 +86,10 @@ class StoreByDateRequest extends FormRequest
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$to = TransactionCurrency::where('code', $key)->first();
|
|
||||||
if (null === $to) {
|
try {
|
||||||
|
$to = Amount::getTransactionCurrencyByCode((string)$key);
|
||||||
|
} catch (FireflyException) {
|
||||||
$validator->errors()->add(sprintf('rates.%s', $key), trans('validation.invalid_currency_code', ['code' => $key]));
|
$validator->errors()->add(sprintf('rates.%s', $key), trans('validation.invalid_currency_code', ['code' => $key]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
@@ -42,7 +43,7 @@ class StoreRequest extends FormRequest
|
|||||||
|
|
||||||
public function getFromCurrency(): TransactionCurrency
|
public function getFromCurrency(): TransactionCurrency
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('code', $this->get('from'))->first();
|
return Amount::getTransactionCurrencyByCode((string) $this->get('from'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRate(): string
|
public function getRate(): string
|
||||||
@@ -52,7 +53,7 @@ class StoreRequest extends FormRequest
|
|||||||
|
|
||||||
public function getToCurrency(): TransactionCurrency
|
public function getToCurrency(): TransactionCurrency
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('code', $this->get('to'))->first();
|
return Amount::getTransactionCurrencyByCode((string) $this->get('to'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,7 +24,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
|
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
|
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
|
||||||
@@ -78,7 +79,7 @@ class StoreRequest extends FormRequest
|
|||||||
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
||||||
'object_group_title' => ['min:1', 'max:255'],
|
'object_group_title' => ['min:1', 'max:255'],
|
||||||
'target_amount' => ['required', new IsValidZeroOrMoreAmount()],
|
'target_amount' => ['required', new IsValidZeroOrMoreAmount()],
|
||||||
'start_date' => 'date|nullable',
|
'start_date' => 'required|date|after:1970-01-01|before:2038-01-17',
|
||||||
'transaction_currency_id' => 'exists:transaction_currencies,id|required_without:transaction_currency_code',
|
'transaction_currency_id' => 'exists:transaction_currencies,id|required_without:transaction_currency_code',
|
||||||
'transaction_currency_code' => 'exists:transaction_currencies,code|required_without:transaction_currency_id',
|
'transaction_currency_code' => 'exists:transaction_currencies,code|required_without:transaction_currency_id',
|
||||||
'target_date' => 'date|nullable|after:start_date',
|
'target_date' => 'date|nullable|after:start_date',
|
||||||
@@ -96,7 +97,7 @@ class StoreRequest extends FormRequest
|
|||||||
// validate start before end only if both are there.
|
// validate start before end only if both are there.
|
||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
$currency = $this->getCurrencyFromData($validator, $data);
|
$currency = $this->getCurrencyFromData($validator, $data);
|
||||||
if (null === $currency) {
|
if (!$currency instanceof TransactionCurrency) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$targetAmount = (string) ($data['target_amount'] ?? '0');
|
$targetAmount = (string) ($data['target_amount'] ?? '0');
|
||||||
@@ -135,16 +136,10 @@ class StoreRequest extends FormRequest
|
|||||||
private function getCurrencyFromData(Validator $validator, array $data): ?TransactionCurrency
|
private function getCurrencyFromData(Validator $validator, array $data): ?TransactionCurrency
|
||||||
{
|
{
|
||||||
if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) {
|
if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) {
|
||||||
$currency = TransactionCurrency::whereCode($data['transaction_currency_code'])->first();
|
return Amount::getTransactionCurrencyByCode((string) $data['transaction_currency_code']);
|
||||||
if (null !== $currency) {
|
|
||||||
return $currency;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) {
|
if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) {
|
||||||
$currency = TransactionCurrency::find((int) $data['transaction_currency_id']);
|
return Amount::getTransactionCurrencyById((int) $data['transaction_currency_id']);
|
||||||
if (null !== $currency) {
|
|
||||||
return $currency;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$validator->errors()->add('transaction_currency_id', trans('validation.require_currency_id_code'));
|
$validator->errors()->add('transaction_currency_id', trans('validation.require_currency_id_code'));
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
|
namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Rules\BelongsUser;
|
use FireflyIII\Rules\BelongsUser;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
|
namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Rules\BelongsUser;
|
use FireflyIII\Rules\BelongsUser;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Rules\IsValidActionExpression;
|
use FireflyIII\Rules\IsValidActionExpression;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\Rule;
|
use FireflyIII\Models\Rule;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Rules\IsValidActionExpression;
|
use FireflyIII\Rules\IsValidActionExpression;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Transaction;
|
namespace FireflyIII\Api\V1\Requests\Models\Transaction;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\Location;
|
use FireflyIII\Models\Location;
|
||||||
use FireflyIII\Rules\BelongsUser;
|
use FireflyIII\Rules\BelongsUser;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Transaction;
|
namespace FireflyIII\Api\V1\Requests\Models\Transaction;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Rules\BelongsUser;
|
use FireflyIII\Rules\BelongsUser;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
|
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
|
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Models\TransactionJournalLink;
|
use FireflyIII\Models\TransactionJournalLink;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||||
|
@@ -24,10 +24,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Webhook;
|
namespace FireflyIII\Api\V1\Requests\Models\Webhook;
|
||||||
|
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Webhook;
|
use FireflyIII\Models\Webhook;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use FireflyIII\Support\Request\ValidatesWebhooks;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,27 +39,28 @@ class CreateRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
use ChecksLogin;
|
use ChecksLogin;
|
||||||
use ConvertsDataTypes;
|
use ConvertsDataTypes;
|
||||||
|
use ValidatesWebhooks;
|
||||||
|
|
||||||
public function getData(): array
|
public function getData(): array
|
||||||
{
|
{
|
||||||
$triggers = Webhook::getTriggersForValidation();
|
$fields = [
|
||||||
$responses = Webhook::getResponsesForValidation();
|
'title' => ['title', 'convertString'],
|
||||||
$deliveries = Webhook::getDeliveriesForValidation();
|
'active' => ['active', 'boolean'],
|
||||||
|
'url' => ['url', 'convertString'],
|
||||||
$fields = [
|
|
||||||
'title' => ['title', 'convertString'],
|
|
||||||
'active' => ['active', 'boolean'],
|
|
||||||
'trigger' => ['trigger', 'convertString'],
|
|
||||||
'response' => ['response', 'convertString'],
|
|
||||||
'delivery' => ['delivery', 'convertString'],
|
|
||||||
'url' => ['url', 'convertString'],
|
|
||||||
];
|
];
|
||||||
|
$triggers = $this->get('triggers', []);
|
||||||
|
$responses = $this->get('responses', []);
|
||||||
|
$deliveries = $this->get('deliveries', []);
|
||||||
|
|
||||||
// this is the way.
|
if (0 === count($triggers) || 0 === count($responses) || 0 === count($deliveries)) {
|
||||||
$return = $this->getAllData($fields);
|
throw new FireflyException('Unexpectedly got no responses, triggers or deliveries.');
|
||||||
$return['trigger'] = $triggers[$return['trigger']] ?? (int) $return['trigger'];
|
}
|
||||||
$return['response'] = $responses[$return['response']] ?? (int) $return['response'];
|
|
||||||
$return['delivery'] = $deliveries[$return['delivery']] ?? (int) $return['delivery'];
|
|
||||||
|
$return = $this->getAllData($fields);
|
||||||
|
$return['triggers'] = $triggers;
|
||||||
|
$return['responses'] = $responses;
|
||||||
|
$return['deliveries'] = $deliveries;
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@@ -67,18 +70,24 @@ class CreateRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$triggers = implode(',', array_keys(Webhook::getTriggersForValidation()));
|
$triggers = implode(',', array_values(Webhook::getTriggers()));
|
||||||
$responses = implode(',', array_keys(Webhook::getResponsesForValidation()));
|
$responses = implode(',', array_values(Webhook::getResponses()));
|
||||||
$deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation()));
|
$deliveries = implode(',', array_values(Webhook::getDeliveries()));
|
||||||
$validProtocols = config('firefly.valid_url_protocols');
|
$validProtocols = config('firefly.valid_url_protocols');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title',
|
'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title',
|
||||||
'active' => [new IsBoolean()],
|
'active' => [new IsBoolean()],
|
||||||
'trigger' => sprintf('required|in:%s', $triggers),
|
'trigger' => 'prohibited',
|
||||||
'response' => sprintf('required|in:%s', $responses),
|
'triggers' => 'required|array|min:1|max:10',
|
||||||
'delivery' => sprintf('required|in:%s', $deliveries),
|
'triggers.*' => sprintf('required|in:%s', $triggers),
|
||||||
'url' => ['required', sprintf('url:%s', $validProtocols), 'uniqueWebhook'],
|
'response' => 'prohibited',
|
||||||
|
'responses' => 'required|array|min:1|max:1',
|
||||||
|
'responses.*' => sprintf('required|in:%s', $responses),
|
||||||
|
'delivery' => 'prohibited',
|
||||||
|
'deliveries' => 'required|array|min:1|max:1',
|
||||||
|
'deliveries.*' => sprintf('required|in:%s', $deliveries),
|
||||||
|
'url' => ['required', sprintf('url:%s', $validProtocols)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,10 +24,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\Models\Webhook;
|
namespace FireflyIII\Api\V1\Requests\Models\Webhook;
|
||||||
|
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Webhook;
|
use FireflyIII\Models\Webhook;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use FireflyIII\Support\Request\ValidatesWebhooks;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,38 +39,29 @@ class UpdateRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
use ChecksLogin;
|
use ChecksLogin;
|
||||||
use ConvertsDataTypes;
|
use ConvertsDataTypes;
|
||||||
|
use ValidatesWebhooks;
|
||||||
|
|
||||||
public function getData(): array
|
public function getData(): array
|
||||||
{
|
{
|
||||||
$triggers = Webhook::getTriggersForValidation();
|
$fields = [
|
||||||
$responses = Webhook::getResponsesForValidation();
|
|
||||||
$deliveries = Webhook::getDeliveriesForValidation();
|
|
||||||
|
|
||||||
$fields = [
|
|
||||||
'title' => ['title', 'convertString'],
|
'title' => ['title', 'convertString'],
|
||||||
'active' => ['active', 'boolean'],
|
'active' => ['active', 'boolean'],
|
||||||
'trigger' => ['trigger', 'convertString'],
|
|
||||||
'response' => ['response', 'convertString'],
|
|
||||||
'delivery' => ['delivery', 'convertString'],
|
|
||||||
'url' => ['url', 'convertString'],
|
'url' => ['url', 'convertString'],
|
||||||
];
|
];
|
||||||
|
|
||||||
// this is the way.
|
$triggers = $this->get('triggers', []);
|
||||||
$return = $this->getAllData($fields);
|
$responses = $this->get('responses', []);
|
||||||
if (array_key_exists('trigger', $return)) {
|
$deliveries = $this->get('deliveries', []);
|
||||||
$return['trigger'] = $triggers[$return['trigger']] ?? 0;
|
|
||||||
}
|
if (0 === count($triggers) || 0 === count($responses) || 0 === count($deliveries)) {
|
||||||
if (array_key_exists('response', $return)) {
|
throw new FireflyException('Unexpectedly got no responses, triggers or deliveries.');
|
||||||
$return['response'] = $responses[$return['response']] ?? 0;
|
|
||||||
}
|
|
||||||
if (array_key_exists('delivery', $return)) {
|
|
||||||
$return['delivery'] = $deliveries[$return['delivery']] ?? 0;
|
|
||||||
}
|
|
||||||
$return['secret'] = null !== $this->get('secret');
|
|
||||||
if (null !== $this->get('title')) {
|
|
||||||
$return['title'] = $this->convertString('title');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$return = $this->getAllData($fields);
|
||||||
|
$return['triggers'] = $triggers;
|
||||||
|
$return['responses'] = $responses;
|
||||||
|
$return['deliveries'] = $deliveries;
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,21 +70,29 @@ class UpdateRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$triggers = implode(',', array_keys(Webhook::getTriggersForValidation()));
|
$triggers = implode(',', array_values(Webhook::getTriggers()));
|
||||||
$responses = implode(',', array_keys(Webhook::getResponsesForValidation()));
|
$responses = implode(',', array_values(Webhook::getResponses()));
|
||||||
$deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation()));
|
$deliveries = implode(',', array_values(Webhook::getDeliveries()));
|
||||||
$validProtocols = config('firefly.valid_url_protocols');
|
$validProtocols = config('firefly.valid_url_protocols');
|
||||||
|
|
||||||
/** @var Webhook $webhook */
|
/** @var Webhook $webhook */
|
||||||
$webhook = $this->route()->parameter('webhook');
|
$webhook = $this->route()->parameter('webhook');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
|
'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
|
||||||
'active' => [new IsBoolean()],
|
'active' => [new IsBoolean()],
|
||||||
'trigger' => sprintf('in:%s', $triggers),
|
|
||||||
'response' => sprintf('in:%s', $responses),
|
'trigger' => 'prohibited',
|
||||||
'delivery' => sprintf('in:%s', $deliveries),
|
'triggers' => 'required|array|min:1|max:10',
|
||||||
'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)],
|
'triggers.*' => sprintf('required|in:%s', $triggers),
|
||||||
|
'response' => 'prohibited',
|
||||||
|
'responses' => 'required|array|min:1|max:1',
|
||||||
|
'responses.*' => sprintf('required|in:%s', $responses),
|
||||||
|
'delivery' => 'prohibited',
|
||||||
|
'deliveries' => 'required|array|min:1|max:1',
|
||||||
|
'deliveries.*' => sprintf('required|in:%s', $deliveries),
|
||||||
|
|
||||||
|
'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Api\V1\Requests\System;
|
namespace FireflyIII\Api\V1\Requests\System;
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
@@ -28,6 +28,7 @@ namespace FireflyIII\Casts;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SeparateTimezoneCaster
|
* Class SeparateTimezoneCaster
|
||||||
@@ -51,6 +52,7 @@ class SeparateTimezoneCaster implements CastsAttributes
|
|||||||
$timeZone = $attributes[sprintf('%s_tz', $key)] ?? config('app.timezone');
|
$timeZone = $attributes[sprintf('%s_tz', $key)] ?? config('app.timezone');
|
||||||
|
|
||||||
return Carbon::parse($value, $timeZone)->setTimezone(config('app.timezone'));
|
return Carbon::parse($value, $timeZone)->setTimezone(config('app.timezone'));
|
||||||
|
// Log::debug(sprintf('SeparateTimezoneCaster: %s.%s = %s', str_replace('FireflyIII\\Models\\','',get_class($model)), $key, $result->toAtomString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -45,9 +45,7 @@ class CorrectsGroupAccounts extends Command
|
|||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$groups = [];
|
$groups = [];
|
||||||
$res = TransactionJournal::groupBy('transaction_group_id')
|
$res = TransactionJournal::groupBy('transaction_group_id')->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
|
||||||
->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')])// @phpstan-ignore-line
|
|
||||||
;
|
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($res as $journal) {
|
foreach ($res as $journal) {
|
||||||
|
@@ -263,9 +263,9 @@ class CorrectsUnevenAmount extends Command
|
|||||||
// Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true)));
|
// Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true)));
|
||||||
// Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int) $source->foreign_currency_id, true)));
|
// Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int) $source->foreign_currency_id, true)));
|
||||||
|
|
||||||
if (0 === bccomp((string) app('steam')->positive($source->amount), (string) app('steam')->positive($destination->foreign_amount))
|
if (0 === bccomp(Steam::positive($source->amount), Steam::positive($destination->foreign_amount))
|
||||||
&& $source->transaction_currency_id === $destination->foreign_currency_id
|
&& $source->transaction_currency_id === $destination->foreign_currency_id
|
||||||
&& 0 === bccomp((string) app('steam')->positive($destination->amount), (string) app('steam')->positive($source->foreign_amount))
|
&& 0 === bccomp(Steam::positive($destination->amount), Steam::positive($source->foreign_amount))
|
||||||
&& (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id
|
&& (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
@@ -302,10 +302,10 @@ class CorrectsUnevenAmount extends Command
|
|||||||
|
|
||||||
private function isBetweenAssetAndLiability(TransactionJournal $journal): bool
|
private function isBetweenAssetAndLiability(TransactionJournal $journal): bool
|
||||||
{
|
{
|
||||||
/** @var Transaction $sourceTransaction */
|
/** @var null|Transaction $sourceTransaction */
|
||||||
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
|
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
|
||||||
|
|
||||||
/** @var Transaction $destinationTransaction */
|
/** @var null|Transaction $destinationTransaction */
|
||||||
$destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first();
|
$destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first();
|
||||||
if (null === $sourceTransaction || null === $destinationTransaction) {
|
if (null === $sourceTransaction || null === $destinationTransaction) {
|
||||||
Log::warning('Either transaction is false, stop.');
|
Log::warning('Either transaction is false, stop.');
|
||||||
|
@@ -55,10 +55,7 @@ class RemovesEmptyJournals extends Command
|
|||||||
*/
|
*/
|
||||||
private function deleteUnevenJournals(): void
|
private function deleteUnevenJournals(): void
|
||||||
{
|
{
|
||||||
$set = Transaction::whereNull('deleted_at')
|
$set = Transaction::whereNull('deleted_at')->groupBy('transactions.transaction_journal_id')->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
|
||||||
->groupBy('transactions.transaction_journal_id')
|
|
||||||
->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']) // @phpstan-ignore-line
|
|
||||||
;
|
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
/** @var Transaction $row */
|
/** @var Transaction $row */
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
/*
|
/*
|
||||||
* ValidatesEnvironmentVariables.php
|
* ValidatesEnvironmentVariables.php
|
||||||
* Copyright (c) 2025 james@firefly-iii.org.
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
*
|
*
|
||||||
@@ -18,9 +18,11 @@ declare(strict_types=1);
|
|||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Console\Commands\Integrity;
|
namespace FireflyIII\Console\Commands\Integrity;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
@@ -30,18 +32,7 @@ class ValidatesEnvironmentVariables extends Command
|
|||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var null|string
|
|
||||||
*/
|
|
||||||
protected $description = 'Makes sure you use the correct variables.';
|
protected $description = 'Makes sure you use the correct variables.';
|
||||||
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'integrity:validates-environment-variables';
|
protected $signature = 'integrity:validates-environment-variables';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -133,6 +133,9 @@ class OutputsInstructions extends Command
|
|||||||
if ('03-31' === $today) {
|
if ('03-31' === $today) {
|
||||||
$colors = ['bright-blue', 'bright-red', 'white', 'white', 'bright-red', 'bright-blue', 'default', 'default'];
|
$colors = ['bright-blue', 'bright-red', 'white', 'white', 'bright-red', 'bright-blue', 'default', 'default'];
|
||||||
}
|
}
|
||||||
|
if ('ru_RU' === config('firefly.default_language')) {
|
||||||
|
$colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default'];
|
||||||
|
}
|
||||||
|
|
||||||
$this->line(sprintf('<fg=%s> ______ _ __ _ _____ _____ _____ </>', $colors[0]));
|
$this->line(sprintf('<fg=%s> ______ _ __ _ _____ _____ _____ </>', $colors[0]));
|
||||||
$this->line(sprintf('<fg=%s> | ____(_) / _| | |_ _|_ _|_ _| </>', $colors[1]));
|
$this->line(sprintf('<fg=%s> | ____(_) / _| | |_ _|_ _|_ _| </>', $colors[1]));
|
||||||
@@ -238,14 +241,38 @@ class OutputsInstructions extends Command
|
|||||||
|
|
||||||
private function someQuote(): void
|
private function someQuote(): void
|
||||||
{
|
{
|
||||||
$lines = [
|
$lines = [
|
||||||
'Forgive yourself for not being at peace.',
|
'Forgive yourself for not being at peace.',
|
||||||
'Doesn\'t look like anything to me.',
|
'Doesn\'t look like anything to me.',
|
||||||
'Be proud of what you make.',
|
'Be proud of what you make.',
|
||||||
'Be there or forever wonder.',
|
'Be there or forever wonder.',
|
||||||
'A year from now you will wish you had started today.',
|
'A year from now you will wish you had started today.',
|
||||||
];
|
];
|
||||||
$random = random_int(0, count($lines) - 1);
|
$addQuotes = true;
|
||||||
$this->line(sprintf(' "%s"', $lines[$random]));
|
|
||||||
|
// fuck the Russian aggression in Ukraine.
|
||||||
|
|
||||||
|
// There is no point even trying to be neutral, because you can’t. When I say you can’t be neutral on
|
||||||
|
// a moving train, it means the world is already moving in certain directions. Children are going
|
||||||
|
// hungry, wars are taking place. In a situation like that, to be neutral or to try to be neutral,
|
||||||
|
// to stand aside, not to take a stand, not to participate, is to collaborate with whatever is
|
||||||
|
// going on, to allow that to happen.
|
||||||
|
|
||||||
|
if ('ru_RU' === config('firefly.default_language')) {
|
||||||
|
$addQuotes = false;
|
||||||
|
$lines = [
|
||||||
|
'🇺🇦 Слава Україні!',
|
||||||
|
'🇺🇦 Slava Ukraini!',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$random = random_int(0, count($lines) - 1);
|
||||||
|
if ($addQuotes) {
|
||||||
|
$this->line(sprintf(' "%s"', $lines[$random]));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->line(sprintf(' %s', $lines[$random]));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
/*
|
/*
|
||||||
* RecalculatesRunningBalance.php
|
* RecalculatesRunningBalance.php
|
||||||
* Copyright (c) 2025 james@firefly-iii.org.
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
*
|
*
|
||||||
@@ -18,9 +18,11 @@ declare(strict_types=1);
|
|||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Console\Commands\System;
|
namespace FireflyIII\Console\Commands\System;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
@@ -48,7 +50,7 @@ class RecalculatesRunningBalance extends Command
|
|||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle(): int
|
||||||
{
|
{
|
||||||
if (true === config('firefly.feature_flags.running_balance_column')) {
|
if (true === config('firefly.feature_flags.running_balance_column')) {
|
||||||
$this->friendlyInfo('Will recalculate account balances. This may take a LONG time. Please be patient.');
|
$this->friendlyInfo('Will recalculate account balances. This may take a LONG time. Please be patient.');
|
||||||
@@ -58,6 +60,8 @@ class RecalculatesRunningBalance extends Command
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$this->friendlyWarning('This command has been disabled.');
|
$this->friendlyWarning('This command has been disabled.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function correctBalanceAmounts(bool $forced): void
|
private function correctBalanceAmounts(bool $forced): void
|
||||||
|
@@ -1,5 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ResetsErrorMailLimit.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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Console\Commands\System;
|
namespace FireflyIII\Console\Commands\System;
|
||||||
@@ -8,6 +29,9 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||||
|
|
||||||
|
use function Safe\file_put_contents;
|
||||||
|
use function Safe\json_encode;
|
||||||
|
|
||||||
class ResetsErrorMailLimit extends Command
|
class ResetsErrorMailLimit extends Command
|
||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
@@ -78,8 +78,8 @@ class ScansAttachments extends Command
|
|||||||
}
|
}
|
||||||
$tempFileName = tempnam(sys_get_temp_dir(), 'FireflyIII');
|
$tempFileName = tempnam(sys_get_temp_dir(), 'FireflyIII');
|
||||||
file_put_contents($tempFileName, $decryptedContent);
|
file_put_contents($tempFileName, $decryptedContent);
|
||||||
$attachment->md5 = (string)md5_file($tempFileName);
|
$attachment->md5 = md5_file($tempFileName);
|
||||||
$attachment->mime = (string)mime_content_type($tempFileName);
|
$attachment->mime = mime_content_type($tempFileName);
|
||||||
$attachment->save();
|
$attachment->save();
|
||||||
$this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id));
|
$this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id));
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,7 @@ class RemovesDatabaseDecryption extends Command
|
|||||||
* @var string $table
|
* @var string $table
|
||||||
* @var array $fields
|
* @var array $fields
|
||||||
*/
|
*/
|
||||||
foreach ($tables as $table => $fields) {
|
foreach ($tables as $table => $fields) { // @phpstan-ignore-line
|
||||||
$this->decryptTable($table, $fields);
|
$this->decryptTable($table, $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,9 +25,11 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Console\Commands\Upgrade;
|
namespace FireflyIII\Console\Commands\Upgrade;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -65,7 +67,7 @@ class UpgradesCurrencyPreferences extends Command
|
|||||||
{
|
{
|
||||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||||
if (null !== $configVar) {
|
if (null !== $configVar) {
|
||||||
return (bool) $configVar->data;
|
return (bool)$configVar->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -104,8 +106,8 @@ class UpgradesCurrencyPreferences extends Command
|
|||||||
|
|
||||||
private function upgradeUserPreferences(User $user): void
|
private function upgradeUserPreferences(User $user): void
|
||||||
{
|
{
|
||||||
$currencies = TransactionCurrency::get();
|
$currencies = TransactionCurrency::get();
|
||||||
$enabled = new Collection();
|
$enabled = new Collection();
|
||||||
|
|
||||||
/** @var TransactionCurrency $currency */
|
/** @var TransactionCurrency $currency */
|
||||||
foreach ($currencies as $currency) {
|
foreach ($currencies as $currency) {
|
||||||
@@ -116,10 +118,11 @@ class UpgradesCurrencyPreferences extends Command
|
|||||||
$user->currencies()->sync($enabled->pluck('id')->toArray());
|
$user->currencies()->sync($enabled->pluck('id')->toArray());
|
||||||
|
|
||||||
// set the default currency for the user and for the group:
|
// set the default currency for the user and for the group:
|
||||||
$preference = $this->getPreference($user);
|
$preference = $this->getPreference($user);
|
||||||
$primaryCurrency = TransactionCurrency::where('code', $preference)->first();
|
|
||||||
if (null === $primaryCurrency) {
|
try {
|
||||||
// get EUR
|
$primaryCurrency = Amount::getTransactionCurrencyByCode($preference);
|
||||||
|
} catch (FireflyException) {
|
||||||
$primaryCurrency = TransactionCurrency::where('code', 'EUR')->first();
|
$primaryCurrency = TransactionCurrency::where('code', 'EUR')->first();
|
||||||
}
|
}
|
||||||
$user->currencies()->updateExistingPivot($primaryCurrency->id, ['user_default' => true]);
|
$user->currencies()->updateExistingPivot($primaryCurrency->id, ['user_default' => true]);
|
||||||
@@ -135,7 +138,7 @@ class UpgradesCurrencyPreferences extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $preference->data && !is_array($preference->data)) {
|
if (null !== $preference->data && !is_array($preference->data)) {
|
||||||
return (string) $preference->data;
|
return (string)$preference->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'EUR';
|
return 'EUR';
|
||||||
|
@@ -75,6 +75,7 @@ class UpgradesDatabase extends Command
|
|||||||
'upgrade:610-currency-preferences',
|
'upgrade:610-currency-preferences',
|
||||||
'upgrade:620-piggy-banks',
|
'upgrade:620-piggy-banks',
|
||||||
'upgrade:620-pc-amounts',
|
'upgrade:620-pc-amounts',
|
||||||
|
'upgrade:640-upgrade-webhooks',
|
||||||
'firefly-iii:correct-database',
|
'firefly-iii:correct-database',
|
||||||
];
|
];
|
||||||
$args = [];
|
$args = [];
|
||||||
|
116
app/Console/Commands/Upgrade/UpgradesWebhooks.php
Normal file
116
app/Console/Commands/Upgrade/UpgradesWebhooks.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UpgradesWebhooks.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\Console\Commands\Upgrade;
|
||||||
|
|
||||||
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Enums\WebhookDelivery;
|
||||||
|
use FireflyIII\Enums\WebhookResponse;
|
||||||
|
use FireflyIII\Enums\WebhookTrigger;
|
||||||
|
use FireflyIII\Models\Webhook;
|
||||||
|
use FireflyIII\Models\WebhookDelivery as WebhookDeliveryModel;
|
||||||
|
use FireflyIII\Models\WebhookResponse as WebhookResponseModel;
|
||||||
|
use FireflyIII\Models\WebhookTrigger as WebhookTriggerModel;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class UpgradesWebhooks extends Command
|
||||||
|
{
|
||||||
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
|
public const string CONFIG_NAME = '640_upgrade_webhooks';
|
||||||
|
protected $description = 'Upgrade webhooks so they can handle multiple triggers.';
|
||||||
|
protected $signature = 'upgrade:640-upgrade-webhooks {--F|force : Force the execution of this command.}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||||
|
$this->friendlyInfo('This command has already been executed.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->upgradeWebhooks();
|
||||||
|
$this->markAsExecuted();
|
||||||
|
$this->friendlyPositive('Upgraded webhooks.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isExecuted(): bool
|
||||||
|
{
|
||||||
|
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||||
|
if (null !== $configVar) {
|
||||||
|
return (bool)$configVar->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upgradeWebhooks(): void
|
||||||
|
{
|
||||||
|
$set = Webhook::where('delivery', '>', 1)->orWhere('trigger', '>', 1)->orWhere('response', '>', 1)->get();
|
||||||
|
|
||||||
|
/** @var Webhook $webhook */
|
||||||
|
foreach ($set as $webhook) {
|
||||||
|
$this->upgradeWebhook($webhook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upgradeWebhook(Webhook $webhook): void
|
||||||
|
{
|
||||||
|
$delivery = WebhookDelivery::tryFrom((int)$webhook->delivery);
|
||||||
|
$response = WebhookResponse::tryFrom((int)$webhook->response);
|
||||||
|
$trigger = WebhookTrigger::tryFrom((int)$webhook->trigger);
|
||||||
|
if (null === $delivery || null === $response || null === $trigger) {
|
||||||
|
$this->friendlyError(sprintf('[a] Webhook #%d has an invalid delivery, response or trigger value. Will not upgrade.', $webhook->id));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$deliveryModel = WebhookDeliveryModel::where('key', $delivery->value)->first();
|
||||||
|
$responseModel = WebhookResponseModel::where('key', $response->value)->first();
|
||||||
|
$triggerModel = WebhookTriggerModel::where('key', $trigger->value)->first();
|
||||||
|
if (null === $deliveryModel || null === $responseModel || null === $triggerModel) {
|
||||||
|
$this->friendlyError(sprintf('[b] Webhook #%d has an invalid delivery, response or trigger model. Will not upgrade.', $webhook->id));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$webhook->webhookDeliveries()->attach([$deliveryModel->id]);
|
||||||
|
$webhook->webhookResponses()->attach([$responseModel->id]);
|
||||||
|
$webhook->webhookTriggers()->attach([$triggerModel->id]);
|
||||||
|
$webhook->delivery = 1;
|
||||||
|
$webhook->response = 1;
|
||||||
|
$webhook->trigger = 1;
|
||||||
|
$webhook->save();
|
||||||
|
$this->friendlyPositive(sprintf('Webhook #%d upgraded.', $webhook->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function markAsExecuted(): void
|
||||||
|
{
|
||||||
|
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||||
|
}
|
||||||
|
}
|
@@ -31,5 +31,7 @@ enum WebhookResponse: int
|
|||||||
{
|
{
|
||||||
case TRANSACTIONS = 200;
|
case TRANSACTIONS = 200;
|
||||||
case ACCOUNTS = 210;
|
case ACCOUNTS = 210;
|
||||||
|
case BUDGET = 230;
|
||||||
|
case RELEVANT = 240;
|
||||||
case NONE = 220;
|
case NONE = 220;
|
||||||
}
|
}
|
||||||
|
@@ -29,10 +29,12 @@ namespace FireflyIII\Enums;
|
|||||||
*/
|
*/
|
||||||
enum WebhookTrigger: int
|
enum WebhookTrigger: int
|
||||||
{
|
{
|
||||||
case STORE_TRANSACTION = 100;
|
case ANY = 50;
|
||||||
// case BEFORE_STORE_TRANSACTION = 101;
|
case STORE_TRANSACTION = 100;
|
||||||
case UPDATE_TRANSACTION = 110;
|
case UPDATE_TRANSACTION = 110;
|
||||||
// case BEFORE_UPDATE_TRANSACTION = 111;
|
case DESTROY_TRANSACTION = 120;
|
||||||
case DESTROY_TRANSACTION = 120;
|
case STORE_BUDGET = 200;
|
||||||
// case BEFORE_DESTROY_TRANSACTION = 121;
|
case UPDATE_BUDGET = 210;
|
||||||
|
case DESTROY_BUDGET = 220;
|
||||||
|
case STORE_UPDATE_BUDGET_LIMIT = 230;
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,7 @@ class ActuallyLoggedIn extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -1,6 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WarnUserAboutBill.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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Events\Model\Bill;
|
namespace FireflyIII\Events\Model\Bill;
|
||||||
|
@@ -1,5 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WarnUserAboutOverdueSubscriptions.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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Events\Model\Bill;
|
namespace FireflyIII\Events\Model\Bill;
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Created.php
|
|
||||||
* Copyright (c) 2023 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\Events\Model\BudgetLimit;
|
|
||||||
|
|
||||||
use FireflyIII\Events\Event;
|
|
||||||
use FireflyIII\Models\BudgetLimit;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Created
|
|
||||||
*/
|
|
||||||
class Created extends Event
|
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
public function __construct(public BudgetLimit $budgetLimit) {}
|
|
||||||
}
|
|
@@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deleted.php
|
|
||||||
* Copyright (c) 2023 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\Events\Model\BudgetLimit;
|
|
||||||
|
|
||||||
use FireflyIII\Events\Event;
|
|
||||||
use FireflyIII\Models\BudgetLimit;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Deleted
|
|
||||||
*/
|
|
||||||
class Deleted extends Event
|
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
public function __construct(public BudgetLimit $budgetLimit) {}
|
|
||||||
}
|
|
@@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Updated.php
|
|
||||||
* Copyright (c) 2023 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\Events\Model\BudgetLimit;
|
|
||||||
|
|
||||||
use FireflyIII\Events\Event;
|
|
||||||
use FireflyIII\Models\BudgetLimit;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Updated
|
|
||||||
*/
|
|
||||||
class Updated extends Event
|
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
public function __construct(public BudgetLimit $budgetLimit) {}
|
|
||||||
}
|
|
@@ -1,5 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ChangedName.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);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Events\Model\PiggyBank;
|
namespace FireflyIII\Events\Model\PiggyBank;
|
||||||
|
@@ -35,7 +35,7 @@ class DisabledMFA extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class EnabledMFA extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class MFABackupFewLeft extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user, public int $count)
|
public function __construct(Authenticatable|User|null $user, public int $count)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class MFABackupNoLeft extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class MFAManyFailedAttempts extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user, public int $count)
|
public function __construct(Authenticatable|User|null $user, public int $count)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class MFANewBackupCodes extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class MFAUsedBackupCode extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -35,7 +35,7 @@ class UserAttemptedLogin extends Event
|
|||||||
|
|
||||||
public User $user;
|
public User $user;
|
||||||
|
|
||||||
public function __construct(null|Authenticatable|User $user)
|
public function __construct(Authenticatable|User|null $user)
|
||||||
{
|
{
|
||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@@ -170,7 +170,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var null|Account $account */
|
/** @var null|Account $account */
|
||||||
$account = $user->accounts()->with(['accountType'])->withTrashed()->find($accountId);
|
$account = $user->accounts()->withTrashed()->with(['accountType'])->find($accountId);
|
||||||
if (null === $account) {
|
if (null === $account) {
|
||||||
app('log')->error(sprintf('Could not find account %d, so give big fat error.', $accountId));
|
app('log')->error(sprintf('Could not find account %d, so give big fat error.', $accountId));
|
||||||
|
|
||||||
|
@@ -282,7 +282,7 @@ class PiggyBankFactory
|
|||||||
|
|
||||||
// create event:
|
// create event:
|
||||||
Log::debug('linkToAccountIds: Trigger change for positive amount [b].');
|
Log::debug('linkToAccountIds: Trigger change for positive amount [b].');
|
||||||
event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'], null, null));
|
event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'] ?? '0', null, null));
|
||||||
}
|
}
|
||||||
if (!array_key_exists('current_amount', $info)) {
|
if (!array_key_exists('current_amount', $info)) {
|
||||||
$toBeLinked[$account->id] ??= [];
|
$toBeLinked[$account->id] ??= [];
|
||||||
|
@@ -30,6 +30,7 @@ use FireflyIII\Models\Recurrence;
|
|||||||
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||||
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\MessageBag;
|
use Illuminate\Support\MessageBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,8 +63,8 @@ class RecurrenceFactory
|
|||||||
$type = $this->findTransactionType(ucfirst((string) $data['recurrence']['type']));
|
$type = $this->findTransactionType(ucfirst((string) $data['recurrence']['type']));
|
||||||
} catch (FireflyException $e) {
|
} catch (FireflyException $e) {
|
||||||
$message = sprintf('Cannot make a recurring transaction of type "%s"', $data['recurrence']['type']);
|
$message = sprintf('Cannot make a recurring transaction of type "%s"', $data['recurrence']['type']);
|
||||||
app('log')->error($message);
|
Log::error($message);
|
||||||
app('log')->error($e->getTraceAsString());
|
Log::error($e->getTraceAsString());
|
||||||
|
|
||||||
throw new FireflyException($message, 0, $e);
|
throw new FireflyException($message, 0, $e);
|
||||||
}
|
}
|
||||||
@@ -101,17 +102,18 @@ class RecurrenceFactory
|
|||||||
|
|
||||||
$recurrence = new Recurrence(
|
$recurrence = new Recurrence(
|
||||||
[
|
[
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'user_group_id' => $this->user->user_group_id,
|
'user_group_id' => $this->user->user_group_id,
|
||||||
'transaction_type_id' => $type->id,
|
'transaction_type_id' => $type->id,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'description' => $description,
|
'description' => $description,
|
||||||
'first_date' => $firstDate?->format('Y-m-d'),
|
'first_date' => $firstDate?->format('Y-m-d'),
|
||||||
'repeat_until' => $repetitions > 0 ? null : $repeatUntilString,
|
'first_date_tz' => $firstDate?->format('e'),
|
||||||
'latest_date' => null,
|
'repeat_until' => $repetitions > 0 ? null : $repeatUntilString,
|
||||||
'repetitions' => $repetitions,
|
'latest_date' => null,
|
||||||
'apply_rules' => $applyRules,
|
'repetitions' => $repetitions,
|
||||||
'active' => $active,
|
'apply_rules' => $applyRules,
|
||||||
|
'active' => $active,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
$recurrence->save();
|
$recurrence->save();
|
||||||
@@ -125,8 +127,8 @@ class RecurrenceFactory
|
|||||||
try {
|
try {
|
||||||
$this->createTransactions($recurrence, $data['transactions'] ?? []);
|
$this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||||
} catch (FireflyException $e) {
|
} catch (FireflyException $e) {
|
||||||
app('log')->error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
app('log')->error($e->getTraceAsString());
|
Log::error($e->getTraceAsString());
|
||||||
$recurrence->forceDelete();
|
$recurrence->forceDelete();
|
||||||
$message = sprintf('Could not create recurring transaction: %s', $e->getMessage());
|
$message = sprintf('Could not create recurring transaction: %s', $e->getMessage());
|
||||||
$this->errors->add('store', $message);
|
$this->errors->add('store', $message);
|
||||||
|
@@ -26,7 +26,9 @@ namespace FireflyIII\Factory;
|
|||||||
|
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TransactionCurrencyFactory
|
* Class TransactionCurrencyFactory
|
||||||
@@ -41,14 +43,14 @@ class TransactionCurrencyFactory
|
|||||||
$data['code'] = e($data['code']);
|
$data['code'] = e($data['code']);
|
||||||
$data['symbol'] = e($data['symbol']);
|
$data['symbol'] = e($data['symbol']);
|
||||||
$data['name'] = e($data['name']);
|
$data['name'] = e($data['name']);
|
||||||
$data['decimal_places'] = (int) $data['decimal_places'];
|
$data['decimal_places'] = (int)$data['decimal_places'];
|
||||||
// if the code already exists (deleted)
|
// if the code already exists (deleted)
|
||||||
// force delete it and then create the transaction:
|
// force delete it and then create the transaction:
|
||||||
$count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
|
$count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
|
||||||
if (1 === $count) {
|
if (1 === $count) {
|
||||||
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
|
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
|
||||||
$old->forceDelete();
|
$old->forceDelete();
|
||||||
app('log')->warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code']));
|
Log::warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code']));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -64,8 +66,8 @@ class TransactionCurrencyFactory
|
|||||||
);
|
);
|
||||||
} catch (QueryException $e) {
|
} catch (QueryException $e) {
|
||||||
$result = null;
|
$result = null;
|
||||||
app('log')->error(sprintf('Could not create new currency: %s', $e->getMessage()));
|
Log::error(sprintf('Could not create new currency: %s', $e->getMessage()));
|
||||||
app('log')->error($e->getTraceAsString());
|
Log::error($e->getTraceAsString());
|
||||||
|
|
||||||
throw new FireflyException('400004: Could not store new currency.', 0, $e);
|
throw new FireflyException('400004: Could not store new currency.', 0, $e);
|
||||||
}
|
}
|
||||||
@@ -76,32 +78,33 @@ class TransactionCurrencyFactory
|
|||||||
public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
|
public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
|
||||||
{
|
{
|
||||||
$currencyCode = e($currencyCode);
|
$currencyCode = e($currencyCode);
|
||||||
$currencyId = (int) $currencyId;
|
$currencyId = (int)$currencyId;
|
||||||
|
$currency = null;
|
||||||
|
|
||||||
if ('' === $currencyCode && 0 === $currencyId) {
|
if ('' === $currencyCode && 0 === $currencyId) {
|
||||||
app('log')->debug('Cannot find anything on empty currency code and empty currency ID!');
|
Log::debug('Cannot find anything on empty currency code and empty currency ID!');
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first by ID:
|
// first by ID:
|
||||||
if ($currencyId > 0) {
|
if ($currencyId > 0) {
|
||||||
$currency = TransactionCurrency::find($currencyId);
|
try {
|
||||||
if (null !== $currency) {
|
$currency = Amount::getTransactionCurrencyById($currencyId);
|
||||||
return $currency;
|
} catch (FireflyException) {
|
||||||
|
Log::warning(sprintf('Currency ID is #%d but found nothing!', $currencyId));
|
||||||
}
|
}
|
||||||
app('log')->warning(sprintf('Currency ID is %d but found nothing!', $currencyId));
|
|
||||||
}
|
}
|
||||||
// then by code:
|
// then by code:
|
||||||
if ('' !== $currencyCode) {
|
if ('' !== $currencyCode && null === $currency) {
|
||||||
$currency = TransactionCurrency::whereCode($currencyCode)->first();
|
try {
|
||||||
if (null !== $currency) {
|
$currency = Amount::getTransactionCurrencyByCode($currencyCode);
|
||||||
return $currency;
|
} catch (FireflyException) {
|
||||||
|
Log::warning(sprintf('Currency code is "%s" but found nothing!', $currencyCode));
|
||||||
}
|
}
|
||||||
app('log')->warning(sprintf('Currency code is %d but found nothing!', $currencyCode));
|
|
||||||
}
|
}
|
||||||
app('log')->warning('Found nothing for currency.');
|
Log::info(sprintf('Found currency #%d based on ID %d and code "%s".', $currency->id, $currencyId, $currencyCode));
|
||||||
|
|
||||||
return null;
|
return $currency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user