mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-01-06 02:21:25 +00:00
Compare commits
208 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8618047bd | ||
|
|
f104b76f73 | ||
|
|
cb701d8506 | ||
|
|
70a334c56e | ||
|
|
e6b2db1e29 | ||
|
|
e8dffa0052 | ||
|
|
c4f0512f39 | ||
|
|
3268019d0c | ||
|
|
a0ef6a1fc8 | ||
|
|
99d0098b20 | ||
|
|
a7a54c042c | ||
|
|
c44e48a793 | ||
|
|
53b501ca73 | ||
|
|
322f70bcca | ||
|
|
35559c077b | ||
|
|
590ffe7c76 | ||
|
|
8a2d8f148e | ||
|
|
4f0e15e07d | ||
|
|
7463861e0c | ||
|
|
1e70fa28be | ||
|
|
26c6ca470b | ||
|
|
5e54034e0e | ||
|
|
25873ef734 | ||
|
|
1092b04b22 | ||
|
|
01ce74dd72 | ||
|
|
41430d8386 | ||
|
|
01eb19169c | ||
|
|
cfaa7d7c68 | ||
|
|
14d3312a10 | ||
|
|
87be478dd8 | ||
|
|
0b6877a20e | ||
|
|
7186f0ef60 | ||
|
|
538933691e | ||
|
|
46c49ddbd8 | ||
|
|
bcfb134b6e | ||
|
|
57981f1cf9 | ||
|
|
0310186fb7 | ||
|
|
4dcb38290e | ||
|
|
2f5c37048b | ||
|
|
370c8b16ae | ||
|
|
af0555592a | ||
|
|
9c07ddaed6 | ||
|
|
bb7355a566 | ||
|
|
1d48347f8c | ||
|
|
060b76ca9c | ||
|
|
2b2b9b6f7a | ||
|
|
f3dd05a0c0 | ||
|
|
47a91aa273 | ||
|
|
41bc236603 | ||
|
|
65349451ea | ||
|
|
e77b6a55a4 | ||
|
|
2379bcff11 | ||
|
|
7133156fa1 | ||
|
|
a59176689d | ||
|
|
bc2d8f3dfb | ||
|
|
ddf89a9d5a | ||
|
|
7daaba17f6 | ||
|
|
9cb5b1384f | ||
|
|
7d13263482 | ||
|
|
d9ff252915 | ||
|
|
51ba550251 | ||
|
|
fd21c467ad | ||
|
|
9aa90650b4 | ||
|
|
d892257e8b | ||
|
|
db0dbcfcf1 | ||
|
|
f591996f04 | ||
|
|
b08d385586 | ||
|
|
20ef22f67e | ||
|
|
c888baf542 | ||
|
|
8b0af3f666 | ||
|
|
7043e1e7c0 | ||
|
|
c5854eba23 | ||
|
|
ddf1a8cebb | ||
|
|
7dcaf167e9 | ||
|
|
b359d51d3a | ||
|
|
3913fa5086 | ||
|
|
ab2772abe0 | ||
|
|
bc7875b17b | ||
|
|
4938fa9990 | ||
|
|
84df2c80ee | ||
|
|
dc17060754 | ||
|
|
e2fa81dddc | ||
|
|
182dfc95fe | ||
|
|
c8979b6c33 | ||
|
|
ab872e8912 | ||
|
|
d36b94fabf | ||
|
|
e3d4ceaecb | ||
|
|
e3a6e5b788 | ||
|
|
57235c0e00 | ||
|
|
2298c3ddaf | ||
|
|
7224f1be6f | ||
|
|
1bd3019c16 | ||
|
|
f0fa21dead | ||
|
|
845eaed8d7 | ||
|
|
b3649cd4d0 | ||
|
|
55f14c587b | ||
|
|
441a8a8408 | ||
|
|
060c9648f1 | ||
|
|
7680c8733f | ||
|
|
5a0af5c93b | ||
|
|
f4b066add1 | ||
|
|
9ecb414b02 | ||
|
|
ad4f908c24 | ||
|
|
025f739442 | ||
|
|
6df7354c48 | ||
|
|
3f77c845ca | ||
|
|
d4771f7a5c | ||
|
|
ec4e2bfa4f | ||
|
|
dfdbfae4b5 | ||
|
|
349d38b956 | ||
|
|
2267aa3ac4 | ||
|
|
2323aa454e | ||
|
|
8b3317b665 | ||
|
|
15f893c343 | ||
|
|
309b3e765e | ||
|
|
d3fad06e00 | ||
|
|
834f24c99c | ||
|
|
35291e1298 | ||
|
|
ac4e9dcbc5 | ||
|
|
d57806f2ba | ||
|
|
3b005c317d | ||
|
|
e91903fed2 | ||
|
|
fee2002b0f | ||
|
|
f12e502eb8 | ||
|
|
24e62b1cee | ||
|
|
f559ec73e0 | ||
|
|
530b501fcf | ||
|
|
d5ea78025e | ||
|
|
3413b9b5b5 | ||
|
|
0b45c1aa76 | ||
|
|
5718d1690a | ||
|
|
67b16cc070 | ||
|
|
5746ac3247 | ||
|
|
8a2c520b11 | ||
|
|
f46c14df8c | ||
|
|
009fbba491 | ||
|
|
53d84347c2 | ||
|
|
1961487055 | ||
|
|
c9ce5df74b | ||
|
|
1371b6773e | ||
|
|
b9f1baf150 | ||
|
|
66b322e844 | ||
|
|
487b65b669 | ||
|
|
9078781d61 | ||
|
|
1ec830521a | ||
|
|
c4bf2aae7d | ||
|
|
69ca88d9f8 | ||
|
|
b38b7b2534 | ||
|
|
f19bfc3b4b | ||
|
|
d22f9c09d7 | ||
|
|
fc2da9eb42 | ||
|
|
f2c9e20aef | ||
|
|
16b8ca2746 | ||
|
|
46ea074821 | ||
|
|
d2c89781e2 | ||
|
|
e54d711891 | ||
|
|
84d3ad4764 | ||
|
|
b908951a2d | ||
|
|
8b87deea58 | ||
|
|
0d7325b3dc | ||
|
|
a3fd99a498 | ||
|
|
0ff405d1e0 | ||
|
|
46a60af966 | ||
|
|
591c9e3b39 | ||
|
|
c30461b20b | ||
|
|
2c3f86d9bc | ||
|
|
34349e4475 | ||
|
|
6acd5be5dc | ||
|
|
55a2b4e789 | ||
|
|
f41397eb43 | ||
|
|
41fc1e8f82 | ||
|
|
bee219ebf7 | ||
|
|
438f602961 | ||
|
|
429e72e681 | ||
|
|
7a134781f2 | ||
|
|
b572c1dcd3 | ||
|
|
95593f847b | ||
|
|
b82fcbd97b | ||
|
|
daddee7806 | ||
|
|
930a08ec90 | ||
|
|
fd2edf3b23 | ||
|
|
0597255c08 | ||
|
|
955ab38a85 | ||
|
|
1311a0db8b | ||
|
|
0ce9ee6a6c | ||
|
|
3a339382d4 | ||
|
|
a5b15bbc16 | ||
|
|
fbf89fd514 | ||
|
|
b3223feba2 | ||
|
|
88a9bc379e | ||
|
|
b442b91b7c | ||
|
|
9fadbbe087 | ||
|
|
1ef7239276 | ||
|
|
ea573e9434 | ||
|
|
34fa24e4a8 | ||
|
|
a1be4a4d8a | ||
|
|
b8e8af1e2a | ||
|
|
c13a3fb30c | ||
|
|
cb8fa4e1f4 | ||
|
|
bf7f4f9887 | ||
|
|
af48548e81 | ||
|
|
90d58ec8fa | ||
|
|
e92dd7f464 | ||
|
|
3bdf9eeed2 | ||
|
|
558ac7b0da | ||
|
|
9d0488ffbc | ||
|
|
d7fa8b283e | ||
|
|
a0097bd613 |
@@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
|
echo "Running PHP CS Fixer"
|
||||||
$SCRIPT_DIR/phpcs.sh
|
$SCRIPT_DIR/phpcs.sh
|
||||||
|
echo "Running PHPStan"
|
||||||
$SCRIPT_DIR/phpstan.sh
|
$SCRIPT_DIR/phpstan.sh
|
||||||
|
echo "Running PHPMD"
|
||||||
$SCRIPT_DIR/phpmd.sh
|
$SCRIPT_DIR/phpmd.sh
|
||||||
|
|||||||
52
.ci/php-cs-fixer/composer.lock
generated
52
.ci/php-cs-fixer/composer.lock
generated
@@ -8,16 +8,16 @@
|
|||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/pcre",
|
"name": "composer/pcre",
|
||||||
"version": "3.1.1",
|
"version": "3.1.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/pcre.git",
|
"url": "https://github.com/composer/pcre.git",
|
||||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
|
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
"url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/composer/pcre/issues",
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
"source": "https://github.com/composer/pcre/tree/3.1.1"
|
"source": "https://github.com/composer/pcre/tree/3.1.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-10-11T07:11:09+00:00"
|
"time": "2024-03-19T10:26:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
@@ -160,16 +160,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/xdebug-handler",
|
"name": "composer/xdebug-handler",
|
||||||
"version": "3.0.3",
|
"version": "3.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/xdebug-handler.git",
|
"url": "https://github.com/composer/xdebug-handler.git",
|
||||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c"
|
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
|
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c",
|
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.0",
|
"phpstan/phpstan": "^1.0",
|
||||||
"phpstan/phpstan-strict-rules": "^1.1",
|
"phpstan/phpstan-strict-rules": "^1.1",
|
||||||
"symfony/phpunit-bridge": "^6.0"
|
"phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -204,9 +204,9 @@
|
|||||||
"performance"
|
"performance"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/composer",
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
|
"source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -222,20 +222,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-02-25T21:32:43+00:00"
|
"time": "2024-03-26T18:29:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "friendsofphp/php-cs-fixer",
|
"name": "friendsofphp/php-cs-fixer",
|
||||||
"version": "v3.51.0",
|
"version": "v3.52.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": "127fa74f010da99053e3f5b62672615b72dd6efd"
|
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd",
|
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/6e77207f0d851862ceeb6da63e6e22c01b1587bc",
|
||||||
"reference": "127fa74f010da99053e3f5b62672615b72dd6efd",
|
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -306,7 +306,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.51.0"
|
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.52.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -314,7 +314,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-02-28T19:50:06+00:00"
|
"time": "2024-03-19T21:02:43+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@@ -471,16 +471,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/diff",
|
"name": "sebastian/diff",
|
||||||
"version": "6.0.0",
|
"version": "6.0.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||||
"reference": "3e3f502419518897a923aa1c64d51f9def2e0aff"
|
"reference": "ab83243ecc233de5655b76f577711de9f842e712"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3e3f502419518897a923aa1c64d51f9def2e0aff",
|
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712",
|
||||||
"reference": "3e3f502419518897a923aa1c64d51f9def2e0aff",
|
"reference": "ab83243ecc233de5655b76f577711de9f842e712",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -526,7 +526,7 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
||||||
"security": "https://github.com/sebastianbergmann/diff/security/policy",
|
"security": "https://github.com/sebastianbergmann/diff/security/policy",
|
||||||
"source": "https://github.com/sebastianbergmann/diff/tree/6.0.0"
|
"source": "https://github.com/sebastianbergmann/diff/tree/6.0.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -534,7 +534,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-02-02T05:56:35+00:00"
|
"time": "2024-03-02T07:30:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
|
|||||||
48
.ci/phpmd/composer.lock
generated
48
.ci/phpmd/composer.lock
generated
@@ -9,16 +9,16 @@
|
|||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "composer/pcre",
|
"name": "composer/pcre",
|
||||||
"version": "3.1.1",
|
"version": "3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/pcre.git",
|
"url": "https://github.com/composer/pcre.git",
|
||||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
|
"reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
"url": "https://api.github.com/repos/composer/pcre/zipball/4775f35b2d70865807c89d32c8e7385b86eb0ace",
|
||||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
"reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/composer/pcre/issues",
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
"source": "https://github.com/composer/pcre/tree/3.1.1"
|
"source": "https://github.com/composer/pcre/tree/3.1.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-10-11T07:11:09+00:00"
|
"time": "2024-03-07T15:38:35+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/xdebug-handler",
|
"name": "composer/xdebug-handler",
|
||||||
@@ -395,16 +395,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/config",
|
"name": "symfony/config",
|
||||||
"version": "v7.0.3",
|
"version": "v7.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/config.git",
|
"url": "https://github.com/symfony/config.git",
|
||||||
"reference": "86a5027869ca3d6bdecae6d5d6c2f77c8f2c1d16"
|
"reference": "44deeba7233f08f383185ffa37dace3b3bc87364"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/config/zipball/86a5027869ca3d6bdecae6d5d6c2f77c8f2c1d16",
|
"url": "https://api.github.com/repos/symfony/config/zipball/44deeba7233f08f383185ffa37dace3b3bc87364",
|
||||||
"reference": "86a5027869ca3d6bdecae6d5d6c2f77c8f2c1d16",
|
"reference": "44deeba7233f08f383185ffa37dace3b3bc87364",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -450,7 +450,7 @@
|
|||||||
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/config/tree/v7.0.3"
|
"source": "https://github.com/symfony/config/tree/v7.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -466,20 +466,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-01-30T08:34:29+00:00"
|
"time": "2024-02-26T07:52:39+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/dependency-injection",
|
"name": "symfony/dependency-injection",
|
||||||
"version": "v7.0.3",
|
"version": "v7.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/dependency-injection.git",
|
"url": "https://github.com/symfony/dependency-injection.git",
|
||||||
"reference": "e915c6684b8e3ae90a4441f6823ebbb40edf0b92"
|
"reference": "47f37af245df8457ea63409fc242b3cc825ce5eb"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e915c6684b8e3ae90a4441f6823ebbb40edf0b92",
|
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/47f37af245df8457ea63409fc242b3cc825ce5eb",
|
||||||
"reference": "e915c6684b8e3ae90a4441f6823ebbb40edf0b92",
|
"reference": "47f37af245df8457ea63409fc242b3cc825ce5eb",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -530,7 +530,7 @@
|
|||||||
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/dependency-injection/tree/v7.0.3"
|
"source": "https://github.com/symfony/dependency-injection/tree/v7.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -546,7 +546,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-01-30T08:34:29+00:00"
|
"time": "2024-02-22T20:27:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
@@ -921,16 +921,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/var-exporter",
|
"name": "symfony/var-exporter",
|
||||||
"version": "v7.0.3",
|
"version": "v7.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/var-exporter.git",
|
"url": "https://github.com/symfony/var-exporter.git",
|
||||||
"reference": "1fb79308cb5fc2b44bff6e8af10a5af6812e05b8"
|
"reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/1fb79308cb5fc2b44bff6e8af10a5af6812e05b8",
|
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
|
||||||
"reference": "1fb79308cb5fc2b44bff6e8af10a5af6812e05b8",
|
"reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -975,7 +975,7 @@
|
|||||||
"serialize"
|
"serialize"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/var-exporter/tree/v7.0.3"
|
"source": "https://github.com/symfony/var-exporter/tree/v7.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -991,7 +991,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-01-23T15:02:46+00:00"
|
"time": "2024-02-26T10:35:24+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|||||||
10
.env.example
10
.env.example
@@ -111,7 +111,10 @@ PGSQL_SSL_CERT=null
|
|||||||
PGSQL_SSL_KEY=null
|
PGSQL_SSL_KEY=null
|
||||||
PGSQL_SSL_CRL_FILE=null
|
PGSQL_SSL_CRL_FILE=null
|
||||||
|
|
||||||
# more PostgreSQL settings
|
# For postgresql 15 and up, setting this to public will no longer work as expected, becasuse the
|
||||||
|
# 'public' schema is without grants. This can be worked around by having a super user grant those
|
||||||
|
# necessary privileges, but in security conscious setups that's not viable.
|
||||||
|
# You will need to set this to the schema you want to use.
|
||||||
PGSQL_SCHEMA=public
|
PGSQL_SCHEMA=public
|
||||||
|
|
||||||
# If you're looking for performance improvements, you could install memcached or redis
|
# If you're looking for performance improvements, you could install memcached or redis
|
||||||
@@ -184,6 +187,11 @@ SEND_REPORT_JOURNALS=true
|
|||||||
# Since this involves an external service, it's optional and disabled by default.
|
# Since this involves an external service, it's optional and disabled by default.
|
||||||
ENABLE_EXTERNAL_MAP=false
|
ENABLE_EXTERNAL_MAP=false
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable or disable exchange rate conversion. This function isn't used yet by Firefly III
|
||||||
|
#
|
||||||
|
ENABLE_EXCHANGE_RATES=false
|
||||||
|
|
||||||
# Set this value to true if you want Firefly III to download currency exchange rates
|
# Set this value to true if you want Firefly III to download currency exchange rates
|
||||||
# from the internet. These rates are hosted by the creator of Firefly III inside
|
# from the internet. These rates are hosted by the creator of Firefly III inside
|
||||||
# an Azure Storage Container.
|
# an Azure Storage Container.
|
||||||
|
|||||||
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# code owners for this Firefly III related repository
|
||||||
|
* @JC5 @SDx3
|
||||||
4
.github/funding.yml
vendored
4
.github/funding.yml
vendored
@@ -1,4 +1,6 @@
|
|||||||
# These are supported funding model platforms
|
# Firefly III sponsor options
|
||||||
|
|
||||||
github: jc5
|
github: jc5
|
||||||
patreon: JC5
|
patreon: JC5
|
||||||
|
ko_fi: jamesc5
|
||||||
|
liberapay: JC5
|
||||||
|
|||||||
2
.github/workflows/cleanup.yml
vendored
2
.github/workflows/cleanup.yml
vendored
@@ -7,7 +7,7 @@ permissions:
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 1 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
prune:
|
prune:
|
||||||
|
|||||||
20
.github/workflows/lock.yml
vendored
20
.github/workflows/lock.yml
vendored
@@ -3,17 +3,27 @@ name: 'Issues - Lock old issues'
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 2 * * *'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: lock-threads
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lock:
|
lock:
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: JC5/lock-threads@main
|
- uses: dessant/lock-threads@v5
|
||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
issue-inactive-days: 21
|
||||||
issue-inactive-days: 7
|
pr-inactive-days: 21
|
||||||
pr-inactive-days: 7
|
discussion-inactive-days: 21
|
||||||
|
log-output: true
|
||||||
|
|||||||
100
.github/workflows/release.yml
vendored
100
.github/workflows/release.yml
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
default: 'develop'
|
default: 'develop'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '15 0 * * MON,THU'
|
- cron: '0 3 * * MON,THU'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -51,7 +51,7 @@ jobs:
|
|||||||
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
|
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
|
||||||
- name: Cleanup translations
|
- name: Cleanup translations
|
||||||
id: cleanup-transactions
|
id: cleanup-transactions
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:crowdin-warning'
|
action: 'ff3:crowdin-warning'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
GH_TOKEN: ''
|
GH_TOKEN: ''
|
||||||
- name: Cleanup changelog
|
- name: Cleanup changelog
|
||||||
id: cleanup-changelog
|
id: cleanup-changelog
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:changelog'
|
action: 'ff3:changelog'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -69,7 +69,7 @@ jobs:
|
|||||||
GH_TOKEN: ${{ secrets.CHANGELOG_TOKEN }}
|
GH_TOKEN: ${{ secrets.CHANGELOG_TOKEN }}
|
||||||
- name: Extract changelog
|
- name: Extract changelog
|
||||||
id: extract-changelog
|
id: extract-changelog
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:extract-changelog'
|
action: 'ff3:extract-changelog'
|
||||||
output: 'output'
|
output: 'output'
|
||||||
@@ -78,7 +78,7 @@ jobs:
|
|||||||
GH_TOKEN: ""
|
GH_TOKEN: ""
|
||||||
- name: Replace version
|
- name: Replace version
|
||||||
id: replace-version
|
id: replace-version
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:version'
|
action: 'ff3:version'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
- name: Generate JSON v1
|
- name: Generate JSON v1
|
||||||
id: json-v1
|
id: json-v1
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:json-translations v1'
|
action: 'ff3:json-translations v1'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -97,7 +97,7 @@ jobs:
|
|||||||
GH_TOKEN: ''
|
GH_TOKEN: ''
|
||||||
- name: Generate JSON v2
|
- name: Generate JSON v2
|
||||||
id: json-v2
|
id: json-v2
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:json-translations v2'
|
action: 'ff3:json-translations v2'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -106,7 +106,7 @@ jobs:
|
|||||||
GH_TOKEN: ''
|
GH_TOKEN: ''
|
||||||
- name: Code cleanup
|
- name: Code cleanup
|
||||||
id: code-cleanup
|
id: code-cleanup
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:code'
|
action: 'ff3:code'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -115,11 +115,12 @@ jobs:
|
|||||||
GH_TOKEN: ''
|
GH_TOKEN: ''
|
||||||
- name: Build new JS
|
- name: Build new JS
|
||||||
run: |
|
run: |
|
||||||
npm upgrade
|
npm install
|
||||||
|
npm update
|
||||||
npm run build
|
npm run build
|
||||||
- name: Build old JS
|
- name: Build old JS
|
||||||
id: old-js
|
id: old-js
|
||||||
uses: JC5/firefly-iii-dev@v33
|
uses: JC5/firefly-iii-dev@v36
|
||||||
with:
|
with:
|
||||||
action: 'ff3:old-js'
|
action: 'ff3:old-js'
|
||||||
output: ''
|
output: ''
|
||||||
@@ -140,8 +141,20 @@ jobs:
|
|||||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||||
git config advice.addIgnoredFile false
|
git config advice.addIgnoredFile false
|
||||||
|
|
||||||
|
# update composer (again)
|
||||||
|
composer validate --strict
|
||||||
|
composer update --no-dev --no-scripts --no-plugins
|
||||||
|
composer dump-autoload
|
||||||
|
|
||||||
|
releaseName=$version
|
||||||
|
zipName=FireflyIII-$version.zip
|
||||||
|
tarName=FireflyIII-$version.tar.gz
|
||||||
|
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||||
|
releaseName=$version-$(date +'%Y%m%d')
|
||||||
|
zipName=FireflyIII-develop.zip
|
||||||
|
tarName=FireflyIII-develop.tar.gz
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git add -A
|
git add -A
|
||||||
@@ -151,19 +164,64 @@ 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
|
||||||
|
|
||||||
|
# zip and tar everything
|
||||||
|
zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*"
|
||||||
|
touch $tarName
|
||||||
|
tar --exclude=$tarName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' -czf $tarName .
|
||||||
|
|
||||||
|
# add sha256 sum
|
||||||
|
sha256sum -b $zipName > $zipName.sha256
|
||||||
|
sha256sum -b $tarName > $tarName.sha256
|
||||||
|
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
echo "Create nightly release."
|
# add text to output.txt (instructions)
|
||||||
git tag -a $version-$(date +'%Y%m%d') -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
|
|
||||||
git push origin $version-$(date +'%Y%m%d')
|
|
||||||
gh release create $version-$(date +'%Y%m%d') -p --verify-tag \
|
|
||||||
-t "Development release for $(date +'%Y-%m-%d')" \
|
|
||||||
-n "Bi-weekly development release of Firefly III with the latest fixes, translations and features. This release was created on **$(date +'%Y-%m-%d')** and may contain bugs. Use at your own risk. Docker users can find this release under the \`develop\` tag."
|
|
||||||
else
|
|
||||||
echo "Create default release."
|
|
||||||
git tag -a $version -m "Here be changelog"
|
|
||||||
git push origin $version
|
|
||||||
gh release create $version -F output.txt -t "$version" --verify-tag
|
|
||||||
rm output.txt
|
rm output.txt
|
||||||
|
echo "Bi-weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible." >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo ":warning: Please be careful with this pre-release, as is may not work as expected." >> output.txt
|
||||||
|
|
||||||
|
# create the release:
|
||||||
|
echo "Create nightly release."
|
||||||
|
git tag -a $releaseName -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
|
||||||
|
git push origin $releaseName
|
||||||
|
gh release create $releaseName -p --verify-tag \
|
||||||
|
-t "Development release for $(date +'%Y-%m-%d')" \
|
||||||
|
-F output.txt
|
||||||
|
|
||||||
|
# add zip file to release.
|
||||||
|
gh release upload $releaseName $zipName
|
||||||
|
gh release upload $releaseName $tarName
|
||||||
|
|
||||||
|
# add sha256 sum to release
|
||||||
|
gh release upload $releaseName $zipName.sha256
|
||||||
|
gh release upload $releaseName $tarName.sha256
|
||||||
|
|
||||||
|
# rm output.txt again
|
||||||
|
rm output.txt
|
||||||
|
else
|
||||||
|
# add text to output.txt (more instructions)
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo '### Instructions' >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
|
||||||
|
echo "Create default release."
|
||||||
|
git tag -a $releaseName -m "Here be changelog"
|
||||||
|
git push origin $releaseName
|
||||||
|
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag
|
||||||
|
# add zip file to release.
|
||||||
|
gh release upload $releaseName $zipName
|
||||||
|
# add sha256 sum to release
|
||||||
|
gh release upload $releaseName $zipName.sha256
|
||||||
|
rm output.txt
|
||||||
|
rm $zipName
|
||||||
|
rm $zipName.sha256
|
||||||
git checkout develop
|
git checkout develop
|
||||||
git merge main
|
git merge main
|
||||||
git push
|
git push
|
||||||
|
|||||||
9
.github/workflows/sonarcloud.yml
vendored
9
.github/workflows/sonarcloud.yml
vendored
@@ -45,15 +45,6 @@ jobs:
|
|||||||
- name: Install Composer dependencies
|
- name: Install Composer dependencies
|
||||||
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
|
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
|
||||||
|
|
||||||
- name: PHPStan
|
|
||||||
run: .ci/phpstan.sh
|
|
||||||
|
|
||||||
- name: PHPMD
|
|
||||||
run: .ci/phpmd.sh
|
|
||||||
|
|
||||||
- name: PHP CS Fixer
|
|
||||||
run: .ci/phpcs.sh
|
|
||||||
|
|
||||||
- name: "Create database file"
|
- name: "Create database file"
|
||||||
run: touch storage/database/database.sqlite
|
run: touch storage/database/database.sqlite
|
||||||
|
|
||||||
|
|||||||
10
.github/workflows/stale.yml
vendored
10
.github/workflows/stale.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
name: "Issues - Mark and close stale issues"
|
name: "Issues - Mark and close stale issues"
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "30 1 * * *"
|
- cron: "0 4 * * *"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -18,16 +18,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
stale-issue-message: >
|
stale-issue-message: >
|
||||||
Hi there!
|
Hi there!
|
||||||
|
|
||||||
This is an automatic reply. `Share and enjoy`
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
stale-pr-message: >
|
stale-pr-message: >
|
||||||
Hi there!
|
Hi there!
|
||||||
|
|
||||||
This is an automatic reply. `Share and enjoy`
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,3 +7,6 @@ yarn-error.log
|
|||||||
.env
|
.env
|
||||||
/.ci/php-cs-fixer/vendor
|
/.ci/php-cs-fixer/vendor
|
||||||
coverage.xml
|
coverage.xml
|
||||||
|
|
||||||
|
# ignore generated files.
|
||||||
|
public/build
|
||||||
|
|||||||
47
app/Api/V1/Controllers/Models/Rule/ExpressionController.php
Normal file
47
app/Api/V1/Controllers/Models/Rule/ExpressionController.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* ExpressionController.php
|
||||||
|
* Copyright (c) 2024 Michael Thomas
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Controllers\Models\Rule;
|
||||||
|
|
||||||
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V1\Requests\Models\Rule\ValidateExpressionRequest;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ExpressionController
|
||||||
|
*/
|
||||||
|
class ExpressionController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This endpoint is documented at:
|
||||||
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/validateExpression
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
|
*/
|
||||||
|
public function validateExpression(ValidateExpressionRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
return response()->json([
|
||||||
|
'valid' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -281,7 +281,7 @@ class BasicController extends Controller
|
|||||||
$spentInCurrency = $row['sum'];
|
$spentInCurrency = $row['sum'];
|
||||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||||
|
|
||||||
$days = $today->diffInDays($end) + 1;
|
$days = (int)$today->diffInDays($end, true) + 1;
|
||||||
$perDay = '0';
|
$perDay = '0';
|
||||||
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
||||||
$perDay = bcdiv($leftToSpend, (string)$days);
|
$perDay = bcdiv($leftToSpend, (string)$days);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class DateRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$start = $this->getCarbonDate('start');
|
$start = $this->getCarbonDate('start');
|
||||||
$end = $this->getCarbonDate('end');
|
$end = $this->getCarbonDate('end');
|
||||||
if ($start->diffInYears($end) > 5) {
|
if ($start->diffInYears($end, true) > 5) {
|
||||||
throw new FireflyException('Date range out of range.');
|
throw new FireflyException('Date range out of range.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
||||||
|
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
|
use FireflyIII\Rules\IsValidActionExpression;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use FireflyIII\Support\Request\GetRuleConfiguration;
|
use FireflyIII\Support\Request\GetRuleConfiguration;
|
||||||
@@ -57,7 +58,6 @@ class StoreRequest extends FormRequest
|
|||||||
'active' => ['active', 'boolean'],
|
'active' => ['active', 'boolean'],
|
||||||
];
|
];
|
||||||
$data = $this->getAllData($fields);
|
$data = $this->getAllData($fields);
|
||||||
|
|
||||||
$data['triggers'] = $this->getRuleTriggers();
|
$data['triggers'] = $this->getRuleTriggers();
|
||||||
$data['actions'] = $this->getRuleActions();
|
$data['actions'] = $this->getRuleActions();
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ class StoreRequest extends FormRequest
|
|||||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||||
'triggers.*.active' => [new IsBoolean()],
|
'triggers.*.active' => [new IsBoolean()],
|
||||||
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
||||||
'actions.*.value' => 'required_if:actions.*.type,'.$contextActions.'|ruleActionValue',
|
'actions.*.value' => [sprintf('required_if:actions.*.type,%s', $contextActions), new IsValidActionExpression(), 'ruleActionValue'],
|
||||||
'actions.*.stop_processing' => [new IsBoolean()],
|
'actions.*.stop_processing' => [new IsBoolean()],
|
||||||
'actions.*.active' => [new IsBoolean()],
|
'actions.*.active' => [new IsBoolean()],
|
||||||
'strict' => [new IsBoolean()],
|
'strict' => [new IsBoolean()],
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
|||||||
|
|
||||||
use FireflyIII\Models\Rule;
|
use FireflyIII\Models\Rule;
|
||||||
use FireflyIII\Rules\IsBoolean;
|
use FireflyIII\Rules\IsBoolean;
|
||||||
|
use FireflyIII\Rules\IsValidActionExpression;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use FireflyIII\Support\Request\GetRuleConfiguration;
|
use FireflyIII\Support\Request\GetRuleConfiguration;
|
||||||
@@ -140,7 +141,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||||
'triggers.*.active' => [new IsBoolean()],
|
'triggers.*.active' => [new IsBoolean()],
|
||||||
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
||||||
'actions.*.value' => 'required_if:actions.*.type,'.$contextActions.'|ruleActionValue',
|
'actions.*.value' => [sprintf('required_if:actions.*.type,%s', $contextActions), new IsValidActionExpression(), 'ruleActionValue'],
|
||||||
'actions.*.stop_processing' => [new IsBoolean()],
|
'actions.*.stop_processing' => [new IsBoolean()],
|
||||||
'actions.*.active' => [new IsBoolean()],
|
'actions.*.active' => [new IsBoolean()],
|
||||||
'strict' => [new IsBoolean()],
|
'strict' => [new IsBoolean()],
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ValidateExpressionRequest.php
|
||||||
|
* Copyright (c) 2024 Michael Thomas
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
||||||
|
|
||||||
|
use FireflyIII\Rules\IsValidActionExpression;
|
||||||
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ValidateExpressionRequest
|
||||||
|
*/
|
||||||
|
class ValidateExpressionRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use ChecksLogin;
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return ['expression' => ['required', new IsValidActionExpression()]];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -158,7 +158,8 @@ class Controller extends BaseController
|
|||||||
|
|
||||||
// the transformer, at this point, needs to collect information that ALL items in the collection
|
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||||
// require, like meta-data and stuff like that, and save it for later.
|
// require, like meta-data and stuff like that, and save it for later.
|
||||||
$transformer->collectMetaData($objects);
|
$objects = $transformer->collectMetaData($objects);
|
||||||
|
$paginator->setCollection($objects);
|
||||||
|
|
||||||
$resource = new FractalCollection($objects, $transformer, $key);
|
$resource = new FractalCollection($objects, $transformer, $key);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|||||||
104
app/Api/V2/Controllers/Model/Account/IndexController.php
Normal file
104
app/Api/V2/Controllers/Model/Account/IndexController.php
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* IndexController.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
||||||
|
|
||||||
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V2\Request\Model\Account\IndexRequest;
|
||||||
|
use FireflyIII\Api\V2\Request\Model\Transaction\InfiniteListRequest;
|
||||||
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
class IndexController extends Controller
|
||||||
|
{
|
||||||
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AccountController constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
$this->repository = app(AccountRepositoryInterface::class);
|
||||||
|
// new way of user group validation
|
||||||
|
$userGroup = $this->validateUserGroup($request);
|
||||||
|
if (null !== $userGroup) {
|
||||||
|
$this->repository->setUserGroup($userGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO see autocomplete/accountcontroller for list.
|
||||||
|
*/
|
||||||
|
public function index(IndexRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$this->repository->resetAccountOrder();
|
||||||
|
$types = $request->getAccountTypes();
|
||||||
|
$instructions = $request->getSortInstructions('accounts');
|
||||||
|
$accounts = $this->repository->getAccountsByType($types, $instructions);
|
||||||
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
$count = $accounts->count();
|
||||||
|
$accounts = $accounts->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||||
|
$transformer = new AccountTransformer();
|
||||||
|
|
||||||
|
$this->parameters->set('sort', $instructions);
|
||||||
|
$transformer->setParameters($this->parameters); // give params to transformer
|
||||||
|
|
||||||
|
return response()
|
||||||
|
->json($this->jsonApiList('accounts', $paginator, $transformer))
|
||||||
|
->header('Content-Type', self::CONTENT_TYPE)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function infiniteList(InfiniteListRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$this->repository->resetAccountOrder();
|
||||||
|
|
||||||
|
// get accounts of the specified type, and return.
|
||||||
|
$types = $request->getAccountTypes();
|
||||||
|
|
||||||
|
// get from repository
|
||||||
|
$accounts = $this->repository->getAccountsInOrder($types, $request->getSortInstructions('accounts'), $request->getStartRow(), $request->getEndRow());
|
||||||
|
$total = $this->repository->countAccounts($types);
|
||||||
|
$count = $request->getEndRow() - $request->getStartRow();
|
||||||
|
$paginator = new LengthAwarePaginator($accounts, $total, $count, $this->parameters->get('page'));
|
||||||
|
$transformer = new AccountTransformer();
|
||||||
|
$transformer->setParameters($this->parameters); // give params to transformer
|
||||||
|
|
||||||
|
return response()
|
||||||
|
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||||
|
->header('Content-Type', self::CONTENT_TYPE)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
79
app/Api/V2/Controllers/Model/Account/UpdateController.php
Normal file
79
app/Api/V2/Controllers/Model/Account/UpdateController.php
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* UpdateController.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
||||||
|
|
||||||
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V2\Request\Model\Account\UpdateRequest;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
class UpdateController extends Controller
|
||||||
|
{
|
||||||
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AccountController constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
$this->repository = app(AccountRepositoryInterface::class);
|
||||||
|
// new way of user group validation
|
||||||
|
$userGroup = $this->validateUserGroup($request);
|
||||||
|
if (null !== $userGroup) {
|
||||||
|
$this->repository->setUserGroup($userGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO this endpoint is not yet reachable.
|
||||||
|
*/
|
||||||
|
public function update(UpdateRequest $request, Account $account): JsonResponse
|
||||||
|
{
|
||||||
|
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||||
|
$data = $request->getUpdateData();
|
||||||
|
$data['type'] = config('firefly.shortNamesByFullName.'.$account->accountType->type);
|
||||||
|
$account = $this->repository->update($account, $data);
|
||||||
|
$account->refresh();
|
||||||
|
app('preferences')->mark();
|
||||||
|
|
||||||
|
$transformer = new AccountTransformer();
|
||||||
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
|
return response()
|
||||||
|
->api($this->jsonApiObject('accounts', $account, $transformer))
|
||||||
|
->header('Content-Type', self::CONTENT_TYPE)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -298,7 +298,7 @@ class BasicController extends Controller
|
|||||||
app('log')->debug(sprintf('Amount left is %s', $left));
|
app('log')->debug(sprintf('Amount left is %s', $left));
|
||||||
|
|
||||||
// how much left per day?
|
// how much left per day?
|
||||||
$days = $today->diffInDays($end) + 1;
|
$days = (int) $today->diffInDays($end, true) + 1;
|
||||||
$perDay = '0';
|
$perDay = '0';
|
||||||
$perDayNative = '0';
|
$perDayNative = '0';
|
||||||
if (0 !== $days && bccomp($left, '0') > -1) {
|
if (0 !== $days && bccomp($left, '0') > -1) {
|
||||||
|
|||||||
@@ -35,6 +35,47 @@ use Illuminate\Http\JsonResponse;
|
|||||||
*/
|
*/
|
||||||
class TransactionController extends Controller
|
class TransactionController extends Controller
|
||||||
{
|
{
|
||||||
|
public function infiniteList(InfiniteListRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
// get sort instructions
|
||||||
|
$instructions = $request->getSortInstructions('transactions');
|
||||||
|
|
||||||
|
// collect transactions:
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
$collector->setUserGroup(auth()->user()->userGroup)
|
||||||
|
->withAPIInformation()
|
||||||
|
->setStartRow($request->getStartRow())
|
||||||
|
->setEndRow($request->getEndRow())
|
||||||
|
->setTypes($request->getTransactionTypes())
|
||||||
|
->setSorting($instructions)
|
||||||
|
;
|
||||||
|
|
||||||
|
$start = $this->parameters->get('start');
|
||||||
|
$end = $this->parameters->get('end');
|
||||||
|
if (null !== $start) {
|
||||||
|
$collector->setStart($start);
|
||||||
|
}
|
||||||
|
if (null !== $end) {
|
||||||
|
$collector->setEnd($end);
|
||||||
|
}
|
||||||
|
|
||||||
|
$paginator = $collector->getPaginatedGroups();
|
||||||
|
$params = $request->buildParams();
|
||||||
|
$paginator->setPath(
|
||||||
|
sprintf(
|
||||||
|
'%s?%s',
|
||||||
|
route('api.v2.infinite.transactions.list'),
|
||||||
|
$params
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()
|
||||||
|
->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
|
||||||
|
->header('Content-Type', self::CONTENT_TYPE)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
public function list(ListRequest $request): JsonResponse
|
public function list(ListRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
// collect transactions:
|
// collect transactions:
|
||||||
@@ -75,45 +116,4 @@ class TransactionController extends Controller
|
|||||||
->header('Content-Type', self::CONTENT_TYPE)
|
->header('Content-Type', self::CONTENT_TYPE)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function infiniteList(InfiniteListRequest $request): JsonResponse
|
|
||||||
{
|
|
||||||
// get sort instructions
|
|
||||||
$instructions = $request->getSortInstructions();
|
|
||||||
|
|
||||||
// collect transactions:
|
|
||||||
/** @var GroupCollectorInterface $collector */
|
|
||||||
$collector = app(GroupCollectorInterface::class);
|
|
||||||
$collector->setUserGroup(auth()->user()->userGroup)
|
|
||||||
->withAPIInformation()
|
|
||||||
->setStartRow($request->getStartRow())
|
|
||||||
->setEndRow($request->getEndRow())
|
|
||||||
->setTypes($request->getTransactionTypes())
|
|
||||||
->setSorting($instructions)
|
|
||||||
;
|
|
||||||
|
|
||||||
$start = $this->parameters->get('start');
|
|
||||||
$end = $this->parameters->get('end');
|
|
||||||
if (null !== $start) {
|
|
||||||
$collector->setStart($start);
|
|
||||||
}
|
|
||||||
if (null !== $end) {
|
|
||||||
$collector->setEnd($end);
|
|
||||||
}
|
|
||||||
|
|
||||||
$paginator = $collector->getPaginatedGroups();
|
|
||||||
$params = $request->buildParams();
|
|
||||||
$paginator->setPath(
|
|
||||||
sprintf(
|
|
||||||
'%s?%s',
|
|
||||||
route('api.v2.infinite.transactions.list'),
|
|
||||||
$params
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return response()
|
|
||||||
->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
|
|
||||||
->header('Content-Type', self::CONTENT_TYPE)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
69
app/Api/V2/Request/Model/Account/IndexRequest.php
Normal file
69
app/Api/V2/Request/Model/Account/IndexRequest.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* IndexRequest.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V2\Request\Model\Account;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use FireflyIII\Support\Request\GetSortInstructions;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class IndexRequest
|
||||||
|
*
|
||||||
|
* Lots of code stolen from the SingleDateRequest.
|
||||||
|
*/
|
||||||
|
class IndexRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use AccountFilter;
|
||||||
|
use ChecksLogin;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
use GetSortInstructions;
|
||||||
|
|
||||||
|
public function getAccountTypes(): array
|
||||||
|
{
|
||||||
|
$type = (string)$this->get('type', 'default');
|
||||||
|
|
||||||
|
return $this->mapAccountTypes($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all data from the request.
|
||||||
|
*/
|
||||||
|
public function getDate(): Carbon
|
||||||
|
{
|
||||||
|
return $this->getCarbonDate('date');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rules that the incoming request must be matched against.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
116
app/Api/V2/Request/Model/Account/UpdateRequest.php
Normal file
116
app/Api/V2/Request/Model/Account/UpdateRequest.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* UpdateRequest.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V2\Request\Model\Account;
|
||||||
|
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use FireflyIII\Models\Location;
|
||||||
|
use FireflyIII\Rules\IsBoolean;
|
||||||
|
use FireflyIII\Rules\UniqueAccountNumber;
|
||||||
|
use FireflyIII\Rules\UniqueIban;
|
||||||
|
use FireflyIII\Support\Request\AppendsLocationData;
|
||||||
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use AppendsLocationData;
|
||||||
|
use ChecksLogin;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO is a duplicate of the v1 update thing.
|
||||||
|
*/
|
||||||
|
public function getUpdateData(): array
|
||||||
|
{
|
||||||
|
$fields = [
|
||||||
|
'name' => ['name', 'convertString'],
|
||||||
|
'active' => ['active', 'boolean'],
|
||||||
|
'include_net_worth' => ['include_net_worth', 'boolean'],
|
||||||
|
'account_type_name' => ['type', 'convertString'],
|
||||||
|
'virtual_balance' => ['virtual_balance', 'convertString'],
|
||||||
|
'iban' => ['iban', 'convertString'],
|
||||||
|
'BIC' => ['bic', 'convertString'],
|
||||||
|
'account_number' => ['account_number', 'convertString'],
|
||||||
|
'account_role' => ['account_role', 'convertString'],
|
||||||
|
'liability_type' => ['liability_type', 'convertString'],
|
||||||
|
'opening_balance' => ['opening_balance', 'convertString'],
|
||||||
|
'opening_balance_date' => ['opening_balance_date', 'convertDateTime'],
|
||||||
|
'cc_type' => ['credit_card_type', 'convertString'],
|
||||||
|
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertDateTime'],
|
||||||
|
'notes' => ['notes', 'stringWithNewlines'],
|
||||||
|
'interest' => ['interest', 'convertString'],
|
||||||
|
'interest_period' => ['interest_period', 'convertString'],
|
||||||
|
'order' => ['order', 'convertInteger'],
|
||||||
|
'currency_id' => ['currency_id', 'convertInteger'],
|
||||||
|
'currency_code' => ['currency_code', 'convertString'],
|
||||||
|
'liability_direction' => ['liability_direction', 'convertString'],
|
||||||
|
'liability_amount' => ['liability_amount', 'convertString'],
|
||||||
|
'liability_start_date' => ['liability_start_date', 'date'],
|
||||||
|
];
|
||||||
|
$data = $this->getAllData($fields);
|
||||||
|
|
||||||
|
return $this->appendLocationData($data, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO is a duplicate of the v1 UpdateRequest method.
|
||||||
|
*
|
||||||
|
* The rules that the incoming request must be matched against.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
/** @var Account $account */
|
||||||
|
$account = $this->route()->parameter('account');
|
||||||
|
$accountRoles = implode(',', config('firefly.accountRoles'));
|
||||||
|
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
|
||||||
|
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
'name' => sprintf('min:1|max:1024|uniqueAccountForUser:%d', $account->id),
|
||||||
|
'type' => sprintf('in:%s', $types),
|
||||||
|
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
|
||||||
|
'bic' => 'bic|nullable',
|
||||||
|
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
|
||||||
|
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
|
||||||
|
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
|
||||||
|
'virtual_balance' => 'numeric|nullable',
|
||||||
|
'order' => 'numeric|nullable',
|
||||||
|
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||||
|
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||||
|
'active' => [new IsBoolean()],
|
||||||
|
'include_net_worth' => [new IsBoolean()],
|
||||||
|
'account_role' => sprintf('in:%s|nullable|required_if:type,asset', $accountRoles),
|
||||||
|
'credit_card_type' => sprintf('in:%s|nullable|required_if:account_role,ccAsset', $ccPaymentTypes),
|
||||||
|
'monthly_payment_date' => 'date|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
|
||||||
|
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage',
|
||||||
|
'liability_direction' => 'required_if:type,liability|in:credit,debit',
|
||||||
|
'interest' => 'required_if:type,liability|min:0|max:100|numeric',
|
||||||
|
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
|
||||||
|
'notes' => 'min:0|max:32768',
|
||||||
|
];
|
||||||
|
|
||||||
|
return Location::requestRules($rules);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,9 +25,11 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V2\Request\Model\Transaction;
|
namespace FireflyIII\Api\V2\Request\Model\Transaction;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use FireflyIII\Support\Request\GetSortInstructions;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,8 +38,10 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
*/
|
*/
|
||||||
class InfiniteListRequest extends FormRequest
|
class InfiniteListRequest extends FormRequest
|
||||||
{
|
{
|
||||||
|
use AccountFilter;
|
||||||
use ChecksLogin;
|
use ChecksLogin;
|
||||||
use ConvertsDataTypes;
|
use ConvertsDataTypes;
|
||||||
|
use GetSortInstructions;
|
||||||
use TransactionFilter;
|
use TransactionFilter;
|
||||||
|
|
||||||
public function buildParams(): string
|
public function buildParams(): string
|
||||||
@@ -81,6 +85,13 @@ class InfiniteListRequest extends FormRequest
|
|||||||
return $this->getCarbonDate('end');
|
return $this->getCarbonDate('end');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAccountTypes(): array
|
||||||
|
{
|
||||||
|
$type = (string)$this->get('type', 'default');
|
||||||
|
|
||||||
|
return $this->mapAccountTypes($type);
|
||||||
|
}
|
||||||
|
|
||||||
public function getPage(): int
|
public function getPage(): int
|
||||||
{
|
{
|
||||||
$page = $this->convertInteger('page');
|
$page = $this->convertInteger('page');
|
||||||
@@ -88,31 +99,6 @@ class InfiniteListRequest extends FormRequest
|
|||||||
return 0 === $page || $page > 65536 ? 1 : $page;
|
return 0 === $page || $page > 65536 ? 1 : $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSortInstructions(): array
|
|
||||||
{
|
|
||||||
$allowed = config('firefly.sorting.allowed.transactions');
|
|
||||||
$set = $this->get('sorting', []);
|
|
||||||
$result = [];
|
|
||||||
if (0 === count($set)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
foreach ($set as $info) {
|
|
||||||
$column = $info['column'] ?? 'NOPE';
|
|
||||||
$direction = $info['direction'] ?? 'NOPE';
|
|
||||||
if ('asc' !== $direction && 'desc' !== $direction) {
|
|
||||||
// skip invalid direction
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (false === in_array($column, $allowed, true)) {
|
|
||||||
// skip invalid column
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$result[$column] = $direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTransactionTypes(): array
|
public function getTransactionTypes(): array
|
||||||
{
|
{
|
||||||
$type = (string)$this->get('type', 'default');
|
$type = (string)$this->get('type', 'default');
|
||||||
|
|||||||
@@ -53,40 +53,40 @@ class ForceDecimalSize extends Command
|
|||||||
{
|
{
|
||||||
use ShowsFriendlyMessages;
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
|
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
|
||||||
protected $signature = 'firefly-iii:force-decimal-size';
|
protected $signature = 'firefly-iii:force-decimal-size';
|
||||||
private string $cast;
|
private string $cast;
|
||||||
private array $classes
|
private array $classes
|
||||||
= [
|
= [
|
||||||
'accounts' => Account::class,
|
'accounts' => Account::class,
|
||||||
'auto_budgets' => AutoBudget::class,
|
'auto_budgets' => AutoBudget::class,
|
||||||
'available_budgets' => AvailableBudget::class,
|
'available_budgets' => AvailableBudget::class,
|
||||||
'bills' => Bill::class,
|
'bills' => Bill::class,
|
||||||
'budget_limits' => BudgetLimit::class,
|
'budget_limits' => BudgetLimit::class,
|
||||||
'piggy_bank_events' => PiggyBankEvent::class,
|
'piggy_bank_events' => PiggyBankEvent::class,
|
||||||
'piggy_bank_repetitions' => PiggyBankRepetition::class,
|
'piggy_bank_repetitions' => PiggyBankRepetition::class,
|
||||||
'piggy_banks' => PiggyBank::class,
|
'piggy_banks' => PiggyBank::class,
|
||||||
'recurrences_transactions' => RecurrenceTransaction::class,
|
'recurrences_transactions' => RecurrenceTransaction::class,
|
||||||
'transactions' => Transaction::class,
|
'transactions' => Transaction::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
private string $operator;
|
private string $operator;
|
||||||
private string $regularExpression;
|
private string $regularExpression;
|
||||||
private array $tables
|
private array $tables
|
||||||
= [
|
= [
|
||||||
'accounts' => ['virtual_balance'],
|
'accounts' => ['virtual_balance'],
|
||||||
'auto_budgets' => ['amount'],
|
'auto_budgets' => ['amount'],
|
||||||
'available_budgets' => ['amount'],
|
'available_budgets' => ['amount'],
|
||||||
'bills' => ['amount_min', 'amount_max'],
|
'bills' => ['amount_min', 'amount_max'],
|
||||||
'budget_limits' => ['amount'],
|
'budget_limits' => ['amount'],
|
||||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||||
'limit_repetitions' => ['amount'],
|
'limit_repetitions' => ['amount'],
|
||||||
'piggy_bank_events' => ['amount'],
|
'piggy_bank_events' => ['amount'],
|
||||||
'piggy_bank_repetitions' => ['currentamount'],
|
'piggy_bank_repetitions' => ['currentamount'],
|
||||||
'piggy_banks' => ['targetamount'],
|
'piggy_banks' => ['targetamount'],
|
||||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||||
'transactions' => ['amount', 'foreign_amount'],
|
'transactions' => ['amount', 'foreign_amount'],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
|
|||||||
65
app/Console/Commands/System/LaravelPassportKeys.php
Normal file
65
app/Console/Commands/System/LaravelPassportKeys.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/*
|
||||||
|
* LaravelPassportKeys.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Console\Commands\System;
|
||||||
|
|
||||||
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||||
|
|
||||||
|
class LaravelPassportKeys extends Command
|
||||||
|
{
|
||||||
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'firefly-iii:laravel-passport-keys';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Calls the Laravel "passport:keys" but doesn\'t exit 1.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
Artisan::call('passport:keys --no-interaction', []);
|
||||||
|
$result = Artisan::output();
|
||||||
|
if (str_contains($result, 'Encryption keys already exist')) {
|
||||||
|
$this->friendlyInfo('Encryption keys exist already.');
|
||||||
|
|
||||||
|
return CommandAlias::SUCCESS;
|
||||||
|
}
|
||||||
|
$this->friendlyPositive('Encryption keys have been created, nice!');
|
||||||
|
|
||||||
|
return CommandAlias::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/*
|
||||||
* ApplyRules.php
|
* ApplyRules.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2024 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).
|
||||||
*
|
*
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
* 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);
|
declare(strict_types=1);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Cron.php
|
* Cron.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2024 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).
|
||||||
*
|
*
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
* 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);
|
declare(strict_types=1);
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class AppendBudgetLimitPeriods extends Command
|
|||||||
return 'daily';
|
return 'daily';
|
||||||
}
|
}
|
||||||
// is weekly
|
// is weekly
|
||||||
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === $limit->end_date->diffInDays($limit->start_date)) {
|
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === (int)$limit->end_date->diffInDays($limit->start_date, true)) {
|
||||||
return 'weekly';
|
return 'weekly';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ class AppendBudgetLimitPeriods extends Command
|
|||||||
if (
|
if (
|
||||||
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
|
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
|
||||||
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
|
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
|
||||||
&& 2 === $limit->start_date->diffInMonths($limit->end_date)
|
&& 2 === (int)$limit->start_date->diffInMonths($limit->end_date, true)
|
||||||
) {
|
) {
|
||||||
return 'quarterly';
|
return 'quarterly';
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ class AppendBudgetLimitPeriods extends Command
|
|||||||
if (
|
if (
|
||||||
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
|
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
|
||||||
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
|
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
|
||||||
&& 5 === $limit->start_date->diffInMonths($limit->end_date)
|
&& 5 === (int)$limit->start_date->diffInMonths($limit->end_date, true)
|
||||||
) {
|
) {
|
||||||
return 'half_year';
|
return 'half_year';
|
||||||
}
|
}
|
||||||
|
|||||||
182
app/Console/Commands/Upgrade/MigrateRuleActions.php
Normal file
182
app/Console/Commands/Upgrade/MigrateRuleActions.php
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/*
|
||||||
|
* MigrateRuleActions.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Console\Commands\Upgrade;
|
||||||
|
|
||||||
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Models\RuleAction;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class MigrateRuleActions extends Command
|
||||||
|
{
|
||||||
|
use ShowsFriendlyMessages;
|
||||||
|
|
||||||
|
public const string CONFIG_NAME = '610_migrate_rule_actions';
|
||||||
|
|
||||||
|
protected $description = 'Migrate rule actions away from expression engine';
|
||||||
|
|
||||||
|
protected $signature = 'firefly-iii:migrate-rule-actions {--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;
|
||||||
|
}
|
||||||
|
if (false === config('firefly.feature_flags.expression_engine')) {
|
||||||
|
$this->friendlyInfo('Expression engine is not enabled. Nothing to do.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$this->replaceEqualSign();
|
||||||
|
$this->replaceObsoleteActions();
|
||||||
|
|
||||||
|
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 replaceEqualSign(): void
|
||||||
|
{
|
||||||
|
$count = 0;
|
||||||
|
$actions = RuleAction::get();
|
||||||
|
|
||||||
|
/** @var RuleAction $action */
|
||||||
|
foreach ($actions as $action) {
|
||||||
|
if (str_starts_with($action->action_value, '=')) {
|
||||||
|
$action->action_value = sprintf('%s%s', '\=', substr($action->action_value, 1));
|
||||||
|
$action->save();
|
||||||
|
++$count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($count > 0) {
|
||||||
|
$this->friendlyInfo(sprintf('Upgrading %d rule action(s) for the new expression engine.', $count));
|
||||||
|
}
|
||||||
|
if (0 === $count) {
|
||||||
|
$this->friendlyInfo('All rule actions are up to date.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function replaceObsoleteActions(): void
|
||||||
|
{
|
||||||
|
$obsolete = [
|
||||||
|
'append_description',
|
||||||
|
'prepend_description',
|
||||||
|
'append_notes',
|
||||||
|
'prepend_notes',
|
||||||
|
'append_descr_to_notes',
|
||||||
|
'append_notes_to_descr',
|
||||||
|
'move_descr_to_notes',
|
||||||
|
'move_notes_to_descr',
|
||||||
|
];
|
||||||
|
$actions = RuleAction::whereIn('action_type', $obsolete)->get();
|
||||||
|
|
||||||
|
/** @var RuleAction $action */
|
||||||
|
foreach ($actions as $action) {
|
||||||
|
$oldType = $action->action_type;
|
||||||
|
|
||||||
|
switch ($action->action_type) {
|
||||||
|
default:
|
||||||
|
$this->friendlyError(sprintf('Cannot deal with action type "%s", skip it.', $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'append_description':
|
||||||
|
$action->action_type = 'set_description';
|
||||||
|
$action->action_value = sprintf('=description~"%s"', str_replace('"', '\"', $action->action_value));
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'prepend_description':
|
||||||
|
$action->action_type = 'set_description';
|
||||||
|
$action->action_value = sprintf('="%s"~description', str_replace('"', '\"', $action->action_value));
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'append_notes':
|
||||||
|
$action->action_type = 'set_notes';
|
||||||
|
$action->action_value = sprintf('=notes~"%s"', str_replace('"', '\"', $action->action_value));
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'prepend_notes':
|
||||||
|
$action->action_type = 'set_notes';
|
||||||
|
$action->action_value = sprintf('="%s"~notes', str_replace('"', '\"', $action->action_value));
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'append_descr_to_notes':
|
||||||
|
$action->action_type = 'set_notes';
|
||||||
|
$action->action_value = '=notes~" "~description';
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'append_notes_to_descr':
|
||||||
|
$action->action_type = 'set_description';
|
||||||
|
$action->action_value = '=description~" "~notes';
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'move_descr_to_notes':
|
||||||
|
$action->action_type = 'set_notes';
|
||||||
|
$action->action_value = '=description';
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'move_notes_to_descr':
|
||||||
|
$action->action_type = 'set_description';
|
||||||
|
$action->action_value = '=notes';
|
||||||
|
$action->save();
|
||||||
|
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,6 +63,7 @@ class UpgradeDatabase extends Command
|
|||||||
'firefly-iii:upgrade-liabilities',
|
'firefly-iii:upgrade-liabilities',
|
||||||
'firefly-iii:liabilities-600',
|
'firefly-iii:liabilities-600',
|
||||||
'firefly-iii:budget-limit-periods',
|
'firefly-iii:budget-limit-periods',
|
||||||
|
'firefly-iii:migrate-rule-actions',
|
||||||
'firefly-iii:restore-oauth-keys',
|
'firefly-iii:restore-oauth-keys',
|
||||||
// also just in case, some integrity commands:
|
// also just in case, some integrity commands:
|
||||||
'firefly-iii:create-group-memberships',
|
'firefly-iii:create-group-memberships',
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ class UpgradeSkeleton extends Command
|
|||||||
{
|
{
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||||
$this->info('FRIENDLY This command has already been executed.');
|
$this->friendlyInfo('This command has already been executed.');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$this->warn('Congrats, you found the skeleton command. Boo!');
|
$this->friendlyWarning('Congrats, you found the skeleton command. Boo!');
|
||||||
|
|
||||||
//$this->markAsExecuted();
|
//$this->markAsExecuted();
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
|||||||
return redirect(route('tags.index'));
|
return redirect(route('tags.index'));
|
||||||
|
|
||||||
case 'categories.show':
|
case 'categories.show':
|
||||||
|
case 'categories.edit':
|
||||||
case 'categories.show.all':
|
case 'categories.show.all':
|
||||||
$request->session()->reflash();
|
$request->session()->reflash();
|
||||||
|
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ class ReportGeneratorFactory
|
|||||||
{
|
{
|
||||||
$period = 'Month';
|
$period = 'Month';
|
||||||
// more than two months date difference means year report.
|
// more than two months date difference means year report.
|
||||||
if ($start->diffInMonths($end) > 1) {
|
if ($start->diffInMonths($end, true) > 1) {
|
||||||
$period = 'Year';
|
$period = 'Year';
|
||||||
}
|
}
|
||||||
|
|
||||||
// more than one year date difference means multi year report.
|
// more than one year date difference means multi-year report.
|
||||||
if ($start->diffInMonths($end) > 12) {
|
if ($start->diffInMonths($end, true) > 12) {
|
||||||
$period = 'MultiYear';
|
$period = 'MultiYear';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,31 +72,6 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
$this->run();
|
$this->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getVersion(): int
|
|
||||||
{
|
|
||||||
return $this->version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setObjects(Collection $objects): void
|
|
||||||
{
|
|
||||||
$this->objects = $objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTrigger(int $trigger): void
|
|
||||||
{
|
|
||||||
$this->trigger = $trigger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setUser(User $user): void
|
|
||||||
{
|
|
||||||
$this->user = $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setWebhooks(Collection $webhooks): void
|
|
||||||
{
|
|
||||||
$this->webhooks = $webhooks;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getWebhooks(): Collection
|
private function getWebhooks(): Collection
|
||||||
{
|
{
|
||||||
return $this->user->webhooks()->where('active', true)->where('trigger', $this->trigger)->get(['webhooks.*']);
|
return $this->user->webhooks()->where('active', true)->where('trigger', $this->trigger)->get(['webhooks.*']);
|
||||||
@@ -206,6 +181,11 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
$this->storeMessage($webhook, $basicMessage);
|
$this->storeMessage($webhook, $basicMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getVersion(): int
|
||||||
|
{
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
private function collectAccounts(TransactionGroup $transactionGroup): Collection
|
private function collectAccounts(TransactionGroup $transactionGroup): Collection
|
||||||
{
|
{
|
||||||
$accounts = new Collection();
|
$accounts = new Collection();
|
||||||
@@ -232,4 +212,24 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
$webhookMessage->save();
|
$webhookMessage->save();
|
||||||
app('log')->debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
|
app('log')->debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setObjects(Collection $objects): void
|
||||||
|
{
|
||||||
|
$this->objects = $objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTrigger(int $trigger): void
|
||||||
|
{
|
||||||
|
$this->trigger = $trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUser(User $user): void
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setWebhooks(Collection $webhooks): void
|
||||||
|
{
|
||||||
|
$this->webhooks = $webhooks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ class UserEventHandler
|
|||||||
}
|
}
|
||||||
// clean up old entries (6 months)
|
// clean up old entries (6 months)
|
||||||
$carbon = Carbon::createFromFormat('Y-m-d H:i:s', $preference[$index]['time']);
|
$carbon = Carbon::createFromFormat('Y-m-d H:i:s', $preference[$index]['time']);
|
||||||
if (false !== $carbon && $carbon->diffInMonths(today()) > 6) {
|
if (false !== $carbon && $carbon->diffInMonths(today(), true) > 6) {
|
||||||
app('log')->debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
|
app('log')->debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
|
||||||
unset($preference[$index]);
|
unset($preference[$index]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,7 +236,9 @@ class AttachmentHelper implements AttachmentHelperInterface
|
|||||||
$fileObject->rewind();
|
$fileObject->rewind();
|
||||||
|
|
||||||
if (0 === $file->getSize()) {
|
if (0 === $file->getSize()) {
|
||||||
throw new FireflyException('Cannot upload empty or non-existent file.');
|
$this->errors->add('attachments', trans('validation.file_zero_length'));
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = (string)$fileObject->fread($file->getSize());
|
$content = (string)$fileObject->fread($file->getSize());
|
||||||
|
|||||||
@@ -33,9 +33,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
*/
|
*/
|
||||||
trait CollectorProperties
|
trait CollectorProperties
|
||||||
{
|
{
|
||||||
public array $sorting;
|
|
||||||
public const string TEST = 'Test';
|
public const string TEST = 'Test';
|
||||||
private ?int $endRow;
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
public array $sorting;
|
||||||
|
private ?int $endRow;
|
||||||
private bool $expandGroupSearch;
|
private bool $expandGroupSearch;
|
||||||
private array $fields;
|
private array $fields;
|
||||||
private bool $hasAccountInfo;
|
private bool $hasAccountInfo;
|
||||||
@@ -51,7 +53,7 @@ trait CollectorProperties
|
|||||||
private ?int $page;
|
private ?int $page;
|
||||||
private array $postFilters;
|
private array $postFilters;
|
||||||
private HasMany $query;
|
private HasMany $query;
|
||||||
private ?int $startRow;
|
private ?int $startRow;
|
||||||
private array $stringFields;
|
private array $stringFields;
|
||||||
/*
|
/*
|
||||||
* This array is used to collect ALL tags the user may search for (using 'setTags').
|
* This array is used to collect ALL tags the user may search for (using 'setTags').
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace FireflyIII\Helpers\Collector;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Carbon\Exceptions\InvalidFormatException;
|
use Carbon\Exceptions\InvalidFormatException;
|
||||||
|
use Exception;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Collector\Extensions\AccountCollection;
|
use FireflyIII\Helpers\Collector\Extensions\AccountCollection;
|
||||||
use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
|
use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
|
||||||
@@ -782,6 +783,35 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
return $currentCollection;
|
return $currentCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\Override]
|
||||||
|
public function sortCollection(Collection $collection): Collection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string $field
|
||||||
|
* @var string $direction
|
||||||
|
*/
|
||||||
|
foreach ($this->sorting as $field => $direction) {
|
||||||
|
$func = 'ASC' === $direction ? 'sortBy' : 'sortByDesc';
|
||||||
|
$collection = $collection->{$func}(function (array $product, int $key) use ($field) { // @phpstan-ignore-line
|
||||||
|
// depends on $field:
|
||||||
|
if ('description' === $field) {
|
||||||
|
if (1 === count($product['transactions'])) {
|
||||||
|
return array_values($product['transactions'])[0][$field];
|
||||||
|
}
|
||||||
|
if (count($product['transactions']) > 1) {
|
||||||
|
return $product['title'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'zzz';
|
||||||
|
}
|
||||||
|
|
||||||
|
exit('here we are');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as getGroups but everything is in a paginator.
|
* Same as getGroups but everything is in a paginator.
|
||||||
*/
|
*/
|
||||||
@@ -792,6 +822,7 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
$this->setLimit(50);
|
$this->setLimit(50);
|
||||||
}
|
}
|
||||||
if (null !== $this->startRow && null !== $this->endRow) {
|
if (null !== $this->startRow && null !== $this->endRow) {
|
||||||
|
/** @var int $total */
|
||||||
$total = $this->endRow - $this->startRow;
|
$total = $this->endRow - $this->startRow;
|
||||||
|
|
||||||
return new LengthAwarePaginator($set, $this->total, $total, 1);
|
return new LengthAwarePaginator($set, $this->total, $total, 1);
|
||||||
@@ -931,6 +962,14 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\Override]
|
||||||
|
public function setSorting(array $instructions): GroupCollectorInterface
|
||||||
|
{
|
||||||
|
$this->sorting = $instructions;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setStartRow(int $startRow): self
|
public function setStartRow(int $startRow): self
|
||||||
{
|
{
|
||||||
$this->startRow = $startRow;
|
$this->startRow = $startRow;
|
||||||
@@ -1091,41 +1130,4 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Override]
|
|
||||||
public function sortCollection(Collection $collection): Collection
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string $field
|
|
||||||
* @var string $direction
|
|
||||||
*/
|
|
||||||
foreach ($this->sorting as $field => $direction) {
|
|
||||||
$func = 'ASC' === $direction ? 'sortBy' : 'sortByDesc';
|
|
||||||
$collection = $collection->{$func}(function (array $product, int $key) use ($field) {
|
|
||||||
// depends on $field:
|
|
||||||
if ('description' === $field) {
|
|
||||||
if (1 === count($product['transactions'])) {
|
|
||||||
return array_values($product['transactions'])[0][$field];
|
|
||||||
}
|
|
||||||
if (count($product['transactions']) > 1) {
|
|
||||||
return $product['title'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'zzz';
|
|
||||||
}
|
|
||||||
|
|
||||||
exit('here we are');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return $collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[\Override]
|
|
||||||
public function setSorting(array $instructions): GroupCollectorInterface
|
|
||||||
{
|
|
||||||
$this->sorting = $instructions;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,13 +285,6 @@ interface GroupCollectorInterface
|
|||||||
*/
|
*/
|
||||||
public function getPaginatedGroups(): LengthAwarePaginator;
|
public function getPaginatedGroups(): LengthAwarePaginator;
|
||||||
|
|
||||||
public function setSorting(array $instructions): self;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort the collection on a column.
|
|
||||||
*/
|
|
||||||
public function sortCollection(Collection $collection): Collection;
|
|
||||||
|
|
||||||
public function hasAnyTag(): self;
|
public function hasAnyTag(): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -560,6 +553,8 @@ interface GroupCollectorInterface
|
|||||||
|
|
||||||
public function setSepaCT(string $sepaCT): self;
|
public function setSepaCT(string $sepaCT): self;
|
||||||
|
|
||||||
|
public function setSorting(array $instructions): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set source accounts.
|
* Set source accounts.
|
||||||
*/
|
*/
|
||||||
@@ -620,6 +615,11 @@ interface GroupCollectorInterface
|
|||||||
*/
|
*/
|
||||||
public function setXorAccounts(Collection $accounts): self;
|
public function setXorAccounts(Collection $accounts): self;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort the collection on a column.
|
||||||
|
*/
|
||||||
|
public function sortCollection(Collection $collection): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically include all stuff required to make API calls work.
|
* Automatically include all stuff required to make API calls work.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class NetWorth implements NetWorthInterface
|
|||||||
|
|
||||||
private CurrencyRepositoryInterface $currencyRepos;
|
private CurrencyRepositoryInterface $currencyRepos;
|
||||||
private User $user;
|
private User $user;
|
||||||
private ?UserGroup $userGroup;
|
private ?UserGroup $userGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method collects the user's net worth in ALL the user's currencies
|
* This method collects the user's net worth in ALL the user's currencies
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class ReconcileController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* */
|
* */
|
||||||
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
|
public function reconcile(Account $account, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
if (!$this->isEditableAccount($account)) {
|
if (!$this->isEditableAccount($account)) {
|
||||||
return $this->redirectAccountToAccount($account);
|
return $this->redirectAccountToAccount($account);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* */
|
* */
|
||||||
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
|
public function show(Request $request, Account $account, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
|
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,18 @@ class LoginController extends Controller
|
|||||||
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
|
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
|
||||||
app('log')->debug('User is trying to login.');
|
app('log')->debug('User is trying to login.');
|
||||||
|
|
||||||
$this->validateLogin($request);
|
try {
|
||||||
|
$this->validateLogin($request);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
return redirect(route('login'))
|
||||||
|
->withErrors(
|
||||||
|
[
|
||||||
|
$this->username => trans('auth.failed'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->onlyInput($this->username)
|
||||||
|
;
|
||||||
|
}
|
||||||
app('log')->debug('Login data is present.');
|
app('log')->debug('Login data is present.');
|
||||||
|
|
||||||
// Copied directly from AuthenticatesUsers, but with logging added:
|
// Copied directly from AuthenticatesUsers, but with logging added:
|
||||||
@@ -91,7 +102,6 @@ class LoginController extends Controller
|
|||||||
Log::channel('audit')->warning(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
Log::channel('audit')->warning(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
||||||
app('log')->error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
app('log')->error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
||||||
$this->fireLockoutEvent($request);
|
$this->fireLockoutEvent($request);
|
||||||
|
|
||||||
$this->sendLockoutResponse($request);
|
$this->sendLockoutResponse($request);
|
||||||
}
|
}
|
||||||
// Copied directly from AuthenticatesUsers, but with logging added:
|
// Copied directly from AuthenticatesUsers, but with logging added:
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class IndexController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* */
|
* */
|
||||||
public function index(Carbon $start = null, Carbon $end = null)
|
public function index(?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
$this->abRepository->cleanup();
|
$this->abRepository->cleanup();
|
||||||
app('log')->debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
|
app('log')->debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
|
||||||
@@ -116,7 +116,6 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
// get all available budgets:
|
// get all available budgets:
|
||||||
$availableBudgets = $this->getAllAvailableBudgets($start, $end);
|
$availableBudgets = $this->getAllAvailableBudgets($start, $end);
|
||||||
|
|
||||||
// get all active budgets:
|
// get all active budgets:
|
||||||
$budgets = $this->getAllBudgets($start, $end, $currencies, $defaultCurrency);
|
$budgets = $this->getAllBudgets($start, $end, $currencies, $defaultCurrency);
|
||||||
$sums = $this->getSums($budgets);
|
$sums = $this->getSums($budgets);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function noBudget(Request $request, Carbon $start = null, Carbon $end = null)
|
public function noBudget(Request $request, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
// @var Carbon $start
|
// @var Carbon $start
|
||||||
$start ??= session('start');
|
$start ??= session('start');
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class NoCategoryController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function show(Request $request, Carbon $start = null, Carbon $end = null)
|
public function show(Request $request, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
app('log')->debug('Start of noCategory()');
|
app('log')->debug('Start of noCategory()');
|
||||||
// @var Carbon $start
|
// @var Carbon $start
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function show(Request $request, Category $category, Carbon $start = null, Carbon $end = null)
|
public function show(Request $request, Category $category, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
// @var Carbon $start
|
// @var Carbon $start
|
||||||
$start ??= session('start', today(config('app.timezone'))->startOfMonth());
|
$start ??= session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ class ReportController extends Controller
|
|||||||
$cache->addProperty($accounts);
|
$cache->addProperty($accounts);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return response()->json($cache->get());
|
// return response()->json($cache->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
app('log')->debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
|
app('log')->debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
|
||||||
@@ -220,11 +220,14 @@ class ReportController extends Controller
|
|||||||
$currentEnd = app('navigation')->endOfPeriod($currentEnd, $preferredRange);
|
$currentEnd = app('navigation')->endOfPeriod($currentEnd, $preferredRange);
|
||||||
}
|
}
|
||||||
while ($currentStart <= $currentEnd) {
|
while ($currentStart <= $currentEnd) {
|
||||||
$key = $currentStart->format($format);
|
$key = $currentStart->format($format);
|
||||||
$title = $currentStart->isoFormat($titleFormat);
|
$title = $currentStart->isoFormat($titleFormat);
|
||||||
$income['entries'][$title] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
|
// #8663 make sure the period exists in the data previously collected.
|
||||||
$expense['entries'][$title] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
|
if (array_key_exists($key, $currency)) {
|
||||||
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0);
|
$income['entries'][$title] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
|
||||||
|
$expense['entries'][$title] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
|
||||||
|
}
|
||||||
|
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$chartData[] = $income;
|
$chartData[] = $income;
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ abstract class Controller extends BaseController
|
|||||||
$authGuard = config('firefly.authentication_guard');
|
$authGuard = config('firefly.authentication_guard');
|
||||||
$logoutUrl = config('firefly.custom_logout_url');
|
$logoutUrl = config('firefly.custom_logout_url');
|
||||||
|
|
||||||
|
// overrule v2 layout back to v1.
|
||||||
|
if ('true' === request()->get('force_default_layout') && 'v2' === config('firefly.layout')) {
|
||||||
|
app('view')->getFinder()->setPaths([realpath(base_path('resources/views'))]); // @phpstan-ignore-line
|
||||||
|
}
|
||||||
|
|
||||||
app('view')->share('authGuard', $authGuard);
|
app('view')->share('authGuard', $authGuard);
|
||||||
app('view')->share('logoutUrl', $logoutUrl);
|
app('view')->share('logoutUrl', $logoutUrl);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Http\Controllers;
|
namespace FireflyIII\Http\Controllers;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class HomeController extends Controller
|
|||||||
$label = $request->get('label');
|
$label = $request->get('label');
|
||||||
$isCustomRange = false;
|
$isCustomRange = false;
|
||||||
|
|
||||||
app('log')->debug('Received dateRange', ['start' => $stringStart, 'end' => $stringEnd, 'label' => $request->get('label')]);
|
app('log')->debug('dateRange: Received dateRange', ['start' => $stringStart, 'end' => $stringEnd, 'label' => $request->get('label')]);
|
||||||
// check if the label is "everything" or "Custom range" which will betray
|
// check if the label is "everything" or "Custom range" which will betray
|
||||||
// a possible problem with the budgets.
|
// a possible problem with the budgets.
|
||||||
if ($label === (string)trans('firefly.everything') || $label === (string)trans('firefly.customRange')) {
|
if ($label === (string)trans('firefly.everything') || $label === (string)trans('firefly.customRange')) {
|
||||||
@@ -97,10 +97,10 @@ class HomeController extends Controller
|
|||||||
app('log')->debug('Range is now marked as "custom".');
|
app('log')->debug('Range is now marked as "custom".');
|
||||||
}
|
}
|
||||||
|
|
||||||
$diff = $start->diffInDays($end) + 1;
|
$diff = $start->diffInDays($end, true) + 1;
|
||||||
|
|
||||||
if ($diff > 50) {
|
if ($diff > 366) {
|
||||||
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => $diff]));
|
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => (int)$diff]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->session()->put('is_custom_range', $isCustomRange);
|
$request->session()->put('is_custom_range', $isCustomRange);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class BoxController extends Controller
|
|||||||
$spentAmount = $spent[$currency->id]['sum'] ?? '0';
|
$spentAmount = $spent[$currency->id]['sum'] ?? '0';
|
||||||
app('log')->debug(sprintf('Spent for default currency for all budgets in this period: %s', $spentAmount));
|
app('log')->debug(sprintf('Spent for default currency for all budgets in this period: %s', $spentAmount));
|
||||||
|
|
||||||
$days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
|
$days = (int)($today->between($start, $end) ? $today->diffInDays($start, true) + 1 : $end->diffInDays($start, true) + 1);
|
||||||
app('log')->debug(sprintf('Number of days left: %d', $days));
|
app('log')->debug(sprintf('Number of days left: %d', $days));
|
||||||
$spentPerDay = bcdiv($spentAmount, (string)$days);
|
$spentPerDay = bcdiv($spentAmount, (string)$days);
|
||||||
app('log')->debug(sprintf('Available to spend per day: %s', $spentPerDay));
|
app('log')->debug(sprintf('Available to spend per day: %s', $spentPerDay));
|
||||||
@@ -130,7 +130,7 @@ class BoxController extends Controller
|
|||||||
$boxTitle = (string)trans('firefly.left_to_spend');
|
$boxTitle = (string)trans('firefly.left_to_spend');
|
||||||
$activeDaysLeft = $this->activeDaysLeft($start, $end); // see method description.
|
$activeDaysLeft = $this->activeDaysLeft($start, $end); // see method description.
|
||||||
$display = 1; // not overspent
|
$display = 1; // not overspent
|
||||||
$leftPerDayAmount = bcdiv($leftToSpendAmount, (string)$activeDaysLeft);
|
$leftPerDayAmount = 0 === (int) $activeDaysLeft ? $leftToSpendAmount : bcdiv($leftToSpendAmount, (string)$activeDaysLeft);
|
||||||
app('log')->debug(sprintf('Left to spend per day is %s', $leftPerDayAmount));
|
app('log')->debug(sprintf('Left to spend per day is %s', $leftPerDayAmount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class IntroController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Returns the introduction wizard for a page.
|
* Returns the introduction wizard for a page.
|
||||||
*/
|
*/
|
||||||
public function getIntroSteps(string $route, string $specificPage = null): JsonResponse
|
public function getIntroSteps(string $route, ?string $specificPage = null): JsonResponse
|
||||||
{
|
{
|
||||||
app('log')->debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
|
app('log')->debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
|
||||||
$specificPage ??= '';
|
$specificPage ??= '';
|
||||||
@@ -91,7 +91,7 @@ class IntroController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function postEnable(string $route, string $specialPage = null): JsonResponse
|
public function postEnable(string $route, ?string $specialPage = null): JsonResponse
|
||||||
{
|
{
|
||||||
$specialPage ??= '';
|
$specialPage ??= '';
|
||||||
$route = str_replace('.', '_', $route);
|
$route = str_replace('.', '_', $route);
|
||||||
@@ -111,7 +111,7 @@ class IntroController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function postFinished(string $route, string $specialPage = null): JsonResponse
|
public function postFinished(string $route, ?string $specialPage = null): JsonResponse
|
||||||
{
|
{
|
||||||
$specialPage ??= '';
|
$specialPage ??= '';
|
||||||
$key = 'shown_demo_'.$route;
|
$key = 'shown_demo_'.$route;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
|||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ReconcileController
|
* Class ReconcileController
|
||||||
@@ -66,14 +67,13 @@ class ReconcileController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function overview(Request $request, Account $account = null, Carbon $start = null, Carbon $end = null): JsonResponse
|
public function overview(Request $request, ?Account $account = null, ?Carbon $start = null, ?Carbon $end = null): JsonResponse
|
||||||
{
|
{
|
||||||
$startBalance = $request->get('startBalance');
|
$startBalance = $request->get('startBalance');
|
||||||
$endBalance = $request->get('endBalance');
|
$endBalance = $request->get('endBalance');
|
||||||
$accountCurrency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$accountCurrency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
||||||
$amount = '0';
|
$amount = '0';
|
||||||
$clearedAmount = '0';
|
$clearedAmount = '0';
|
||||||
$route = '';
|
|
||||||
|
|
||||||
if (null === $start && null === $end) {
|
if (null === $start && null === $end) {
|
||||||
throw new FireflyException('Invalid dates submitted.');
|
throw new FireflyException('Invalid dates submitted.');
|
||||||
@@ -103,14 +103,11 @@ class ReconcileController extends Controller
|
|||||||
$clearedJournals = $collector->getExtractedJournals();
|
$clearedJournals = $collector->getExtractedJournals();
|
||||||
}
|
}
|
||||||
|
|
||||||
app('log')->debug('Start transaction loop');
|
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$amount = $this->processJournal($account, $accountCurrency, $journal, $amount);
|
$amount = $this->processJournal($account, $accountCurrency, $journal, $amount);
|
||||||
}
|
}
|
||||||
app('log')->debug(sprintf('Final amount is %s', $amount));
|
app('log')->debug(sprintf('Final amount is %s', $amount));
|
||||||
app('log')->debug('End transaction loop');
|
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($clearedJournals as $journal) {
|
foreach ($clearedJournals as $journal) {
|
||||||
@@ -118,31 +115,17 @@ class ReconcileController extends Controller
|
|||||||
$clearedAmount = $this->processJournal($account, $accountCurrency, $journal, $clearedAmount);
|
$clearedAmount = $this->processJournal($account, $accountCurrency, $journal, $clearedAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Log::debug(sprintf('Start balance: "%s"', $startBalance));
|
||||||
|
Log::debug(sprintf('End balance: "%s"', $endBalance));
|
||||||
|
Log::debug(sprintf('Cleared amount: "%s"', $clearedAmount));
|
||||||
|
Log::debug(sprintf('Amount: "%s"', $amount));
|
||||||
$difference = bcadd(bcadd(bcsub($startBalance, $endBalance), $clearedAmount), $amount);
|
$difference = bcadd(bcadd(bcsub($startBalance, $endBalance), $clearedAmount), $amount);
|
||||||
$diffCompare = bccomp($difference, '0');
|
$diffCompare = bccomp($difference, '0');
|
||||||
$countCleared = count($clearedJournals);
|
$countCleared = count($clearedJournals);
|
||||||
|
|
||||||
$reconSum = bcadd(bcadd($startBalance, $amount), $clearedAmount);
|
$reconSum = bcadd(bcadd($startBalance, $amount), $clearedAmount);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$view = view(
|
$view = view('accounts.reconcile.overview', compact('account', 'start', 'diffCompare', 'difference', 'end', 'clearedAmount', 'startBalance', 'endBalance', 'amount', 'route', 'countCleared', 'reconSum', 'selectedIds'))->render();
|
||||||
'accounts.reconcile.overview',
|
|
||||||
compact(
|
|
||||||
'account',
|
|
||||||
'start',
|
|
||||||
'diffCompare',
|
|
||||||
'difference',
|
|
||||||
'end',
|
|
||||||
'clearedAmount',
|
|
||||||
'startBalance',
|
|
||||||
'endBalance',
|
|
||||||
'amount',
|
|
||||||
'route',
|
|
||||||
'countCleared',
|
|
||||||
'reconSum',
|
|
||||||
'selectedIds'
|
|
||||||
)
|
|
||||||
)->render();
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
app('log')->debug(sprintf('View error: %s', $e->getMessage()));
|
app('log')->debug(sprintf('View error: %s', $e->getMessage()));
|
||||||
app('log')->error($e->getTraceAsString());
|
app('log')->error($e->getTraceAsString());
|
||||||
@@ -151,14 +134,42 @@ class ReconcileController extends Controller
|
|||||||
throw new FireflyException($view, 0, $e);
|
throw new FireflyException($view, 0, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
$return = [
|
$return = ['post_url' => $route, 'html' => $view];
|
||||||
'post_url' => $route,
|
|
||||||
'html' => $view,
|
|
||||||
];
|
|
||||||
|
|
||||||
return response()->json($return);
|
return response()->json($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string
|
||||||
|
{
|
||||||
|
$toAdd = '0';
|
||||||
|
app('log')->debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description']));
|
||||||
|
|
||||||
|
// not much magic below we need to cover using tests.
|
||||||
|
|
||||||
|
if ($account->id === $journal['source_account_id']) {
|
||||||
|
if ($currency->id === $journal['currency_id']) {
|
||||||
|
$toAdd = $journal['amount'];
|
||||||
|
}
|
||||||
|
if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) {
|
||||||
|
$toAdd = $journal['foreign_amount'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($account->id === $journal['destination_account_id']) {
|
||||||
|
if ($currency->id === $journal['currency_id']) {
|
||||||
|
$toAdd = bcmul($journal['amount'], '-1');
|
||||||
|
}
|
||||||
|
if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) {
|
||||||
|
$toAdd = bcmul($journal['foreign_amount'], '-1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app('log')->debug(sprintf('Going to add %s to %s', $toAdd, $amount));
|
||||||
|
$amount = bcadd($amount, $toAdd);
|
||||||
|
app('log')->debug(sprintf('Result is %s', $amount));
|
||||||
|
|
||||||
|
return $amount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of transactions in a modal.
|
* Returns a list of transactions in a modal.
|
||||||
*
|
*
|
||||||
@@ -166,7 +177,7 @@ class ReconcileController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function transactions(Account $account, Carbon $start = null, Carbon $end = null)
|
public function transactions(Account $account, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
if (null === $start || null === $end) {
|
if (null === $start || null === $end) {
|
||||||
throw new FireflyException('Invalid dates submitted.');
|
throw new FireflyException('Invalid dates submitted.');
|
||||||
@@ -176,6 +187,7 @@ class ReconcileController extends Controller
|
|||||||
}
|
}
|
||||||
$startDate = clone $start;
|
$startDate = clone $start;
|
||||||
$startDate->subDay();
|
$startDate->subDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
||||||
$startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
|
$startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
|
||||||
@@ -214,37 +226,6 @@ class ReconcileController extends Controller
|
|||||||
return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
|
return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string
|
|
||||||
{
|
|
||||||
$toAdd = '0';
|
|
||||||
app('log')->debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description']));
|
|
||||||
|
|
||||||
// not much magic below we need to cover using tests.
|
|
||||||
|
|
||||||
if ($account->id === $journal['source_account_id']) {
|
|
||||||
if ($currency->id === $journal['currency_id']) {
|
|
||||||
$toAdd = $journal['amount'];
|
|
||||||
}
|
|
||||||
if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) {
|
|
||||||
$toAdd = $journal['foreign_amount'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($account->id === $journal['destination_account_id']) {
|
|
||||||
if ($currency->id === $journal['currency_id']) {
|
|
||||||
$toAdd = bcmul($journal['amount'], '-1');
|
|
||||||
}
|
|
||||||
if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) {
|
|
||||||
$toAdd = bcmul($journal['foreign_amount'], '-1');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app('log')->debug(sprintf('Going to add %s to %s', $toAdd, $amount));
|
|
||||||
$amount = bcadd($amount, $toAdd);
|
|
||||||
app('log')->debug(sprintf('Result is %s', $amount));
|
|
||||||
|
|
||||||
return $amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "fix" amounts to make it easier on the reconciliation overview:
|
* "fix" amounts to make it easier on the reconciliation overview:
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class CreateController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function create(Request $request, RuleGroup $ruleGroup = null)
|
public function create(Request $request, ?RuleGroup $ruleGroup = null)
|
||||||
{
|
{
|
||||||
$this->createDefaultRuleGroup();
|
$this->createDefaultRuleGroup();
|
||||||
$preFilled = [
|
$preFilled = [
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class TagController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function show(Request $request, Tag $tag, Carbon $start = null, Carbon $end = null)
|
public function show(Request $request, Tag $tag, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
// default values:
|
// default values:
|
||||||
$subTitleIcon = 'fa-tag';
|
$subTitleIcon = 'fa-tag';
|
||||||
@@ -312,6 +312,9 @@ class TagController extends Controller
|
|||||||
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
|
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
|
||||||
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
|
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
|
||||||
}
|
}
|
||||||
|
if (count($this->attachmentsHelper->getErrors()->get('attachments')) > 0) {
|
||||||
|
$request->session()->flash('error', $this->attachmentsHelper->getErrors()->get('attachments'));
|
||||||
|
}
|
||||||
$redirect = redirect($this->getPreviousUrl('tags.create.url'));
|
$redirect = redirect($this->getPreviousUrl('tags.create.url'));
|
||||||
if (1 === (int)$request->get('create_another')) {
|
if (1 === (int)$request->get('create_another')) {
|
||||||
session()->put('tags.create.fromStore', true);
|
session()->put('tags.create.fromStore', true);
|
||||||
@@ -347,6 +350,9 @@ class TagController extends Controller
|
|||||||
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
|
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
|
||||||
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
|
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
|
||||||
}
|
}
|
||||||
|
if (count($this->attachmentsHelper->getErrors()->get('attachments')) > 0) {
|
||||||
|
$request->session()->flash('error', $this->attachmentsHelper->getErrors()->get('attachments'));
|
||||||
|
}
|
||||||
$redirect = redirect($this->getPreviousUrl('tags.edit.url'));
|
$redirect = redirect($this->getPreviousUrl('tags.edit.url'));
|
||||||
if (1 === (int)$request->get('return_to_edit')) {
|
if (1 === (int)$request->get('return_to_edit')) {
|
||||||
session()->put('tags.edit.fromUpdate', true);
|
session()->put('tags.edit.fromUpdate', true);
|
||||||
|
|||||||
@@ -69,58 +69,51 @@ class IndexController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, string $objectType, Carbon $start = null, Carbon $end = null)
|
public function index(Request $request, string $objectType, ?Carbon $start = null, ?Carbon $end = null)
|
||||||
{
|
{
|
||||||
if ('transfers' === $objectType) {
|
if ('transfers' === $objectType) {
|
||||||
$objectType = 'transfer';
|
$objectType = 'transfer';
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a split for the (future) v2 release.
|
$subTitleIcon = config('firefly.transactionIconsByType.'.$objectType);
|
||||||
$periods = [];
|
$types = config('firefly.transactionTypesByType.'.$objectType);
|
||||||
$groups = [];
|
$page = (int)$request->get('page');
|
||||||
$subTitle = 'TODO page subtitle in v2';
|
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||||
|
|
||||||
$subTitleIcon = config('firefly.transactionIconsByType.'.$objectType);
|
if (null === $start) {
|
||||||
$types = config('firefly.transactionTypesByType.'.$objectType);
|
$start = session('start');
|
||||||
$page = (int)$request->get('page');
|
$end = session('end');
|
||||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
|
||||||
|
|
||||||
if ('v2' !== (string)config('firefly.layout')) {
|
|
||||||
if (null === $start) {
|
|
||||||
$start = session('start');
|
|
||||||
$end = session('end');
|
|
||||||
}
|
|
||||||
if (null === $end) {
|
|
||||||
// get last transaction ever?
|
|
||||||
$last = $this->repository->getLast();
|
|
||||||
$end = null !== $last ? $last->date : session('end');
|
|
||||||
}
|
|
||||||
|
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
|
||||||
$startStr = $start->isoFormat($this->monthAndDayFormat);
|
|
||||||
$endStr = $end->isoFormat($this->monthAndDayFormat);
|
|
||||||
$subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
|
|
||||||
$path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
|
||||||
$firstJournal = $this->repository->firstNull();
|
|
||||||
$startPeriod = null === $firstJournal ? new Carbon() : $firstJournal->date;
|
|
||||||
$endPeriod = clone $end;
|
|
||||||
$periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
|
|
||||||
|
|
||||||
/** @var GroupCollectorInterface $collector */
|
|
||||||
$collector = app(GroupCollectorInterface::class);
|
|
||||||
|
|
||||||
$collector->setRange($start, $end)
|
|
||||||
->setTypes($types)
|
|
||||||
->setLimit($pageSize)
|
|
||||||
->setPage($page)
|
|
||||||
->withBudgetInformation()
|
|
||||||
->withCategoryInformation()
|
|
||||||
->withAccountInformation()
|
|
||||||
->withAttachmentInformation()
|
|
||||||
;
|
|
||||||
$groups = $collector->getPaginatedGroups();
|
|
||||||
$groups->setPath($path);
|
|
||||||
}
|
}
|
||||||
|
if (null === $end) {
|
||||||
|
// get last transaction ever?
|
||||||
|
$last = $this->repository->getLast();
|
||||||
|
$end = null !== $last ? $last->date : session('end');
|
||||||
|
}
|
||||||
|
|
||||||
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
|
$startStr = $start->isoFormat($this->monthAndDayFormat);
|
||||||
|
$endStr = $end->isoFormat($this->monthAndDayFormat);
|
||||||
|
$subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
|
||||||
|
$path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
||||||
|
$firstJournal = $this->repository->firstNull();
|
||||||
|
$startPeriod = null === $firstJournal ? new Carbon() : $firstJournal->date;
|
||||||
|
$endPeriod = clone $end;
|
||||||
|
$periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
|
||||||
|
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
|
||||||
|
$collector->setRange($start, $end)
|
||||||
|
->setTypes($types)
|
||||||
|
->setLimit($pageSize)
|
||||||
|
->setPage($page)
|
||||||
|
->withBudgetInformation()
|
||||||
|
->withCategoryInformation()
|
||||||
|
->withAccountInformation()
|
||||||
|
->withAttachmentInformation()
|
||||||
|
;
|
||||||
|
$groups = $collector->getPaginatedGroups();
|
||||||
|
$groups->setPath($path);
|
||||||
|
|
||||||
return view('transactions.index', compact('subTitle', 'objectType', 'subTitleIcon', 'groups', 'periods', 'start', 'end'));
|
return view('transactions.index', compact('subTitle', 'objectType', 'subTitleIcon', 'groups', 'periods', 'start', 'end'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,12 +50,12 @@ class SecureHeaders
|
|||||||
$csp = [
|
$csp = [
|
||||||
"default-src 'none'",
|
"default-src 'none'",
|
||||||
"object-src 'none'",
|
"object-src 'none'",
|
||||||
sprintf("script-src 'unsafe-eval' 'strict-dynamic' 'self' 'unsafe-inline' 'nonce-%1s' %2s", $nonce, $trackingScriptSrc),
|
sprintf("script-src 'unsafe-eval' 'strict-dynamic' 'nonce-%1s'", $nonce),
|
||||||
"style-src 'unsafe-inline' 'self'",
|
"style-src 'unsafe-inline' 'self'",
|
||||||
"base-uri 'self'",
|
"base-uri 'self'",
|
||||||
"font-src 'self' data:",
|
"font-src 'self' data:",
|
||||||
sprintf("connect-src 'self' %s", $trackingScriptSrc),
|
sprintf("connect-src 'self' %s", $trackingScriptSrc),
|
||||||
sprintf("img-src data: 'strict-dynamic' 'self' *.tile.openstreetmap.org %s", $trackingScriptSrc),
|
sprintf("img-src 'self' 'nonce-%1s'", $nonce),
|
||||||
"manifest-src 'self'",
|
"manifest-src 'self'",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ class TrustProxies extends Middleware
|
|||||||
// After...
|
// After...
|
||||||
protected $headers
|
protected $headers
|
||||||
= Request::HEADER_X_FORWARDED_FOR |
|
= Request::HEADER_X_FORWARDED_FOR |
|
||||||
Request::HEADER_X_FORWARDED_HOST |
|
Request::HEADER_X_FORWARDED_HOST |
|
||||||
Request::HEADER_X_FORWARDED_PORT |
|
Request::HEADER_X_FORWARDED_PORT |
|
||||||
Request::HEADER_X_FORWARDED_PROTO |
|
Request::HEADER_X_FORWARDED_PROTO |
|
||||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TrustProxies constructor.
|
* TrustProxies constructor.
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Http\Requests;
|
namespace FireflyIII\Http\Requests;
|
||||||
|
|
||||||
use FireflyIII\Models\Rule;
|
use FireflyIII\Models\Rule;
|
||||||
|
use FireflyIII\Rules\IsValidActionExpression;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use FireflyIII\Support\Request\GetRuleConfiguration;
|
use FireflyIII\Support\Request\GetRuleConfiguration;
|
||||||
@@ -147,7 +148,7 @@ class RuleFormRequest extends FormRequest
|
|||||||
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
|
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
|
||||||
'triggers.*.value' => sprintf('required_if:triggers.*.type,%s|max:1024|min:1|ruleTriggerValue', $contextTriggers),
|
'triggers.*.value' => sprintf('required_if:triggers.*.type,%s|max:1024|min:1|ruleTriggerValue', $contextTriggers),
|
||||||
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
||||||
'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:0|max:1024|ruleActionValue', $contextActions),
|
'actions.*.value' => [sprintf('required_if:actions.*.type,%s|min:0|max:1024', $contextActions), new IsValidActionExpression(), 'ruleActionValue'],
|
||||||
'strict' => 'in:0,1',
|
'strict' => 'in:0,1',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class WarnAboutBills implements ShouldQueue
|
|||||||
$today = clone $this->date;
|
$today = clone $this->date;
|
||||||
$carbon = clone $bill->{$field};
|
$carbon = clone $bill->{$field};
|
||||||
|
|
||||||
return $today->diffInDays($carbon, false);
|
return (int) $today->diffInDays($carbon);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sendWarning(Bill $bill, string $field): void
|
private function sendWarning(Bill $bill, string $field): void
|
||||||
|
|||||||
@@ -122,13 +122,13 @@ class Account extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'user_id' => 'integer',
|
'user_id' => 'integer',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'encrypted' => 'boolean',
|
'encrypted' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban'];
|
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban'];
|
||||||
|
|
||||||
@@ -274,6 +274,13 @@ class Account extends Model
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function iban(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: static fn ($value) => null === $value ? null : trim(str_replace(' ', '', (string)$value)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected function order(): Attribute
|
protected function order(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ class AccountMeta extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['account_id', 'name', 'data'];
|
protected $fillable = ['account_id', 'name', 'data'];
|
||||||
|
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ class AccountType extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['type'];
|
protected $fillable = ['type'];
|
||||||
|
|
||||||
|
|||||||
@@ -97,11 +97,11 @@ class Attachment extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'uploaded' => 'boolean',
|
'uploaded' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded'];
|
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded'];
|
||||||
|
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ class AvailableBudget extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'start_date' => 'date',
|
'start_date' => 'date',
|
||||||
'end_date' => 'date',
|
'end_date' => 'date',
|
||||||
'transaction_currency_id' => 'int',
|
'transaction_currency_id' => 'int',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date'];
|
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date'];
|
||||||
|
|
||||||
|
|||||||
@@ -114,36 +114,36 @@ class Bill extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'date' => 'date',
|
'date' => 'date',
|
||||||
'end_date' => 'date',
|
'end_date' => 'date',
|
||||||
'extension_date' => 'date',
|
'extension_date' => 'date',
|
||||||
'skip' => 'int',
|
'skip' => 'int',
|
||||||
'automatch' => 'boolean',
|
'automatch' => 'boolean',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'name_encrypted' => 'boolean',
|
'name_encrypted' => 'boolean',
|
||||||
'match_encrypted' => 'boolean',
|
'match_encrypted' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable
|
protected $fillable
|
||||||
= [
|
= [
|
||||||
'name',
|
'name',
|
||||||
'match',
|
'match',
|
||||||
'amount_min',
|
'amount_min',
|
||||||
'user_id',
|
'user_id',
|
||||||
'user_group_id',
|
'user_group_id',
|
||||||
'amount_max',
|
'amount_max',
|
||||||
'date',
|
'date',
|
||||||
'repeat_freq',
|
'repeat_freq',
|
||||||
'skip',
|
'skip',
|
||||||
'automatch',
|
'automatch',
|
||||||
'active',
|
'active',
|
||||||
'transaction_currency_id',
|
'transaction_currency_id',
|
||||||
'end_date',
|
'end_date',
|
||||||
'extension_date',
|
'extension_date',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
|
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
|
||||||
|
|
||||||
|
|||||||
@@ -97,12 +97,12 @@ class Budget extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'encrypted' => 'boolean',
|
'encrypted' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'name', 'active', 'order', 'user_group_id'];
|
protected $fillable = ['user_id', 'name', 'active', 'order', 'user_group_id'];
|
||||||
|
|
||||||
|
|||||||
@@ -74,18 +74,18 @@ class BudgetLimit extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'start_date' => 'date',
|
'start_date' => 'date',
|
||||||
'end_date' => 'date',
|
'end_date' => 'date',
|
||||||
'auto_budget' => 'boolean',
|
'auto_budget' => 'boolean',
|
||||||
];
|
];
|
||||||
protected $dispatchesEvents
|
protected $dispatchesEvents
|
||||||
= [
|
= [
|
||||||
'created' => Created::class,
|
'created' => Created::class,
|
||||||
'updated' => Updated::class,
|
'updated' => Updated::class,
|
||||||
'deleted' => Deleted::class,
|
'deleted' => Deleted::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id'];
|
protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id'];
|
||||||
|
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ class Category extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'encrypted' => 'boolean',
|
'encrypted' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'user_group_id', 'name'];
|
protected $fillable = ['user_id', 'user_group_id', 'name'];
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,10 @@ class Configuration extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var string The table to store the data in */
|
/** @var string The table to store the data in */
|
||||||
protected $table = 'configuration';
|
protected $table = 'configuration';
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ class CurrencyExchangeRate extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'user_id' => 'int',
|
'user_id' => 'int',
|
||||||
'from_currency_id' => 'int',
|
'from_currency_id' => 'int',
|
||||||
'to_currency_id' => 'int',
|
'to_currency_id' => 'int',
|
||||||
'date' => 'datetime',
|
'date' => 'datetime',
|
||||||
];
|
];
|
||||||
protected $fillable = ['user_id', 'from_currency_id', 'to_currency_id', 'date', 'rate'];
|
protected $fillable = ['user_id', 'from_currency_id', 'to_currency_id', 'date', 'rate'];
|
||||||
|
|
||||||
public function fromCurrency(): BelongsTo
|
public function fromCurrency(): BelongsTo
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ class InvitedUser extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'expires' => 'datetime',
|
'expires' => 'datetime',
|
||||||
'redeemed' => 'boolean',
|
'redeemed' => 'boolean',
|
||||||
];
|
];
|
||||||
protected $fillable = ['user_id', 'email', 'invite_code', 'expires', 'redeemed'];
|
protected $fillable = ['user_id', 'email', 'invite_code', 'expires', 'redeemed'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -72,11 +72,11 @@ class LinkType extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'editable' => 'boolean',
|
'editable' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['name', 'inward', 'outward', 'editable'];
|
protected $fillable = ['name', 'inward', 'outward', 'editable'];
|
||||||
|
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ class Location extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'zoomLevel' => 'int',
|
'zoomLevel' => 'int',
|
||||||
'latitude' => 'float',
|
'latitude' => 'float',
|
||||||
'longitude' => 'float',
|
'longitude' => 'float',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['locatable_id', 'locatable_type', 'latitude', 'longitude', 'zoom_level'];
|
protected $fillable = ['locatable_id', 'locatable_type', 'latitude', 'longitude', 'zoom_level'];
|
||||||
|
|
||||||
|
|||||||
@@ -69,10 +69,10 @@ class Note extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['title', 'text', 'noteable_id', 'noteable_type'];
|
protected $fillable = ['title', 'text', 'noteable_id', 'noteable_type'];
|
||||||
|
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ class ObjectGroup extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'user_id' => 'integer',
|
'user_id' => 'integer',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
];
|
];
|
||||||
protected $fillable = ['title', 'order', 'user_id', 'user_group_id'];
|
protected $fillable = ['title', 'order', 'user_id', 'user_group_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -92,15 +92,15 @@ class PiggyBank extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'startdate' => 'date',
|
'startdate' => 'date',
|
||||||
'targetdate' => 'date',
|
'targetdate' => 'date',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'encrypted' => 'boolean',
|
'encrypted' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'active'];
|
protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'active'];
|
||||||
|
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ class PiggyBankEvent extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'date' => 'date',
|
'date' => 'date',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount'];
|
protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount'];
|
||||||
|
|
||||||
|
|||||||
@@ -64,11 +64,11 @@ class PiggyBankRepetition extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'startdate' => 'date',
|
'startdate' => 'date',
|
||||||
'targetdate' => 'date',
|
'targetdate' => 'date',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount'];
|
protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount'];
|
||||||
|
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ class Preference extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'data' => 'array',
|
'data' => 'array',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'data', 'name'];
|
protected $fillable = ['user_id', 'data', 'name'];
|
||||||
|
|
||||||
|
|||||||
@@ -104,19 +104,19 @@ class Recurrence extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'title' => 'string',
|
'title' => 'string',
|
||||||
'id' => 'int',
|
'id' => 'int',
|
||||||
'description' => 'string',
|
'description' => 'string',
|
||||||
'first_date' => 'date',
|
'first_date' => 'date',
|
||||||
'repeat_until' => 'date',
|
'repeat_until' => 'date',
|
||||||
'latest_date' => 'date',
|
'latest_date' => 'date',
|
||||||
'repetitions' => 'int',
|
'repetitions' => 'int',
|
||||||
'active' => 'bool',
|
'active' => 'bool',
|
||||||
'apply_rules' => 'bool',
|
'apply_rules' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable
|
protected $fillable
|
||||||
= ['user_id', 'transaction_type_id', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active'];
|
= ['user_id', 'transaction_type_id', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active'];
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ class RecurrenceMeta extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'name' => 'string',
|
'name' => 'string',
|
||||||
'value' => 'string',
|
'value' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['recurrence_id', 'name', 'value'];
|
protected $fillable = ['recurrence_id', 'name', 'value'];
|
||||||
|
|
||||||
|
|||||||
@@ -76,14 +76,14 @@ class RecurrenceRepetition extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'repetition_type' => 'string',
|
'repetition_type' => 'string',
|
||||||
'repetition_moment' => 'string',
|
'repetition_moment' => 'string',
|
||||||
'repetition_skip' => 'int',
|
'repetition_skip' => 'int',
|
||||||
'weekend' => 'int',
|
'weekend' => 'int',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['recurrence_id', 'weekend', 'repetition_type', 'repetition_moment', 'repetition_skip'];
|
protected $fillable = ['recurrence_id', 'weekend', 'repetition_type', 'repetition_moment', 'repetition_skip'];
|
||||||
|
|
||||||
|
|||||||
@@ -91,25 +91,25 @@ class RecurrenceTransaction extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'amount' => 'string',
|
'amount' => 'string',
|
||||||
'foreign_amount' => 'string',
|
'foreign_amount' => 'string',
|
||||||
'description' => 'string',
|
'description' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable
|
protected $fillable
|
||||||
= [
|
= [
|
||||||
'recurrence_id',
|
'recurrence_id',
|
||||||
'transaction_currency_id',
|
'transaction_currency_id',
|
||||||
'foreign_currency_id',
|
'foreign_currency_id',
|
||||||
'source_id',
|
'source_id',
|
||||||
'destination_id',
|
'destination_id',
|
||||||
'amount',
|
'amount',
|
||||||
'foreign_amount',
|
'foreign_amount',
|
||||||
'description',
|
'description',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var string The table to store the data in */
|
/** @var string The table to store the data in */
|
||||||
protected $table = 'recurrences_transactions';
|
protected $table = 'recurrences_transactions';
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ class RecurrenceTransactionMeta extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'name' => 'string',
|
'name' => 'string',
|
||||||
'value' => 'string',
|
'value' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['rt_id', 'name', 'value'];
|
protected $fillable = ['rt_id', 'name', 'value'];
|
||||||
|
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ class Role extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['name', 'display_name', 'description'];
|
protected $fillable = ['name', 'display_name', 'description'];
|
||||||
|
|
||||||
|
|||||||
@@ -95,15 +95,15 @@ class Rule extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
'stop_processing' => 'boolean',
|
'stop_processing' => 'boolean',
|
||||||
'id' => 'int',
|
'id' => 'int',
|
||||||
'strict' => 'boolean',
|
'strict' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['rule_group_id', 'order', 'active', 'title', 'description', 'user_id', 'strict'];
|
protected $fillable = ['rule_group_id', 'order', 'active', 'title', 'description', 'user_id', 'strict'];
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,13 @@ namespace FireflyIII\Models;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Eloquent;
|
use Eloquent;
|
||||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||||
|
use FireflyIII\TransactionRules\Expressions\ActionExpression;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Symfony\Component\ExpressionLanguage\SyntaxError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FireflyIII\Models\RuleAction
|
* FireflyIII\Models\RuleAction
|
||||||
@@ -66,15 +69,39 @@ class RuleAction extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
'stop_processing' => 'boolean',
|
'stop_processing' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['rule_id', 'action_type', 'action_value', 'order', 'active', 'stop_processing'];
|
protected $fillable = ['rule_id', 'action_type', 'action_value', 'order', 'active', 'stop_processing'];
|
||||||
|
|
||||||
|
public function getValue(array $journal): string
|
||||||
|
{
|
||||||
|
if (false === config('firefly.feature_flags.expression_engine')) {
|
||||||
|
Log::debug('Expression engine is disabled, returning action value as string.');
|
||||||
|
|
||||||
|
return (string)$this->action_value;
|
||||||
|
}
|
||||||
|
if (true === config('firefly.feature_flags.expression_engine') && str_starts_with($this->action_value, '\=')) {
|
||||||
|
// return literal string.
|
||||||
|
return substr($this->action_value, 1);
|
||||||
|
}
|
||||||
|
$expr = new ActionExpression($this->action_value);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $expr->evaluate($journal);
|
||||||
|
} catch (SyntaxError $e) {
|
||||||
|
Log::error(sprintf('Expression engine failed to evaluate expression "%s" with error "%s".', $this->action_value, $e->getMessage()));
|
||||||
|
$result = (string)$this->action_value;
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Expression engine is enabled, result of expression "%s" is "%s".', $this->action_value, $result));
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
public function rule(): BelongsTo
|
public function rule(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Rule::class);
|
return $this->belongsTo(Rule::class);
|
||||||
|
|||||||
@@ -85,13 +85,13 @@ class RuleGroup extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'stop_processing' => 'boolean',
|
'stop_processing' => 'boolean',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'user_group_id', 'stop_processing', 'order', 'title', 'description', 'active'];
|
protected $fillable = ['user_id', 'user_group_id', 'stop_processing', 'order', 'title', 'description', 'active'];
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ class RuleTrigger extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
'stop_processing' => 'boolean',
|
'stop_processing' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['rule_id', 'trigger_type', 'trigger_value', 'order', 'active', 'stop_processing'];
|
protected $fillable = ['rule_id', 'trigger_type', 'trigger_value', 'order', 'active', 'stop_processing'];
|
||||||
|
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ class Tag extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'date' => 'date',
|
'date' => 'date',
|
||||||
'zoomLevel' => 'int',
|
'zoomLevel' => 'int',
|
||||||
'latitude' => 'float',
|
'latitude' => 'float',
|
||||||
'longitude' => 'float',
|
'longitude' => 'float',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'description', 'tagMode'];
|
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'description', 'tagMode'];
|
||||||
|
|
||||||
|
|||||||
@@ -99,28 +99,28 @@ class Transaction extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'identifier' => 'int',
|
'identifier' => 'int',
|
||||||
'encrypted' => 'boolean', // model does not have these fields though
|
'encrypted' => 'boolean', // model does not have these fields though
|
||||||
'bill_name_encrypted' => 'boolean',
|
'bill_name_encrypted' => 'boolean',
|
||||||
'reconciled' => 'boolean',
|
'reconciled' => 'boolean',
|
||||||
'date' => 'datetime',
|
'date' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable
|
protected $fillable
|
||||||
= [
|
= [
|
||||||
'account_id',
|
'account_id',
|
||||||
'transaction_journal_id',
|
'transaction_journal_id',
|
||||||
'description',
|
'description',
|
||||||
'amount',
|
'amount',
|
||||||
'identifier',
|
'identifier',
|
||||||
'transaction_currency_id',
|
'transaction_currency_id',
|
||||||
'foreign_currency_id',
|
'foreign_currency_id',
|
||||||
'foreign_amount',
|
'foreign_amount',
|
||||||
'reconciled',
|
'reconciled',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = ['encrypted'];
|
protected $hidden = ['encrypted'];
|
||||||
|
|
||||||
|
|||||||
@@ -89,12 +89,12 @@ class TransactionCurrency extends Model
|
|||||||
public ?bool $userGroupEnabled;
|
public ?bool $userGroupEnabled;
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'decimal_places' => 'int',
|
'decimal_places' => 'int',
|
||||||
'enabled' => 'bool',
|
'enabled' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];
|
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];
|
||||||
|
|
||||||
|
|||||||
@@ -78,13 +78,13 @@ class TransactionGroup extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'id' => 'integer',
|
'id' => 'integer',
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'title' => 'string',
|
'title' => 'string',
|
||||||
'date' => 'datetime',
|
'date' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['user_id', 'user_group_id', 'title'];
|
protected $fillable = ['user_id', 'user_group_id', 'title'];
|
||||||
|
|
||||||
|
|||||||
@@ -138,32 +138,32 @@ class TransactionJournal extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'date' => 'datetime',
|
'date' => 'datetime',
|
||||||
'interest_date' => 'date',
|
'interest_date' => 'date',
|
||||||
'book_date' => 'date',
|
'book_date' => 'date',
|
||||||
'process_date' => 'date',
|
'process_date' => 'date',
|
||||||
'order' => 'int',
|
'order' => 'int',
|
||||||
'tag_count' => 'int',
|
'tag_count' => 'int',
|
||||||
'encrypted' => 'boolean',
|
'encrypted' => 'boolean',
|
||||||
'completed' => 'boolean',
|
'completed' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable
|
protected $fillable
|
||||||
= [
|
= [
|
||||||
'user_id',
|
'user_id',
|
||||||
'user_group_id',
|
'user_group_id',
|
||||||
'transaction_type_id',
|
'transaction_type_id',
|
||||||
'bill_id',
|
'bill_id',
|
||||||
'tag_count',
|
'tag_count',
|
||||||
'transaction_currency_id',
|
'transaction_currency_id',
|
||||||
'description',
|
'description',
|
||||||
'completed',
|
'completed',
|
||||||
'order',
|
'order',
|
||||||
'date',
|
'date',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = ['encrypted'];
|
protected $hidden = ['encrypted'];
|
||||||
|
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ class TransactionJournalLink extends Model
|
|||||||
|
|
||||||
protected $casts
|
protected $casts
|
||||||
= [
|
= [
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var string The table to store the data in */
|
/** @var string The table to store the data in */
|
||||||
protected $table = 'journal_links';
|
protected $table = 'journal_links';
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user