mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-25 07:03:32 +00:00
Compare commits
159 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7096c65f50 | ||
|
1462b0de69 | ||
|
86a1f170c4 | ||
|
40389fb6d5 | ||
|
36021d84cf | ||
|
1278f92355 | ||
|
573f9adb49 | ||
|
431c99c27b | ||
|
77cc558931 | ||
|
42043de34f | ||
|
f2b2c2109f | ||
|
7fe29ad983 | ||
|
07d9bcfb9d | ||
|
fdd235e4cb | ||
|
2646acadb8 | ||
|
5ef646b810 | ||
|
e8bdb5ef38 | ||
|
7a851c2cc6 | ||
|
624784e54e | ||
|
20eb2ebe58 | ||
|
25f8acb417 | ||
|
f75e6430b1 | ||
|
e72a483c49 | ||
|
68934858ce | ||
|
c08b5177d9 | ||
|
fe8635f1ce | ||
|
e96d28b981 | ||
|
784cc3d52d | ||
|
2ab3fb3a71 | ||
|
ff765d4687 | ||
|
f6e778e1d4 | ||
|
ed36604050 | ||
|
cbf8c6e80d | ||
|
f11db0de61 | ||
|
34f16dcdd5 | ||
|
f18aae39b8 | ||
|
924171e7b9 | ||
|
6b580212bf | ||
|
208ae1cae7 | ||
|
3aa7fe47de | ||
|
5318082467 | ||
|
941ec095e5 | ||
|
d5ebd8e57c | ||
|
ebe087984d | ||
|
fa993e02dd | ||
|
44df77f45a | ||
|
0f8f95de9a | ||
|
f32283d2f1 | ||
|
14f8695599 | ||
|
f8b48f7455 | ||
|
70e2aab073 | ||
|
12db745f17 | ||
|
8a48cc690f | ||
|
eb313c65a5 | ||
|
07d6cbc194 | ||
|
8975a462c4 | ||
|
2e4f07d058 | ||
|
74a2935fea | ||
|
3d02468828 | ||
|
0438fb5a2e | ||
|
a4f9a6fd42 | ||
|
a0be4c9daa | ||
|
2dc003bd85 | ||
|
78aa8bd838 | ||
|
f55fde2b52 | ||
|
232572549e | ||
|
d07705c329 | ||
|
688ca8e374 | ||
|
160c364d2a | ||
|
2b3e6bfbb9 | ||
|
5a55d1db24 | ||
|
bd252dbc16 | ||
|
30124855e3 | ||
|
463ebd296f | ||
|
2e7a17560d | ||
|
374d5a074d | ||
|
88b294d873 | ||
|
0aa6d5b322 | ||
|
1357074dcd | ||
|
4a03847c14 | ||
|
346289fdb2 | ||
|
673c7d98f6 | ||
|
9473fb849a | ||
|
f60e244739 | ||
|
a571106f0f | ||
|
244d9be46e | ||
|
dcf71c6fdf | ||
|
1e1497ff4e | ||
|
b72aa92e55 | ||
|
527f18c1e3 | ||
|
788003dcdc | ||
|
c764ddd3be | ||
|
057ac0691c | ||
|
4334e9bed7 | ||
|
a9bb87b0c6 | ||
|
43f668dc65 | ||
|
6ed5892cf9 | ||
|
023a3fdade | ||
|
1b52147a05 | ||
|
7f7644c92f | ||
|
70b756baaf | ||
|
0f008b9b1e | ||
|
4d956858de | ||
|
959370a204 | ||
|
336829cd24 | ||
|
5975ab5170 | ||
|
eba0e942e8 | ||
|
f45c20db1e | ||
|
79afe09d8d | ||
|
334d010a24 | ||
|
91947daa5b | ||
|
aad2ca4488 | ||
|
7c68a96f7b | ||
|
2e1e8b5d39 | ||
|
178df1ed4a | ||
|
28749e2513 | ||
|
6cbe57ef40 | ||
|
13d3b86309 | ||
|
cf8f43cdf2 | ||
|
cc83268b2c | ||
|
8f23b47a78 | ||
|
529611170c | ||
|
c1114e889e | ||
|
d20e03a7b6 | ||
|
6303233bdf | ||
|
baa8c00144 | ||
|
e6daaa5b6d | ||
|
f711fcfd52 | ||
|
74992e95f2 | ||
|
20c8c1043f | ||
|
f00898afba | ||
|
95b431535e | ||
|
cafd8a9674 | ||
|
e1e7f914f9 | ||
|
19c2f7d2bf | ||
|
7daacd9b66 | ||
|
af715de566 | ||
|
93e3c89f20 | ||
|
b0456c5252 | ||
|
f7fa03ddd8 | ||
|
4c78e23a9c | ||
|
79c2065471 | ||
|
c19b89ac93 | ||
|
62a1837d61 | ||
|
56b34aa624 | ||
|
e8392155f9 | ||
|
6d532470e6 | ||
|
15f683ef7e | ||
|
18ba2e563e | ||
|
63984f1c37 | ||
|
3c082dcf0e | ||
|
090eb55226 | ||
|
4706cd44de | ||
|
cf7c01e5d0 | ||
|
0b5e0a268a | ||
|
9eea4497e5 | ||
|
63fdc2487f | ||
|
cf59da7e0c | ||
|
e0621affb6 |
185
.ci/php-cs-fixer/composer.lock
generated
185
.ci/php-cs-fixer/composer.lock
generated
@@ -379,16 +379,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.16.0",
|
||||
"version": "v3.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "d40f9436e1c448d309fa995ab9c14c5c7a96f2dc"
|
||||
"reference": "b123395c9fa3a70801f816f13606c0f3a7ada8df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d40f9436e1c448d309fa995ab9c14c5c7a96f2dc",
|
||||
"reference": "d40f9436e1c448d309fa995ab9c14c5c7a96f2dc",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/b123395c9fa3a70801f816f13606c0f3a7ada8df",
|
||||
"reference": "b123395c9fa3a70801f816f13606c0f3a7ada8df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -463,7 +463,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.16.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.18.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -471,7 +471,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-02T19:30:06+00:00"
|
||||
"time": "2023-06-18T22:25:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@@ -744,23 +744,23 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v6.2.10",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "12288d9f4500f84a4d02254d4aa968b15488476f"
|
||||
"reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/12288d9f4500f84a4d02254d4aa968b15488476f",
|
||||
"reference": "12288d9f4500f84a4d02254d4aa968b15488476f",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7",
|
||||
"reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/service-contracts": "^1.1|^2|^3",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/string": "^5.4|^6.0"
|
||||
},
|
||||
"conflict": {
|
||||
@@ -782,12 +782,6 @@
|
||||
"symfony/process": "^5.4|^6.0",
|
||||
"symfony/var-dumper": "^5.4|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "For using the console logger",
|
||||
"symfony/event-dispatcher": "",
|
||||
"symfony/lock": "",
|
||||
"symfony/process": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -820,7 +814,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v6.2.10"
|
||||
"source": "https://github.com/symfony/console/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -836,20 +830,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-28T13:37:43+00:00"
|
||||
"time": "2023-05-29T12:49:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.2.1",
|
||||
"version": "v3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
|
||||
"reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
|
||||
"reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
|
||||
"reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -858,7 +852,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.3-dev"
|
||||
"dev-main": "3.4-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -887,7 +881,7 @@
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -903,28 +897,29 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-01T10:25:55+00:00"
|
||||
"time": "2023-05-23T14:45:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v6.2.8",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339"
|
||||
"reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
|
||||
"reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa",
|
||||
"reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/event-dispatcher-contracts": "^2|^3"
|
||||
"symfony/event-dispatcher-contracts": "^2.5|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<5.4"
|
||||
"symfony/dependency-injection": "<5.4",
|
||||
"symfony/service-contracts": "<2.5"
|
||||
},
|
||||
"provide": {
|
||||
"psr/event-dispatcher-implementation": "1.0",
|
||||
@@ -937,13 +932,9 @@
|
||||
"symfony/error-handler": "^5.4|^6.0",
|
||||
"symfony/expression-language": "^5.4|^6.0",
|
||||
"symfony/http-foundation": "^5.4|^6.0",
|
||||
"symfony/service-contracts": "^1.1|^2|^3",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/stopwatch": "^5.4|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
"symfony/http-kernel": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -970,7 +961,7 @@
|
||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -986,33 +977,30 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-20T16:06:02+00:00"
|
||||
"time": "2023-04-21T14:41:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
"version": "v3.2.1",
|
||||
"version": "v3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
|
||||
"reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd"
|
||||
"reference": "a76aed96a42d2b521153fb382d418e30d18b59df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
|
||||
"reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df",
|
||||
"reference": "a76aed96a42d2b521153fb382d418e30d18b59df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"psr/event-dispatcher": "^1"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/event-dispatcher-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.3-dev"
|
||||
"dev-main": "3.4-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -1049,7 +1037,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.1"
|
||||
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1065,20 +1053,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-01T10:32:47+00:00"
|
||||
"time": "2023-05-23T14:45:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v6.2.10",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894"
|
||||
"reference": "97b698e1d77d356304def77a8d0cd73090b359ea"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/fd588debf7d1bc16a2c84b4b3b71145d9946b894",
|
||||
"reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/97b698e1d77d356304def77a8d0cd73090b359ea",
|
||||
"reference": "97b698e1d77d356304def77a8d0cd73090b359ea",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1112,7 +1100,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.2.10"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1128,20 +1116,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-18T13:46:08+00:00"
|
||||
"time": "2023-05-30T17:12:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v6.2.7",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb"
|
||||
"reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb",
|
||||
"reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2",
|
||||
"reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1176,7 +1164,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v6.2.7"
|
||||
"source": "https://github.com/symfony/finder/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1192,25 +1180,25 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-16T09:57:23+00:00"
|
||||
"time": "2023-04-02T01:25:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v6.2.7",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "aa0e85b53bbb2b4951960efd61d295907eacd629"
|
||||
"reference": "a10f19f5198d589d5c33333cffe98dc9820332dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/aa0e85b53bbb2b4951960efd61d295907eacd629",
|
||||
"reference": "aa0e85b53bbb2b4951960efd61d295907eacd629",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd",
|
||||
"reference": "a10f19f5198d589d5c33333cffe98dc9820332dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
"symfony/deprecation-contracts": "^2.5|^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -1243,7 +1231,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v6.2.7"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1259,7 +1247,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-14T08:44:56+00:00"
|
||||
"time": "2023-05-12T14:21:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -1755,16 +1743,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v6.2.10",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e"
|
||||
"reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
|
||||
"reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628",
|
||||
"reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1796,7 +1784,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v6.2.10"
|
||||
"source": "https://github.com/symfony/process/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1812,20 +1800,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-18T13:56:57+00:00"
|
||||
"time": "2023-05-19T08:06:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v3.2.1",
|
||||
"version": "v3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "a8c9cedf55f314f3a186041d19537303766df09a"
|
||||
"reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a",
|
||||
"reference": "a8c9cedf55f314f3a186041d19537303766df09a",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
|
||||
"reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1835,13 +1823,10 @@
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/service-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.3-dev"
|
||||
"dev-main": "3.4-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -1881,7 +1866,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.2.1"
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1897,25 +1882,25 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-01T10:32:47+00:00"
|
||||
"time": "2023-05-23T14:45:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v6.2.7",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
"reference": "f3adc98c1061875dd2edcd45e5b04e63d0e29f8f"
|
||||
"reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/f3adc98c1061875dd2edcd45e5b04e63d0e29f8f",
|
||||
"reference": "f3adc98c1061875dd2edcd45e5b04e63d0e29f8f",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2",
|
||||
"reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/service-contracts": "^1|^2|^3"
|
||||
"symfony/service-contracts": "^2.5|^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -1943,7 +1928,7 @@
|
||||
"description": "Provides a way to profile code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v6.2.7"
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1959,20 +1944,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-14T08:44:56+00:00"
|
||||
"time": "2023-02-16T10:14:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v6.2.8",
|
||||
"version": "v6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
|
||||
"reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
|
||||
"reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f",
|
||||
"reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1983,13 +1968,13 @@
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/translation-contracts": "<2.0"
|
||||
"symfony/translation-contracts": "<2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/error-handler": "^5.4|^6.0",
|
||||
"symfony/http-client": "^5.4|^6.0",
|
||||
"symfony/intl": "^6.2",
|
||||
"symfony/translation-contracts": "^2.0|^3.0",
|
||||
"symfony/translation-contracts": "^2.5|^3.0",
|
||||
"symfony/var-exporter": "^5.4|^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -2029,7 +2014,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v6.2.8"
|
||||
"source": "https://github.com/symfony/string/tree/v6.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2045,7 +2030,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-20T16:06:02+00:00"
|
||||
"time": "2023-03-21T21:06:29+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
@@ -32,7 +32,10 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd $SCRIPT_DIR/php-cs-fixer
|
||||
composer update
|
||||
rm -f .php-cs-fixer.cache
|
||||
echo 'Removed cache...'
|
||||
echo 'Running...'
|
||||
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php --allow-risky=yes
|
||||
echo 'Done!'
|
||||
cd $SCRIPT_DIR/..
|
||||
|
||||
exit 0
|
||||
|
@@ -13,8 +13,10 @@ hu_HU
|
||||
id_ID
|
||||
it_IT
|
||||
ja_JP
|
||||
ko_KR
|
||||
nb_NO
|
||||
nl_NL
|
||||
nn_NO
|
||||
pl_PL
|
||||
pt_BR
|
||||
pt_PT
|
||||
|
11
.env.example
11
.env.example
@@ -62,7 +62,7 @@ APP_LOG_LEVEL=notice
|
||||
AUDIT_LOG_LEVEL=info
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
|
||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
# Use "pgsql" for PostgreSQL
|
||||
# Use "mysql" for MySQL and MariaDB.
|
||||
@@ -134,7 +134,7 @@ COOKIE_SECURE=false
|
||||
COOKIE_SAMESITE=lax
|
||||
|
||||
# If you want Firefly III to email you, update these settings
|
||||
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
|
||||
# For instructions, see: https://docs.firefly-iii.org/firefly-iii/advanced-installation/email/#email
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=null
|
||||
@@ -163,9 +163,8 @@ SEND_ERROR_MESSAGE=true
|
||||
# These messages contain (sensitive) transaction information:
|
||||
SEND_REPORT_JOURNALS=true
|
||||
|
||||
# Set this value to true if you want to set the location
|
||||
# of certain things, like transactions. Since this involves an external service, it's optional
|
||||
# and disabled by default.
|
||||
# Set this value to true if you want to set the location of certain things, like transactions.
|
||||
# Since this involves an external service, it's optional and disabled by default.
|
||||
ENABLE_EXTERNAL_MAP=false
|
||||
|
||||
# Set this value to true if you want Firefly III to download currency exchange rates
|
||||
@@ -188,7 +187,7 @@ MAP_DEFAULT_ZOOM=6
|
||||
# - 'web' (default, uses built in DB)
|
||||
# - 'remote_user_guard' for Authelia etc
|
||||
# Read more about these settings in the documentation.
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
# https://docs.firefly-iii.org/firefly-iii/advanced-installation/authentication
|
||||
#
|
||||
# LDAP is no longer supported :(
|
||||
#
|
||||
|
4
.github/contributing.md
vendored
4
.github/contributing.md
vendored
@@ -1,3 +1,3 @@
|
||||
# [Contributing guidelines](https://docs.firefly-iii.org/other-pages/contributing)
|
||||
# [Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
|
||||
|
||||
[Contributing guidelines](https://docs.firefly-iii.org/other-pages/contributing)
|
||||
[Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
|
||||
|
3
.github/workflows/cleanup.yml
vendored
3
.github/workflows/cleanup.yml
vendored
@@ -56,9 +56,12 @@ jobs:
|
||||
|
||||
const workflows = [
|
||||
'cleanup.yml',
|
||||
'closed-issues.yml',
|
||||
'depsreview.yaml',
|
||||
'laravel.yml',
|
||||
'lock.yml',
|
||||
'qodana.yml',
|
||||
'sonarcloud.yml',
|
||||
'stale.yml'
|
||||
]
|
||||
|
||||
|
9
.github/workflows/closed-issues.yml
vendored
9
.github/workflows/closed-issues.yml
vendored
@@ -13,10 +13,11 @@ jobs:
|
||||
message: |
|
||||
Hi there! This is an automatic reply. `Share and enjoy`
|
||||
|
||||
This issue is now closed. Please be aware that closed issues are not actively monitored. If you reply, you may get no response.
|
||||
This issue is now 🔒 closed. Please be aware that closed issues are **not** watched.
|
||||
|
||||
- If the original bug is not actually fixed, please feel free to open a new issue. Please refer to this issue for clarity.
|
||||
- Follow-up questions can also be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/)
|
||||
- If the original bug is not actually fixed, please feel free to open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose). Please refer to this issue for clarity.
|
||||
- Follow-up questions must be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/)
|
||||
- Further replies to this issue will get **no response**.
|
||||
|
||||
Thank you for your consideration.
|
||||
Thank you for your contributions.
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
2
.github/workflows/qodana.yml
vendored
2
.github/workflows/qodana.yml
vendored
@@ -5,8 +5,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
jobs:
|
||||
qodana:
|
||||
runs-on: ubuntu-latest
|
||||
|
19
.github/workflows/sonarcloud.yml
vendored
Normal file
19
.github/workflows/sonarcloud.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Sonarcloud
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
jobs:
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: SonarCloud Scan
|
||||
uses: SonarSource/sonarcloud-github-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
@@ -81,8 +81,9 @@ class AccountController extends Controller
|
||||
$query = $data['query'];
|
||||
$date = $data['date'] ?? today(config('app.timezone'));
|
||||
|
||||
$return = [];
|
||||
$result = $this->repository->searchAccount((string)$query, $types, $data['limit']);
|
||||
$return = [];
|
||||
$result = $this->repository->searchAccount((string)$query, $types, $data['limit']);
|
||||
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
/** @var Account $account */
|
||||
@@ -92,7 +93,11 @@ class AccountController extends Controller
|
||||
|
||||
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
||||
$balance = app('steam')->balance($account, $date);
|
||||
$nameWithBalance = sprintf('%s (%s)', $account->name, app('amount')->formatAnything($currency, $balance, false));
|
||||
$nameWithBalance = sprintf(
|
||||
'%s (%s)',
|
||||
$account->name,
|
||||
app('amount')->formatAnything($currency, $balance, false)
|
||||
);
|
||||
}
|
||||
|
||||
$return[] = [
|
||||
@@ -109,14 +114,14 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
// custom order.
|
||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
||||
usort(
|
||||
$return,
|
||||
function ($a, $b) use ($order) {
|
||||
$pos_a = array_search($a['type'], $order, true);
|
||||
$pos_b = array_search($b['type'], $order, true);
|
||||
function ($a, $b) {
|
||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
||||
$posA = array_search($a['type'], $order, true);
|
||||
$posB = array_search($b['type'], $order, true);
|
||||
|
||||
return $pos_a - $pos_b;
|
||||
return $posA - $posB;
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -113,7 +113,7 @@ class AccountController extends Controller
|
||||
if (null === $currency) {
|
||||
$currency = $default;
|
||||
}
|
||||
$currentSet = [
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
@@ -125,6 +125,7 @@ class AccountController extends Controller
|
||||
'yAxisID' => 0, // 0, 1, 2
|
||||
'entries' => [],
|
||||
];
|
||||
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
||||
$currentStart = clone $start;
|
||||
$range = app('steam')->balanceInRange($account, $start, clone $end);
|
||||
// 2022-10-11 this method no longer converts to float.
|
||||
|
@@ -74,6 +74,42 @@ abstract class Controller extends BaseController
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to help build URL's.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function buildParams(): string
|
||||
{
|
||||
$return = '?';
|
||||
$params = [];
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
if ('page' === $key) {
|
||||
continue;
|
||||
}
|
||||
if ($value instanceof Carbon) {
|
||||
$params[$key] = $value->format('Y-m-d');
|
||||
continue;
|
||||
}
|
||||
$params[$key] = $value;
|
||||
}
|
||||
|
||||
return $return.http_build_query($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Manager
|
||||
*/
|
||||
final protected function getManager(): Manager
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
return $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to grab all parameters from the URL.
|
||||
*
|
||||
@@ -110,7 +146,13 @@ abstract class Controller extends BaseController
|
||||
$obj = Carbon::parse($date);
|
||||
} catch (InvalidDateException|InvalidFormatException $e) {
|
||||
// don't care
|
||||
app('log')->warning(sprintf('Ignored invalid date "%s" in API controller parameter check: %s', substr($date, 0, 20), $e->getMessage()));
|
||||
app('log')->warning(
|
||||
sprintf(
|
||||
'Ignored invalid date "%s" in API controller parameter check: %s',
|
||||
substr($date, 0, 20),
|
||||
$e->getMessage()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
$bag->set($field, $obj);
|
||||
@@ -169,41 +211,4 @@ abstract class Controller extends BaseController
|
||||
|
||||
return $bag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to help build URL's.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function buildParams(): string
|
||||
{
|
||||
$return = '?';
|
||||
$params = [];
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
if ('page' === $key) {
|
||||
continue;
|
||||
}
|
||||
if ($value instanceof Carbon) {
|
||||
$params[$key] = $value->format('Y-m-d');
|
||||
continue;
|
||||
}
|
||||
$params[$key] = $value;
|
||||
}
|
||||
|
||||
return $return.http_build_query($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Manager
|
||||
*/
|
||||
final protected function getManager(): Manager
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
return $manager;
|
||||
}
|
||||
}
|
||||
|
@@ -201,91 +201,6 @@ class DestroyController extends Controller
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyBudgets(): void
|
||||
{
|
||||
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
||||
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$abRepository->destroyAll();
|
||||
|
||||
/** @var BudgetLimitRepositoryInterface $blRepository */
|
||||
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$blRepository->destroyAll();
|
||||
|
||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||
$budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
$budgetRepository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyBills(): void
|
||||
{
|
||||
/** @var BillRepositoryInterface $repository */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyPiggyBanks(): void
|
||||
{
|
||||
/** @var PiggyBankRepositoryInterface $repository */
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyRules(): void
|
||||
{
|
||||
/** @var RuleGroupRepositoryInterface $repository */
|
||||
$repository = app(RuleGroupRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyRecurringTransactions(): void
|
||||
{
|
||||
/** @var RecurringRepositoryInterface $repository */
|
||||
$repository = app(RecurringRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyCategories(): void
|
||||
{
|
||||
/** @var CategoryRepositoryInterface $categoryRepos */
|
||||
$categoryRepos = app(CategoryRepositoryInterface::class);
|
||||
$categoryRepos->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyTags(): void
|
||||
{
|
||||
/** @var TagRepositoryInterface $tagRepository */
|
||||
$tagRepository = app(TagRepositoryInterface::class);
|
||||
$tagRepository->destroyAll();
|
||||
}
|
||||
|
||||
private function destroyObjectGroups(): void
|
||||
{
|
||||
/** @var ObjectGroupRepositoryInterface $repository */
|
||||
$repository = app(ObjectGroupRepositoryInterface::class);
|
||||
$repository->deleteAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*/
|
||||
@@ -311,6 +226,91 @@ class DestroyController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyBills(): void
|
||||
{
|
||||
/** @var BillRepositoryInterface $repository */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyBudgets(): void
|
||||
{
|
||||
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
||||
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$abRepository->destroyAll();
|
||||
|
||||
/** @var BudgetLimitRepositoryInterface $blRepository */
|
||||
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$blRepository->destroyAll();
|
||||
|
||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||
$budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
$budgetRepository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyCategories(): void
|
||||
{
|
||||
/** @var CategoryRepositoryInterface $categoryRepos */
|
||||
$categoryRepos = app(CategoryRepositoryInterface::class);
|
||||
$categoryRepos->destroyAll();
|
||||
}
|
||||
|
||||
private function destroyObjectGroups(): void
|
||||
{
|
||||
/** @var ObjectGroupRepositoryInterface $repository */
|
||||
$repository = app(ObjectGroupRepositoryInterface::class);
|
||||
$repository->deleteAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyPiggyBanks(): void
|
||||
{
|
||||
/** @var PiggyBankRepositoryInterface $repository */
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyRecurringTransactions(): void
|
||||
{
|
||||
/** @var RecurringRepositoryInterface $repository */
|
||||
$repository = app(RecurringRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyRules(): void
|
||||
{
|
||||
/** @var RuleGroupRepositoryInterface $repository */
|
||||
$repository = app(RuleGroupRepositoryInterface::class);
|
||||
$repository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function destroyTags(): void
|
||||
{
|
||||
/** @var TagRepositoryInterface $tagRepository */
|
||||
$tagRepository = app(TagRepositoryInterface::class);
|
||||
$tagRepository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*/
|
||||
|
@@ -69,34 +69,6 @@ class ExportController extends Controller
|
||||
return $this->returnExport('accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return LaravelResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function returnExport(string $key): LaravelResponse
|
||||
{
|
||||
$date = date('Y-m-d-H-i-s');
|
||||
$fileName = sprintf('%s-export-%s.csv', $date, $key);
|
||||
$data = $this->exporter->export();
|
||||
|
||||
/** @var LaravelResponse $response */
|
||||
$response = response($data[$key]);
|
||||
$response
|
||||
->header('Content-Description', 'File Transfer')
|
||||
->header('Content-Type', 'application/octet-stream')
|
||||
->header('Content-Disposition', 'attachment; filename='.$fileName)
|
||||
->header('Content-Transfer-Encoding', 'binary')
|
||||
->header('Connection', 'Keep-Alive')
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', (string)strlen($data[$key]));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills
|
||||
@@ -228,4 +200,32 @@ class ExportController extends Controller
|
||||
|
||||
return $this->returnExport('transactions');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return LaravelResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function returnExport(string $key): LaravelResponse
|
||||
{
|
||||
$date = date('Y-m-d-H-i-s');
|
||||
$fileName = sprintf('%s-export-%s.csv', $date, $key);
|
||||
$data = $this->exporter->export();
|
||||
|
||||
/** @var LaravelResponse $response */
|
||||
$response = response($data[$key]);
|
||||
$response
|
||||
->header('Content-Description', 'File Transfer')
|
||||
->header('Content-Type', 'application/octet-stream')
|
||||
->header('Content-Disposition', 'attachment; filename='.$fileName)
|
||||
->header('Content-Transfer-Encoding', 'binary')
|
||||
->header('Connection', 'Keep-Alive')
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', (string)strlen($data[$key]));
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
@@ -43,6 +43,7 @@ class PurgeController extends Controller
|
||||
* TODO cleanup and use repositories.
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/purgeData
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function purge(): JsonResponse
|
||||
|
@@ -29,8 +29,8 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
|
@@ -34,8 +34,8 @@ use FireflyIII\Transformers\AttachmentTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class StoreController
|
||||
|
@@ -96,6 +96,7 @@ class TriggerController extends Controller
|
||||
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
|
||||
}
|
||||
|
||||
|
||||
// file the rule(s)
|
||||
$transactions = $ruleEngine->find();
|
||||
$count = $transactions->count();
|
||||
@@ -149,6 +150,7 @@ class TriggerController extends Controller
|
||||
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
|
||||
}
|
||||
|
||||
|
||||
// fire the rule(s)
|
||||
$ruleEngine->fire();
|
||||
|
||||
|
@@ -97,21 +97,6 @@ class ShowController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransactionByJournal
|
||||
*
|
||||
* Show a single transaction, by transaction journal.
|
||||
*
|
||||
* @param TransactionJournal $transactionJournal
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function showJournal(TransactionJournal $transactionJournal): JsonResponse
|
||||
{
|
||||
return $this->show($transactionJournal->transactionGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransaction
|
||||
@@ -148,4 +133,19 @@ class ShowController extends Controller
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransactionByJournal
|
||||
*
|
||||
* Show a single transaction, by transaction journal.
|
||||
*
|
||||
* @param TransactionJournal $transactionJournal
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function showJournal(TransactionJournal $transactionJournal): JsonResponse
|
||||
{
|
||||
return $this->show($transactionJournal->transactionGroup);
|
||||
}
|
||||
}
|
||||
|
@@ -35,9 +35,9 @@ use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
|
@@ -32,8 +32,8 @@ use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
|
@@ -97,6 +97,35 @@ class UpdateController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/enableCurrency
|
||||
*
|
||||
* Enable a currency.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function enable(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
$this->repository->enable($currency);
|
||||
$manager = $this->getManager();
|
||||
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||
|
||||
/** @var CurrencyTransformer $transformer */
|
||||
$transformer = app(CurrencyTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Item($currency, $transformer, 'currencies');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/defaultCurrency
|
||||
@@ -128,35 +157,6 @@ class UpdateController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/enableCurrency
|
||||
*
|
||||
* Enable a currency.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function enable(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
$this->repository->enable($currency);
|
||||
$manager = $this->getManager();
|
||||
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||
|
||||
/** @var CurrencyTransformer $transformer */
|
||||
$transformer = app(CurrencyTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Item($currency, $transformer, 'currencies');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/updateCurrency
|
||||
|
@@ -32,10 +32,10 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use JsonException;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
@@ -61,12 +61,12 @@ class AccountController extends Controller
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchAccounts
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse|Response
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function search(Request $request)
|
||||
public function search(Request $request): JsonResponse|Response
|
||||
{
|
||||
Log::debug('Now in account search()');
|
||||
$manager = $this->getManager();
|
||||
|
@@ -71,6 +71,8 @@ class TransactionController extends Controller
|
||||
$resource = new Collection($transactions, $transformer, 'transactions');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($groups));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
$array = $manager->createData($resource)->toArray();
|
||||
|
||||
return response()->json($array)->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
}
|
||||
|
@@ -121,6 +121,30 @@ class BasicController extends Controller
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if date is outside session range.
|
||||
*
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
|
||||
{
|
||||
$result = false;
|
||||
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
// start and end in the past? use $end
|
||||
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@@ -240,44 +264,43 @@ class BasicController extends Controller
|
||||
* Since both this method and the chart use the exact same data, we can suffice
|
||||
* with calling the one method in the bill repository that will get this amount.
|
||||
*/
|
||||
$paidAmount = $this->billRepository->getBillsPaidInRangePerCurrency($start, $end);
|
||||
$unpaidAmount = $this->billRepository->getBillsUnpaidInRangePerCurrency($start, $end);
|
||||
$return = [];
|
||||
foreach ($paidAmount as $currencyId => $amount) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
$currency = $this->currencyRepos->find((int)$currencyId);
|
||||
if (null === $currency) {
|
||||
continue;
|
||||
}
|
||||
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
|
||||
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
|
||||
|
||||
$return = [];
|
||||
/**
|
||||
* @var array $info
|
||||
*/
|
||||
foreach ($paidAmount as $info) {
|
||||
$amount = bcmul($info['sum'], '-1');
|
||||
$return[] = [
|
||||
'key' => sprintf('bills-paid-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $currency->symbol]),
|
||||
'key' => sprintf('bills-paid-in-%s', $info['code']),
|
||||
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
|
||||
'monetary_value' => $amount,
|
||||
'currency_id' => $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $amount, false),
|
||||
'currency_id' => $info['id'],
|
||||
'currency_code' => $info['code'],
|
||||
'currency_symbol' => $info['symbol'],
|
||||
'currency_decimal_places' => $info['decimal_places'],
|
||||
'value_parsed' => app('amount')->formatFlat($info['symbol'], $info['decimal_places'], $amount, false),
|
||||
'local_icon' => 'check',
|
||||
'sub_title' => '',
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($unpaidAmount as $currencyId => $amount) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
$currency = $this->currencyRepos->find((int)$currencyId);
|
||||
if (null === $currency) {
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* @var array $info
|
||||
*/
|
||||
foreach ($unpaidAmount as $info) {
|
||||
$amount = bcmul($info['sum'], '-1');
|
||||
$return[] = [
|
||||
'key' => sprintf('bills-unpaid-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $currency->symbol]),
|
||||
'key' => sprintf('bills-unpaid-in-%s', $info['code']),
|
||||
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
|
||||
'monetary_value' => $amount,
|
||||
'currency_id' => $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $amount, false),
|
||||
'currency_id' => $info['id'],
|
||||
'currency_code' => $info['code'],
|
||||
'currency_symbol' => $info['symbol'],
|
||||
'currency_decimal_places' => $info['decimal_places'],
|
||||
'value_parsed' => app('amount')->formatFlat($info['symbol'], $info['decimal_places'], $amount, false),
|
||||
'local_icon' => 'calendar-o',
|
||||
'sub_title' => '',
|
||||
];
|
||||
@@ -399,28 +422,4 @@ class BasicController extends Controller
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if date is outside session range.
|
||||
*
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
|
||||
{
|
||||
$result = false;
|
||||
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
// start and end in the past? use $end
|
||||
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@@ -94,42 +94,6 @@ class ConfigurationController extends Controller
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all config values.
|
||||
*
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
private function getDynamicConfiguration(): array
|
||||
{
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
|
||||
$updateCheck = app('fireflyconfig')->get('permission_update_check');
|
||||
$lastCheck = app('fireflyconfig')->get('last_update_check');
|
||||
$singleUser = app('fireflyconfig')->get('single_user_mode');
|
||||
|
||||
return [
|
||||
'is_demo_site' => $isDemoSite?->data,
|
||||
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
|
||||
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
|
||||
'single_user_mode' => $singleUser?->data,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getStaticConfiguration(): array
|
||||
{
|
||||
$list = EitherConfigKey::$static;
|
||||
$return = [];
|
||||
foreach ($list as $key) {
|
||||
$return[$key] = config($key);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getSingleConfiguration
|
||||
@@ -200,4 +164,40 @@ class ConfigurationController extends Controller
|
||||
|
||||
return response()->json(['data' => $data])->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all config values.
|
||||
*
|
||||
* @return array
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
private function getDynamicConfiguration(): array
|
||||
{
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
|
||||
$updateCheck = app('fireflyconfig')->get('permission_update_check');
|
||||
$lastCheck = app('fireflyconfig')->get('last_update_check');
|
||||
$singleUser = app('fireflyconfig')->get('single_user_mode');
|
||||
|
||||
return [
|
||||
'is_demo_site' => $isDemoSite?->data,
|
||||
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
|
||||
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
|
||||
'single_user_mode' => $singleUser?->data,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getStaticConfiguration(): array
|
||||
{
|
||||
$list = EitherConfigKey::$static;
|
||||
$return = [];
|
||||
foreach ($list as $key) {
|
||||
$return[$key] = config($key);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@@ -54,6 +54,10 @@ class CronController extends Controller
|
||||
$return = [];
|
||||
$return['recurring_transactions'] = $this->runRecurring($config['force'], $config['date']);
|
||||
$return['auto_budgets'] = $this->runAutoBudget($config['force'], $config['date']);
|
||||
if (true === config('cer.enabled')) {
|
||||
$return['exchange_rates'] = $this->exchangeRatesCronJob($config['force'], $config['date']);
|
||||
}
|
||||
$return['bill_warnings'] = $this->billWarningCronJob($config['force'], $config['date']);
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
@@ -122,6 +122,7 @@ class ShowController extends Controller
|
||||
*
|
||||
* @param Webhook $webhook
|
||||
* @param TransactionGroup $group
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function triggerTransaction(Webhook $webhook, TransactionGroup $group): JsonResponse
|
||||
@@ -141,6 +142,7 @@ class ShowController extends Controller
|
||||
|
||||
// trigger event to send them:
|
||||
event(new RequestedSendWebhookMessages());
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
}
|
||||
|
@@ -83,6 +83,7 @@ class MoveTransactionsRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function validateMove(Validator $validator): void
|
||||
|
@@ -30,9 +30,9 @@ use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
use JsonException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class TransactionRequest
|
||||
|
@@ -82,28 +82,6 @@ class GenericRequest extends FormRequest
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseAccounts(): void
|
||||
{
|
||||
if (0 !== $this->accounts->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('accounts');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $accountId) {
|
||||
$accountId = (int)$accountId;
|
||||
$account = $repository->find($accountId);
|
||||
if (null !== $account) {
|
||||
$this->accounts->push($account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -114,28 +92,6 @@ class GenericRequest extends FormRequest
|
||||
return $this->bills;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseBills(): void
|
||||
{
|
||||
if (0 !== $this->bills->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('bills');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $billId) {
|
||||
$billId = (int)$billId;
|
||||
$bill = $repository->find($billId);
|
||||
if (null !== $bill) {
|
||||
$this->bills->push($bill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -146,28 +102,6 @@ class GenericRequest extends FormRequest
|
||||
return $this->budgets;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseBudgets(): void
|
||||
{
|
||||
if (0 !== $this->budgets->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('budgets');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $budgetId) {
|
||||
$budgetId = (int)$budgetId;
|
||||
$budget = $repository->find($budgetId);
|
||||
if (null !== $budget) {
|
||||
$this->budgets->push($budget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -178,28 +112,6 @@ class GenericRequest extends FormRequest
|
||||
return $this->categories;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseCategories(): void
|
||||
{
|
||||
if (0 !== $this->categories->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('categories');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $categoryId) {
|
||||
$categoryId = (int)$categoryId;
|
||||
$category = $repository->find($categoryId);
|
||||
if (null !== $category) {
|
||||
$this->categories->push($category);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
@@ -268,6 +180,114 @@ class GenericRequest extends FormRequest
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
// this is cheating, but it works to initialize the collections.
|
||||
$this->accounts = new Collection();
|
||||
$this->budgets = new Collection();
|
||||
$this->categories = new Collection();
|
||||
$this->bills = new Collection();
|
||||
$this->tags = new Collection();
|
||||
|
||||
return [
|
||||
'start' => 'required|date',
|
||||
'end' => 'required|date|after_or_equal:start',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseAccounts(): void
|
||||
{
|
||||
if (0 !== $this->accounts->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('accounts');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $accountId) {
|
||||
$accountId = (int)$accountId;
|
||||
$account = $repository->find($accountId);
|
||||
if (null !== $account) {
|
||||
$this->accounts->push($account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseBills(): void
|
||||
{
|
||||
if (0 !== $this->bills->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('bills');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $billId) {
|
||||
$billId = (int)$billId;
|
||||
$bill = $repository->find($billId);
|
||||
if (null !== $bill) {
|
||||
$this->bills->push($bill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseBudgets(): void
|
||||
{
|
||||
if (0 !== $this->budgets->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('budgets');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $budgetId) {
|
||||
$budgetId = (int)$budgetId;
|
||||
$budget = $repository->find($budgetId);
|
||||
if (null !== $budget) {
|
||||
$this->budgets->push($budget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function parseCategories(): void
|
||||
{
|
||||
if (0 !== $this->categories->count()) {
|
||||
return;
|
||||
}
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$array = $this->get('categories');
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $categoryId) {
|
||||
$categoryId = (int)$categoryId;
|
||||
$category = $repository->find($categoryId);
|
||||
if (null !== $category) {
|
||||
$this->categories->push($category);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -289,24 +309,4 @@ class GenericRequest extends FormRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
// this is cheating, but it works to initialize the collections.
|
||||
$this->accounts = new Collection();
|
||||
$this->budgets = new Collection();
|
||||
$this->categories = new Collection();
|
||||
$this->bills = new Collection();
|
||||
$this->tags = new Collection();
|
||||
|
||||
return [
|
||||
'start' => 'required|date',
|
||||
'end' => 'required|date|after_or_equal:start',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ use FireflyIII\Support\Request\AppendsLocationData;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class UpdateRequest
|
||||
@@ -63,9 +62,9 @@ class UpdateRequest extends FormRequest
|
||||
'account_role' => ['account_role', 'convertString'],
|
||||
'liability_type' => ['liability_type', 'convertString'],
|
||||
'opening_balance' => ['opening_balance', 'convertString'],
|
||||
'opening_balance_date' => ['opening_balance_date', 'date'],
|
||||
'opening_balance_date' => ['opening_balance_date', 'convertDateTime'],
|
||||
'cc_type' => ['credit_card_type', 'convertString'],
|
||||
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertString'],
|
||||
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertDateTime'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'interest' => ['interest', 'convertString'],
|
||||
'interest_period' => ['interest_period', 'convertString'],
|
||||
@@ -77,6 +76,7 @@ class UpdateRequest extends FormRequest
|
||||
'liability_start_date' => ['liability_start_date', 'date'],
|
||||
];
|
||||
$data = $this->getAllData($fields);
|
||||
|
||||
return $this->appendLocationData($data, null);
|
||||
}
|
||||
|
||||
|
@@ -28,8 +28,8 @@ use FireflyIII\Rules\IsBoolean;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class StoreRequest
|
||||
@@ -105,8 +105,8 @@ class StoreRequest extends FormRequest
|
||||
$validator->after(
|
||||
static function (Validator $validator) {
|
||||
$data = $validator->getData();
|
||||
$min = $data['amount_min'] ?? '0';
|
||||
$max = $data['amount_max'] ?? '0';
|
||||
$min = (string)($data['amount_min'] ?? '0');
|
||||
$max = (string)($data['amount_max'] ?? '0');
|
||||
|
||||
if (1 === bccomp($min, $max)) {
|
||||
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max'));
|
||||
|
@@ -79,9 +79,9 @@ class StoreRequest extends FormRequest
|
||||
'currency_code' => 'exists:transaction_currencies,code',
|
||||
'notes' => 'nullable|between:1,65536',
|
||||
// auto budget info
|
||||
'auto_budget_type' => 'in:reset,rollover,none',
|
||||
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
|
||||
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
|
||||
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
|
||||
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
|
||||
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -67,6 +67,7 @@ class UpdateRequest extends FormRequest
|
||||
'none' => 0,
|
||||
'reset' => 1,
|
||||
'rollover' => 2,
|
||||
'adjusted' => 3,
|
||||
];
|
||||
$allData['auto_budget_type'] = $types[$allData['auto_budget_type']] ?? 0;
|
||||
}
|
||||
@@ -88,7 +89,7 @@ class UpdateRequest extends FormRequest
|
||||
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
|
||||
'active' => [new IsBoolean()],
|
||||
'notes' => 'nullable|between:1,65536',
|
||||
'auto_budget_type' => 'in:reset,rollover,none',
|
||||
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
|
||||
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
|
||||
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
|
||||
'auto_budget_amount' => 'min:0|max:1000000000',
|
||||
|
@@ -52,8 +52,8 @@ class UpdateRequest extends FormRequest
|
||||
'account_id' => ['account_id', 'convertInteger'],
|
||||
'targetamount' => ['target_amount', 'convertString'],
|
||||
'current_amount' => ['current_amount', 'convertString'],
|
||||
'startdate' => ['start_date', 'date'],
|
||||
'targetdate' => ['target_date', 'convertString'],
|
||||
'startdate' => ['start_date', 'convertDateTime'],
|
||||
'targetdate' => ['target_date', 'convertDateTime'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'order' => ['order', 'convertInteger'],
|
||||
'object_group_title' => ['object_group_title', 'convertString'],
|
||||
|
@@ -57,8 +57,8 @@ class StoreRequest extends FormRequest
|
||||
'type' => ['type', 'convertString'],
|
||||
'title' => ['title', 'convertString'],
|
||||
'description' => ['description', 'convertString'],
|
||||
'first_date' => ['first_date', 'date'],
|
||||
'repeat_until' => ['repeat_until', 'date'],
|
||||
'first_date' => ['first_date', 'convertDateTime'],
|
||||
'repeat_until' => ['repeat_until', 'convertDateTime'],
|
||||
'nr_of_repetitions' => ['nr_of_repetitions', 'convertInteger'],
|
||||
'apply_rules' => ['apply_rules', 'boolean'],
|
||||
'active' => ['active', 'boolean'],
|
||||
@@ -73,65 +73,6 @@ class StoreRequest extends FormRequest
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array|null $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
if (null === $transactions) {
|
||||
return [];
|
||||
}
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return[] = $this->getSingleTransactionData($transaction);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the repetition data as it is found in the submitted data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getRepetitionData(): array
|
||||
{
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array|null $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
if (null === $repetitions) {
|
||||
return [];
|
||||
}
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$current = [];
|
||||
if (array_key_exists('type', $repetition)) {
|
||||
$current['type'] = $repetition['type'];
|
||||
}
|
||||
if (array_key_exists('moment', $repetition)) {
|
||||
$current['moment'] = $repetition['moment'];
|
||||
}
|
||||
if (array_key_exists('skip', $repetition)) {
|
||||
$current['skip'] = (int)$repetition['skip'];
|
||||
}
|
||||
if (array_key_exists('weekend', $repetition)) {
|
||||
$current['weekend'] = (int)$repetition['weekend'];
|
||||
}
|
||||
|
||||
$return[] = $current;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
@@ -198,4 +139,63 @@ class StoreRequest extends FormRequest
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the repetition data as it is found in the submitted data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getRepetitionData(): array
|
||||
{
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array|null $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
if (null === $repetitions) {
|
||||
return [];
|
||||
}
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$current = [];
|
||||
if (array_key_exists('type', $repetition)) {
|
||||
$current['type'] = $repetition['type'];
|
||||
}
|
||||
if (array_key_exists('moment', $repetition)) {
|
||||
$current['moment'] = $repetition['moment'];
|
||||
}
|
||||
if (array_key_exists('skip', $repetition)) {
|
||||
$current['skip'] = (int)$repetition['skip'];
|
||||
}
|
||||
if (array_key_exists('weekend', $repetition)) {
|
||||
$current['weekend'] = (int)$repetition['weekend'];
|
||||
}
|
||||
|
||||
$return[] = $current;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array|null $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
if (null === $transactions) {
|
||||
return [];
|
||||
}
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return[] = $this->getSingleTransactionData($transaction);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@@ -58,8 +58,8 @@ class UpdateRequest extends FormRequest
|
||||
$fields = [
|
||||
'title' => ['title', 'convertString'],
|
||||
'description' => ['description', 'convertString'],
|
||||
'first_date' => ['first_date', 'date'],
|
||||
'repeat_until' => ['repeat_until', 'date'],
|
||||
'first_date' => ['first_date', 'convertDateTime'],
|
||||
'repeat_until' => ['repeat_until', 'convertDateTime'],
|
||||
'nr_of_repetitions' => ['nr_of_repetitions', 'convertInteger'],
|
||||
'apply_rules' => ['apply_rules', 'boolean'],
|
||||
'active' => ['active', 'boolean'],
|
||||
@@ -80,70 +80,6 @@ class UpdateRequest extends FormRequest
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the repetition data as it is found in the submitted data.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function getRepetitionData(): ?array
|
||||
{
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array|null $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
if (null === $repetitions) {
|
||||
return null;
|
||||
}
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$current = [];
|
||||
if (array_key_exists('type', $repetition)) {
|
||||
$current['type'] = $repetition['type'];
|
||||
}
|
||||
|
||||
if (array_key_exists('moment', $repetition)) {
|
||||
$current['moment'] = (string)$repetition['moment'];
|
||||
}
|
||||
|
||||
if (array_key_exists('skip', $repetition)) {
|
||||
$current['skip'] = (int)$repetition['skip'];
|
||||
}
|
||||
|
||||
if (array_key_exists('weekend', $repetition)) {
|
||||
$current['weekend'] = (int)$repetition['weekend'];
|
||||
}
|
||||
$return[] = $current;
|
||||
}
|
||||
if (0 === count($return)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function getTransactionData(): ?array
|
||||
{
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array|null $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
if (null === $transactions) {
|
||||
return null;
|
||||
}
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return[] = $this->getSingleTransactionData($transaction);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
@@ -205,6 +141,11 @@ class UpdateRequest extends FormRequest
|
||||
function (Validator $validator) {
|
||||
//$this->validateOneRecurrenceTransaction($validator);
|
||||
//$this->validateOneRepetitionUpdate($validator);
|
||||
|
||||
|
||||
/** @var Recurrence $recurrence */
|
||||
$recurrence = $this->route()->parameter('recurrence');
|
||||
$this->validateTransactionId($recurrence, $validator);
|
||||
$this->validateRecurrenceRepetition($validator);
|
||||
$this->validateRepetitionMoment($validator);
|
||||
$this->validateForeignCurrencyInformation($validator);
|
||||
@@ -212,4 +153,69 @@ class UpdateRequest extends FormRequest
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the repetition data as it is found in the submitted data.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function getRepetitionData(): ?array
|
||||
{
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array|null $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
if (null === $repetitions) {
|
||||
return null;
|
||||
}
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$current = [];
|
||||
if (array_key_exists('type', $repetition)) {
|
||||
$current['type'] = $repetition['type'];
|
||||
}
|
||||
|
||||
if (array_key_exists('moment', $repetition)) {
|
||||
$current['moment'] = (string)$repetition['moment'];
|
||||
}
|
||||
|
||||
if (array_key_exists('skip', $repetition)) {
|
||||
$current['skip'] = (int)$repetition['skip'];
|
||||
}
|
||||
|
||||
if (array_key_exists('weekend', $repetition)) {
|
||||
$current['weekend'] = (int)$repetition['weekend'];
|
||||
}
|
||||
$return[] = $current;
|
||||
}
|
||||
if (0 === count($return)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function getTransactionData(): ?array
|
||||
{
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array|null $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
if (null === $transactions) {
|
||||
return null;
|
||||
}
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return[] = $this->getSingleTransactionData($transaction);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -67,48 +67,6 @@ class StoreRequest extends FormRequest
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getRuleTriggers(): array
|
||||
{
|
||||
$triggers = $this->get('triggers');
|
||||
$return = [];
|
||||
if (is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$return[] = [
|
||||
'type' => $trigger['type'],
|
||||
'value' => $trigger['value'],
|
||||
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')),
|
||||
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getRuleActions(): array
|
||||
{
|
||||
$actions = $this->get('actions');
|
||||
$return = [];
|
||||
if (is_array($actions)) {
|
||||
foreach ($actions as $action) {
|
||||
$return[] = [
|
||||
'type' => $action['type'],
|
||||
'value' => $action['value'],
|
||||
'active' => $this->convertBoolean((string)($action['active'] ?? 'true')),
|
||||
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
@@ -162,21 +120,6 @@ class StoreRequest extends FormRequest
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no triggers in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneTrigger(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($triggers) || 0 === count($triggers)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
@@ -192,6 +135,35 @@ class StoreRequest extends FormRequest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no ACTIVE actions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneActiveAction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($actions) || 0 === count($actions)) {
|
||||
return;
|
||||
}
|
||||
$allInactive = true;
|
||||
$inactiveIndex = 0;
|
||||
foreach ($actions as $index => $action) {
|
||||
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
|
||||
if (true === $active) {
|
||||
$allInactive = false;
|
||||
}
|
||||
if (false === $active) {
|
||||
$inactiveIndex = $index;
|
||||
}
|
||||
}
|
||||
if (true === $allInactive) {
|
||||
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no ACTIVE triggers in the array of data.
|
||||
*
|
||||
@@ -222,31 +194,59 @@ class StoreRequest extends FormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no ACTIVE actions in the array of data.
|
||||
* Adds an error to the validator when there are no triggers in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneActiveAction(Validator $validator): void
|
||||
protected function atLeastOneTrigger(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? [];
|
||||
$data = $validator->getData();
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($actions) || 0 === count($actions)) {
|
||||
return;
|
||||
}
|
||||
$allInactive = true;
|
||||
$inactiveIndex = 0;
|
||||
foreach ($actions as $index => $action) {
|
||||
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
|
||||
if (true === $active) {
|
||||
$allInactive = false;
|
||||
}
|
||||
if (false === $active) {
|
||||
$inactiveIndex = $index;
|
||||
}
|
||||
}
|
||||
if (true === $allInactive) {
|
||||
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
|
||||
if (!is_countable($triggers) || 0 === count($triggers)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getRuleActions(): array
|
||||
{
|
||||
$actions = $this->get('actions');
|
||||
$return = [];
|
||||
if (is_array($actions)) {
|
||||
foreach ($actions as $action) {
|
||||
$return[] = [
|
||||
'type' => $action['type'],
|
||||
'value' => $action['value'],
|
||||
'active' => $this->convertBoolean((string)($action['active'] ?? 'true')),
|
||||
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getRuleTriggers(): array
|
||||
{
|
||||
$triggers = $this->get('triggers');
|
||||
$return = [];
|
||||
if (is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$return[] = [
|
||||
'type' => $trigger['type'],
|
||||
'value' => $trigger['value'],
|
||||
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')),
|
||||
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@@ -52,11 +52,24 @@ class TestRequest extends FormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @return array
|
||||
*/
|
||||
private function getPage(): int
|
||||
public function rules(): array
|
||||
{
|
||||
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page');
|
||||
return [
|
||||
'start' => 'date',
|
||||
'end' => 'date|after_or_equal:start',
|
||||
'accounts' => '',
|
||||
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getAccounts(): array
|
||||
{
|
||||
return $this->get('accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,23 +83,10 @@ class TestRequest extends FormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return int
|
||||
*/
|
||||
private function getAccounts(): array
|
||||
private function getPage(): int
|
||||
{
|
||||
return $this->get('accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date',
|
||||
'end' => 'date|after_or_equal:start',
|
||||
'accounts' => '',
|
||||
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page');
|
||||
}
|
||||
}
|
||||
|
@@ -49,24 +49,6 @@ class TriggerRequest extends FormRequest
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getDate(string $field): ?Carbon
|
||||
{
|
||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field), 0, 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getAccounts(): array
|
||||
{
|
||||
return $this->get('accounts') ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -79,4 +61,22 @@ class TriggerRequest extends FormRequest
|
||||
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getAccounts(): array
|
||||
{
|
||||
return $this->get('accounts') ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getDate(string $field): ?Carbon
|
||||
{
|
||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field), 0, 10));
|
||||
}
|
||||
}
|
||||
|
@@ -73,56 +73,6 @@ class UpdateRequest extends FormRequest
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
private function getRuleTriggers(): ?array
|
||||
{
|
||||
if (!$this->has('triggers')) {
|
||||
return null;
|
||||
}
|
||||
$triggers = $this->get('triggers');
|
||||
$return = [];
|
||||
if (is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true;
|
||||
$stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false;
|
||||
$return[] = [
|
||||
'type' => $trigger['type'],
|
||||
'value' => $trigger['value'],
|
||||
'active' => $active,
|
||||
'stop_processing' => $stopProcessing,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
private function getRuleActions(): ?array
|
||||
{
|
||||
if (!$this->has('actions')) {
|
||||
return null;
|
||||
}
|
||||
$actions = $this->get('actions');
|
||||
$return = [];
|
||||
if (is_array($actions)) {
|
||||
foreach ($actions as $action) {
|
||||
$return[] = [
|
||||
'type' => $action['type'],
|
||||
'value' => $action['value'],
|
||||
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
|
||||
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
@@ -180,6 +130,21 @@ class UpdateRequest extends FormRequest
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneAction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? null;
|
||||
// need at least one action
|
||||
if (is_array($actions) && 0 === count($actions)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
@@ -195,6 +160,36 @@ class UpdateRequest extends FormRequest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneValidAction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? [];
|
||||
$allInactive = true;
|
||||
$inactiveIndex = 0;
|
||||
// need at least one action
|
||||
if (is_array($actions) && 0 === count($actions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($actions as $index => $action) {
|
||||
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
|
||||
if (true === $active) {
|
||||
$allInactive = false;
|
||||
}
|
||||
if (false === $active) {
|
||||
$inactiveIndex = $index;
|
||||
}
|
||||
}
|
||||
if (true === $allInactive) {
|
||||
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
@@ -225,47 +220,52 @@ class UpdateRequest extends FormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @return array|null
|
||||
*/
|
||||
protected function atLeastOneAction(Validator $validator): void
|
||||
private function getRuleActions(): ?array
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? null;
|
||||
// need at least one action
|
||||
if (is_array($actions) && 0 === count($actions)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||
if (!$this->has('actions')) {
|
||||
return null;
|
||||
}
|
||||
$actions = $this->get('actions');
|
||||
$return = [];
|
||||
if (is_array($actions)) {
|
||||
foreach ($actions as $action) {
|
||||
$return[] = [
|
||||
'type' => $action['type'],
|
||||
'value' => $action['value'],
|
||||
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
|
||||
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @return array|null
|
||||
*/
|
||||
protected function atLeastOneValidAction(Validator $validator): void
|
||||
private function getRuleTriggers(): ?array
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? [];
|
||||
$allInactive = true;
|
||||
$inactiveIndex = 0;
|
||||
// need at least one action
|
||||
if (is_array($actions) && 0 === count($actions)) {
|
||||
return;
|
||||
if (!$this->has('triggers')) {
|
||||
return null;
|
||||
}
|
||||
$triggers = $this->get('triggers');
|
||||
$return = [];
|
||||
if (is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true;
|
||||
$stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false;
|
||||
$return[] = [
|
||||
'type' => $trigger['type'],
|
||||
'value' => $trigger['value'],
|
||||
'active' => $active,
|
||||
'stop_processing' => $stopProcessing,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($actions as $index => $action) {
|
||||
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
|
||||
if (true === $active) {
|
||||
$allInactive = false;
|
||||
}
|
||||
if (false === $active) {
|
||||
$inactiveIndex = $index;
|
||||
}
|
||||
}
|
||||
if (true === $allInactive) {
|
||||
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@@ -49,24 +49,6 @@ class TestRequest extends FormRequest
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getDate(string $field): ?Carbon
|
||||
{
|
||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getAccounts(): array
|
||||
{
|
||||
return $this->get('accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -79,4 +61,22 @@ class TestRequest extends FormRequest
|
||||
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getAccounts(): array
|
||||
{
|
||||
return $this->get('accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getDate(string $field): ?Carbon
|
||||
{
|
||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
|
||||
}
|
||||
}
|
||||
|
@@ -50,13 +50,14 @@ class TriggerRequest extends FormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
* @return array
|
||||
*/
|
||||
private function getDate(string $field): ?Carbon
|
||||
public function rules(): array
|
||||
{
|
||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
|
||||
return [
|
||||
'start' => 'date',
|
||||
'end' => 'date|after_or_equal:start',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,13 +69,12 @@ class TriggerRequest extends FormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function rules(): array
|
||||
private function getDate(string $field): ?Carbon
|
||||
{
|
||||
return [
|
||||
'start' => 'date',
|
||||
'end' => 'date|after_or_equal:start',
|
||||
];
|
||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
|
||||
}
|
||||
}
|
||||
|
@@ -35,8 +35,8 @@ use FireflyIII\Validation\CurrencyValidation;
|
||||
use FireflyIII\Validation\GroupValidation;
|
||||
use FireflyIII\Validation\TransactionValidation;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class StoreRequest
|
||||
@@ -69,103 +69,6 @@ class StoreRequest extends FormRequest
|
||||
// TODO include location and ability to process it.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transaction data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
$return = [];
|
||||
/**
|
||||
* @var array $transaction
|
||||
*/
|
||||
foreach ($this->get('transactions') as $transaction) {
|
||||
$object = new NullArrayObject($transaction);
|
||||
$return[] = [
|
||||
'type' => $this->clearString($object['type'], false),
|
||||
'date' => $this->dateFromValue($object['date']),
|
||||
'order' => $this->integerFromValue((string)$object['order']),
|
||||
|
||||
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
|
||||
'currency_code' => $this->clearString((string)$object['currency_code'], false),
|
||||
|
||||
// foreign currency info:
|
||||
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
|
||||
'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code'], false),
|
||||
|
||||
// amount and foreign amount. Cannot be 0.
|
||||
'amount' => $this->clearString((string)$object['amount'], false),
|
||||
'foreign_amount' => $this->clearString((string)$object['foreign_amount'], false),
|
||||
|
||||
// description.
|
||||
'description' => $this->clearString($object['description'], false),
|
||||
|
||||
// source of transaction. If everything is null, assume cash account.
|
||||
'source_id' => $this->integerFromValue((string)$object['source_id']),
|
||||
'source_name' => $this->clearString((string)$object['source_name'], false),
|
||||
'source_iban' => $this->clearString((string)$object['source_iban'], false),
|
||||
'source_number' => $this->clearString((string)$object['source_number'], false),
|
||||
'source_bic' => $this->clearString((string)$object['source_bic'], false),
|
||||
|
||||
// destination of transaction. If everything is null, assume cash account.
|
||||
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
|
||||
'destination_name' => $this->clearString((string)$object['destination_name'], false),
|
||||
'destination_iban' => $this->clearString((string)$object['destination_iban'], false),
|
||||
'destination_number' => $this->clearString((string)$object['destination_number'], false),
|
||||
'destination_bic' => $this->clearString((string)$object['destination_bic'], false),
|
||||
|
||||
// budget info
|
||||
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
|
||||
'budget_name' => $this->clearString((string)$object['budget_name'], false),
|
||||
|
||||
// category info
|
||||
'category_id' => $this->integerFromValue((string)$object['category_id']),
|
||||
'category_name' => $this->clearString((string)$object['category_name'], false),
|
||||
|
||||
// journal bill reference. Optional. Will only work for withdrawals
|
||||
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
|
||||
'bill_name' => $this->clearString((string)$object['bill_name'], false),
|
||||
|
||||
// piggy bank reference. Optional. Will only work for transfers
|
||||
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
|
||||
'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name'], false),
|
||||
|
||||
// some other interesting properties
|
||||
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
|
||||
'notes' => $this->clearString((string)$object['notes']),
|
||||
'tags' => $this->arrayFromValue($object['tags']),
|
||||
|
||||
// all custom fields:
|
||||
'internal_reference' => $this->clearString((string)$object['internal_reference'], false),
|
||||
'external_id' => $this->clearString((string)$object['external_id'], false),
|
||||
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
|
||||
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
||||
'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id'], false),
|
||||
'external_url' => $this->clearString((string)$object['external_url'], false),
|
||||
|
||||
'sepa_cc' => $this->clearString((string)$object['sepa_cc'], false),
|
||||
'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op'], false),
|
||||
'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id'], false),
|
||||
'sepa_db' => $this->clearString((string)$object['sepa_db'], false),
|
||||
'sepa_country' => $this->clearString((string)$object['sepa_country'], false),
|
||||
'sepa_ep' => $this->clearString((string)$object['sepa_ep'], false),
|
||||
'sepa_ci' => $this->clearString((string)$object['sepa_ci'], false),
|
||||
'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id'], false),
|
||||
// custom date fields. Must be Carbon objects. Presence is optional.
|
||||
'interest_date' => $this->dateFromValue($object['interest_date']),
|
||||
'book_date' => $this->dateFromValue($object['book_date']),
|
||||
'process_date' => $this->dateFromValue($object['process_date']),
|
||||
'due_date' => $this->dateFromValue($object['due_date']),
|
||||
'payment_date' => $this->dateFromValue($object['payment_date']),
|
||||
'invoice_date' => $this->dateFromValue($object['invoice_date']),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
@@ -294,4 +197,101 @@ class StoreRequest extends FormRequest
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transaction data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
$return = [];
|
||||
/**
|
||||
* @var array $transaction
|
||||
*/
|
||||
foreach ($this->get('transactions') as $transaction) {
|
||||
$object = new NullArrayObject($transaction);
|
||||
$return[] = [
|
||||
'type' => $this->clearString($object['type'], false),
|
||||
'date' => $this->dateFromValue($object['date']),
|
||||
'order' => $this->integerFromValue((string)$object['order']),
|
||||
|
||||
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
|
||||
'currency_code' => $this->clearString((string)$object['currency_code'], false),
|
||||
|
||||
// foreign currency info:
|
||||
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
|
||||
'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code'], false),
|
||||
|
||||
// amount and foreign amount. Cannot be 0.
|
||||
'amount' => $this->clearString((string)$object['amount'], false),
|
||||
'foreign_amount' => $this->clearString((string)$object['foreign_amount'], false),
|
||||
|
||||
// description.
|
||||
'description' => $this->clearString($object['description'], false),
|
||||
|
||||
// source of transaction. If everything is null, assume cash account.
|
||||
'source_id' => $this->integerFromValue((string)$object['source_id']),
|
||||
'source_name' => $this->clearString((string)$object['source_name'], false),
|
||||
'source_iban' => $this->clearString((string)$object['source_iban'], false),
|
||||
'source_number' => $this->clearString((string)$object['source_number'], false),
|
||||
'source_bic' => $this->clearString((string)$object['source_bic'], false),
|
||||
|
||||
// destination of transaction. If everything is null, assume cash account.
|
||||
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
|
||||
'destination_name' => $this->clearString((string)$object['destination_name'], false),
|
||||
'destination_iban' => $this->clearString((string)$object['destination_iban'], false),
|
||||
'destination_number' => $this->clearString((string)$object['destination_number'], false),
|
||||
'destination_bic' => $this->clearString((string)$object['destination_bic'], false),
|
||||
|
||||
// budget info
|
||||
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
|
||||
'budget_name' => $this->clearString((string)$object['budget_name'], false),
|
||||
|
||||
// category info
|
||||
'category_id' => $this->integerFromValue((string)$object['category_id']),
|
||||
'category_name' => $this->clearString((string)$object['category_name'], false),
|
||||
|
||||
// journal bill reference. Optional. Will only work for withdrawals
|
||||
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
|
||||
'bill_name' => $this->clearString((string)$object['bill_name'], false),
|
||||
|
||||
// piggy bank reference. Optional. Will only work for transfers
|
||||
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
|
||||
'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name'], false),
|
||||
|
||||
// some other interesting properties
|
||||
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
|
||||
'notes' => $this->clearString((string)$object['notes']),
|
||||
'tags' => $this->arrayFromValue($object['tags']),
|
||||
|
||||
// all custom fields:
|
||||
'internal_reference' => $this->clearString((string)$object['internal_reference'], false),
|
||||
'external_id' => $this->clearString((string)$object['external_id'], false),
|
||||
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
|
||||
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
||||
'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id'], false),
|
||||
'external_url' => $this->clearString((string)$object['external_url'], false),
|
||||
|
||||
'sepa_cc' => $this->clearString((string)$object['sepa_cc'], false),
|
||||
'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op'], false),
|
||||
'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id'], false),
|
||||
'sepa_db' => $this->clearString((string)$object['sepa_db'], false),
|
||||
'sepa_country' => $this->clearString((string)$object['sepa_country'], false),
|
||||
'sepa_ep' => $this->clearString((string)$object['sepa_ep'], false),
|
||||
'sepa_ci' => $this->clearString((string)$object['sepa_ci'], false),
|
||||
'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id'], false),
|
||||
// custom date fields. Must be Carbon objects. Presence is optional.
|
||||
'interest_date' => $this->dateFromValue($object['interest_date']),
|
||||
'book_date' => $this->dateFromValue($object['book_date']),
|
||||
'process_date' => $this->dateFromValue($object['process_date']),
|
||||
'due_date' => $this->dateFromValue($object['due_date']),
|
||||
'payment_date' => $this->dateFromValue($object['payment_date']),
|
||||
'invoice_date' => $this->dateFromValue($object['invoice_date']),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@@ -62,7 +62,6 @@ class UpdateRequest extends FormRequest
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$this->integerFields = [
|
||||
'order',
|
||||
@@ -165,7 +164,7 @@ class UpdateRequest extends FormRequest
|
||||
|
||||
/** @var array $transaction */
|
||||
foreach ($this->get('transactions') as $transaction) {
|
||||
if(!is_array($transaction)) {
|
||||
if (!is_array($transaction)) {
|
||||
throw new FireflyException('Invalid data submitted: transaction is not array.');
|
||||
}
|
||||
// default response is to update nothing in the transaction:
|
||||
@@ -292,6 +291,7 @@ class UpdateRequest extends FormRequest
|
||||
/**
|
||||
* @param array $current
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getFloatData(array $current, array $transaction): array
|
||||
@@ -300,7 +300,7 @@ class UpdateRequest extends FormRequest
|
||||
if (array_key_exists($fieldName, $transaction)) {
|
||||
$value = $transaction[$fieldName];
|
||||
if (is_float($value)) {
|
||||
$current[$fieldName] = sprintf('%.24f', $value);
|
||||
$current[$fieldName] = sprintf('%.12f', $value);
|
||||
}
|
||||
if (!is_float($value)) {
|
||||
$current[$fieldName] = (string)$value;
|
||||
@@ -319,6 +319,7 @@ class UpdateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
|
||||
return [
|
||||
// basic fields for group:
|
||||
'group_title' => 'between:1,1000',
|
||||
|
@@ -64,9 +64,9 @@ class UpdateRequest extends FormRequest
|
||||
$linkType = $this->route()->parameter('linkType');
|
||||
|
||||
return [
|
||||
'name' => [Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1','max:1024'],
|
||||
'outward' => ['different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1','max:1024'],
|
||||
'inward' => ['different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1','max:1024'],
|
||||
'name' => [Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1', 'max:1024'],
|
||||
'outward' => ['different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1', 'max:1024'],
|
||||
'inward' => ['different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1', 'max:1024'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -29,8 +29,8 @@ use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -43,9 +43,9 @@ class AccountController extends Controller
|
||||
{
|
||||
use AccountFilter;
|
||||
|
||||
private array $balanceTypes;
|
||||
private AdminAccountRepositoryInterface $adminRepository;
|
||||
private AccountRepositoryInterface $repository;
|
||||
private array $balanceTypes;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
@@ -55,9 +55,7 @@ class AccountController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->adminRepository = app(AdminAccountRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
@@ -113,10 +111,10 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
// custom order.
|
||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
||||
usort(
|
||||
$return,
|
||||
function ($a, $b) use ($order) {
|
||||
function ($a, $b) {
|
||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
||||
$pos_a = array_search($a['type'], $order, true);
|
||||
$pos_b = array_search($b['type'], $order, true);
|
||||
|
||||
|
@@ -53,6 +53,7 @@ class AccountController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -63,6 +64,7 @@ class AccountController extends Controller
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/charts/getChartAccountOverview
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
|
@@ -64,6 +64,54 @@ class Controller extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param LengthAwarePaginator $paginator
|
||||
* @param AbstractTransformer $transformer
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
|
||||
{
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$objects = $paginator->getCollection();
|
||||
|
||||
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||
// require, like meta data and stuff like that, and save it for later.
|
||||
$transformer->collectMetaData($objects);
|
||||
|
||||
$resource = new FractalCollection($objects, $transformer, $key);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return $manager->createData($resource)->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON API object and returns it.
|
||||
*
|
||||
* @param string $key
|
||||
* @param Model $object
|
||||
* @param AbstractTransformer $transformer
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final protected function jsonApiObject(string $key, Model $object, AbstractTransformer $transformer): array
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$transformer->collectMetaData(new Collection([$object]));
|
||||
|
||||
$resource = new Item($object, $transformer, $key);
|
||||
|
||||
return $manager->createData($resource)->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO duplicate from V1 controller
|
||||
* Method to grab all parameters from the URL.
|
||||
@@ -131,49 +179,4 @@ class Controller extends BaseController
|
||||
|
||||
return $bag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param LengthAwarePaginator $paginator
|
||||
* @param AbstractTransformer $transformer
|
||||
* @return array
|
||||
*/
|
||||
final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
|
||||
{
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$objects = $paginator->getCollection();
|
||||
|
||||
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||
// require, like meta data and stuff like that, and save it for later.
|
||||
$transformer->collectMetaData($objects);
|
||||
|
||||
$resource = new FractalCollection($objects, $transformer, $key);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return $manager->createData($resource)->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON API object and returns it.
|
||||
*
|
||||
* @param string $key
|
||||
* @param Model $object
|
||||
* @param AbstractTransformer $transformer
|
||||
* @return array
|
||||
*/
|
||||
final protected function jsonApiObject(string $key, Model $object, AbstractTransformer $transformer): array
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$transformer->collectMetaData(new Collection([$object]));
|
||||
|
||||
$resource = new Item($object, $transformer, $key);
|
||||
return $manager->createData($resource)->toArray();
|
||||
}
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ class SumController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -58,6 +59,7 @@ class SumController extends Controller
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/transactions-sum/getBillsPaidTrSum
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function paid(DateRequest $request): JsonResponse
|
||||
@@ -75,6 +77,7 @@ class SumController extends Controller
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/transactions-sum/getBillsUnpaidTrSum
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function unpaid(DateRequest $request): JsonResponse
|
||||
|
@@ -41,6 +41,7 @@ class ListController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -51,6 +52,7 @@ class ListController extends Controller
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/listBudgets
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
@@ -61,6 +63,7 @@ class ListController extends Controller
|
||||
|
||||
$paginator = new LengthAwarePaginator($collection, $total, $this->pageSize, $this->parameters->get('page'));
|
||||
$transformer = new BudgetTransformer();
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiList('budgets', $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
|
@@ -48,6 +48,7 @@ class ShowController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
|
@@ -48,6 +48,7 @@ class SumController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -58,6 +59,7 @@ class SumController extends Controller
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/getBudgetedForBudget
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function budgeted(DateRequest $request): JsonResponse
|
||||
@@ -72,7 +74,9 @@ class SumController extends Controller
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/getSpentForBudget
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function spent(DateRequest $request): JsonResponse
|
||||
|
@@ -42,6 +42,7 @@ class ListController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BudgetLimitRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -60,6 +61,7 @@ class ListController extends Controller
|
||||
|
||||
$paginator = new LengthAwarePaginator($collection, $total, $this->pageSize, $this->parameters->get('page'));
|
||||
$transformer = new BudgetLimitTransformer();
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiList('budget_limits', $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
|
@@ -48,6 +48,7 @@ class NetWorthController extends Controller
|
||||
function ($request, $next) {
|
||||
$this->netWorth = app(NetWorthInterface::class);
|
||||
$this->netWorth->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -56,7 +57,9 @@ class NetWorthController extends Controller
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/net-worth/getNetWorth
|
||||
*
|
||||
* @param SingleDateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function get(SingleDateRequest $request): JsonResponse
|
||||
|
@@ -37,7 +37,9 @@ class PreferencesController extends Controller
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/preferences/getPreference
|
||||
*
|
||||
* @param Preference $preference
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function get(Preference $preference): JsonResponse
|
||||
|
@@ -46,6 +46,7 @@ class AccountController extends Controller
|
||||
*
|
||||
* @param ListRequest $request
|
||||
* @param Account $account
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function listTransactions(ListRequest $request, Account $account): JsonResponse
|
||||
|
@@ -60,6 +60,7 @@ class AutocompleteRequest extends FormRequest
|
||||
$array = array_diff($array, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION]);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
'types' => $array,
|
||||
'query' => $this->convertString('query'),
|
||||
|
@@ -25,12 +25,14 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V2\Response\Sum;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class AutoSum
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class AutoSum
|
||||
@@ -39,7 +41,9 @@ class AutoSum
|
||||
* @param Collection $objects
|
||||
* @param Closure $getCurrency
|
||||
* @param Closure $getSum
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function autoSum(Collection $objects, Closure $getCurrency, Closure $getSum): array
|
||||
{
|
||||
@@ -64,6 +68,6 @@ class AutoSum
|
||||
}
|
||||
|
||||
var_dump(array_values($return));
|
||||
exit;
|
||||
throw new FireflyException('Not implemented');
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\Bill;
|
||||
@@ -39,22 +40,12 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class CorrectAmounts extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'This command makes sure positive and negative amounts are recorded correctly.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-amount-pos-neg';
|
||||
protected $signature = 'firefly-iii:fix-amount-pos-neg';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
@@ -90,7 +81,8 @@ class CorrectAmounts extends Command
|
||||
$set = AutoBudget::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All auto budget amounts are positive.');
|
||||
$this->friendlyPositive('All auto budget amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var AutoBudget $item */
|
||||
@@ -98,7 +90,7 @@ class CorrectAmounts extends Command
|
||||
$item->amount = app('steam')->positive((string)$item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d auto budget amount(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d auto budget amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +101,8 @@ class CorrectAmounts extends Command
|
||||
$set = AvailableBudget::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All available budget amounts are positive.');
|
||||
$this->friendlyPositive('All available budget amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var AvailableBudget $item */
|
||||
@@ -117,7 +110,7 @@ class CorrectAmounts extends Command
|
||||
$item->amount = app('steam')->positive((string)$item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d available budget amount(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d available budget amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +121,8 @@ class CorrectAmounts extends Command
|
||||
$set = Bill::where('amount_min', '<', 0)->orWhere('amount_max', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All bill amounts are positive.');
|
||||
$this->friendlyPositive('All bill amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var Bill $item */
|
||||
@@ -137,6 +131,7 @@ class CorrectAmounts extends Command
|
||||
$item->amount_max = app('steam')->positive((string)$item->amount_max);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d bill amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,7 +142,8 @@ class CorrectAmounts extends Command
|
||||
$set = BudgetLimit::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All budget limit amounts are positive.');
|
||||
$this->friendlyPositive('All budget limit amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var BudgetLimit $item */
|
||||
@@ -155,7 +151,7 @@ class CorrectAmounts extends Command
|
||||
$item->amount = app('steam')->positive((string)$item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d budget limit amount(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d budget limit amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +162,8 @@ class CorrectAmounts extends Command
|
||||
$set = CurrencyExchangeRate::where('rate', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All currency exchange rates are positive.');
|
||||
$this->friendlyPositive('All currency exchange rates are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var BudgetLimit $item */
|
||||
@@ -174,7 +171,7 @@ class CorrectAmounts extends Command
|
||||
$item->rate = app('steam')->positive((string)$item->rate);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d currency exchange rate(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d currency exchange rate(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +182,8 @@ class CorrectAmounts extends Command
|
||||
$set = PiggyBank::where('targetamount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All piggy bank amounts are positive.');
|
||||
$this->friendlyPositive('All piggy bank amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var PiggyBankRepetition $item */
|
||||
@@ -193,7 +191,7 @@ class CorrectAmounts extends Command
|
||||
$item->targetamount = app('steam')->positive((string)$item->targetamount);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d piggy bank amount(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d piggy bank amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,7 +204,8 @@ class CorrectAmounts extends Command
|
||||
->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All recurring transaction amounts are positive.');
|
||||
$this->friendlyPositive('All recurring transaction amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var PiggyBankRepetition $item */
|
||||
@@ -215,7 +214,7 @@ class CorrectAmounts extends Command
|
||||
$item->foreign_amount = app('steam')->positive((string)$item->foreign_amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d recurring transaction amount(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d recurring transaction amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +225,8 @@ class CorrectAmounts extends Command
|
||||
$set = PiggyBankRepetition::where('currentamount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('Correct: All piggy bank repetition amounts are positive.');
|
||||
$this->friendlyPositive('All piggy bank repetition amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var PiggyBankRepetition $item */
|
||||
@@ -234,7 +234,7 @@ class CorrectAmounts extends Command
|
||||
$item->currentamount = app('steam')->positive((string)$item->currentamount);
|
||||
$item->save();
|
||||
}
|
||||
$this->line(sprintf('Corrected %d piggy bank repetition amount(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Corrected %d piggy bank repetition amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,10 +254,11 @@ class CorrectAmounts extends Command
|
||||
}
|
||||
}
|
||||
if (0 === $fixed) {
|
||||
$this->info('Correct: All rule trigger amounts are positive.');
|
||||
$this->friendlyPositive('All rule trigger amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->line(sprintf('Corrected %d rule trigger amount(s).', $fixed));
|
||||
$this->friendlyInfo(sprintf('Corrected %d rule trigger amount(s).', $fixed));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use Artisan;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Schema;
|
||||
|
||||
@@ -34,28 +35,20 @@ use Schema;
|
||||
*/
|
||||
class CorrectDatabase extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Will correct the integrity of your database, if necessary.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:correct-database';
|
||||
protected $signature = 'firefly-iii:correct-database';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->line('Handle Firefly III database correction commands.');
|
||||
// if table does not exist, return false
|
||||
if (!Schema::hasTable('users')) {
|
||||
$this->error('No "users"-table, will not continue.');
|
||||
$this->friendlyError('No "users"-table, will not continue.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
$commands = [
|
||||
@@ -86,7 +79,7 @@ class CorrectDatabase extends Command
|
||||
'firefly-iii:trigger-credit-recalculation',
|
||||
];
|
||||
foreach ($commands as $command) {
|
||||
$this->line(sprintf('Now executing command "%s"', $command));
|
||||
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
||||
$this->call($command);
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -33,26 +33,17 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use JsonException;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CorrectOpeningBalanceCurrencies
|
||||
*/
|
||||
class CorrectOpeningBalanceCurrencies extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Will make sure that opening balance transaction currencies match the account they\'re for.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-ob-currencies';
|
||||
protected $signature = 'firefly-iii:fix-ob-currencies';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -61,32 +52,22 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
// get all OB journals:
|
||||
$set = TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*']);
|
||||
|
||||
$this->line(sprintf('Going to verify %d opening balance transactions.', $set->count()));
|
||||
$count = 0;
|
||||
$journals = $this->getJournals();
|
||||
$count = 0;
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($set as $journal) {
|
||||
foreach ($journals as $journal) {
|
||||
$count += $this->correctJournal($journal);
|
||||
}
|
||||
|
||||
if ($count > 0) {
|
||||
$message = sprintf('Corrected %d opening balance transaction(s).', $count);
|
||||
Log::debug($message);
|
||||
$this->line($message);
|
||||
$this->friendlyInfo($message);
|
||||
}
|
||||
if (0 === $count) {
|
||||
$message = 'There was nothing to fix in the opening balance transactions.';
|
||||
Log::debug($message);
|
||||
$this->info($message);
|
||||
$this->friendlyPositive($message);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Done with %s', __METHOD__));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -94,24 +75,21 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return int
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
*/
|
||||
private function correctJournal(TransactionJournal $journal): int
|
||||
{
|
||||
// get the asset account for this opening balance:
|
||||
$account = $this->getAccount($journal);
|
||||
if (null === $account) {
|
||||
$message = sprintf('Transaction journal #%d has no valid account. Cant fix this line.', $journal->id);
|
||||
$message = sprintf('Transaction journal #%d has no valid account. Can\'t fix this line.', $journal->id);
|
||||
app('log')->warning($message);
|
||||
$this->warn($message);
|
||||
$this->friendlyError($message);
|
||||
|
||||
return 0;
|
||||
}
|
||||
$currency = $this->getCurrency($account);
|
||||
|
||||
// update journal and all transactions:
|
||||
return $this->setCurrency($journal, $currency);
|
||||
return $this->setCorrectCurrency($account, $journal);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +108,7 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -137,8 +116,6 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
* @param Account $account
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
* @throws JsonException
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getCurrency(Account $account): TransactionCurrency
|
||||
{
|
||||
@@ -150,14 +127,25 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
private function getJournals(): Collection
|
||||
{
|
||||
/** @var Collection */
|
||||
return TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param TransactionJournal $journal
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function setCurrency(TransactionJournal $journal, TransactionCurrency $currency): int
|
||||
private function setCorrectCurrency(Account $account, TransactionJournal $journal): int
|
||||
{
|
||||
$count = 0;
|
||||
$currency = $this->getCurrency($account);
|
||||
$count = 0;
|
||||
if ((int)$journal->transaction_currency_id !== (int)$currency->id) {
|
||||
$journal->transaction_currency_id = $currency->id;
|
||||
$journal->save();
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -33,6 +34,8 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class CreateAccessTokens extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -58,7 +61,6 @@ class CreateAccessTokens extends Command
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
|
||||
$start = microtime(true);
|
||||
$count = 0;
|
||||
$users = $repository->all();
|
||||
/** @var User $user */
|
||||
@@ -67,15 +69,13 @@ class CreateAccessTokens extends Command
|
||||
if (null === $pref) {
|
||||
$token = $user->generateAccessToken();
|
||||
app('preferences')->setForUser($user, 'access_token', $token);
|
||||
$this->line(sprintf('Generated access token for user %s', $user->email));
|
||||
$this->friendlyInfo(sprintf('Generated access token for user %s', $user->email));
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->info('All access tokens OK!');
|
||||
$this->friendlyPositive('Verified access tokens.');
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verify access tokens in %s seconds.', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\LinkType;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
@@ -31,6 +32,8 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class CreateLinkTypes extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -51,7 +54,6 @@ class CreateLinkTypes extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$count = 0;
|
||||
$set = [
|
||||
'Related' => ['relates to', 'relates to'],
|
||||
@@ -68,17 +70,14 @@ class CreateLinkTypes extends Command
|
||||
$link->inward = $values[1];
|
||||
$link->outward = $values[0];
|
||||
++$count;
|
||||
$this->line(sprintf('Created missing link type "%s"', $name));
|
||||
$this->friendlyInfo(sprintf('Created missing link type "%s"', $name));
|
||||
}
|
||||
$link->editable = false;
|
||||
$link->save();
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->info('All link types OK!');
|
||||
$this->friendlyPositive('All link types are OK');
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified link types in %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -24,27 +24,19 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class DeleteEmptyGroups
|
||||
*/
|
||||
class DeleteEmptyGroups extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Delete empty transaction groups.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:delete-empty-groups';
|
||||
protected $signature = 'firefly-iii:delete-empty-groups';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -55,16 +47,13 @@ class DeleteEmptyGroups extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$start = microtime(true);
|
||||
$groupIds
|
||||
= TransactionGroup::leftJoin('transaction_journals', 'transaction_groups.id', '=', 'transaction_journals.transaction_group_id')
|
||||
->whereNull('transaction_journals.id')->get(['transaction_groups.id'])->pluck('id')->toArray();
|
||||
= TransactionGroup::leftJoin('transaction_journals', 'transaction_groups.id', '=', 'transaction_journals.transaction_group_id')
|
||||
->whereNull('transaction_journals.id')->get(['transaction_groups.id'])->pluck('id')->toArray();
|
||||
|
||||
$total = count($groupIds);
|
||||
Log::debug(sprintf('Count is %d', $total));
|
||||
if ($total > 0) {
|
||||
$this->info(sprintf('Deleted %d empty transaction group(s).', $total));
|
||||
$this->friendlyInfo(sprintf('Deleted %d empty transaction group(s).', $total));
|
||||
|
||||
// again, chunks for SQLite.
|
||||
$chunks = array_chunk($groupIds, 500);
|
||||
@@ -72,8 +61,9 @@ class DeleteEmptyGroups extends Command
|
||||
TransactionGroup::whereNull('deleted_at')->whereIn('id', $chunk)->delete();
|
||||
}
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified empty groups in %s seconds', $end));
|
||||
if (0 === $total) {
|
||||
$this->friendlyInfo('Verified there are no empty groups.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -35,6 +36,8 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class DeleteEmptyJournals extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -63,7 +66,6 @@ class DeleteEmptyJournals extends Command
|
||||
|
||||
private function deleteEmptyJournals(): void
|
||||
{
|
||||
$start = microtime(true);
|
||||
$count = 0;
|
||||
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->groupBy('transaction_journals.id')
|
||||
@@ -78,14 +80,12 @@ class DeleteEmptyJournals extends Command
|
||||
}
|
||||
|
||||
|
||||
$this->info(sprintf('Deleted empty transaction journal #%d', $entry->id));
|
||||
$this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id));
|
||||
++$count;
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->info('No empty transaction journals.');
|
||||
$this->friendlyPositive('No empty transaction journals.');
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified empty journals in %s seconds', $end));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,12 +110,14 @@ class DeleteEmptyJournals extends Command
|
||||
|
||||
|
||||
Transaction::where('transaction_journal_id', (int)$row->transaction_journal_id)->delete();
|
||||
$this->info(sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id));
|
||||
$this->friendlyWarning(
|
||||
sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id)
|
||||
);
|
||||
$total++;
|
||||
}
|
||||
}
|
||||
if (0 === $total) {
|
||||
$this->info('No uneven transaction journals.');
|
||||
$this->friendlyPositive('No uneven transaction journals.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -34,6 +35,8 @@ use stdClass;
|
||||
*/
|
||||
class DeleteOrphanedTransactions extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -55,12 +58,9 @@ class DeleteOrphanedTransactions extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$this->deleteOrphanedJournals();
|
||||
$this->deleteOrphanedTransactions();
|
||||
$this->deleteFromOrphanedAccounts();
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified orphans in %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ class DeleteOrphanedTransactions extends Command
|
||||
$journal->delete();
|
||||
}
|
||||
Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
|
||||
$this->line(
|
||||
$this->friendlyWarning(
|
||||
sprintf(
|
||||
'Deleted transaction journal #%d because account #%d was already deleted.',
|
||||
$transaction->transaction_journal_id,
|
||||
@@ -93,7 +93,7 @@ class DeleteOrphanedTransactions extends Command
|
||||
$count++;
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->info('No orphaned accounts.');
|
||||
$this->friendlyPositive('No orphaned accounts.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,22 +105,21 @@ class DeleteOrphanedTransactions extends Command
|
||||
->get(['transaction_journals.id', 'transaction_journals.transaction_group_id']);
|
||||
$count = $set->count();
|
||||
if (0 === $count) {
|
||||
$this->info('No orphaned journals.');
|
||||
$this->friendlyPositive('No orphaned journals.');
|
||||
return;
|
||||
}
|
||||
if ($count > 0) {
|
||||
$this->info(sprintf('Found %d orphaned journal(s).', $count));
|
||||
foreach ($set as $entry) {
|
||||
$journal = TransactionJournal::withTrashed()->find((int)$entry->id);
|
||||
if (null !== $journal) {
|
||||
$journal->delete();
|
||||
$this->info(
|
||||
sprintf(
|
||||
'Journal #%d (part of deleted transaction group #%d) has been deleted as well.',
|
||||
$entry->id,
|
||||
$entry->transaction_group_id
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Found %d orphaned journal(s).', $count));
|
||||
foreach ($set as $entry) {
|
||||
$journal = TransactionJournal::withTrashed()->find((int)$entry->id);
|
||||
if (null !== $journal) {
|
||||
$journal->delete();
|
||||
$this->friendlyWarning(
|
||||
sprintf(
|
||||
'Journal #%d (part of deleted transaction group #%d) has been deleted as well.',
|
||||
$entry->id,
|
||||
$entry->transaction_group_id
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +145,7 @@ class DeleteOrphanedTransactions extends Command
|
||||
$transaction = Transaction::find((int)$entry->transaction_id);
|
||||
if (null !== $transaction) {
|
||||
$transaction->delete();
|
||||
$this->info(
|
||||
$this->friendlyWarning(
|
||||
sprintf(
|
||||
'Transaction #%d (part of deleted transaction journal #%d) has been deleted as well.',
|
||||
$entry->transaction_id,
|
||||
@@ -157,7 +156,7 @@ class DeleteOrphanedTransactions extends Command
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->info('No orphaned transactions.');
|
||||
$this->friendlyPositive('No orphaned transactions.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -32,6 +33,8 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class DeleteZeroAmount extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -52,24 +55,20 @@ class DeleteZeroAmount extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$set = Transaction::where('amount', 0)->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
|
||||
$set = array_unique($set);
|
||||
$journals = TransactionJournal::whereIn('id', $set)->get();
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$this->info(sprintf('Deleted transaction journal #%d because the amount is zero (0.00).', $journal->id));
|
||||
$this->friendlyWarning(sprintf('Deleted transaction journal #%d because the amount is zero (0.00).', $journal->id));
|
||||
$journal->delete();
|
||||
|
||||
Transaction::where('transaction_journal_id', $journal->id)->delete();
|
||||
}
|
||||
if (0 === $journals->count()) {
|
||||
$this->info('No zero-amount transaction journals.');
|
||||
$this->friendlyPositive('No zero-amount transaction journals.');
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified zero-amount integrity in %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -37,18 +38,10 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class EnableCurrencies extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Enables all currencies in use.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:enable-currencies';
|
||||
protected $signature = 'firefly-iii:enable-currencies';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -57,7 +50,6 @@ class EnableCurrencies extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$found = [];
|
||||
// get all meta entries
|
||||
/** @var Collection $meta */
|
||||
@@ -85,8 +77,8 @@ class EnableCurrencies extends Command
|
||||
$found[] = (int)$entry->transaction_currency_id;
|
||||
}
|
||||
|
||||
$found = array_values(array_unique($found));
|
||||
$found = array_values(
|
||||
$found = array_values(array_unique($found));
|
||||
$found = array_values(
|
||||
array_filter(
|
||||
$found,
|
||||
function (int $currencyId) {
|
||||
@@ -94,22 +86,15 @@ class EnableCurrencies extends Command
|
||||
}
|
||||
)
|
||||
);
|
||||
$message = sprintf('%d different currencies are currently in use.', count($found));
|
||||
$this->info($message);
|
||||
Log::debug($message, $found);
|
||||
|
||||
$disabled = TransactionCurrency::whereIn('id', $found)->where('enabled', false)->count();
|
||||
if ($disabled > 0) {
|
||||
$this->info(sprintf('%d were (was) still disabled. This has been corrected.', $disabled));
|
||||
$this->friendlyInfo(sprintf('%d currencies were (was) disabled while in use by transactions. This has been corrected.', $disabled));
|
||||
}
|
||||
if (0 === $disabled) {
|
||||
$this->info('All currencies are correctly enabled or disabled.');
|
||||
$this->friendlyPositive('All currencies are correctly enabled or disabled.');
|
||||
}
|
||||
TransactionCurrency::whereIn('id', $found)->update(['enabled' => true]);
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified currencies in %s seconds.', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -32,18 +33,10 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class FixAccountOrder extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Make sure account order is correct.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-account-order';
|
||||
protected $signature = 'firefly-iii:fix-account-order';
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
@@ -55,7 +48,6 @@ class FixAccountOrder extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$this->stupidLaravel();
|
||||
$start = microtime(true);
|
||||
|
||||
$users = User::get();
|
||||
foreach ($users as $user) {
|
||||
@@ -63,8 +55,7 @@ class FixAccountOrder extends Command
|
||||
$this->repository->resetAccountOrder();
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verifying account order took %s seconds', $end));
|
||||
$this->friendlyPositive('All accounts are ordered correctly');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\AccountFactory;
|
||||
use FireflyIII\Models\AccountType;
|
||||
@@ -38,18 +39,10 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class FixAccountTypes extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Make sure all journals have the correct from/to account types.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-account-types';
|
||||
protected $signature = 'firefly-iii:fix-account-types';
|
||||
private int $count;
|
||||
private array $expected;
|
||||
private AccountFactory $factory;
|
||||
@@ -63,103 +56,23 @@ class FixAccountTypes extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$this->stupidLaravel();
|
||||
Log::debug('Now in fix-account-types');
|
||||
$start = microtime(true);
|
||||
$this->factory = app(AccountFactory::class);
|
||||
$this->expected = config('firefly.source_dests');
|
||||
$journals = TransactionJournal::with(['TransactionType', 'transactions', 'transactions.account', 'transactions.account.accounttype'])->get();
|
||||
Log::debug(sprintf('Found %d journals to inspect.', $journals->count()));
|
||||
foreach ($journals as $journal) {
|
||||
$this->inspectJournal($journal);
|
||||
}
|
||||
if (0 === $this->count) {
|
||||
Log::debug('No journals had to be fixed.');
|
||||
$this->info('All account types are OK!');
|
||||
$this->friendlyPositive('All account types are OK');
|
||||
}
|
||||
if (0 !== $this->count) {
|
||||
Log::debug(sprintf('%d journals had to be fixed.', $this->count));
|
||||
$this->info(sprintf('Acted on %d transaction(s)!', $this->count));
|
||||
$this->friendlyInfo(sprintf('Acted on %d transaction(s)', $this->count));
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verifying account types took %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
|
||||
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
|
||||
* be called from the handle method instead of using the constructor to initialize the command.
|
||||
*
|
||||
|
||||
*/
|
||||
private function stupidLaravel(): void
|
||||
{
|
||||
$this->count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function inspectJournal(TransactionJournal $journal): void
|
||||
{
|
||||
$transactions = $journal->transactions()->count();
|
||||
if (2 !== $transactions) {
|
||||
Log::debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions));
|
||||
$this->info(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions));
|
||||
|
||||
return;
|
||||
}
|
||||
$type = $journal->transactionType->type;
|
||||
$sourceTransaction = $this->getSourceTransaction($journal);
|
||||
$destTransaction = $this->getDestinationTransaction($journal);
|
||||
$sourceAccount = $sourceTransaction->account;
|
||||
$sourceAccountType = $sourceAccount->accountType->type;
|
||||
$destAccount = $destTransaction->account;
|
||||
$destAccountType = $destAccount->accountType->type;
|
||||
|
||||
if (!array_key_exists($type, $this->expected)) {
|
||||
Log::info(sprintf('No source/destination info for transaction type %s.', $type));
|
||||
$this->info(sprintf('No source/destination info for transaction type %s.', $type));
|
||||
|
||||
return;
|
||||
}
|
||||
if (!array_key_exists($sourceAccountType, $this->expected[$type])) {
|
||||
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
|
||||
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
|
||||
|
||||
return;
|
||||
}
|
||||
$expectedTypes = $this->expected[$type][$sourceAccountType];
|
||||
if (!in_array($destAccountType, $expectedTypes, true)) {
|
||||
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
|
||||
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
private function getSourceTransaction(TransactionJournal $journal): Transaction
|
||||
{
|
||||
return $journal->transactions->firstWhere('amount', '<', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
private function getDestinationTransaction(TransactionJournal $journal): Transaction
|
||||
{
|
||||
return $journal->transactions->firstWhere('amount', '>', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param string $type
|
||||
@@ -184,7 +97,7 @@ class FixAccountTypes extends Command
|
||||
$journal->transactionType()->associate($withdrawal);
|
||||
$journal->save();
|
||||
$message = sprintf('Converted transaction #%d from a transfer to a withdrawal.', $journal->id);
|
||||
$this->info($message);
|
||||
$this->friendlyInfo($message);
|
||||
Log::debug($message);
|
||||
// check it again:
|
||||
$this->inspectJournal($journal);
|
||||
@@ -197,7 +110,7 @@ class FixAccountTypes extends Command
|
||||
$journal->transactionType()->associate($deposit);
|
||||
$journal->save();
|
||||
$message = sprintf('Converted transaction #%d from a transfer to a deposit.', $journal->id);
|
||||
$this->info($message);
|
||||
$this->friendlyInfo($message);
|
||||
Log::debug($message);
|
||||
// check it again:
|
||||
$this->inspectJournal($journal);
|
||||
@@ -218,7 +131,7 @@ class FixAccountTypes extends Command
|
||||
$result->id,
|
||||
$result->name
|
||||
);
|
||||
$this->info($message);
|
||||
$this->friendlyWarning($message);
|
||||
Log::debug($message);
|
||||
$this->inspectJournal($journal);
|
||||
break;
|
||||
@@ -238,20 +151,93 @@ class FixAccountTypes extends Command
|
||||
$result->id,
|
||||
$result->name
|
||||
);
|
||||
$this->info($message);
|
||||
$this->friendlyWarning($message);
|
||||
Log::debug($message);
|
||||
$this->inspectJournal($journal);
|
||||
break;
|
||||
default:
|
||||
$message = sprintf('The source account of %s #%d cannot be of type "%s".', $type, $journal->id, $source->account->accountType->type);
|
||||
$this->info($message);
|
||||
$this->friendlyError($message);
|
||||
Log::debug($message);
|
||||
|
||||
$message = sprintf('The destination account of %s #%d cannot be of type "%s".', $type, $journal->id, $dest->account->accountType->type);
|
||||
$this->info($message);
|
||||
$this->friendlyError($message);
|
||||
Log::debug($message);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
private function getDestinationTransaction(TransactionJournal $journal): Transaction
|
||||
{
|
||||
return $journal->transactions->firstWhere('amount', '>', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
private function getSourceTransaction(TransactionJournal $journal): Transaction
|
||||
{
|
||||
return $journal->transactions->firstWhere('amount', '<', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function inspectJournal(TransactionJournal $journal): void
|
||||
{
|
||||
$transactions = $journal->transactions()->count();
|
||||
if (2 !== $transactions) {
|
||||
Log::debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions));
|
||||
$this->friendlyError(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions));
|
||||
|
||||
return;
|
||||
}
|
||||
$type = $journal->transactionType->type;
|
||||
$sourceTransaction = $this->getSourceTransaction($journal);
|
||||
$destTransaction = $this->getDestinationTransaction($journal);
|
||||
$sourceAccount = $sourceTransaction->account;
|
||||
$sourceAccountType = $sourceAccount->accountType->type;
|
||||
$destAccount = $destTransaction->account;
|
||||
$destAccountType = $destAccount->accountType->type;
|
||||
|
||||
if (!array_key_exists($type, $this->expected)) {
|
||||
Log::info(sprintf('No source/destination info for transaction type %s.', $type));
|
||||
$this->friendlyError(sprintf('No source/destination info for transaction type %s.', $type));
|
||||
|
||||
return;
|
||||
}
|
||||
if (!array_key_exists($sourceAccountType, $this->expected[$type])) {
|
||||
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
|
||||
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
|
||||
|
||||
return;
|
||||
}
|
||||
$expectedTypes = $this->expected[$type][$sourceAccountType];
|
||||
if (!in_array($destAccountType, $expectedTypes, true)) {
|
||||
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
|
||||
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
|
||||
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
|
||||
* be called from the handle method instead of using the constructor to initialize the command.
|
||||
*
|
||||
|
||||
*/
|
||||
private function stupidLaravel(): void
|
||||
{
|
||||
$this->count = 0;
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
@@ -36,18 +37,10 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class FixFrontpageAccounts extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes a preference that may include deleted accounts or accounts of another type.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-frontpage-accounts';
|
||||
protected $signature = 'firefly-iii:fix-frontpage-accounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -56,8 +49,6 @@ class FixFrontpageAccounts extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
$users = User::get();
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
@@ -66,8 +57,7 @@ class FixFrontpageAccounts extends Command
|
||||
$this->fixPreference($preference);
|
||||
}
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verifying account preferences took %s seconds', $end));
|
||||
$this->friendlyPositive('Account preferences are OK');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Events\UpdatedTransactionGroup;
|
||||
use FireflyIII\Handlers\Events\UpdatedGroupEventHandler;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
@@ -36,18 +37,10 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class FixGroupAccounts extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Unify the source / destination accounts of split groups.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:unify-group-accounts';
|
||||
protected $signature = 'firefly-iii:unify-group-accounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -72,7 +65,7 @@ class FixGroupAccounts extends Command
|
||||
$handler->unifyAccounts($event);
|
||||
}
|
||||
|
||||
$this->line('Updated inconsistent transaction groups.');
|
||||
$this->friendlyPositive('Updated possible inconsistent transaction groups.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -34,18 +35,11 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class FixIbans extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Removes spaces from IBANs';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-ibans';
|
||||
protected $signature = 'firefly-iii:fix-ibans';
|
||||
private int $count = 0;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -57,12 +51,16 @@ class FixIbans extends Command
|
||||
$accounts = Account::whereNotNull('iban')->get();
|
||||
$this->filterIbans($accounts);
|
||||
$this->countAndCorrectIbans($accounts);
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('All IBANs are valid.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function countAndCorrectIbans(Collection $accounts): void
|
||||
@@ -70,9 +68,9 @@ class FixIbans extends Command
|
||||
$set = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$userId = (int)$account->user_id;
|
||||
$userId = (int)$account->user_id;
|
||||
$set[$userId] = $set[$userId] ?? [];
|
||||
$iban = (string)$account->iban;
|
||||
$iban = (string)$account->iban;
|
||||
if ('' === $iban) {
|
||||
continue;
|
||||
}
|
||||
@@ -83,10 +81,11 @@ class FixIbans extends Command
|
||||
if (array_key_exists($iban, $set[$userId])) {
|
||||
// iban already in use! two exceptions exist:
|
||||
if (
|
||||
!(AccountType::EXPENSE === $set[$userId][$iban] && AccountType::REVENUE === $type) && // allowed combination
|
||||
!(AccountType::EXPENSE === $set[$userId][$iban] && AccountType::REVENUE === $type)
|
||||
&& // allowed combination
|
||||
!(AccountType::REVENUE === $set[$userId][$iban] && AccountType::EXPENSE === $type) // also allowed combination.
|
||||
) {
|
||||
$this->line(
|
||||
$this->friendlyWarning(
|
||||
sprintf(
|
||||
'IBAN "%s" is used more than once and will be removed from %s #%d ("%s")',
|
||||
$iban,
|
||||
@@ -97,6 +96,7 @@ class FixIbans extends Command
|
||||
);
|
||||
$account->iban = null;
|
||||
$account->save();
|
||||
$this->count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ class FixIbans extends Command
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function filterIbans(Collection $accounts): void
|
||||
@@ -120,7 +121,8 @@ class FixIbans extends Command
|
||||
if ('' !== $iban) {
|
||||
$account->iban = $iban;
|
||||
$account->save();
|
||||
$this->line(sprintf('Removed spaces from IBAN of account #%d', $account->id));
|
||||
$this->friendlyInfo(sprintf('Removed spaces from IBAN of account #%d', $account->id));
|
||||
$this->count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -33,19 +34,11 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class FixLongDescriptions extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
private const MAX_LENGTH = 1000;
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Fixes long descriptions in journals and groups.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-long-descriptions';
|
||||
protected $signature = 'firefly-iii:fix-long-descriptions';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -54,14 +47,15 @@ class FixLongDescriptions extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$journals = TransactionJournal::get(['id', 'description']);
|
||||
$count = 0;
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if (strlen($journal->description) > self::MAX_LENGTH) {
|
||||
$journal->description = substr($journal->description, 0, self::MAX_LENGTH);
|
||||
$journal->save();
|
||||
$this->line(sprintf('Truncated description of transaction journal #%d', $journal->id));
|
||||
$this->friendlyWarning(sprintf('Truncated description of transaction journal #%d', $journal->id));
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,12 +65,13 @@ class FixLongDescriptions extends Command
|
||||
if (strlen((string)$group->title) > self::MAX_LENGTH) {
|
||||
$group->title = substr($group->title, 0, self::MAX_LENGTH);
|
||||
$group->save();
|
||||
$this->line(sprintf('Truncated description of transaction group #%d', $group->id));
|
||||
$this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id));
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info('Verified all transaction group and journal title lengths.');
|
||||
$this->info(sprintf('Took %s seconds.', $end));
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All transaction group and journal title lengths are within bounds.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,30 +23,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Report (and fix) piggy banks. Make sure there are only transfers linked to piggy bank events.
|
||||
* Report (and fix) piggy banks.
|
||||
*
|
||||
* Class FixPiggies
|
||||
*/
|
||||
class FixPiggies extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes common issues with piggy banks.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-piggies';
|
||||
protected $signature = 'firefly-iii:fix-piggies';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -56,8 +48,7 @@ class FixPiggies extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$count = 0;
|
||||
$start = microtime(true);
|
||||
$set = PiggyBankEvent::with(['PiggyBank', 'TransactionJournal', 'TransactionJournal.TransactionType'])->get();
|
||||
$set = PiggyBankEvent::with(['PiggyBank', 'TransactionJournal'])->get();
|
||||
|
||||
/** @var PiggyBankEvent $event */
|
||||
foreach ($set as $event) {
|
||||
@@ -73,26 +64,14 @@ class FixPiggies extends Command
|
||||
$count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$type = $journal->transactionType->type;
|
||||
if (TransactionType::TRANSFER !== $type) {
|
||||
$event->transaction_journal_id = null;
|
||||
$event->save();
|
||||
$this->line(sprintf('Piggy bank #%d was referenced by an invalid event. This has been fixed.', $event->piggy_bank_id));
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->line('All piggy bank events are correct.');
|
||||
$this->friendlyPositive('All piggy bank events are OK.');
|
||||
}
|
||||
if (0 !== $count) {
|
||||
$this->line(sprintf('Fixed %d piggy bank event(s).', $count));
|
||||
$this->friendlyInfo(sprintf('Fixed %d piggy bank event(s).', $count));
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->line(sprintf('Verified the content of %d piggy bank events in %s seconds.', $set->count(), $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
@@ -37,22 +38,13 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class FixRecurringTransactions extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fixes recurring transactions with the wrong transaction type.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-recurring-transactions';
|
||||
/** @var RecurringRepositoryInterface */
|
||||
private $recurringRepos;
|
||||
/** @var UserRepositoryInterface */
|
||||
private $userRepos;
|
||||
protected $signature = 'firefly-iii:fix-recurring-transactions';
|
||||
private int $count = 0;
|
||||
private RecurringRepositoryInterface $recurringRepos;
|
||||
private UserRepositoryInterface $userRepos;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -61,11 +53,11 @@ class FixRecurringTransactions extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$this->stupidLaravel();
|
||||
$this->correctTransactions();
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Corrected recurring transactions in %s seconds.', $end));
|
||||
if (0 === $this->count) {
|
||||
$this->friendlyPositive('All recurring transactions are OK.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -104,13 +96,14 @@ class FixRecurringTransactions extends Command
|
||||
$type = $recurrence->transactionType;
|
||||
$link = config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type));
|
||||
if (null !== $link && strtolower($type->type) !== strtolower($link)) {
|
||||
$this->warn(
|
||||
$this->friendlyWarning(
|
||||
sprintf('Recurring transaction #%d should be a "%s" but is a "%s" and will be corrected.', $recurrence->id, $link, $type->type)
|
||||
);
|
||||
$transactionType = TransactionType::whereType($link)->first();
|
||||
if (null !== $transactionType) {
|
||||
$recurrence->transaction_type_id = $transactionType->id;
|
||||
$recurrence->save();
|
||||
$this->count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -37,18 +38,10 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class FixTransactionTypes extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Make sure all transactions are of the correct type, based on source + dest.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-transaction-types';
|
||||
protected $signature = 'firefly-iii:fix-transaction-types';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -57,7 +50,6 @@ class FixTransactionTypes extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$count = 0;
|
||||
$journals = $this->collectJournals();
|
||||
/** @var TransactionJournal $journal */
|
||||
@@ -67,13 +59,12 @@ class FixTransactionTypes extends Command
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
if ($count > 0) {
|
||||
$this->info(sprintf('Corrected transaction type of %d transaction journals in %s seconds.', $count, $end));
|
||||
$this->friendlyInfo('Corrected transaction type of %d transaction journals.', $count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
$this->line(sprintf('All transaction journals are of the correct transaction type (in %s seconds).', $end));
|
||||
$this->friendlyPositive('All transaction journals are of the correct transaction type');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -114,13 +105,13 @@ class FixTransactionTypes extends Command
|
||||
$source = $this->getSourceAccount($journal);
|
||||
$destination = $this->getDestinationAccount($journal);
|
||||
} catch (FireflyException $e) {
|
||||
$this->error($e->getMessage());
|
||||
$this->friendlyError($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
$expectedType = (string)config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type));
|
||||
if ($expectedType !== $type) {
|
||||
$this->line(
|
||||
$this->friendlyWarning(
|
||||
sprintf(
|
||||
'Transaction journal #%d was of type "%s" but is corrected to "%s" (%s -> %s)',
|
||||
$journal->id,
|
||||
|
@@ -24,10 +24,10 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
@@ -35,18 +35,10 @@ use stdClass;
|
||||
*/
|
||||
class FixUnevenAmount extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Fix journals with uneven amounts.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-uneven-amount';
|
||||
protected $signature = 'firefly-iii:fix-uneven-amount';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -55,36 +47,46 @@ class FixUnevenAmount extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$start = microtime(true);
|
||||
$count = 0;
|
||||
// get invalid journals
|
||||
$journals = DB::table('transactions')
|
||||
->groupBy('transaction_journal_id')
|
||||
->whereNull('deleted_at')
|
||||
->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]);
|
||||
/** @var stdClass $entry */
|
||||
foreach ($journals as $entry) {
|
||||
$sum = (string)$entry->the_sum;
|
||||
if (!is_numeric($sum) || '' === $sum || str_contains($sum, 'e') || str_contains($sum, ',')) {
|
||||
$message = sprintf(
|
||||
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
|
||||
$entry->transaction_journal_id,
|
||||
$entry->the_sum
|
||||
);
|
||||
$this->friendlyWarning($message);
|
||||
app('log')->warning($message);
|
||||
$count++;
|
||||
continue;
|
||||
}
|
||||
if (0 !== bccomp((string)$entry->the_sum, '0')) {
|
||||
$message = sprintf('Sum of journal #%d is %s instead of zero.', $entry->transaction_journal_id, $entry->the_sum);
|
||||
$this->warn($message);
|
||||
$message = sprintf(
|
||||
'Sum of journal #%d is %s instead of zero.',
|
||||
$entry->transaction_journal_id,
|
||||
$entry->the_sum
|
||||
);
|
||||
$this->friendlyWarning($message);
|
||||
app('log')->warning($message);
|
||||
$this->fixJournal((int)$entry->transaction_journal_id);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->info('Amount integrity OK!');
|
||||
$this->friendlyPositive('Database amount integrity is OK');
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified amount integrity in %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $param
|
||||
* @param int $param
|
||||
*/
|
||||
private function fixJournal(int $param): void
|
||||
{
|
||||
@@ -97,7 +99,7 @@ class FixUnevenAmount extends Command
|
||||
$source = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
|
||||
if (null === $source) {
|
||||
$this->error(
|
||||
$this->friendlyError(
|
||||
sprintf(
|
||||
'Journal #%d ("%s") has no source transaction. It will be deleted to maintain database consistency.',
|
||||
$journal->id ?? 0,
|
||||
@@ -117,7 +119,7 @@ class FixUnevenAmount extends Command
|
||||
$destination = $journal->transactions()->where('amount', '>', 0)->first();
|
||||
|
||||
if (null === $destination) {
|
||||
$this->error(
|
||||
$this->friendlyError(
|
||||
sprintf(
|
||||
'Journal #%d ("%s") has no destination transaction. It will be deleted to maintain database consistency.',
|
||||
$journal->id ?? 0,
|
||||
@@ -135,6 +137,6 @@ class FixUnevenAmount extends Command
|
||||
$destination->save();
|
||||
|
||||
$message = sprintf('Corrected amount in transaction journal #%d', $param);
|
||||
$this->line($message);
|
||||
$this->friendlyInfo($message);
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -32,18 +33,10 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class RemoveBills extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Remove bills from transactions that shouldn\'t have one.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:remove-bills';
|
||||
protected $signature = 'firefly-iii:remove-bills';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -52,7 +45,6 @@ class RemoveBills extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
/** @var TransactionType|null $withdrawal */
|
||||
$withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
|
||||
if (null === $withdrawal) {
|
||||
@@ -61,18 +53,14 @@ class RemoveBills extends Command
|
||||
$journals = TransactionJournal::whereNotNull('bill_id')->where('transaction_type_id', '!=', $withdrawal->id)->get();
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$this->line(sprintf('Transaction journal #%d should not be linked to bill #%d.', $journal->id, $journal->bill_id));
|
||||
$this->friendlyWarning(sprintf('Transaction journal #%d will be unlinked from bill #%d.', $journal->id, $journal->bill_id));
|
||||
$journal->bill_id = null;
|
||||
$journal->save();
|
||||
}
|
||||
if (0 === $journals->count()) {
|
||||
$this->info('All transaction journals have correct bill information.');
|
||||
}
|
||||
if ($journals->count() > 0) {
|
||||
$this->info('Fixed all transaction journals so they have correct bill information.');
|
||||
$this->friendlyInfo('Fixed all transaction journals so they have correct bill information.');
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified bills / journals in %s seconds', $end));
|
||||
$this->friendlyPositive('All bills and journals are OK');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
@@ -31,18 +32,10 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class RenameMetaFields extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Rename changed meta fields.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:rename-meta-fields';
|
||||
protected $signature = 'firefly-iii:rename-meta-fields';
|
||||
|
||||
private int $count;
|
||||
|
||||
@@ -54,7 +47,6 @@ class RenameMetaFields extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$this->count = 0;
|
||||
$start = microtime(true);
|
||||
|
||||
$changes = [
|
||||
'original-source' => 'original_source',
|
||||
@@ -74,15 +66,11 @@ class RenameMetaFields extends Command
|
||||
$this->rename($original, $update);
|
||||
}
|
||||
if (0 === $this->count) {
|
||||
$this->line('All meta fields are correct.');
|
||||
$this->friendlyPositive('All meta fields are correct.');
|
||||
}
|
||||
if (0 !== $this->count) {
|
||||
$this->line(sprintf('Renamed %d meta field(s).', $this->count));
|
||||
$this->friendlyInfo(sprintf('Renamed %d meta field(s).', $this->count));
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Renamed meta fields in %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -33,18 +34,10 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class TransferBudgets extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Removes budgets from transfers.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:fix-transfer-budgets';
|
||||
protected $signature = 'firefly-iii:fix-transfer-budgets';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -53,7 +46,6 @@ class TransferBudgets extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$set = TransactionJournal::distinct()
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('budget_transaction_journal', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
|
||||
@@ -63,24 +55,20 @@ class TransferBudgets extends Command
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($set as $entry) {
|
||||
$message = sprintf('Transaction journal #%d is a %s, so has no longer a budget.', $entry->id, $entry->transactionType->type);
|
||||
$this->info($message);
|
||||
$this->friendlyInfo($message);
|
||||
Log::debug($message);
|
||||
$entry->budgets()->sync([]);
|
||||
$count++;
|
||||
}
|
||||
if (0 === $count) {
|
||||
$message = 'No invalid budget/journal entries.';
|
||||
Log::debug($message);
|
||||
$this->info($message);
|
||||
$this->friendlyPositive($message);
|
||||
}
|
||||
if (0 !== $count) {
|
||||
$message = sprintf('Corrected %d invalid budget/journal entries (entry).', $count);
|
||||
Log::debug($message);
|
||||
$this->line($message);
|
||||
$this->friendlyInfo($message);
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified budget/journals in %s seconds.', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -15,18 +15,8 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class TriggerCreditCalculation extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Triggers the credit recalculation service for liabilities.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:trigger-credit-recalculation';
|
||||
protected $signature = 'firefly-iii:trigger-credit-recalculation';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -36,11 +26,13 @@ class TriggerCreditCalculation extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
$this->processAccounts();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function processAccount(Account $account): void
|
||||
@@ -57,7 +49,6 @@ class TriggerCreditCalculation extends Command
|
||||
->whereIn('account_types.type', config('firefly.valid_liabilities'))
|
||||
->get(['accounts.*']);
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Processing account #%d ("%s")', $account->id, $account->name));
|
||||
$this->processAccount($account);
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Console\Commands\Export;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Console\Commands\VerifiesAccessToken;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
@@ -43,6 +44,7 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class ExportData extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
use VerifiesAccessToken;
|
||||
|
||||
/**
|
||||
@@ -86,7 +88,7 @@ class ExportData extends Command
|
||||
{
|
||||
// verify access token
|
||||
if (!$this->verifyAccessToken()) {
|
||||
$this->error('Invalid access token. Check /profile.');
|
||||
$this->friendlyError('Invalid access token. Check /profile.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -99,7 +101,7 @@ class ExportData extends Command
|
||||
try {
|
||||
$options = $this->parseOptions();
|
||||
} catch (FireflyException $e) {
|
||||
$this->error(sprintf('Could not work with your options: %s', $e));
|
||||
$this->friendlyError(sprintf('Could not work with your options: %s', $e));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -122,14 +124,14 @@ class ExportData extends Command
|
||||
$exporter->setExportPiggies($options['export']['piggies']);
|
||||
$data = $exporter->export();
|
||||
if (0 === count($data)) {
|
||||
$this->error('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
|
||||
$this->friendlyError('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
|
||||
}
|
||||
$returnCode = 0;
|
||||
if (0 !== count($data)) {
|
||||
try {
|
||||
$this->exportData($options, $data);
|
||||
} catch (FireflyException $e) {
|
||||
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
|
||||
$this->friendlyError(sprintf('Could not store data: %s', $e->getMessage()));
|
||||
|
||||
$returnCode = 1;
|
||||
}
|
||||
@@ -139,16 +141,116 @@ class ExportData extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
|
||||
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
|
||||
* be called from the handle method instead of using the constructor to initialize the command.
|
||||
* @param array $options
|
||||
* @param array $data
|
||||
*
|
||||
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function stupidLaravel(): void
|
||||
private function exportData(array $options, array $data): void
|
||||
{
|
||||
$this->journalRepository = app(JournalRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$date = date('Y_m_d');
|
||||
foreach ($data as $key => $content) {
|
||||
$file = sprintf('%s%s_%s.csv', $options['directory'], $date, $key);
|
||||
if (false === $options['force'] && file_exists($file)) {
|
||||
throw new FireflyException(sprintf('File "%s" exists already. Use --force to overwrite.', $file));
|
||||
}
|
||||
if (true === $options['force'] && file_exists($file)) {
|
||||
$this->friendlyWarning(sprintf('File "%s" exists already but will be replaced.', $file));
|
||||
}
|
||||
// continue to write to file.
|
||||
file_put_contents($file, $content);
|
||||
$this->friendlyPositive(sprintf('Wrote %s-export to file "%s".', $key, $file));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getAccountsParameter(): Collection
|
||||
{
|
||||
$final = new Collection();
|
||||
$accounts = new Collection();
|
||||
$accountList = $this->option('accounts');
|
||||
$types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
if (null !== $accountList && '' !== (string)$accountList) {
|
||||
$accountIds = explode(',', $accountList);
|
||||
$accounts = $this->accountRepository->getAccountsById($accountIds);
|
||||
}
|
||||
if (null === $accountList) {
|
||||
$accounts = $this->accountRepository->getAccountsByType($types);
|
||||
}
|
||||
// filter accounts,
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
if (in_array($account->accountType->type, $types, true)) {
|
||||
$final->push($account);
|
||||
}
|
||||
}
|
||||
if (0 === $final->count()) {
|
||||
throw new FireflyException('300007: Ended up with zero valid accounts to export from.');
|
||||
}
|
||||
|
||||
return $final;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getDateParameter(string $field): Carbon
|
||||
{
|
||||
$date = today(config('app.timezone'))->subYear();
|
||||
$error = false;
|
||||
if (null !== $this->option($field)) {
|
||||
try {
|
||||
$date = Carbon::createFromFormat('!Y-m-d', $this->option($field));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$this->friendlyError(sprintf('%s date "%s" must be formatted YYYY-MM-DD. Field will be ignored.', $field, $this->option('start')));
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
if (null === $this->option($field)) {
|
||||
Log::info(sprintf('No date given in field "%s"', $field));
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (true === $error && 'start' === $field) {
|
||||
$journal = $this->journalRepository->firstNull();
|
||||
$date = null === $journal ? today(config('app.timezone'))->subYear() : $journal->date;
|
||||
$date->startOfDay();
|
||||
}
|
||||
|
||||
if (true === $error && 'end' === $field) {
|
||||
$date = today(config('app.timezone'));
|
||||
$date->endOfDay();
|
||||
}
|
||||
if ('end' === $field) {
|
||||
$date->endOfDay();
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
private function getExportDirectory(): string
|
||||
{
|
||||
$directory = (string)$this->option('export_directory');
|
||||
if (null === $directory) {
|
||||
$directory = './';
|
||||
}
|
||||
if (!is_writable($directory)) {
|
||||
throw new FireflyException(sprintf('Directory "%s" isn\'t writeable.', $directory));
|
||||
}
|
||||
|
||||
return $directory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,115 +286,15 @@ class ExportData extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
|
||||
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
|
||||
* be called from the handle method instead of using the constructor to initialize the command.
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws Exception
|
||||
|
||||
*/
|
||||
private function getDateParameter(string $field): Carbon
|
||||
private function stupidLaravel(): void
|
||||
{
|
||||
$date = today(config('app.timezone'))->subYear();
|
||||
$error = false;
|
||||
if (null !== $this->option($field)) {
|
||||
try {
|
||||
$date = Carbon::createFromFormat('!Y-m-d', $this->option($field));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$this->error(sprintf('%s date "%s" must be formatted YYYY-MM-DD. Field will be ignored.', $field, $this->option('start')));
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
if (null === $this->option($field)) {
|
||||
Log::info(sprintf('No date given in field "%s"', $field));
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (true === $error && 'start' === $field) {
|
||||
$journal = $this->journalRepository->firstNull();
|
||||
$date = null === $journal ? today(config('app.timezone'))->subYear() : $journal->date;
|
||||
$date->startOfDay();
|
||||
}
|
||||
|
||||
if (true === $error && 'end' === $field) {
|
||||
$date = today(config('app.timezone'));
|
||||
$date->endOfDay();
|
||||
}
|
||||
if ('end' === $field) {
|
||||
$date->endOfDay();
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getAccountsParameter(): Collection
|
||||
{
|
||||
$final = new Collection();
|
||||
$accounts = new Collection();
|
||||
$accountList = $this->option('accounts');
|
||||
$types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
if (null !== $accountList && '' !== (string)$accountList) {
|
||||
$accountIds = explode(',', $accountList);
|
||||
$accounts = $this->accountRepository->getAccountsById($accountIds);
|
||||
}
|
||||
if (null === $accountList) {
|
||||
$accounts = $this->accountRepository->getAccountsByType($types);
|
||||
}
|
||||
// filter accounts,
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
if (in_array($account->accountType->type, $types, true)) {
|
||||
$final->push($account);
|
||||
}
|
||||
}
|
||||
if (0 === $final->count()) {
|
||||
throw new FireflyException('300007: Ended up with zero valid accounts to export from.');
|
||||
}
|
||||
|
||||
return $final;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
private function getExportDirectory(): string
|
||||
{
|
||||
$directory = (string)$this->option('export_directory');
|
||||
if (null === $directory) {
|
||||
$directory = './';
|
||||
}
|
||||
if (!is_writable($directory)) {
|
||||
throw new FireflyException(sprintf('Directory "%s" isn\'t writeable.', $directory));
|
||||
}
|
||||
|
||||
return $directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function exportData(array $options, array $data): void
|
||||
{
|
||||
$date = date('Y_m_d');
|
||||
foreach ($data as $key => $content) {
|
||||
$file = sprintf('%s%s_%s.csv', $options['directory'], $date, $key);
|
||||
if (false === $options['force'] && file_exists($file)) {
|
||||
throw new FireflyException(sprintf('File "%s" exists already. Use --force to overwrite.', $file));
|
||||
}
|
||||
if (true === $options['force'] && file_exists($file)) {
|
||||
$this->warn(sprintf('File "%s" exists already but will be replaced.', $file));
|
||||
}
|
||||
// continue to write to file.
|
||||
file_put_contents($file, $content);
|
||||
$this->info(sprintf('Wrote %s-export to file "%s".', $key, $file));
|
||||
}
|
||||
$this->journalRepository = app(JournalRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\GroupMembership;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
@@ -37,22 +38,15 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class CreateGroupMemberships extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const CONFIG_NAME = '560_create_group_memberships';
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Update group memberships';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:create-group-memberships';
|
||||
protected $signature = 'firefly-iii:create-group-memberships';
|
||||
|
||||
/**
|
||||
* TODO move to helper.
|
||||
*
|
||||
* @param User $user
|
||||
*
|
||||
* @throws FireflyException
|
||||
@@ -63,7 +57,6 @@ class CreateGroupMemberships extends Command
|
||||
$userGroup = UserGroup::where('title', $user->email)->first();
|
||||
if (null === $userGroup) {
|
||||
$userGroup = UserGroup::create(['title' => $user->email]);
|
||||
Log::debug(sprintf('Created new user group #%d ("%s")', $userGroup->id, $userGroup->title));
|
||||
}
|
||||
|
||||
$userRole = UserRole::where('title', UserRole::OWNER)->first();
|
||||
@@ -82,15 +75,11 @@ class CreateGroupMemberships extends Command
|
||||
'user_group_id' => $userGroup->id,
|
||||
]
|
||||
);
|
||||
Log::debug('Created new membership.');
|
||||
}
|
||||
if (null === $user->user_group_id) {
|
||||
$user->user_group_id = $userGroup->id;
|
||||
$user->save();
|
||||
Log::debug('Put user in default group.');
|
||||
}
|
||||
|
||||
Log::debug(sprintf('User #%d now has main group.', $user->id));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,12 +90,8 @@ class CreateGroupMemberships extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
$this->createGroupMemberships();
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Validated group memberships in %s seconds.', $end));
|
||||
$this->friendlyPositive('Validated group memberships');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -120,9 +105,7 @@ class CreateGroupMemberships extends Command
|
||||
$users = User::get();
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
Log::debug(sprintf('Manage group memberships for user #%d', $user->id));
|
||||
self::createGroupMembership($user);
|
||||
Log::debug(sprintf('Done with user #%d', $user->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
@@ -35,6 +36,8 @@ use stdClass;
|
||||
*/
|
||||
class ReportEmptyObjects extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -55,14 +58,11 @@ class ReportEmptyObjects extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$this->reportEmptyBudgets();
|
||||
$this->reportEmptyCategories();
|
||||
$this->reportEmptyTags();
|
||||
$this->reportAccounts();
|
||||
$this->reportBudgetLimits();
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Report on empty objects finished in %s seconds', $end));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class ReportEmptyObjects extends Command
|
||||
foreach ($set as $entry) {
|
||||
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
|
||||
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name);
|
||||
$this->line($line);
|
||||
$this->friendlyWarning($line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ class ReportEmptyObjects extends Command
|
||||
$entry->id,
|
||||
$entry->name
|
||||
);
|
||||
$this->line($line);
|
||||
$this->friendlyWarning($line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ class ReportEmptyObjects extends Command
|
||||
$entry->id,
|
||||
$entry->name
|
||||
);
|
||||
$this->line($line);
|
||||
$this->friendlyWarning($line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ class ReportEmptyObjects extends Command
|
||||
$entry->id,
|
||||
$entry->name
|
||||
);
|
||||
$this->line($line);
|
||||
$this->friendlyWarning($line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ class ReportEmptyObjects extends Command
|
||||
$entry->id,
|
||||
$entry->tag
|
||||
);
|
||||
$this->line($line);
|
||||
$this->friendlyWarning($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use Artisan;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Schema;
|
||||
|
||||
@@ -34,6 +35,8 @@ use Schema;
|
||||
*/
|
||||
class ReportIntegrity extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -60,11 +63,10 @@ class ReportIntegrity extends Command
|
||||
'firefly-iii:create-group-memberships',
|
||||
'firefly-iii:report-empty-objects',
|
||||
'firefly-iii:report-sum',
|
||||
'firefly-iii:restore-oauth-keys',
|
||||
'firefly-iii:upgrade-group-information',
|
||||
];
|
||||
foreach ($commands as $command) {
|
||||
$this->line(sprintf('Now executing %s', $command));
|
||||
$this->friendlyLine(sprintf('Now executing %s', $command));
|
||||
$this->call($command);
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -32,18 +33,10 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class ReportSum extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Report on the total sum of transactions. Must be 0.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:report-sum';
|
||||
protected $signature = 'firefly-iii:report-sum';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -62,22 +55,24 @@ class ReportSum extends Command
|
||||
*/
|
||||
private function reportSum(): void
|
||||
{
|
||||
$start = microtime(true);
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($userRepository->all() as $user) {
|
||||
$sum = (string)$user->transactions()->sum('amount');
|
||||
if (!is_numeric($sum)) {
|
||||
$message = sprintf('Error: Transactions for user #%d (%s) have an invalid sum ("%s").', $user->id, $user->email, $sum);
|
||||
$this->friendlyError($message);
|
||||
continue;
|
||||
}
|
||||
if (0 !== bccomp($sum, '0')) {
|
||||
$message = sprintf('Error: Transactions for user #%d (%s) are off by %s!', $user->id, $user->email, $sum);
|
||||
$this->error($message);
|
||||
$this->friendlyError($message);
|
||||
}
|
||||
if (0 === bccomp($sum, '0')) {
|
||||
$this->info(sprintf('Amount integrity OK for user #%d', $user->id));
|
||||
$this->friendlyPositive(sprintf('Amount integrity OK for user #%d', $user->id));
|
||||
}
|
||||
}
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Report on total sum finished in %s seconds', $end));
|
||||
}
|
||||
}
|
||||
|
@@ -24,27 +24,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Support\System\OAuthKeys;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class RestoreOAuthKeys
|
||||
*/
|
||||
class RestoreOAuthKeys extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Will restore the OAuth keys generated for the system.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:restore-oauth-keys';
|
||||
protected $signature = 'firefly-iii:restore-oauth-keys';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -95,38 +87,33 @@ class RestoreOAuthKeys extends Command
|
||||
*/
|
||||
private function restoreOAuthKeys(): void
|
||||
{
|
||||
Log::debug('Going to restoreOAuthKeys()');
|
||||
if (!$this->keysInDatabase() && !$this->keysOnDrive()) {
|
||||
Log::debug('Keys are not in DB and keys are not on the drive.');
|
||||
$this->generateKeys();
|
||||
$this->storeKeysInDB();
|
||||
$this->line('Generated and stored new keys.');
|
||||
$this->friendlyInfo('Generated and stored new keys.');
|
||||
|
||||
return;
|
||||
}
|
||||
if ($this->keysInDatabase() && !$this->keysOnDrive()) {
|
||||
Log::debug('Keys are in DB and keys are not on the drive. Restore.');
|
||||
$result = $this->restoreKeysFromDB();
|
||||
if (true === $result) {
|
||||
$this->line('Restored OAuth keys from database.');
|
||||
$this->friendlyInfo('Restored OAuth keys from database.');
|
||||
|
||||
return;
|
||||
}
|
||||
app('log')->warning('Could not restore keys. Will create new ones.');
|
||||
$this->generateKeys();
|
||||
$this->storeKeysInDB();
|
||||
$this->line('Generated and stored new keys.');
|
||||
$this->friendlyInfo('Generated and stored new keys.');
|
||||
|
||||
return;
|
||||
}
|
||||
if (!$this->keysInDatabase() && $this->keysOnDrive()) {
|
||||
Log::debug('Keys are not in DB and keys are on the drive. Save in DB.');
|
||||
$this->storeKeysInDB();
|
||||
$this->line('Stored OAuth keys in database.');
|
||||
$this->friendlyInfo('Stored OAuth keys in database.');
|
||||
|
||||
return;
|
||||
}
|
||||
$this->line('OAuth keys are OK');
|
||||
$this->friendlyPositive('OAuth keys are OK');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
@@ -48,18 +49,10 @@ use Illuminate\Database\QueryException;
|
||||
*/
|
||||
class UpdateGroupInformation extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Makes sure that every object is linked to a group';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:upgrade-group-information';
|
||||
protected $signature = 'firefly-iii:upgrade-group-information';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -84,7 +77,8 @@ class UpdateGroupInformation extends Command
|
||||
{
|
||||
$group = $user->userGroup;
|
||||
if (null === $group) {
|
||||
$this->warn(sprintf('User "%s" has no group.', $user->email));
|
||||
$this->friendlyWarning(sprintf('User "%s" has no group.', $user->email));
|
||||
|
||||
return;
|
||||
}
|
||||
$set = [
|
||||
@@ -112,6 +106,7 @@ class UpdateGroupInformation extends Command
|
||||
* @param User $user
|
||||
* @param UserGroup $group
|
||||
* @param string $className
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function updateGroupInfoForObject(User $user, UserGroup $group, string $className): void
|
||||
@@ -119,11 +114,12 @@ class UpdateGroupInformation extends Command
|
||||
try {
|
||||
$result = $className::where('user_id', $user->id)->where('user_group_id', null)->update(['user_group_id' => $group->id]);
|
||||
} catch (QueryException $e) {
|
||||
$this->error(sprintf('Could not update group information for "%s" because of error "%s"', $className, $e->getMessage()));
|
||||
$this->friendlyError(sprintf('Could not update group information for "%s" because of error "%s"', $className, $e->getMessage()));
|
||||
|
||||
return;
|
||||
}
|
||||
if (0 !== $result) {
|
||||
$this->line(sprintf('Moved %d %s objects to the correct group.', $result, str_replace('FireflyIII\\Models\\', '', $className)));
|
||||
$this->friendlyPositive(sprintf('Moved %d %s objects to the correct group.', $result, str_replace('FireflyIII\\Models\\', '', $className)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
85
app/Console/Commands/ShowsFriendlyMessages.php
Normal file
85
app/Console/Commands/ShowsFriendlyMessages.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* ShowsFriendlyMessages.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
/**
|
||||
* Trait ShowsFriendlyMessages
|
||||
*/
|
||||
trait ShowsFriendlyMessages
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyError(string $message): void
|
||||
{
|
||||
$this->error(sprintf(' [x] %s', trim($message)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyInfo(string $message): void
|
||||
{
|
||||
$this->friendlyNeutral($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyLine(string $message): void
|
||||
{
|
||||
$this->line(sprintf(' %s', trim($message)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyNeutral(string $message): void
|
||||
{
|
||||
$this->line(sprintf(' [i] %s', trim($message)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyPositive(string $message): void
|
||||
{
|
||||
$this->info(sprintf(' [✓] %s', trim($message)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyWarning(string $message): void
|
||||
{
|
||||
$this->warn(sprintf(' [!] %s', trim($message)));
|
||||
}
|
||||
|
||||
}
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
@@ -33,6 +34,8 @@ use PDOException;
|
||||
*/
|
||||
class CreateDatabase extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -54,7 +57,7 @@ class CreateDatabase extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
if ('mysql' !== env('DB_CONNECTION', 'mysql')) {
|
||||
$this->info(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION')));
|
||||
$this->friendlyInfo(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION')));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -67,7 +70,7 @@ class CreateDatabase extends Command
|
||||
if ('' !== env('DB_SOCKET', '')) {
|
||||
$dsn = sprintf('mysql:unix_socket=%s;charset=utf8mb4', env('DB_SOCKET', ''));
|
||||
}
|
||||
$this->info(sprintf('DSN is %s', $dsn));
|
||||
$this->friendlyLine(sprintf('DSN is %s', $dsn));
|
||||
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
@@ -79,7 +82,7 @@ class CreateDatabase extends Command
|
||||
try {
|
||||
$pdo = new PDO($dsn, env('DB_USERNAME'), env('DB_PASSWORD'), $options);
|
||||
} catch (PDOException $e) {
|
||||
$this->error(sprintf('Error when connecting to DB: %s', $e->getMessage()));
|
||||
$this->friendlyError(sprintf('Error when connecting to DB: %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
// only continue when no error.
|
||||
@@ -96,14 +99,14 @@ class CreateDatabase extends Command
|
||||
}
|
||||
}
|
||||
if (false === $exists && true === $checked) {
|
||||
$this->error(sprintf('Database "%s" does not exist.', env('DB_DATABASE')));
|
||||
$this->friendlyError(sprintf('Database "%s" does not exist.', env('DB_DATABASE')));
|
||||
|
||||
// try to create it.
|
||||
$pdo->exec(sprintf('CREATE DATABASE `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;', env('DB_DATABASE')));
|
||||
$this->info(sprintf('Created database "%s"', env('DB_DATABASE')));
|
||||
$this->friendlyInfo(sprintf('Created database "%s"', env('DB_DATABASE')));
|
||||
}
|
||||
if (true === $exists && true === $checked) {
|
||||
$this->info(sprintf('Database "%s" exists.', env('DB_DATABASE')));
|
||||
$this->friendlyInfo(sprintf('Database "%s" exists.', env('DB_DATABASE')));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@@ -36,6 +37,8 @@ use Str;
|
||||
*/
|
||||
class CreateFirstUser extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -58,14 +61,14 @@ class CreateFirstUser extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
if ('testing' !== env('APP_ENV', 'local')) {
|
||||
$this->error('This command only works in the testing environment.');
|
||||
$this->friendlyError('This command only works in the testing environment.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
$this->stupidLaravel();
|
||||
$count = $this->repository->count();
|
||||
if ($count > 0) {
|
||||
$this->error('Already have more than zero users in DB.');
|
||||
$this->friendlyError('Already have more than zero users in DB.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -81,8 +84,8 @@ class CreateFirstUser extends Command
|
||||
$user->save();
|
||||
$user->setRememberToken(Str::random(60));
|
||||
|
||||
$this->info(sprintf('Created new admin user (ID #%d) with email address "%s" and password "%s".', $user->id, $user->email, $password));
|
||||
$this->error('Change this password.');
|
||||
$this->friendlyInfo(sprintf('Created new admin user (ID #%d) with email address "%s" and password "%s".', $user->id, $user->email, $password));
|
||||
$this->friendlyWarning('Change this password.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
@@ -51,38 +52,42 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class ForceDecimalSize extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
|
||||
protected $signature = 'firefly-iii:force-decimal-size';
|
||||
private string $cast;
|
||||
private array $classes = [
|
||||
'accounts' => Account::class,
|
||||
'auto_budgets' => AutoBudget::class,
|
||||
'available_budgets' => AvailableBudget::class,
|
||||
'bills' => Bill::class,
|
||||
'budget_limits' => BudgetLimit::class,
|
||||
'piggy_bank_events' => PiggyBankEvent::class,
|
||||
'piggy_bank_repetitions' => PiggyBankRepetition::class,
|
||||
'piggy_banks' => PiggyBank::class,
|
||||
'recurrences_transactions' => RecurrenceTransaction::class,
|
||||
'transactions' => Transaction::class,
|
||||
];
|
||||
private array $classes
|
||||
= [
|
||||
'accounts' => Account::class,
|
||||
'auto_budgets' => AutoBudget::class,
|
||||
'available_budgets' => AvailableBudget::class,
|
||||
'bills' => Bill::class,
|
||||
'budget_limits' => BudgetLimit::class,
|
||||
'piggy_bank_events' => PiggyBankEvent::class,
|
||||
'piggy_bank_repetitions' => PiggyBankRepetition::class,
|
||||
'piggy_banks' => PiggyBank::class,
|
||||
'recurrences_transactions' => RecurrenceTransaction::class,
|
||||
'transactions' => Transaction::class,
|
||||
];
|
||||
|
||||
private string $operator;
|
||||
private string $regularExpression;
|
||||
private array $tables = [
|
||||
'accounts' => ['virtual_balance'],
|
||||
'auto_budgets' => ['amount'],
|
||||
'available_budgets' => ['amount'],
|
||||
'bills' => ['amount_min', 'amount_max'],
|
||||
'budget_limits' => ['amount'],
|
||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||
'limit_repetitions' => ['amount'],
|
||||
'piggy_bank_events' => ['amount'],
|
||||
'piggy_bank_repetitions' => ['currentamount'],
|
||||
'piggy_banks' => ['targetamount'],
|
||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||
'transactions' => ['amount', 'foreign_amount'],
|
||||
];
|
||||
private array $tables
|
||||
= [
|
||||
'accounts' => ['virtual_balance'],
|
||||
'auto_budgets' => ['amount'],
|
||||
'available_budgets' => ['amount'],
|
||||
'bills' => ['amount_min', 'amount_max'],
|
||||
'budget_limits' => ['amount'],
|
||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||
'limit_repetitions' => ['amount'],
|
||||
'piggy_bank_events' => ['amount'],
|
||||
'piggy_bank_repetitions' => ['currentamount'],
|
||||
'piggy_banks' => ['targetamount'],
|
||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||
'transactions' => ['amount', 'foreign_amount'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -94,14 +99,14 @@ class ForceDecimalSize extends Command
|
||||
Log::debug('Now in ForceDecimalSize::handle()');
|
||||
$this->determineDatabaseType();
|
||||
|
||||
$this->error('Running this command is dangerous and can cause data loss.');
|
||||
$this->error('Please do not continue.');
|
||||
$this->friendlyError('Running this command is dangerous and can cause data loss.');
|
||||
$this->friendlyError('Please do not continue.');
|
||||
$question = $this->confirm('Do you want to continue?');
|
||||
if (true === $question) {
|
||||
$this->correctAmounts();
|
||||
$this->updateDecimals();
|
||||
}
|
||||
$this->line('Done!');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -110,6 +115,7 @@ class ForceDecimalSize extends Command
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $fields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function correctAccountAmounts(TransactionCurrency $currency, array $fields): void
|
||||
@@ -133,7 +139,8 @@ class ForceDecimalSize extends Command
|
||||
});
|
||||
$result = $query->get(['accounts.*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All accounts in %s', $currency->code));
|
||||
$this->friendlyPositive(sprintf('All accounts in %s are OK', $currency->code));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var Account $account */
|
||||
@@ -146,7 +153,7 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
|
||||
$this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
|
||||
Account::find($account->id)->update([$field => $correct]);
|
||||
}
|
||||
}
|
||||
@@ -164,12 +171,14 @@ class ForceDecimalSize extends Command
|
||||
DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', function ($pattern, $value) {
|
||||
mb_regex_encoding('UTF-8');
|
||||
$pattern = trim($pattern, '"');
|
||||
return (false !== mb_ereg($pattern, (string) $value)) ? 1 : 0;
|
||||
|
||||
return (false !== mb_ereg($pattern, (string)$value)) ? 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (!in_array((string)config('database.default'), ['mysql', 'pgsql', 'sqlite'], true)) {
|
||||
$this->line(sprintf('Skip correcting amounts, does not support "%s"...', (string)config('database.default')));
|
||||
$this->friendlyWarning(sprintf('Skip correcting amounts, does not support "%s"...', (string)config('database.default')));
|
||||
|
||||
return;
|
||||
}
|
||||
$this->correctAmountsByCurrency();
|
||||
@@ -182,7 +191,6 @@ class ForceDecimalSize extends Command
|
||||
*/
|
||||
private function correctAmountsByCurrency(): void
|
||||
{
|
||||
$this->line('Going to correct amounts.');
|
||||
/** @var Collection $enabled */
|
||||
$enabled = TransactionCurrency::whereEnabled(1)->get();
|
||||
/** @var TransactionCurrency $currency */
|
||||
@@ -195,12 +203,12 @@ class ForceDecimalSize extends Command
|
||||
* This method loops the available tables that may need fixing, and calls for the right method that can fix them.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return void
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function correctByCurrency(TransactionCurrency $currency): void
|
||||
{
|
||||
$this->line(sprintf('Going to correct amounts in currency %s ("%s").', $currency->code, $currency->name));
|
||||
/**
|
||||
* @var string $name
|
||||
* @var array $fields
|
||||
@@ -209,7 +217,7 @@ class ForceDecimalSize extends Command
|
||||
switch ($name) {
|
||||
default:
|
||||
$message = sprintf('Cannot handle table "%s"', $name);
|
||||
$this->line($message);
|
||||
$this->friendlyError($message);
|
||||
throw new FireflyException($message);
|
||||
case 'accounts':
|
||||
$this->correctAccountAmounts($currency, $fields);
|
||||
@@ -243,8 +251,10 @@ class ForceDecimalSize extends Command
|
||||
|
||||
/**
|
||||
* This method fixes all auto budgets in currency $currency.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
* @param string $table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function correctGeneric(TransactionCurrency $currency, string $table): void
|
||||
@@ -270,7 +280,8 @@ class ForceDecimalSize extends Command
|
||||
|
||||
$result = $query->get(['*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All %s in %s', $table, $currency->code));
|
||||
$this->friendlyPositive(sprintf('All %s in %s are OK', $table, $currency->code));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var Model $item */
|
||||
@@ -283,7 +294,7 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
|
||||
$this->friendlyWarning(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
|
||||
$class::find($item->id)->update([$field => $correct]);
|
||||
}
|
||||
}
|
||||
@@ -294,6 +305,7 @@ class ForceDecimalSize extends Command
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $fields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function correctPiggyAmounts(TransactionCurrency $currency, array $fields): void
|
||||
@@ -319,7 +331,8 @@ class ForceDecimalSize extends Command
|
||||
|
||||
$result = $query->get(['piggy_banks.*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All piggy banks in %s', $currency->code));
|
||||
$this->friendlyPositive(sprintf('All piggy banks in %s are OK', $currency->code));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var PiggyBank $item */
|
||||
@@ -332,7 +345,7 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
|
||||
$this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
|
||||
PiggyBank::find($item->id)->update([$field => $correct]);
|
||||
}
|
||||
}
|
||||
@@ -340,8 +353,10 @@ class ForceDecimalSize extends Command
|
||||
|
||||
/**
|
||||
* This method fixes all piggy bank events in currency $currency.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $fields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function correctPiggyEventAmounts(TransactionCurrency $currency, array $fields): void
|
||||
@@ -368,7 +383,8 @@ class ForceDecimalSize extends Command
|
||||
|
||||
$result = $query->get(['piggy_bank_events.*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All piggy bank events in %s', $currency->code));
|
||||
$this->friendlyPositive(sprintf('All piggy bank events in %s are OK', $currency->code));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var PiggyBankEvent $item */
|
||||
@@ -381,7 +397,9 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('Piggy bank event #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
|
||||
$this->friendlyWarning(
|
||||
sprintf('Piggy bank event #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
|
||||
);
|
||||
PiggyBankEvent::find($item->id)->update([$field => $correct]);
|
||||
}
|
||||
}
|
||||
@@ -392,6 +410,7 @@ class ForceDecimalSize extends Command
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $fields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function correctPiggyRepetitionAmounts(TransactionCurrency $currency, array $fields)
|
||||
@@ -418,7 +437,8 @@ class ForceDecimalSize extends Command
|
||||
|
||||
$result = $query->get(['piggy_bank_repetitions.*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All piggy bank repetitions in %s', $currency->code));
|
||||
$this->friendlyPositive(sprintf('All piggy bank repetitions in %s', $currency->code));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var PiggyBankRepetition $item */
|
||||
@@ -431,7 +451,9 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
|
||||
$this->friendlyWarning(
|
||||
sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
|
||||
);
|
||||
PiggyBankRepetition::find($item->id)->update([$field => $correct]);
|
||||
}
|
||||
}
|
||||
@@ -441,6 +463,7 @@ class ForceDecimalSize extends Command
|
||||
* This method fixes all transactions in currency $currency.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function correctTransactionAmounts(TransactionCurrency $currency): void
|
||||
@@ -455,7 +478,7 @@ class ForceDecimalSize extends Command
|
||||
|
||||
$result = $query->get(['transactions.*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All transactions in %s', $currency->code));
|
||||
$this->friendlyPositive(sprintf('All transactions in %s are OK', $currency->code));
|
||||
}
|
||||
|
||||
/** @var Transaction $item */
|
||||
@@ -467,7 +490,7 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
|
||||
$this->friendlyWarning(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
|
||||
Transaction::find($item->id)->update(['amount' => $correct]);
|
||||
}
|
||||
|
||||
@@ -481,7 +504,8 @@ class ForceDecimalSize extends Command
|
||||
|
||||
$result = $query->get(['*']);
|
||||
if (0 === $result->count()) {
|
||||
$this->line(sprintf('Correct: All transactions in foreign currency %s', $currency->code));
|
||||
$this->friendlyPositive(sprintf('All transactions in foreign currency %s are OK', $currency->code));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var Transaction $item */
|
||||
@@ -493,7 +517,9 @@ class ForceDecimalSize extends Command
|
||||
// fix $field by rounding it down correctly.
|
||||
$pow = pow(10, (int)$currency->decimal_places);
|
||||
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
|
||||
$this->line(sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
|
||||
$this->friendlyWarning(
|
||||
sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct)
|
||||
);
|
||||
Transaction::find($item->id)->update(['foreign_amount' => $correct]);
|
||||
}
|
||||
}
|
||||
@@ -519,7 +545,7 @@ class ForceDecimalSize extends Command
|
||||
*/
|
||||
private function updateDecimals(): void
|
||||
{
|
||||
$this->info('Going to force the size of DECIMAL columns. Please hold.');
|
||||
$this->friendlyInfo('Going to force the size of DECIMAL columns. Please hold.');
|
||||
$type = (string)config('database.default');
|
||||
|
||||
/**
|
||||
@@ -529,11 +555,12 @@ class ForceDecimalSize extends Command
|
||||
foreach ($this->tables as $name => $fields) {
|
||||
/** @var string $field */
|
||||
foreach ($fields as $field) {
|
||||
$this->line(sprintf('Updating table "%s", field "%s"...', $name, $field));
|
||||
$this->friendlyLine(sprintf('Updating table "%s", field "%s"...', $name, $field));
|
||||
|
||||
switch ($type) {
|
||||
default:
|
||||
$this->error(sprintf('Cannot handle database type "%s".', $type));
|
||||
$this->friendlyError(sprintf('Cannot handle database type "%s".', $type));
|
||||
|
||||
return;
|
||||
case 'pgsql':
|
||||
$query = sprintf('ALTER TABLE %s ALTER COLUMN %s TYPE DECIMAL(32,12);', $name, $field);
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Console\Commands\VerifiesAccessToken;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -33,6 +34,7 @@ use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ForceMigration extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
use VerifiesAccessToken;
|
||||
|
||||
/**
|
||||
@@ -52,43 +54,44 @@ class ForceMigration extends Command
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
if (!$this->verifyAccessToken()) {
|
||||
$this->error('Invalid access token.');
|
||||
$this->friendlyError('Invalid access token.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->error('Running this command is dangerous and can cause data loss.');
|
||||
$this->error('Please do not continue.');
|
||||
$this->friendlyError('Running this command is dangerous and can cause data loss.');
|
||||
$this->friendlyError('Please do not continue.');
|
||||
$question = $this->confirm('Do you want to continue?');
|
||||
if (true === $question) {
|
||||
$user = $this->getUser();
|
||||
Log::channel('audit')->info(sprintf('User #%d ("%s") forced migrations.', $user->id, $user->email));
|
||||
$this->forceMigration();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function forceMigration(): void
|
||||
{
|
||||
DB::commit();
|
||||
$this->line('Dropping "migrations" table...');
|
||||
$this->friendlyLine('Dropping "migrations" table...');
|
||||
sleep(2);
|
||||
Schema::dropIfExists('migrations');
|
||||
$this->line('Done!');
|
||||
$this->line('Re-run all migrations...');
|
||||
$this->friendlyLine('Re-run all migrations...');
|
||||
Artisan::call('migrate', ['--seed' => true]);
|
||||
sleep(2);
|
||||
$this->line('');
|
||||
$this->info('Done!');
|
||||
$this->line('There is a good chance you just saw a lot of error messages.');
|
||||
$this->line('No need to panic yet. First try to access Firefly III (again).');
|
||||
$this->line('The issue, whatever it was, may have been solved now.');
|
||||
$this->line('');
|
||||
$this->friendlyLine('');
|
||||
$this->friendlyWarning('There is a good chance you just saw a lot of error messages.');
|
||||
$this->friendlyWarning('No need to panic yet. First try to access Firefly III (again).');
|
||||
$this->friendlyWarning('The issue, whatever it was, may have been solved now.');
|
||||
$this->friendlyLine('');
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use Crypt;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
@@ -37,6 +38,8 @@ use Storage;
|
||||
*/
|
||||
class ScanAttachments extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -79,7 +82,7 @@ class ScanAttachments extends Command
|
||||
$attachment->md5 = $md5;
|
||||
$attachment->mime = $mime;
|
||||
$attachment->save();
|
||||
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
||||
$this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,8 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class SetLatestVersion extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -52,13 +55,13 @@ class SetLatestVersion extends Command
|
||||
public function handle(): int
|
||||
{
|
||||
if (!$this->option('james-is-cool')) {
|
||||
$this->error('Am too!');
|
||||
$this->friendlyError('Am too!');
|
||||
|
||||
return 0;
|
||||
}
|
||||
app('fireflyconfig')->set('db_version', config('firefly.db_version'));
|
||||
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
|
||||
$this->line('Updated version.');
|
||||
$this->friendlyInfo('Updated version.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -107,6 +107,9 @@ class UpgradeFireflyInstructions extends Command
|
||||
$text = $config[$compare];
|
||||
}
|
||||
}
|
||||
$this->newLine();
|
||||
$this->showLogo();
|
||||
$this->newLine();
|
||||
$this->showLine();
|
||||
$this->boxed('');
|
||||
if (null === $text || '' === $text) {
|
||||
@@ -136,6 +139,43 @@ class UpgradeFireflyInstructions extends Command
|
||||
$this->line($line);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logo takes up 8 lines of code. So 8 colors can be used.
|
||||
* @return void
|
||||
*/
|
||||
private function showLogo(): void
|
||||
{
|
||||
$today = date('m-d');
|
||||
$month = date('m');
|
||||
// variation in colors and effects just because I can!
|
||||
// default is Ukraine flag:
|
||||
$colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default'];
|
||||
|
||||
// 5th of May is Dutch liberation day and 29th of April is Dutch King's Day and September 17 is my birthday.
|
||||
if ('05-01' === $today || '04-29' === $today || '09-17' === $today) {
|
||||
$colors = ['red', 'red', 'red', 'white', 'white', 'blue', 'blue', 'blue'];
|
||||
}
|
||||
|
||||
// National Coming Out Day, International Day Against Homophobia, Biphobia and Transphobia and Pride Month
|
||||
if ('10-11' === $today || '05-17' === $today || '06' === $month) {
|
||||
$colors = ['red', 'bright-red', 'yellow', 'green', 'blue', 'magenta', 'default', 'default'];
|
||||
}
|
||||
|
||||
// International Transgender Day of Visibility
|
||||
if ('03-31' === $today) {
|
||||
$colors = ['bright-blue', 'bright-red', 'white', 'white', 'bright-red', 'bright-blue', 'default', 'default'];
|
||||
}
|
||||
|
||||
$this->line(sprintf('<fg=%s> ______ _ __ _ _____ _____ _____ </>', $colors[0]));
|
||||
$this->line(sprintf('<fg=%s> | ____(_) / _| | |_ _|_ _|_ _| </>', $colors[1]));
|
||||
$this->line(sprintf('<fg=%s> | |__ _ _ __ ___| |_| |_ _ | | | | | | </>', $colors[2]));
|
||||
$this->line(sprintf('<fg=%s> | __| | | \'__/ _ \ _| | | | | | | | | | | </>', $colors[3]));
|
||||
$this->line(sprintf('<fg=%s> | | | | | | __/ | | | |_| | _| |_ _| |_ _| |_ </>', $colors[4]));
|
||||
$this->line(sprintf('<fg=%s> |_| |_|_| \___|_| |_|\__, | |_____|_____|_____| </>', $colors[5]));
|
||||
$this->line(sprintf('<fg=%s> __/ | </>', $colors[6]));
|
||||
$this->line(sprintf('<fg=%s> |___/ </>', $colors[7]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render upgrade instructions.
|
||||
*/
|
||||
@@ -152,7 +192,11 @@ class UpgradeFireflyInstructions extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
$this->showLogo();
|
||||
$this->newLine();
|
||||
$this->showLine();
|
||||
|
||||
$this->boxed('');
|
||||
if (null === $text || '' === $text) {
|
||||
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version));
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -35,6 +36,8 @@ use Storage;
|
||||
*/
|
||||
class VerifySecurityAlerts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -80,23 +83,23 @@ class VerifySecurityAlerts extends Command
|
||||
// depends on level
|
||||
if ('info' === $array['level']) {
|
||||
Log::debug('INFO level alert');
|
||||
$this->info($array['message']);
|
||||
$this->friendlyInfo($array['message']);
|
||||
|
||||
return 0;
|
||||
}
|
||||
if ('warning' === $array['level']) {
|
||||
Log::debug('WARNING level alert');
|
||||
$this->warn('------------------------ :o');
|
||||
$this->warn($array['message']);
|
||||
$this->warn('------------------------ :o');
|
||||
$this->friendlyWarning('------------------------ :o');
|
||||
$this->friendlyWarning($array['message']);
|
||||
$this->friendlyWarning('------------------------ :o');
|
||||
|
||||
return 0;
|
||||
}
|
||||
if ('danger' === $array['level']) {
|
||||
Log::debug('DANGER level alert');
|
||||
$this->error('------------------------ :-(');
|
||||
$this->error($array['message']);
|
||||
$this->error('------------------------ :-(');
|
||||
$this->friendlyError('------------------------ :-(');
|
||||
$this->friendlyError($array['message']);
|
||||
$this->friendlyError('------------------------ :-(');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -104,8 +107,8 @@ class VerifySecurityAlerts extends Command
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log::debug('This version is not mentioned.');
|
||||
|
||||
Log::debug(sprintf('No security alerts for version %s', $version));
|
||||
$this->friendlyPositive(sprintf('No security alerts for version %s', $version));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -124,6 +127,7 @@ class VerifySecurityAlerts extends Command
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function saveSecurityAdvisory(array $array): void
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user