mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-18 18:44:16 +00:00
Compare commits
340 Commits
v6.2.9
...
develop-20
Author | SHA1 | Date | |
---|---|---|---|
|
3385e12c01 | ||
|
3566a4afa3 | ||
|
68ff033342 | ||
|
f141b0be5c | ||
|
d399dd160f | ||
|
4c8ed784cd | ||
|
fb3402acd4 | ||
|
8cad430816 | ||
|
01502b456e | ||
|
9b6314066b | ||
|
e61dadcbc6 | ||
|
f7baf5b2fd | ||
|
0545826d57 | ||
|
a29904704c | ||
|
899d374222 | ||
|
07ff2305fd | ||
|
ee96dd3ab6 | ||
|
a766d3a133 | ||
|
67545b0371 | ||
|
6b86d825ea | ||
|
31dbc57e8b | ||
|
00050f629c | ||
|
3760aabf13 | ||
|
22e092b513 | ||
|
a4f7c90e09 | ||
|
4b92ab46a3 | ||
|
0573bf2402 | ||
|
e28e538272 | ||
|
6f8f175890 | ||
|
fbf9ab6c5f | ||
|
3c67175e68 | ||
|
b0d25a1d33 | ||
|
9ea8709835 | ||
|
ae22c59f21 | ||
|
12b8ba68b3 | ||
|
6b086c9bff | ||
|
546a1198a1 | ||
|
1001e04b63 | ||
|
2c96729d76 | ||
|
194d22ad90 | ||
|
51e86448c7 | ||
|
e42107c03c | ||
|
abd9260193 | ||
|
042e2ba97d | ||
|
d5240f7afd | ||
|
cda90df995 | ||
|
446e855b74 | ||
|
fb31f25d71 | ||
|
ba43d8c3f5 | ||
|
3924781797 | ||
|
b99a6a9fc9 | ||
|
2967f4d4c7 | ||
|
285eeb1d12 | ||
|
6374215ebc | ||
|
8f0c0f215c | ||
|
5fc764e72b | ||
|
b330313c55 | ||
|
aa9ce73758 | ||
|
d97fda41b2 | ||
|
945ad79c03 | ||
|
6273807525 | ||
|
50803a2c24 | ||
|
a0e9b05680 | ||
|
41e74cd816 | ||
|
b379c8e36b | ||
|
76e893f86e | ||
|
5da1599959 | ||
|
1d997e7c86 | ||
|
35e2eba303 | ||
|
b50f8f8ecd | ||
|
c16d3be85f | ||
|
bd1232644f | ||
|
37ca460ff2 | ||
|
478acdc847 | ||
|
f9ec94ea97 | ||
|
576c5f242c | ||
|
dba8bba41a | ||
|
55a00aa6fe | ||
|
22133f64cf | ||
|
2efb2377b6 | ||
|
9f75a96ad6 | ||
|
d0be9bb957 | ||
|
c25adf0a56 | ||
|
0ca79fd843 | ||
|
efc516eb3b | ||
|
dca3ac9250 | ||
|
33668a3688 | ||
|
5414a70abb | ||
|
85aee63d1e | ||
|
ad09c851f6 | ||
|
c57f36820b | ||
|
6bb2702e07 | ||
|
b1dbd3ee17 | ||
|
2d41db349a | ||
|
6b73b9327a | ||
|
e3ea54329d | ||
|
686a76f32c | ||
|
cdafb82a49 | ||
|
0075f10f98 | ||
|
b70c0e4ab3 | ||
|
01aca092a1 | ||
|
8e6449ec12 | ||
|
984c4e2449 | ||
|
002c5485f5 | ||
|
12d74f15c0 | ||
|
2e87e179f0 | ||
|
a861126c0f | ||
|
8f5e58e8ad | ||
|
6c26f1f677 | ||
|
d7caaca5e4 | ||
|
835c81f329 | ||
|
1615b0cb29 | ||
|
c07a279c81 | ||
|
1478dae316 | ||
|
83a1e6616a | ||
|
66bd786842 | ||
|
33d73d8be8 | ||
|
75e190ba64 | ||
|
820569a52b | ||
|
05005eac32 | ||
|
5aa677c6fb | ||
|
456a3a9216 | ||
|
be25a7596f | ||
|
59a07e5dde | ||
|
6946a815e2 | ||
|
4a84e94022 | ||
|
5ba5d1f90e | ||
|
beb2bbcdc9 | ||
|
805fd5ae08 | ||
|
96093e313a | ||
|
afe9e88f9a | ||
|
b43048c674 | ||
|
11c38a599b | ||
|
0ce245f480 | ||
|
aef15cf3d3 | ||
|
d1880de30e | ||
|
9d900a69ed | ||
|
1653f77b15 | ||
|
9418436d51 | ||
|
1c9a6a194a | ||
|
11cfb5a962 | ||
|
7d21467447 | ||
|
5ce9f32deb | ||
|
337440259f | ||
|
c483e0768f | ||
|
fd9b0d9417 | ||
|
c3165f4937 | ||
|
a5c9adc872 | ||
|
59cc007931 | ||
|
8b0b12b521 | ||
|
6ae1cfd82e | ||
|
4d7eb27fd0 | ||
|
fe0b8d0128 | ||
|
04f0fcfbf7 | ||
|
7e182cf070 | ||
|
ad78c302ef | ||
|
36b4c69491 | ||
|
30bd0711f4 | ||
|
d847827584 | ||
|
786c1fcd58 | ||
|
90e7f0c0f7 | ||
|
63f334abe5 | ||
|
2466cd942f | ||
|
ea37db87f4 | ||
|
c168fb6960 | ||
|
03fb707b93 | ||
|
db226c2584 | ||
|
1c6ec82c91 | ||
|
40eb77ffde | ||
|
17ddb01cd1 | ||
|
ca56c7af70 | ||
|
55c428070f | ||
|
574eec1c08 | ||
|
15cde8173e | ||
|
ccb581b4ee | ||
|
c5f8db5b50 | ||
|
611748fbaf | ||
|
b57dfa9432 | ||
|
253982d579 | ||
|
94c7a19aa0 | ||
|
e9b360a721 | ||
|
ebf7f5932a | ||
|
4427f2fb99 | ||
|
6626dfbac3 | ||
|
093a6387a2 | ||
|
21ddde9e0d | ||
|
44d4e4e6da | ||
|
e34e53eeb3 | ||
|
07fb45bb34 | ||
|
d381669733 | ||
|
fb9eb15ae1 | ||
|
a2127c382b | ||
|
e10d39c093 | ||
|
a933b49e7c | ||
|
38bcd610df | ||
|
5beb476a28 | ||
|
3a43ce6546 | ||
|
c11fddb097 | ||
|
98f79cd9bf | ||
|
a3d3fe758b | ||
|
93587cf1b6 | ||
|
361e95f102 | ||
|
be212e7d1d | ||
|
003a30727f | ||
|
27b662e2dc | ||
|
0b4d7ad95e | ||
|
7acbfb230a | ||
|
b974310798 | ||
|
e391725eed | ||
|
f505580b33 | ||
|
270f932a48 | ||
|
b9afa908e3 | ||
|
6dcc78b9e5 | ||
|
7b0e7e8612 | ||
|
1ece4abd9d | ||
|
07c03b672b | ||
|
27ea50ec16 | ||
|
e1195e6663 | ||
|
faeb17f319 | ||
|
db91b1b127 | ||
|
b5b511c86b | ||
|
8c805fe0c9 | ||
|
b0672eb294 | ||
|
750019808c | ||
|
7f4510467f | ||
|
a46f8430df | ||
|
5e1ecb2b11 | ||
|
4fff59f16b | ||
|
eea8f5e07e | ||
|
a3fcd636e7 | ||
|
de6dc19077 | ||
|
7a8e3aca03 | ||
|
076047ad24 | ||
|
a4e1c8c24f | ||
|
3bf1c0075e | ||
|
1821ade319 | ||
|
dcd4f072d5 | ||
|
1734c7f545 | ||
|
aef3d340ae | ||
|
e39d4bc288 | ||
|
ed35b0f81a | ||
|
4805c9e1c9 | ||
|
eebcbe0f67 | ||
|
61e2b79357 | ||
|
fd3b03d3de | ||
|
9423a28158 | ||
|
55062068fd | ||
|
542b6f670d | ||
|
5b163b42b4 | ||
|
613dce51fb | ||
|
40adb5b203 | ||
|
fba796fa84 | ||
|
db4c3f9bfa | ||
|
d960cc6ad7 | ||
|
c620ec1f24 | ||
|
2d78bba6f4 | ||
|
b7a3f5d740 | ||
|
96def3c5d4 | ||
|
e1941d9d87 | ||
|
a30cf03678 | ||
|
aa0dcd3b7e | ||
|
810e92f7a3 | ||
|
5dd49fc1e1 | ||
|
8517af105d | ||
|
442cf7f9b3 | ||
|
82878b5214 | ||
|
b0f1102540 | ||
|
2efee7e6de | ||
|
abcecc7476 | ||
|
c28005f649 | ||
|
a369e61f18 | ||
|
05d82b6c05 | ||
|
68ca8fd250 | ||
|
b55b565ee5 | ||
|
fc98d66ef4 | ||
|
f6642c075d | ||
|
458a337521 | ||
|
37d2299a1d | ||
|
f69cffc50b | ||
|
fd77a17ba5 | ||
|
b481cf53e7 | ||
|
a4a4590c45 | ||
|
9e398beb07 | ||
|
38ae3df423 | ||
|
2f17701b68 | ||
|
4c797c1d4c | ||
|
a8e1c22c93 | ||
|
b60021e0ce | ||
|
453ccd3271 | ||
|
08f13aebe3 | ||
|
26df1be871 | ||
|
fe2def9684 | ||
|
db2cab3cef | ||
|
d84405191f | ||
|
349d32a268 | ||
|
30b7e17b6f | ||
|
2d3d3bc0a4 | ||
|
a4f887921a | ||
|
710732d7f5 | ||
|
cd08c16dee | ||
|
a8f36a2490 | ||
|
7f12d06989 | ||
|
8eb0313841 | ||
|
113eb84461 | ||
|
cdf42e50f0 | ||
|
e59cf03d80 | ||
|
0bd0e6caeb | ||
|
605623a7af | ||
|
042d055d85 | ||
|
cc29d0a850 | ||
|
7dede49aee | ||
|
775282ae02 | ||
|
e49806078a | ||
|
71d8c0d219 | ||
|
0031c5a5ad | ||
|
3ce111550e | ||
|
58af83cc8c | ||
|
422a23e700 | ||
|
8c2672cdf8 | ||
|
764e49985b | ||
|
84251f8f10 | ||
|
3d878cb5dd | ||
|
8b4740d28c | ||
|
0845e265c2 | ||
|
b4455a3802 | ||
|
8d12d47691 | ||
|
3dc01b0d5c | ||
|
b442645280 | ||
|
eda2b5f822 | ||
|
d9593db5e2 | ||
|
9dcb8e2680 | ||
|
56bac9fc97 | ||
|
f7ad9c56c8 | ||
|
0086a0ddc8 | ||
|
25ebfd6978 | ||
|
de8149137a | ||
|
79ae110368 | ||
|
60aef0de1a | ||
|
8d464962a8 | ||
|
b93cfc5de2 |
@@ -61,7 +61,7 @@ return $config->setRules(
|
|||||||
'comment_to_phpdoc' => false, // breaks phpstan lines in combination with PHPStorm.
|
'comment_to_phpdoc' => false, // breaks phpstan lines in combination with PHPStorm.
|
||||||
'type_declaration_spaces' => false,
|
'type_declaration_spaces' => false,
|
||||||
'cast_spaces' => false,
|
'cast_spaces' => false,
|
||||||
'phpdoc_to_comment' => false, // do not overrule single line comment style, breaks phpstan.
|
'phpdoc_to_comment' => false, // do not overrule single line comment style, breaks phpstan.
|
||||||
|
|
||||||
// complex rules
|
// complex rules
|
||||||
'array_syntax' => ['syntax' => 'short'],
|
'array_syntax' => ['syntax' => 'short'],
|
||||||
|
114
.ci/php-cs-fixer/composer.lock
generated
114
.ci/php-cs-fixer/composer.lock
generated
@@ -406,16 +406,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "friendsofphp/php-cs-fixer",
|
"name": "friendsofphp/php-cs-fixer",
|
||||||
"version": "v3.69.1",
|
"version": "v3.75.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||||
"reference": "13b0c0eede38c11cd674b080f2b485d0f14ffa9f"
|
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/13b0c0eede38c11cd674b080f2b485d0f14ffa9f",
|
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||||
"reference": "13b0c0eede38c11cd674b080f2b485d0f14ffa9f",
|
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -423,6 +423,7 @@
|
|||||||
"composer/semver": "^3.4",
|
"composer/semver": "^3.4",
|
||||||
"composer/xdebug-handler": "^3.0.3",
|
"composer/xdebug-handler": "^3.0.3",
|
||||||
"ext-filter": "*",
|
"ext-filter": "*",
|
||||||
|
"ext-hash": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-tokenizer": "*",
|
"ext-tokenizer": "*",
|
||||||
"fidry/cpu-core-counter": "^1.2",
|
"fidry/cpu-core-counter": "^1.2",
|
||||||
@@ -445,18 +446,18 @@
|
|||||||
"symfony/stopwatch": "^5.4 || ^6.4 || ^7.0"
|
"symfony/stopwatch": "^5.4 || ^6.4 || ^7.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"facile-it/paraunit": "^1.3.1 || ^2.5",
|
"facile-it/paraunit": "^1.3.1 || ^2.6",
|
||||||
"infection/infection": "^0.29.10",
|
"infection/infection": "^0.29.14",
|
||||||
"justinrainbow/json-schema": "^5.3 || ^6.0",
|
"justinrainbow/json-schema": "^5.3 || ^6.2",
|
||||||
"keradus/cli-executor": "^2.1",
|
"keradus/cli-executor": "^2.1",
|
||||||
"mikey179/vfsstream": "^1.6.12",
|
"mikey179/vfsstream": "^1.6.12",
|
||||||
"php-coveralls/php-coveralls": "^2.7",
|
"php-coveralls/php-coveralls": "^2.7",
|
||||||
"php-cs-fixer/accessible-object": "^1.1",
|
"php-cs-fixer/accessible-object": "^1.1",
|
||||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
||||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
||||||
"phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.7",
|
"phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12",
|
||||||
"symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.0",
|
"symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3",
|
||||||
"symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.0"
|
"symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-dom": "For handling output formats in XML",
|
"ext-dom": "For handling output formats in XML",
|
||||||
@@ -497,7 +498,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.69.1"
|
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -505,7 +506,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-02-18T23:57:43+00:00"
|
"time": "2025-03-31T18:40:42+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@@ -1255,16 +1256,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v7.2.1",
|
"version": "v7.2.6",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3"
|
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
"url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
|
||||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1328,7 +1329,7 @@
|
|||||||
"terminal"
|
"terminal"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v7.2.1"
|
"source": "https://github.com/symfony/console/tree/v7.2.6"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1344,7 +1345,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-12-11T03:49:26+00:00"
|
"time": "2025-04-07T19:09:28+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
@@ -1768,7 +1769,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.31.0",
|
"version": "v1.32.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
@@ -1827,7 +1828,7 @@
|
|||||||
"portable"
|
"portable"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1847,7 +1848,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-grapheme",
|
"name": "symfony/polyfill-intl-grapheme",
|
||||||
"version": "v1.31.0",
|
"version": "v1.32.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||||
@@ -1905,7 +1906,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0"
|
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1925,7 +1926,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-normalizer",
|
"name": "symfony/polyfill-intl-normalizer",
|
||||||
"version": "v1.31.0",
|
"version": "v1.32.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||||
@@ -1986,7 +1987,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0"
|
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2006,19 +2007,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.31.0",
|
"version": "v1.32.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
|
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"ext-iconv": "*",
|
||||||
"php": ">=7.2"
|
"php": ">=7.2"
|
||||||
},
|
},
|
||||||
"provide": {
|
"provide": {
|
||||||
@@ -2066,7 +2068,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2082,20 +2084,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
"time": "2024-12-23T08:48:59+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
"version": "v1.31.0",
|
"version": "v1.32.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
|
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
|
||||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2146,7 +2148,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
|
"source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2162,11 +2164,11 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
"time": "2025-01-02T08:10:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php81",
|
"name": "symfony/polyfill-php81",
|
||||||
"version": "v1.31.0",
|
"version": "v1.32.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||||
@@ -2222,7 +2224,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
|
"source": "https://github.com/symfony/polyfill-php81/tree/v1.32.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2242,16 +2244,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e"
|
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e",
|
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||||
"reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e",
|
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2283,7 +2285,7 @@
|
|||||||
"description": "Executes commands in sub-processes",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v7.2.0"
|
"source": "https://github.com/symfony/process/tree/v7.2.5"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2299,7 +2301,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-06T14:24:19+00:00"
|
"time": "2025-03-13T12:21:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
@@ -2386,16 +2388,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/stopwatch",
|
"name": "symfony/stopwatch",
|
||||||
"version": "v7.2.2",
|
"version": "v7.2.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/stopwatch.git",
|
"url": "https://github.com/symfony/stopwatch.git",
|
||||||
"reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df"
|
"reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df",
|
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd",
|
||||||
"reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df",
|
"reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2428,7 +2430,7 @@
|
|||||||
"description": "Provides a way to profile code",
|
"description": "Provides a way to profile code",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/stopwatch/tree/v7.2.2"
|
"source": "https://github.com/symfony/stopwatch/tree/v7.2.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2444,20 +2446,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-12-18T14:28:33+00:00"
|
"time": "2025-02-24T10:49:57+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/string",
|
"name": "symfony/string",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.6",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/string.git",
|
"url": "https://github.com/symfony/string.git",
|
||||||
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82"
|
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82",
|
"url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
|
||||||
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82",
|
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2515,7 +2517,7 @@
|
|||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/string/tree/v7.2.0"
|
"source": "https://github.com/symfony/string/tree/v7.2.6"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2531,7 +2533,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-13T13:31:26+00:00"
|
"time": "2025-04-20T20:18:16+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
|
21
.ci/rector.php
Normal file
21
.ci/rector.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Rector\Config\RectorConfig;
|
||||||
|
|
||||||
|
return RectorConfig::configure()
|
||||||
|
->withPaths([
|
||||||
|
__DIR__ . '/../app',
|
||||||
|
__DIR__ . '/../bootstrap',
|
||||||
|
__DIR__ . '/../config',
|
||||||
|
__DIR__ . '/../public',
|
||||||
|
__DIR__ . '/../resources',
|
||||||
|
__DIR__ . '/../routes',
|
||||||
|
__DIR__ . '/../tests',
|
||||||
|
])
|
||||||
|
// uncomment to reach your current PHP version
|
||||||
|
->withPhpSets()
|
||||||
|
->withTypeCoverageLevel(0)
|
||||||
|
->withDeadCodeLevel(0)
|
||||||
|
->withCodeQualityLevel(0);
|
28
.ci/rector.sh
Executable file
28
.ci/rector.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# phpstan.sh
|
||||||
|
# Copyright (c) 2021 james@firefly-iii.org
|
||||||
|
#
|
||||||
|
# This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Install composer packages
|
||||||
|
#composer install --no-scripts --no-ansi
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
|
$SCRIPT_DIR/../vendor/bin/rector --config $SCRIPT_DIR/rector.php
|
16
.env.example
16
.env.example
@@ -164,6 +164,13 @@ MAIL_PASSWORD=null
|
|||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=null
|
||||||
MAIL_SENDMAIL_COMMAND=
|
MAIL_SENDMAIL_COMMAND=
|
||||||
|
|
||||||
|
#
|
||||||
|
# If you use self-signed certificates for your STMP server, you can use the following settings.
|
||||||
|
#
|
||||||
|
MAIL_ALLOW_SELF_SIGNED=false
|
||||||
|
MAIL_VERIFY_PEER=true
|
||||||
|
MAIL_VERIFY_PEER_NAME=true
|
||||||
|
|
||||||
# Other mail drivers:
|
# Other mail drivers:
|
||||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||||
MAILGUN_DOMAIN=
|
MAILGUN_DOMAIN=
|
||||||
@@ -289,13 +296,6 @@ STATIC_CRON_TOKEN=
|
|||||||
# However if you know what you're doing you can significantly speed up container start times.
|
# However if you know what you're doing you can significantly speed up container start times.
|
||||||
# Set each value to true to enable, or false to disable.
|
# Set each value to true to enable, or false to disable.
|
||||||
|
|
||||||
# Set this to true to build all locales supported by Firefly III.
|
|
||||||
# This may take quite some time (several minutes) and is generally not recommended.
|
|
||||||
# If you wish to change or alter the list of locales, start your Docker container with
|
|
||||||
# `docker run -v locale.gen:/etc/locale.gen -e DKR_BUILD_LOCALE=true`
|
|
||||||
# and make sure your preferred locales are in your own locale.gen.
|
|
||||||
DKR_BUILD_LOCALE=false
|
|
||||||
|
|
||||||
# Check if the SQLite database exists. Can be skipped if you're not using SQLite.
|
# Check if the SQLite database exists. Can be skipped if you're not using SQLite.
|
||||||
# Won't significantly speed up things.
|
# Won't significantly speed up things.
|
||||||
DKR_CHECK_SQLITE=true
|
DKR_CHECK_SQLITE=true
|
||||||
@@ -326,7 +326,7 @@ USE_RUNNING_BALANCE=false
|
|||||||
FIREFLY_III_LAYOUT=v1
|
FIREFLY_III_LAYOUT=v1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Which Query Parser implementation to use for the search rngine and rules
|
# Which Query Parser implementation to use for the search engine and rules
|
||||||
# 'new' is experimental, 'legacy' is the classic one
|
# 'new' is experimental, 'legacy' is the classic one
|
||||||
#
|
#
|
||||||
QUERY_PARSER_IMPLEMENTATION=legacy
|
QUERY_PARSER_IMPLEMENTATION=legacy
|
||||||
|
8
.github/mergify.yml
vendored
8
.github/mergify.yml
vendored
@@ -1,5 +1,11 @@
|
|||||||
---
|
|
||||||
pull_request_rules:
|
pull_request_rules:
|
||||||
|
- name: Make sure PR are up to date before merging
|
||||||
|
description: This automatically updates PRs when they are out-of-date with the
|
||||||
|
base branch to avoid semantic conflicts (next step is using a merge
|
||||||
|
queue).
|
||||||
|
conditions: []
|
||||||
|
actions:
|
||||||
|
update:
|
||||||
- name: Close all on main
|
- name: Close all on main
|
||||||
conditions:
|
conditions:
|
||||||
- base=main
|
- base=main
|
||||||
|
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -21,5 +21,3 @@ Changes in this pull request:
|
|||||||
-
|
-
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
|
|
||||||
@JC5
|
|
||||||
|
2
.github/workflows/close-duplicates.yml
vendored
2
.github/workflows/close-duplicates.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
close_duplicates:
|
close_duplicates:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: github/command@v1.3.0
|
- uses: github/command@v2.0.0
|
||||||
id: command
|
id: command
|
||||||
with:
|
with:
|
||||||
allowed_contexts: "issue"
|
allowed_contexts: "issue"
|
||||||
|
352
.github/workflows/release.yml
vendored
352
.github/workflows/release.yml
vendored
@@ -22,32 +22,65 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Switch branch
|
- name: Import GPG key
|
||||||
run: |
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
if [[ "develop" == "$version" ]]; then
|
with:
|
||||||
git checkout --track origin/develop
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||||
git pull
|
passphrase: ${{ secrets.PASSPHRASE }}
|
||||||
elif [[ "$version" == branch* ]]; then
|
git_user_signingkey: true
|
||||||
PULLBRANCH=${version:7}
|
git_commit_gpgsign: true
|
||||||
echo "The branch is '$PULLBRANCH' ($version)"
|
|
||||||
git checkout --track origin/$PULLBRANCH
|
|
||||||
git pull
|
|
||||||
else
|
|
||||||
git config user.name github-actions
|
|
||||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
||||||
git checkout --track origin/develop
|
|
||||||
git pull
|
|
||||||
git checkout main
|
|
||||||
git merge develop
|
|
||||||
fi
|
|
||||||
env:
|
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: ${{ github.event.inputs.phpversion }}
|
php-version: ${{ github.event.inputs.phpversion }}
|
||||||
extensions: mbstring, intl, zip, bcmath
|
extensions: mbstring, intl, zip, bcmath
|
||||||
- name: crowdin action
|
- name: Switch and pull
|
||||||
|
run: |
|
||||||
|
#
|
||||||
|
# Always check out origin/develop, unless its a branch release.
|
||||||
|
#
|
||||||
|
BRANCH_TO_PULL=origin/develop
|
||||||
|
if [[ "$version" == branch* ]]; then
|
||||||
|
BRANCH_TO_PULL=origin/$version
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Version is '$version', check out '$BRANCH_TO_PULL'-branch"
|
||||||
|
|
||||||
|
git checkout --track $BRANCH_TO_PULL
|
||||||
|
git pull
|
||||||
|
echo "Current branch is $(git branch --show-current)"
|
||||||
|
env:
|
||||||
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- name: Configure Git
|
||||||
|
run: |
|
||||||
|
# do some configuration
|
||||||
|
sudo timedatectl set-timezone Europe/Amsterdam
|
||||||
|
git config user.name JC5
|
||||||
|
git config user.email release@firefly-iii.org
|
||||||
|
git config advice.addIgnoredFile false
|
||||||
|
git config push.autoSetupRemote true
|
||||||
|
- name: Lint PHP
|
||||||
|
run: |
|
||||||
|
php_lint_file()
|
||||||
|
{
|
||||||
|
local php_file="$1"
|
||||||
|
php -l "$php_file" &> /dev/null
|
||||||
|
if [ "$?" -ne 0 ]
|
||||||
|
then
|
||||||
|
echo -e "[FAIL] $php_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
export -f php_lint_file
|
||||||
|
|
||||||
|
find . -path ./vendor -prune -o -name '*.php' | parallel -j 4 php_lint_file {}
|
||||||
|
|
||||||
|
if [ "$?" -ne 0 ]
|
||||||
|
then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Crowdin action
|
||||||
uses: crowdin/github-action@v2
|
uses: crowdin/github-action@v2
|
||||||
with:
|
with:
|
||||||
upload_sources: true
|
upload_sources: true
|
||||||
@@ -76,15 +109,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
FIREFLY_III_ROOT: /github/workspace
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
GH_TOKEN: ''
|
GH_TOKEN: ''
|
||||||
- name: Extract changelog
|
|
||||||
id: extract-changelog
|
|
||||||
uses: JC5/firefly-iii-dev@main
|
|
||||||
with:
|
|
||||||
action: 'ff3:extract-changelog'
|
|
||||||
output: 'output'
|
|
||||||
env:
|
|
||||||
FIREFLY_III_ROOT: /github/workspace
|
|
||||||
GH_TOKEN: ""
|
|
||||||
- name: Replace version
|
- name: Replace version
|
||||||
id: replace-version
|
id: replace-version
|
||||||
uses: JC5/firefly-iii-dev@main
|
uses: JC5/firefly-iii-dev@main
|
||||||
@@ -134,18 +158,8 @@ jobs:
|
|||||||
composer update --no-dev --no-scripts --no-plugins -q
|
composer update --no-dev --no-scripts --no-plugins -q
|
||||||
sudo chown -R runner:docker resources/lang
|
sudo chown -R runner:docker resources/lang
|
||||||
.ci/phpcs.sh || true
|
.ci/phpcs.sh || true
|
||||||
- name: Import GPG key
|
- name: Calculate variables
|
||||||
uses: crazy-max/ghaction-import-gpg@v6
|
|
||||||
with:
|
|
||||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
||||||
passphrase: ${{ secrets.PASSPHRASE }}
|
|
||||||
- name: Release
|
|
||||||
run: |
|
run: |
|
||||||
# do some configuration
|
|
||||||
sudo timedatectl set-timezone Europe/Amsterdam
|
|
||||||
git config user.name github-actions
|
|
||||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
||||||
git config advice.addIgnoredFile false
|
|
||||||
|
|
||||||
# set some variables
|
# set some variables
|
||||||
releaseName=$version
|
releaseName=$version
|
||||||
@@ -153,10 +167,6 @@ jobs:
|
|||||||
zipName=FireflyIII-$version.zip
|
zipName=FireflyIII-$version.zip
|
||||||
tarName=FireflyIII-$version.tar.gz
|
tarName=FireflyIII-$version.tar.gz
|
||||||
|
|
||||||
# update composer (again)
|
|
||||||
composer update --no-dev --no-scripts --no-plugins
|
|
||||||
composer dump-autoload
|
|
||||||
|
|
||||||
# if this is a develop build, slightly different variable names.
|
# if this is a develop build, slightly different variable names.
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
#[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
#[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||||
@@ -191,35 +201,53 @@ jobs:
|
|||||||
tagFound=false
|
tagFound=false
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo "Will use tag and release name $releaseName."
|
|
||||||
|
|
||||||
|
# set some variables
|
||||||
|
echo "Release name is $releaseName."
|
||||||
|
echo "Original name is $originalName."
|
||||||
|
echo "Zip name is $zipName."
|
||||||
|
echo "Tar name is $tarName."
|
||||||
|
|
||||||
|
# create a new branch to store the difference in.
|
||||||
|
BRANCH_NAME=release-$(date +'%s')
|
||||||
|
git checkout -b $BRANCH_NAME
|
||||||
|
|
||||||
|
echo "Temporary branch name is '$BRANCH_NAME'."
|
||||||
|
|
||||||
|
# share variables with next step.
|
||||||
|
echo "releaseName=$releaseName" >> "$GITHUB_ENV"
|
||||||
|
echo "originalName=$originalName" >> "$GITHUB_ENV"
|
||||||
|
echo "zipName=$zipName" >> "$GITHUB_ENV"
|
||||||
|
echo "tarName=$tarName" >> "$GITHUB_ENV"
|
||||||
|
echo "BRANCH_NAME=$BRANCH_NAME" >> "$GITHUB_ENV"
|
||||||
|
env:
|
||||||
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- name: Commit all changes
|
||||||
|
run: |
|
||||||
# add all content, except output.txt (this contains the changelog and/or the download instructions)
|
# add all content, except output.txt (this contains the changelog and/or the download instructions)
|
||||||
echo 'Add all and reset output.txt'
|
echo 'Add all'
|
||||||
git add -A
|
git add -A
|
||||||
if test -f "output.txt"; then
|
# push to a new branch.
|
||||||
git reset output.txt
|
echo "Auto commit on branch '$(git branch --show-current)'."
|
||||||
fi
|
git commit -m "🤖 Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
|
||||||
git commit -m "Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
|
|
||||||
git push
|
git push
|
||||||
|
env:
|
||||||
# zip and tar everything
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
echo 'Zip and tar...'
|
- name: Extract changelog
|
||||||
zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" "*Procfile*" "*crowdin.yml*" "*sonar-project.properties*"
|
id: extract-changelog
|
||||||
touch $tarName
|
uses: JC5/firefly-iii-dev@main
|
||||||
tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' --exclude='./Procfile' --exclude='../crowdin.yml' --exclude='./sonar-project.properties' -czf $tarName .
|
with:
|
||||||
|
action: 'ff3:extract-changelog'
|
||||||
# add sha256 sum
|
output: 'output'
|
||||||
echo 'Sha sum ...'
|
env:
|
||||||
sha256sum -b $zipName > $zipName.sha256
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
sha256sum -b $tarName > $tarName.sha256
|
GH_TOKEN: ""
|
||||||
|
- name: Describe new release
|
||||||
# add signatures:
|
run: |
|
||||||
gpg --armor --detach-sign $zipName
|
|
||||||
gpg --armor --detach-sign $tarName
|
|
||||||
|
|
||||||
# describe the development release.
|
# describe the development release.
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
echo 'Develop release.'
|
echo 'Describe the latest develop release'
|
||||||
rm -f output.txt
|
rm -f output.txt
|
||||||
touch output.txt
|
touch output.txt
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
@@ -234,7 +262,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
# describe a branch release
|
# describe a branch release
|
||||||
if [[ "$version" == branch* ]]; then
|
if [[ "$version" == branch* ]]; then
|
||||||
echo 'Branch release.'
|
echo 'Describe a branch release'
|
||||||
rm -f output.txt
|
rm -f output.txt
|
||||||
touch output.txt
|
touch output.txt
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
@@ -249,8 +277,11 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
# describe the main release
|
# describe the main release
|
||||||
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
||||||
echo 'Main release.'
|
echo 'Describe the latest release'
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
|
touch output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "Welcome to release $version of Firefly III. It contains the the latest fixes, translations and features. Docker users can find this release under the \`latest\` tag." >> output.txt
|
||||||
echo '' >> output.txt
|
echo '' >> output.txt
|
||||||
echo '### Instructions' >> output.txt
|
echo '### Instructions' >> output.txt
|
||||||
echo '' >> output.txt
|
echo '' >> output.txt
|
||||||
@@ -262,7 +293,7 @@ jobs:
|
|||||||
|
|
||||||
# describe alpha release
|
# describe alpha release
|
||||||
if [[ "$version" == *alpha* ]]; then
|
if [[ "$version" == *alpha* ]]; then
|
||||||
echo 'ALPHA release.'
|
echo 'Describe an ALPHA release'
|
||||||
rm -f output.txt
|
rm -f output.txt
|
||||||
touch output.txt
|
touch output.txt
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
@@ -280,7 +311,7 @@ jobs:
|
|||||||
|
|
||||||
# describe beta release
|
# describe beta release
|
||||||
if [[ "$version" == *beta* ]]; then
|
if [[ "$version" == *beta* ]]; then
|
||||||
echo 'BETA release.'
|
echo 'Describe a BETA release'
|
||||||
rm -f output.txt
|
rm -f output.txt
|
||||||
touch output.txt
|
touch output.txt
|
||||||
sudo chown -R runner:docker output.txt
|
sudo chown -R runner:docker output.txt
|
||||||
@@ -295,55 +326,125 @@ jobs:
|
|||||||
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
env:
|
||||||
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- name: Merge all into working branch
|
||||||
|
run: |
|
||||||
|
MERGE_INTO=develop
|
||||||
|
if [[ "$version" == branch* ]]; then
|
||||||
|
MERGE_INTO=$version
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Merge all changes from $BRANCH_NAME back into '$MERGE_INTO' using a PR"
|
||||||
|
PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 Created by GitHub action')
|
||||||
|
echo "PR URL is '$PR_URL'"
|
||||||
|
IFS='/' read -ra parts <<< "$PR_URL"
|
||||||
|
PR_NR=$(printf %s\\n "${parts[@]:(-1)}")
|
||||||
|
echo "PR number is '$PR_NR'"
|
||||||
|
gh pr merge $PR_NR -b "🤖 Automatically merge the PR into the $MERGE_INTO branch." -d --merge
|
||||||
|
|
||||||
|
# pull the changes from the $MERGE_INTO branch.
|
||||||
|
git checkout $MERGE_INTO
|
||||||
|
git merge origin/$MERGE_INTO
|
||||||
|
git pull
|
||||||
|
git status
|
||||||
|
echo "Current branch '$(git branch --show-current)'."
|
||||||
|
|
||||||
|
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]]; then
|
||||||
|
git checkout main
|
||||||
|
git merge origin/main
|
||||||
|
git pull
|
||||||
|
git status
|
||||||
|
|
||||||
|
echo "Also merge everything into main since this is a release."
|
||||||
|
echo 'create PR'
|
||||||
|
PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body "🤖 Created by GitHub action")
|
||||||
|
echo "PR URL is '$PR_URL'"
|
||||||
|
|
||||||
|
IFS='/' read -ra parts <<< "$PR_URL"
|
||||||
|
PR_NR=$(printf %s\\n "${parts[@]:(-1)}")
|
||||||
|
echo "PR number is '$PR_NR'"
|
||||||
|
|
||||||
|
echo 'Merge PR'
|
||||||
|
gh pr merge $PR_NR -b "🤖 Automatically merge the PR into the main branch." --merge
|
||||||
|
git checkout main
|
||||||
|
git merge origin/main
|
||||||
|
git pull
|
||||||
|
git status
|
||||||
|
echo "Current branch '$(git branch --show-current)'."
|
||||||
|
|
||||||
|
fi
|
||||||
|
echo "DONE!"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- name: Create archives
|
||||||
|
run: |
|
||||||
|
echo "Create zip file $zipName"
|
||||||
|
zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" "*Procfile*" "*crowdin.yml*" "*sonar-project.properties*"
|
||||||
|
touch $tarName
|
||||||
|
|
||||||
|
echo "Create tar file $tarName"
|
||||||
|
tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' --exclude='./Procfile' --exclude='../crowdin.yml' --exclude='./sonar-project.properties' -czf $tarName .
|
||||||
|
# add sha256 sum
|
||||||
|
echo 'Sha sum ...'
|
||||||
|
sha256sum -b $zipName > $zipName.sha256
|
||||||
|
sha256sum -b $tarName > $tarName.sha256
|
||||||
|
|
||||||
|
# add signatures:
|
||||||
|
gpg --armor --detach-sign $zipName
|
||||||
|
gpg --armor --detach-sign $tarName
|
||||||
|
- name: Create release
|
||||||
|
run: |
|
||||||
|
|
||||||
# create a development release:
|
# create a development release:
|
||||||
if [[ "develop" == "$version" ]]; then
|
if [[ "develop" == "$version" ]]; then
|
||||||
# create the release:
|
# pull the changes from the develop branch.
|
||||||
echo "Create develop release."
|
git checkout develop
|
||||||
git tag -a $releaseName -m "Development release '$version' on $(date +'%Y-%m-%d')"
|
git merge origin/develop
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# create the release:
|
||||||
|
echo "Create develop release under tag '$releaseName'."
|
||||||
|
git tag -a $releaseName -m "🤖 Development release '$version' on $(date +'%Y-%m-%d')"
|
||||||
git push origin $releaseName
|
git push origin $releaseName
|
||||||
|
|
||||||
gh release create $releaseName -p --verify-tag \
|
gh release create $releaseName -p --verify-tag \
|
||||||
-t "Development release for $(date +'%Y-%m-%d')" \
|
-t "Development release for $(date +'%Y-%m-%d')" \
|
||||||
--latest=false \
|
--latest=false \
|
||||||
-F output.txt
|
-F output.txt
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# create a branch release:
|
# create a branch release:
|
||||||
if [[ "$version" == branch* ]]; then
|
if [[ "$version" == branch* ]]; then
|
||||||
|
|
||||||
|
# pull the changes from the branch-* branch.
|
||||||
|
git checkout $version
|
||||||
|
git merge origin/$version
|
||||||
|
git pull
|
||||||
|
|
||||||
# create the release:
|
# create the release:
|
||||||
echo "Create branch release."
|
echo "Create branch release."
|
||||||
git tag -a $releaseName -m "Branch release '$version' on $(date +'%Y-%m-%d')"
|
git tag -a $releaseName -m "Branch release '$version' on $(date +'%Y-%m-%d')"
|
||||||
|
|
||||||
git push origin $releaseName
|
git push origin $releaseName
|
||||||
|
|
||||||
gh release create $releaseName -p --verify-tag \
|
gh release create $releaseName -p --verify-tag \
|
||||||
-t "Branch release for $(date +'%Y-%m-%d')" \
|
-t "Branch release for $(date +'%Y-%m-%d')" \
|
||||||
--latest=false \
|
--latest=false \
|
||||||
-F output.txt
|
-F output.txt
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# create a development (nightly) release:
|
# Create a production release.
|
||||||
if [[ "develop" == "$version" ]] || [[ "$version" == branch* ]]; then
|
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]]; then
|
||||||
# add zip file to release.
|
git checkout main
|
||||||
gh release upload $releaseName $zipName
|
git merge origin/main
|
||||||
gh release upload $releaseName $tarName
|
git pull
|
||||||
|
git status
|
||||||
|
|
||||||
# add sha256 sum to release
|
echo "Create prod release."
|
||||||
gh release upload $releaseName $zipName.sha256
|
git tag -a $releaseName -m "Release $version"
|
||||||
gh release upload $releaseName $tarName.sha256
|
|
||||||
|
|
||||||
# add signatures to release
|
|
||||||
gh release upload $releaseName $zipName.asc
|
|
||||||
gh release upload $releaseName $tarName.asc
|
|
||||||
|
|
||||||
# get current HEAD and add as file to the release
|
|
||||||
HEAD=$(git rev-parse HEAD)
|
|
||||||
echo $HEAD > HEAD.txt
|
|
||||||
gh release upload $releaseName HEAD.txt
|
|
||||||
else
|
|
||||||
echo 'MAIN (real) release'
|
|
||||||
git tag -a $releaseName -m "Here be changelog"
|
|
||||||
git push origin $releaseName
|
git push origin $releaseName
|
||||||
|
|
||||||
# do not tag as latest when alpha or beta.
|
# do not tag as latest when alpha or beta.
|
||||||
@@ -355,39 +456,38 @@ jobs:
|
|||||||
# tag as latest when NOT alpha or beta.
|
# tag as latest when NOT alpha or beta.
|
||||||
if [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
if [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
||||||
echo 'Mark prod as the latest.'
|
echo 'Mark prod as the latest.'
|
||||||
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag
|
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag --latest=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# add archive files to release
|
|
||||||
gh release upload $releaseName $zipName
|
|
||||||
gh release upload $releaseName $tarName
|
|
||||||
|
|
||||||
# add sha256 sums to release
|
|
||||||
gh release upload $releaseName $zipName.sha256
|
|
||||||
gh release upload $releaseName $tarName.sha256
|
|
||||||
|
|
||||||
# add signatures to release
|
|
||||||
gh release upload $releaseName $zipName.asc
|
|
||||||
gh release upload $releaseName $tarName.asc
|
|
||||||
|
|
||||||
# get current HEAD and add as file to the release
|
|
||||||
HEAD=$(git rev-parse HEAD)
|
|
||||||
echo $HEAD > HEAD.txt
|
|
||||||
gh release upload $releaseName HEAD.txt
|
|
||||||
|
|
||||||
# remove all temporary files
|
|
||||||
rm -f output.txt
|
|
||||||
rm -f HEAD.txt
|
|
||||||
rm -f $zipName
|
|
||||||
rm -f $zipName.sha256
|
|
||||||
rm -f $tarName
|
|
||||||
rm -f $tarName.sha256
|
|
||||||
|
|
||||||
# merge main back into develop
|
|
||||||
git checkout develop
|
|
||||||
git merge main
|
|
||||||
git push
|
|
||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- name: Upload artifacts
|
||||||
|
run: |
|
||||||
|
# add zip file to release.
|
||||||
|
gh release upload $releaseName $zipName
|
||||||
|
gh release upload $releaseName $tarName
|
||||||
|
|
||||||
|
# add sha256 sum to release
|
||||||
|
gh release upload $releaseName $zipName.sha256
|
||||||
|
gh release upload $releaseName $tarName.sha256
|
||||||
|
|
||||||
|
# add signatures to release
|
||||||
|
gh release upload $releaseName $zipName.asc
|
||||||
|
gh release upload $releaseName $tarName.asc
|
||||||
|
|
||||||
|
# get current HEAD and add as file to the release
|
||||||
|
HEAD=$(git rev-parse HEAD)
|
||||||
|
echo $HEAD > HEAD.txt
|
||||||
|
gh release upload $releaseName HEAD.txt
|
||||||
|
|
||||||
|
# remove all temporary files
|
||||||
|
rm -f output.txt
|
||||||
|
rm -f HEAD.txt
|
||||||
|
rm -f $zipName
|
||||||
|
rm -f $zipName.sha256
|
||||||
|
rm -f $tarName
|
||||||
|
rm -f $tarName.sha256
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@ yarn-error.log
|
|||||||
.env
|
.env
|
||||||
/.ci/php-cs-fixer/vendor
|
/.ci/php-cs-fixer/vendor
|
||||||
coverage.xml
|
coverage.xml
|
||||||
|
output.txt
|
||||||
|
|
||||||
# ignore generated files.
|
# ignore generated files.
|
||||||
public/build
|
public/build
|
||||||
|
@@ -4,6 +4,9 @@ Over time, many people have contributed to Firefly III. Their efforts are not al
|
|||||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
||||||
|
|
||||||
## 2025
|
## 2025
|
||||||
|
- Denis Iskandarov
|
||||||
|
- =
|
||||||
|
- Lompi
|
||||||
- Jose Diaz-Gonzalez
|
- Jose Diaz-Gonzalez
|
||||||
- SoftBrix
|
- SoftBrix
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ use FireflyIII\Enums\AccountTypeEnum;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Debug\Timer;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
@@ -42,6 +43,7 @@ use Illuminate\Support\Facades\Log;
|
|||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
use AccountFilter;
|
use AccountFilter;
|
||||||
|
|
||||||
// this array only exists to test if the constructor will use it properly.
|
// this array only exists to test if the constructor will use it properly.
|
||||||
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
||||||
|
|
||||||
@@ -82,10 +84,11 @@ class AccountController extends Controller
|
|||||||
$query = $data['query'];
|
$query = $data['query'];
|
||||||
$date = $data['date'] ?? today(config('app.timezone'));
|
$date = $data['date'] ?? today(config('app.timezone'));
|
||||||
$return = [];
|
$return = [];
|
||||||
|
Timer::start(sprintf('AC accounts "%s"', $query));
|
||||||
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
||||||
|
|
||||||
// set date to subday + end-of-day for account balance. so it is at $date 23:59:59
|
// set date to subday + end-of-day for account balance. so it is at $date 23:59:59
|
||||||
$date->subDay()->endOfDay();
|
$date->endOfDay();
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($result as $account) {
|
foreach ($result as $account) {
|
||||||
@@ -135,6 +138,7 @@ class AccountController extends Controller
|
|||||||
return $posA - $posB;
|
return $posA - $posB;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Timer::stop(sprintf('AC accounts "%s"', $query));
|
||||||
|
|
||||||
return response()->api($return);
|
return response()->api($return);
|
||||||
}
|
}
|
||||||
|
@@ -65,13 +65,11 @@ class BillController extends Controller
|
|||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchBill($data['query'], $this->parameters->get('limit'));
|
$result = $this->repository->searchBill($data['query'], $this->parameters->get('limit'));
|
||||||
$filtered = $result->map(
|
$filtered = $result->map(
|
||||||
static function (Bill $item) {
|
static fn (Bill $item) => [
|
||||||
return [
|
'id' => (string) $item->id,
|
||||||
'id' => (string) $item->id,
|
'name' => $item->name,
|
||||||
'name' => $item->name,
|
'active' => $item->active,
|
||||||
'active' => $item->active,
|
]
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->api($filtered->toArray());
|
return response()->api($filtered->toArray());
|
||||||
|
@@ -65,12 +65,10 @@ class BudgetController extends Controller
|
|||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchBudget($data['query'], $this->parameters->get('limit'));
|
$result = $this->repository->searchBudget($data['query'], $this->parameters->get('limit'));
|
||||||
$filtered = $result->map(
|
$filtered = $result->map(
|
||||||
static function (Budget $item) {
|
static fn (Budget $item) => [
|
||||||
return [
|
'id' => (string) $item->id,
|
||||||
'id' => (string) $item->id,
|
'name' => $item->name,
|
||||||
'name' => $item->name,
|
]
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->api($filtered->toArray());
|
return response()->api($filtered->toArray());
|
||||||
|
@@ -65,12 +65,10 @@ class CategoryController extends Controller
|
|||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchCategory($data['query'], $this->parameters->get('limit'));
|
$result = $this->repository->searchCategory($data['query'], $this->parameters->get('limit'));
|
||||||
$filtered = $result->map(
|
$filtered = $result->map(
|
||||||
static function (Category $item) {
|
static fn (Category $item) => [
|
||||||
return [
|
'id' => (string) $item->id,
|
||||||
'id' => (string) $item->id,
|
'name' => $item->name,
|
||||||
'name' => $item->name,
|
]
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->api($filtered->toArray());
|
return response()->api($filtered->toArray());
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
|
|||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@@ -39,11 +39,10 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
class TransactionController extends Controller
|
class TransactionController extends Controller
|
||||||
{
|
{
|
||||||
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
private TransactionGroupRepositoryInterface $groupRepository;
|
private TransactionGroupRepositoryInterface $groupRepository;
|
||||||
private JournalRepositoryInterface $repository;
|
private JournalRepositoryInterface $repository;
|
||||||
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TransactionController constructor.
|
* TransactionController constructor.
|
||||||
*/
|
*/
|
||||||
|
@@ -26,14 +26,17 @@ namespace FireflyIII\Api\V1\Controllers\Chart;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V1\Requests\Chart\ChartRequest;
|
||||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
||||||
use FireflyIII\Enums\AccountTypeEnum;
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Chart\ChartData;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||||
|
use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -43,7 +46,9 @@ use Illuminate\Http\JsonResponse;
|
|||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
use ApiSupport;
|
use ApiSupport;
|
||||||
|
use CollectsAccountsFromFilter;
|
||||||
|
|
||||||
|
private ChartData $chartData;
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +61,7 @@ class AccountController extends Controller
|
|||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
$this->chartData = new ChartData();
|
||||||
$this->repository = app(AccountRepositoryInterface::class);
|
$this->repository = app(AccountRepositoryInterface::class);
|
||||||
$this->repository->setUser($user);
|
$this->repository->setUser($user);
|
||||||
|
|
||||||
@@ -64,6 +70,70 @@ class AccountController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO fix documentation
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
public function dashboard(ChartRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$queryParameters = $request->getParameters();
|
||||||
|
$accounts = $this->getAccountList($queryParameters);
|
||||||
|
|
||||||
|
// move date to end of day
|
||||||
|
$queryParameters['start']->startOfDay();
|
||||||
|
$queryParameters['end']->endOfDay();
|
||||||
|
|
||||||
|
// loop each account, and collect info:
|
||||||
|
/** @var Account $account */
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$this->renderAccountData($queryParameters, $account);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($this->chartData->render());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function renderAccountData(array $params, Account $account): void
|
||||||
|
{
|
||||||
|
$currency = $this->repository->getAccountCurrency($account);
|
||||||
|
if (null === $currency) {
|
||||||
|
$currency = $this->default;
|
||||||
|
}
|
||||||
|
$currentSet = [
|
||||||
|
'label' => $account->name,
|
||||||
|
|
||||||
|
// the currency that belongs to the account.
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
|
||||||
|
// the default currency of the user (could be the same!)
|
||||||
|
'date' => $params['start']->toAtomString(),
|
||||||
|
'start' => $params['start']->toAtomString(),
|
||||||
|
'end' => $params['end']->toAtomString(),
|
||||||
|
'period' => '1D',
|
||||||
|
'entries' => [],
|
||||||
|
];
|
||||||
|
$currentStart = clone $params['start'];
|
||||||
|
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||||
|
|
||||||
|
$previous = array_values($range)[0]['balance'];
|
||||||
|
while ($currentStart <= $params['end']) {
|
||||||
|
$format = $currentStart->format('Y-m-d');
|
||||||
|
$label = $currentStart->toAtomString();
|
||||||
|
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||||
|
$previous = $balance;
|
||||||
|
|
||||||
|
$currentStart->addDay();
|
||||||
|
$currentSet['entries'][$label] = $balance;
|
||||||
|
}
|
||||||
|
$this->chartData->add($currentSet);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
|
||||||
|
260
app/Api/V1/Controllers/Chart/BudgetController.php
Normal file
260
app/Api/V1/Controllers/Chart/BudgetController.php
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BudgetController.php
|
||||||
|
* Copyright (c) 2023 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V1\Requests\Generic\DateRequest;
|
||||||
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Models\Budget;
|
||||||
|
use FireflyIII\Models\BudgetLimit;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BudgetController
|
||||||
|
*/
|
||||||
|
class BudgetController extends Controller
|
||||||
|
{
|
||||||
|
use CleansChartData;
|
||||||
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
|
|
||||||
|
protected OperationsRepositoryInterface $opsRepository;
|
||||||
|
private BudgetLimitRepositoryInterface $blRepository;
|
||||||
|
private array $currencies = [];
|
||||||
|
private TransactionCurrency $currency;
|
||||||
|
private BudgetRepositoryInterface $repository;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
$this->repository = app(BudgetRepositoryInterface::class);
|
||||||
|
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||||
|
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||||
|
$userGroup = $this->validateUserGroup($request);
|
||||||
|
$this->repository->setUserGroup($userGroup);
|
||||||
|
$this->opsRepository->setUserGroup($userGroup);
|
||||||
|
$this->blRepository->setUserGroup($userGroup);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO see autocomplete/accountcontroller
|
||||||
|
*/
|
||||||
|
public function dashboard(DateRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$params = $request->getAll();
|
||||||
|
|
||||||
|
/** @var Carbon $start */
|
||||||
|
$start = $params['start'];
|
||||||
|
|
||||||
|
/** @var Carbon $end */
|
||||||
|
$end = $params['end'];
|
||||||
|
|
||||||
|
// code from FrontpageChartGenerator, but not in separate class
|
||||||
|
$budgets = $this->repository->getActiveBudgets();
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
/** @var Budget $budget */
|
||||||
|
foreach ($budgets as $budget) {
|
||||||
|
// could return multiple arrays, so merge.
|
||||||
|
$data = array_merge($data, $this->processBudget($budget, $start, $end));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($this->clean($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function processBudget(Budget $budget, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
// get all limits:
|
||||||
|
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||||
|
$rows = [];
|
||||||
|
|
||||||
|
// if no limits
|
||||||
|
if (0 === $limits->count()) {
|
||||||
|
// return as a single item in an array
|
||||||
|
$rows = $this->noBudgetLimits($budget, $start, $end);
|
||||||
|
}
|
||||||
|
if ($limits->count() > 0) {
|
||||||
|
$rows = $this->budgetLimits($budget, $limits);
|
||||||
|
}
|
||||||
|
// is always an array
|
||||||
|
$return = [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$current = [
|
||||||
|
'label' => $budget->name,
|
||||||
|
'currency_id' => (string) $row['currency_id'],
|
||||||
|
'currency_code' => $row['currency_code'],
|
||||||
|
'currency_name' => $row['currency_name'],
|
||||||
|
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||||
|
'period' => null,
|
||||||
|
'start' => $row['start'],
|
||||||
|
'end' => $row['end'],
|
||||||
|
'entries' => [
|
||||||
|
'spent' => $row['spent'],
|
||||||
|
'left' => $row['left'],
|
||||||
|
'overspent' => $row['overspent'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$return[] = $current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When no budget limits are present, the expenses of the whole period are collected and grouped.
|
||||||
|
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
$spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||||
|
|
||||||
|
return $this->processExpenses($budget->id, $spent, $start, $end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
|
||||||
|
* its info.
|
||||||
|
*
|
||||||
|
* @param array<int, array<int, string>> $array
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function processExpenses(int $budgetId, array $array, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This array contains the expenses in this budget. Grouped per currency.
|
||||||
|
* The grouping is on the main currency only.
|
||||||
|
*
|
||||||
|
* @var int $currencyId
|
||||||
|
* @var array $block
|
||||||
|
*/
|
||||||
|
foreach ($array as $currencyId => $block) {
|
||||||
|
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
|
||||||
|
$return[$currencyId] ??= [
|
||||||
|
'currency_id' => (string) $currencyId,
|
||||||
|
'currency_code' => $block['currency_code'],
|
||||||
|
'currency_name' => $block['currency_name'],
|
||||||
|
'currency_symbol' => $block['currency_symbol'],
|
||||||
|
'currency_decimal_places' => (int) $block['currency_decimal_places'],
|
||||||
|
'start' => $start->toAtomString(),
|
||||||
|
'end' => $end->toAtomString(),
|
||||||
|
'spent' => '0',
|
||||||
|
'left' => '0',
|
||||||
|
'overspent' => '0',
|
||||||
|
];
|
||||||
|
$currentBudgetArray = $block['budgets'][$budgetId];
|
||||||
|
|
||||||
|
// var_dump($return);
|
||||||
|
/** @var array $journal */
|
||||||
|
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
||||||
|
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string) $journal['amount']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that processes each budget limit (per budget).
|
||||||
|
*
|
||||||
|
* If you have a budget limit in EUR, only transactions in EUR will be considered.
|
||||||
|
* If you have a budget limit in GBP, only transactions in GBP will be considered.
|
||||||
|
*
|
||||||
|
* If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function budgetLimits(Budget $budget, Collection $limits): array
|
||||||
|
{
|
||||||
|
app('log')->debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
/** @var BudgetLimit $limit */
|
||||||
|
foreach ($limits as $limit) {
|
||||||
|
$data = array_merge($data, $this->processLimit($budget, $limit));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function processLimit(Budget $budget, BudgetLimit $limit): array
|
||||||
|
{
|
||||||
|
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
|
||||||
|
$end = clone $limit->end_date;
|
||||||
|
$end->endOfDay();
|
||||||
|
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||||
|
$limitCurrencyId = $limit->transaction_currency_id;
|
||||||
|
$filtered = [];
|
||||||
|
|
||||||
|
/** @var array $entry */
|
||||||
|
foreach ($spent as $currencyId => $entry) {
|
||||||
|
// only spent the entry where the entry's currency matches the budget limit's currency
|
||||||
|
// so $filtered will only have 1 or 0 entries
|
||||||
|
if ($entry['currency_id'] === $limitCurrencyId) {
|
||||||
|
$filtered[$currencyId] = $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||||
|
if (1 === count($result)) {
|
||||||
|
$compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||||
|
if (1 === $compare) {
|
||||||
|
// convert this amount into the native currency:
|
||||||
|
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']);
|
||||||
|
}
|
||||||
|
if ($compare <= 0) {
|
||||||
|
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
126
app/Api/V1/Controllers/Chart/CategoryController.php
Normal file
126
app/Api/V1/Controllers/Chart/CategoryController.php
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CategoryController.php
|
||||||
|
* Copyright (c) 2023 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
|
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||||
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BudgetController
|
||||||
|
*/
|
||||||
|
class CategoryController extends Controller
|
||||||
|
{
|
||||||
|
use CleansChartData;
|
||||||
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
|
private AccountRepositoryInterface $accountRepos;
|
||||||
|
private CurrencyRepositoryInterface $currencyRepos;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||||
|
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||||
|
$userGroup = $this->validateUserGroup($request);
|
||||||
|
$this->accountRepos->setUserGroup($userGroup);
|
||||||
|
$this->currencyRepos->setUserGroup($userGroup);
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO may be worth to move to a handler but the data is simple enough.
|
||||||
|
* TODO see autoComplete/account controller
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
|
*/
|
||||||
|
public function dashboard(DateRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
/** @var Carbon $start */
|
||||||
|
$start = $this->parameters->get('start');
|
||||||
|
|
||||||
|
/** @var Carbon $end */
|
||||||
|
$end = $this->parameters->get('end');
|
||||||
|
$accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]);
|
||||||
|
$currencies = [];
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
// get journals for entire period:
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
$collector->setRange($start, $end)->withAccountInformation();
|
||||||
|
$collector->setXorAccounts($accounts)->withCategoryInformation();
|
||||||
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::RECONCILIATION->value]);
|
||||||
|
$journals = $collector->getExtractedJournals();
|
||||||
|
|
||||||
|
/** @var array $journal */
|
||||||
|
foreach ($journals as $journal) {
|
||||||
|
$currencyId = (int) $journal['currency_id'];
|
||||||
|
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||||
|
$currencies[$currencyId] = $currency;
|
||||||
|
$categoryName = $journal['category_name'] ?? (string) trans('firefly.no_category');
|
||||||
|
$amount = app('steam')->positive($journal['amount']);
|
||||||
|
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
||||||
|
// create arrays
|
||||||
|
$return[$key] ??= [
|
||||||
|
'label' => $categoryName,
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_name' => $currency->name,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
'period' => null,
|
||||||
|
'start' => $start->toAtomString(),
|
||||||
|
'end' => $end->toAtomString(),
|
||||||
|
'amount' => '0',
|
||||||
|
];
|
||||||
|
|
||||||
|
// add monies
|
||||||
|
$return[$key]['amount'] = bcadd($return[$key]['amount'], (string) $amount);
|
||||||
|
}
|
||||||
|
$return = array_values($return);
|
||||||
|
|
||||||
|
// order by amount
|
||||||
|
usort($return, static fn (array $a, array $b) => (float) $a['amount'] < (float) $b['amount'] ? 1 : -1);
|
||||||
|
|
||||||
|
return response()->json($this->clean($return));
|
||||||
|
}
|
||||||
|
}
|
@@ -32,7 +32,7 @@ use FireflyIII\Models\TransactionCurrency;
|
|||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\AbstractTransformer;
|
use FireflyIII\Transformers\AbstractTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
@@ -40,7 +40,6 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
|||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
@@ -62,15 +61,15 @@ abstract class Controller extends BaseController
|
|||||||
use ValidatesRequests;
|
use ValidatesRequests;
|
||||||
use ValidatesUserGroupTrait;
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
||||||
protected const string JSON_CONTENT_TYPE = 'application/json';
|
protected const string JSON_CONTENT_TYPE = 'application/json';
|
||||||
|
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
||||||
|
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
protected array $allowedSort;
|
protected array $allowedSort;
|
||||||
protected ParameterBag $parameters;
|
protected bool $convertToNative = false;
|
||||||
protected bool $convertToNative = false;
|
|
||||||
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
|
||||||
protected TransactionCurrency $nativeCurrency;
|
protected TransactionCurrency $nativeCurrency;
|
||||||
|
protected ParameterBag $parameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller constructor.
|
* Controller constructor.
|
||||||
@@ -263,7 +262,7 @@ abstract class Controller extends BaseController
|
|||||||
|
|
||||||
// the transformer, at this point, needs to collect information that ALL items in the collection
|
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||||
// require, like meta-data and stuff like that, and save it for later.
|
// require, like meta-data and stuff like that, and save it for later.
|
||||||
$objects = $transformer->collectMetaData($objects);
|
// $objects = $transformer->collectMetaData($objects);
|
||||||
$paginator->setCollection($objects);
|
$paginator->setCollection($objects);
|
||||||
|
|
||||||
$resource = new FractalCollection($objects, $transformer, $key);
|
$resource = new FractalCollection($objects, $transformer, $key);
|
||||||
@@ -284,7 +283,7 @@ abstract class Controller extends BaseController
|
|||||||
$baseUrl = sprintf('%s/api/v1', request()->getSchemeAndHttpHost());
|
$baseUrl = sprintf('%s/api/v1', request()->getSchemeAndHttpHost());
|
||||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
$transformer->collectMetaData(new Collection([$object]));
|
// $transformer->collectMetaData(new Collection([$object]));
|
||||||
|
|
||||||
$resource = new Item($object, $transformer, $key);
|
$resource = new Item($object, $transformer, $key);
|
||||||
|
|
||||||
|
@@ -30,6 +30,8 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Support\Export\ExportDataGenerator;
|
use FireflyIII\Support\Export\ExportDataGenerator;
|
||||||
use Illuminate\Http\Response as LaravelResponse;
|
use Illuminate\Http\Response as LaravelResponse;
|
||||||
|
|
||||||
|
use function Safe\date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ExportController
|
* Class ExportController
|
||||||
*/
|
*/
|
||||||
@@ -88,7 +90,7 @@ class ExportController extends Controller
|
|||||||
->header('Expires', '0')
|
->header('Expires', '0')
|
||||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||||
->header('Pragma', 'public')
|
->header('Pragma', 'public')
|
||||||
->header('Content-Length', (string) strlen($data[$key]))
|
->header('Content-Length', (string) strlen((string) $data[$key]))
|
||||||
;
|
;
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
|
@@ -160,7 +160,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $journal['currency_code'],
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
|
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) $journal['amount']);
|
||||||
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
|
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $foreignCurrencyId,
|
'currency_id' => (string) $foreignCurrencyId,
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
'currency_code' => $journal['foreign_currency_code'],
|
||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
|
$response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], (string) $journal['foreign_amount']);
|
||||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
|
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ class PeriodController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -100,7 +100,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $journal['currency_code'],
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount']));
|
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount']));
|
||||||
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,8 +167,8 @@ class TagController extends Controller
|
|||||||
'currency_code' => $journal['foreign_currency_code'],
|
'currency_code' => $journal['foreign_currency_code'],
|
||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd(
|
$response[$foreignKey]['difference'] = bcadd(
|
||||||
$response[$foreignKey]['difference'],
|
(string) $response[$foreignKey]['difference'],
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
(string) app('steam')->positive($journal['foreign_amount'])
|
||||||
);
|
);
|
||||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
|
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ class PeriodController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -99,7 +99,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $currencyCode,
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ class TagController extends Controller
|
|||||||
'currency_id' => (string) $currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $journal['currency_code'],
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount']));
|
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount']));
|
||||||
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
$response[$key]['difference_float'] = (float) $response[$key]['difference'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +166,8 @@ class TagController extends Controller
|
|||||||
'currency_code' => $journal['foreign_currency_code'],
|
'currency_code' => $journal['foreign_currency_code'],
|
||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd(
|
$response[$foreignKey]['difference'] = bcadd(
|
||||||
$response[$foreignKey]['difference'],
|
(string) $response[$foreignKey]['difference'],
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
(string) app('steam')->positive($journal['foreign_amount'])
|
||||||
);
|
);
|
||||||
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
|
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
|
||||||
}
|
}
|
||||||
|
@@ -97,7 +97,6 @@ class ShowController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
@@ -133,7 +132,6 @@ class ShowController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -76,7 +76,6 @@ class StoreController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -80,7 +80,6 @@ class UpdateController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$account = $enrichment->enrichSingle($account);
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ use FireflyIII\Enums\UserRoleEnum;
|
|||||||
use FireflyIII\Exceptions\ValidationException;
|
use FireflyIII\Exceptions\ValidationException;
|
||||||
use FireflyIII\Models\CurrencyExchangeRate;
|
use FireflyIII\Models\CurrencyExchangeRate;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
@@ -39,10 +39,8 @@ class DestroyController extends Controller
|
|||||||
{
|
{
|
||||||
use ValidatesUserGroupTrait;
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::OWNER];
|
|
||||||
|
|
||||||
public const string RESOURCE_KEY = 'exchange-rates';
|
public const string RESOURCE_KEY = 'exchange-rates';
|
||||||
|
protected array $acceptedRoles = [UserRoleEnum::OWNER];
|
||||||
private ExchangeRateRepositoryInterface $repository;
|
private ExchangeRateRepositoryInterface $repository;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
|
@@ -25,9 +25,9 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
|
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
|
||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
use FireflyIII\Transformers\ExchangeRateTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -27,9 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Models\CurrencyExchangeRate;
|
use FireflyIII\Models\CurrencyExchangeRate;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
use FireflyIII\Transformers\ExchangeRateTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -26,9 +26,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreRequest;
|
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreRequest;
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
use FireflyIII\Transformers\ExchangeRateTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
class StoreController extends Controller
|
class StoreController extends Controller
|
||||||
|
@@ -27,9 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
|
|||||||
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\UpdateRequest;
|
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\UpdateRequest;
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Models\CurrencyExchangeRate;
|
use FireflyIII\Models\CurrencyExchangeRate;
|
||||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
use FireflyIII\Transformers\ExchangeRateTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
class UpdateController extends Controller
|
class UpdateController extends Controller
|
||||||
|
@@ -84,7 +84,6 @@ class ListController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
|
@@ -50,9 +50,8 @@ class StoreController extends Controller
|
|||||||
{
|
{
|
||||||
use TransactionFilter;
|
use TransactionFilter;
|
||||||
|
|
||||||
private TransactionGroupRepositoryInterface $groupRepository;
|
|
||||||
|
|
||||||
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
|
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||||
|
private TransactionGroupRepositoryInterface $groupRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TransactionController constructor.
|
* TransactionController constructor.
|
||||||
|
@@ -27,8 +27,8 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
|
|||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@@ -107,7 +107,6 @@ class ListController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
@@ -178,9 +177,7 @@ class ListController extends Controller
|
|||||||
|
|
||||||
// filter and paginate list:
|
// filter and paginate list:
|
||||||
$collection = $unfiltered->filter(
|
$collection = $unfiltered->filter(
|
||||||
static function (Bill $bill) use ($currency) {
|
static fn (Bill $bill) => $bill->transaction_currency_id === $currency->id
|
||||||
return $bill->transaction_currency_id === $currency->id;
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
|
|||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
|
|||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\StoreRequest;
|
use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\StoreRequest;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
|
@@ -28,7 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\UpdateRequest;
|
use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\UpdateRequest;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
|
@@ -88,7 +88,6 @@ class AccountController extends Controller
|
|||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
$enrichment = new AccountEnrichment();
|
$enrichment = new AccountEnrichment();
|
||||||
$enrichment->setUser($admin);
|
$enrichment->setUser($admin);
|
||||||
$enrichment->setConvertToNative($this->convertToNative);
|
|
||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$accounts = $enrichment->enrich($accounts);
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
|
@@ -37,10 +37,13 @@ use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
|||||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
|
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,16 +100,15 @@ class BasicController extends Controller
|
|||||||
$start = $dates['start'];
|
$start = $dates['start'];
|
||||||
$end = $dates['end'];
|
$end = $dates['end'];
|
||||||
$code = $request->get('currency_code');
|
$code = $request->get('currency_code');
|
||||||
|
|
||||||
// balance information:
|
// balance information:
|
||||||
$balanceData = $this->getBalanceInformation($start, $end);
|
$balanceData = $this->getBalanceInformation($start, $end);
|
||||||
$billData = $this->getBillInformation($start, $end);
|
$billData = $this->getSubscriptionInformation($start, $end);
|
||||||
$spentData = $this->getLeftToSpendInfo($start, $end);
|
$spentData = $this->getLeftToSpendInfo($start, $end);
|
||||||
$netWorthData = $this->getNetWorthInfo($end);
|
$netWorthData = $this->getNetWorthInfo($end);
|
||||||
// $balanceData = [];
|
// $balanceData = [];
|
||||||
// $billData = [];
|
// $billData = [];
|
||||||
// $spentData = [];
|
// $spentData = [];
|
||||||
// $netWorthData = [];
|
// $netWorthData = [];
|
||||||
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
|
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
|
||||||
|
|
||||||
// give new keys
|
// give new keys
|
||||||
@@ -122,6 +124,7 @@ class BasicController extends Controller
|
|||||||
|
|
||||||
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
|
Log::debug('getBalanceInformation');
|
||||||
// some config settings
|
// some config settings
|
||||||
$convertToNative = Amount::convertToNative();
|
$convertToNative = Amount::convertToNative();
|
||||||
$default = Amount::getNativeCurrency();
|
$default = Amount::getNativeCurrency();
|
||||||
@@ -130,47 +133,110 @@ class BasicController extends Controller
|
|||||||
$expenses = [];
|
$expenses = [];
|
||||||
$sums = [];
|
$sums = [];
|
||||||
$return = [];
|
$return = [];
|
||||||
|
$currencies = [
|
||||||
|
$default->id => $default,
|
||||||
|
];
|
||||||
|
|
||||||
// collect income of user using the new group collector.
|
// collect income of user using the new group collector.
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
$summarizer = new TransactionSummarizer();
|
||||||
|
$set = $collector->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value])->getExtractedJournals();
|
||||||
|
$incomes = $summarizer->groupByCurrencyId($set, 'positive', false);
|
||||||
|
|
||||||
$set = $collector->getExtractedJournals();
|
|
||||||
|
|
||||||
/** @var array $journal */
|
|
||||||
foreach ($set as $journal) {
|
|
||||||
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
|
||||||
$amount = Amount::getAmountFromJournal($journal);
|
|
||||||
$incomes[$currencyId] ??= '0';
|
|
||||||
$incomes[$currencyId] = bcadd(
|
|
||||||
$incomes[$currencyId],
|
|
||||||
bcmul($amount, '-1')
|
|
||||||
);
|
|
||||||
$sums[$currencyId] ??= '0';
|
|
||||||
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($amount, '-1'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// collect expenses of user.
|
||||||
// collect expenses of user using the new group collector.
|
// collect expenses of user using the new group collector.
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
$set = $collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->getExtractedJournals();
|
||||||
$set = $collector->getExtractedJournals();
|
$expenses = $summarizer->groupByCurrencyId($set, 'negative', false);
|
||||||
|
|
||||||
/** @var array $journal */
|
// if convert to native, do so right now.
|
||||||
foreach ($set as $journal) {
|
if ($convertToNative) {
|
||||||
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
$newExpenses = [
|
||||||
$amount = Amount::getAmountFromJournal($journal);
|
$default->id => [
|
||||||
$expenses[$currencyId] ??= '0';
|
'currency_id' => $default->id,
|
||||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
'currency_code' => $default->code,
|
||||||
$sums[$currencyId] ??= '0';
|
'currency_symbol' => $default->symbol,
|
||||||
$sums[$currencyId] = bcadd($sums[$currencyId], $amount);
|
'currency_decimal_places' => $default->decimal_places,
|
||||||
|
'sum' => '0',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$newIncomes = [
|
||||||
|
$default->id => [
|
||||||
|
'currency_id' => $default->id,
|
||||||
|
'currency_code' => $default->code,
|
||||||
|
'currency_symbol' => $default->symbol,
|
||||||
|
'currency_decimal_places' => $default->decimal_places,
|
||||||
|
'sum' => '0',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$sums = [
|
||||||
|
$default->id => [
|
||||||
|
'currency_id' => $default->id,
|
||||||
|
'currency_code' => $default->code,
|
||||||
|
'currency_symbol' => $default->symbol,
|
||||||
|
'currency_decimal_places' => $default->decimal_places,
|
||||||
|
'sum' => '0',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$converter = new ExchangeRateConverter();
|
||||||
|
// loop over income and expenses
|
||||||
|
foreach ([$expenses, $incomes] as $index => $array) {
|
||||||
|
|
||||||
|
// loop over either one.
|
||||||
|
foreach ($array as $entry) {
|
||||||
|
|
||||||
|
// if it is the native currency already.
|
||||||
|
if ($entry['currency_id'] === $default->id) {
|
||||||
|
$sums[$default->id]['sum'] = bcadd((string) $entry['sum'], $sums[$default->id]['sum']);
|
||||||
|
|
||||||
|
// don't forget to add it to newExpenses and newIncome
|
||||||
|
if (0 === $index) {
|
||||||
|
$newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], (string) $entry['sum']);
|
||||||
|
}
|
||||||
|
if (1 === $index) {
|
||||||
|
$newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], (string) $entry['sum']);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencies[$entry['currency_id']] ??= $this->currencyRepos->find($entry['currency_id']);
|
||||||
|
$convertedSum = $converter->convert($currencies[$entry['currency_id']], $default, $start, $entry['sum']);
|
||||||
|
$sums[$default->id]['sum'] = bcadd($sums[$default->id]['sum'], $convertedSum);
|
||||||
|
if (0 === $index) {
|
||||||
|
$newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], $convertedSum);
|
||||||
|
}
|
||||||
|
if (1 === $index) {
|
||||||
|
$newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], $convertedSum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$incomes = $newIncomes;
|
||||||
|
$expenses = $newExpenses;
|
||||||
|
}
|
||||||
|
if (!$convertToNative) {
|
||||||
|
foreach ([$expenses, $incomes] as $array) {
|
||||||
|
foreach ($array as $entry) {
|
||||||
|
$currencyId = $entry['currency_id'];
|
||||||
|
$sums[$currencyId] ??= [
|
||||||
|
'currency_id' => $entry['currency_id'],
|
||||||
|
'currency_code' => $entry['currency_code'],
|
||||||
|
'currency_symbol' => $entry['currency_symbol'],
|
||||||
|
'currency_decimal_places' => $entry['currency_decimal_places'],
|
||||||
|
'sum' => '0',
|
||||||
|
];
|
||||||
|
$sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], (string) $entry['sum']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// format amounts:
|
// format amounts:
|
||||||
$keys = array_keys($sums);
|
$keys = array_keys($sums);
|
||||||
foreach ($keys as $currencyId) {
|
foreach ($keys as $currencyId) {
|
||||||
$currency = $this->currencyRepos->find($currencyId);
|
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -178,37 +244,78 @@ class BasicController extends Controller
|
|||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('balance-in-%s', $currency->code),
|
'key' => sprintf('balance-in-%s', $currency->code),
|
||||||
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
|
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
|
||||||
'monetary_value' => $sums[$currencyId] ?? '0',
|
'monetary_value' => $sums[$currencyId]['sum'] ?? '0',
|
||||||
'currency_id' => (string) $currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $currency->symbol,
|
||||||
'currency_decimal_places' => $currency->decimal_places,
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false),
|
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId]['sum'] ?? '0', false),
|
||||||
'local_icon' => 'balance-scale',
|
'local_icon' => 'balance-scale',
|
||||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false).
|
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId]['sum'] ?? '0', false)
|
||||||
' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
.' + '.app('amount')->formatAnything($currency, $incomes[$currencyId]['sum'] ?? '0', false),
|
||||||
];
|
];
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('spent-in-%s', $currency->code),
|
'key' => sprintf('spent-in-%s', $currency->code),
|
||||||
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
|
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
|
||||||
'monetary_value' => $expenses[$currencyId] ?? '0',
|
'monetary_value' => $expenses[$currencyId]['sum'] ?? '0',
|
||||||
'currency_id' => (string) $currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $currency->symbol,
|
||||||
'currency_decimal_places' => $currency->decimal_places,
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
'value_parsed' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false),
|
'value_parsed' => app('amount')->formatAnything($currency, $expenses[$currencyId]['sum'] ?? '0', false),
|
||||||
'local_icon' => 'balance-scale',
|
'local_icon' => 'balance-scale',
|
||||||
'sub_title' => '',
|
'sub_title' => '',
|
||||||
];
|
];
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('earned-in-%s', $currency->code),
|
'key' => sprintf('earned-in-%s', $currency->code),
|
||||||
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
|
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
|
||||||
'monetary_value' => $incomes[$currencyId] ?? '0',
|
'monetary_value' => $incomes[$currencyId]['sum'] ?? '0',
|
||||||
'currency_id' => (string) $currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $currency->symbol,
|
||||||
'currency_decimal_places' => $currency->decimal_places,
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
'value_parsed' => app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
'value_parsed' => app('amount')->formatAnything($currency, $incomes[$currencyId]['sum'] ?? '0', false),
|
||||||
|
'local_icon' => 'balance-scale',
|
||||||
|
'sub_title' => '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (0 === count($return)) {
|
||||||
|
$currency = $this->nativeCurrency;
|
||||||
|
// create objects for big array.
|
||||||
|
$return[] = [
|
||||||
|
'key' => sprintf('balance-in-%s', $currency->code),
|
||||||
|
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
|
||||||
|
'monetary_value' => '0',
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
'value_parsed' => app('amount')->formatAnything($currency, '0', false),
|
||||||
|
'local_icon' => 'balance-scale',
|
||||||
|
'sub_title' => app('amount')->formatAnything($currency, '0', false)
|
||||||
|
.' + '.app('amount')->formatAnything($currency, '0', false),
|
||||||
|
];
|
||||||
|
$return[] = [
|
||||||
|
'key' => sprintf('spent-in-%s', $currency->code),
|
||||||
|
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
|
||||||
|
'monetary_value' => '0',
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
'value_parsed' => app('amount')->formatAnything($currency, '0', false),
|
||||||
|
'local_icon' => 'balance-scale',
|
||||||
|
'sub_title' => '',
|
||||||
|
];
|
||||||
|
$return[] = [
|
||||||
|
'key' => sprintf('earned-in-%s', $currency->code),
|
||||||
|
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
|
||||||
|
'monetary_value' => '0',
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
'value_parsed' => app('amount')->formatAnything($currency, '0', false),
|
||||||
'local_icon' => 'balance-scale',
|
'local_icon' => 'balance-scale',
|
||||||
'sub_title' => '',
|
'sub_title' => '',
|
||||||
];
|
];
|
||||||
@@ -217,15 +324,72 @@ class BasicController extends Controller
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getBillInformation(Carbon $start, Carbon $end): array
|
private function getSubscriptionInformation(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
app('log')->debug(sprintf('Now in getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
Log::debug(sprintf('Now in getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
||||||
/*
|
/*
|
||||||
* Since both this method and the chart use the exact same data, we can suffice
|
* 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.
|
* with calling the one method in the bill repository that will get this amount.
|
||||||
*/
|
*/
|
||||||
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
|
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
|
||||||
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
|
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
|
||||||
|
$currencies = [
|
||||||
|
$this->nativeCurrency->id => $this->nativeCurrency,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->convertToNative) {
|
||||||
|
$converter = new ExchangeRateConverter();
|
||||||
|
$newPaidAmount = [[
|
||||||
|
'id' => $this->nativeCurrency->id,
|
||||||
|
'name' => $this->nativeCurrency->name,
|
||||||
|
'symbol' => $this->nativeCurrency->symbol,
|
||||||
|
'code' => $this->nativeCurrency->code,
|
||||||
|
'decimal_places' => $this->nativeCurrency->decimal_places,
|
||||||
|
'sum' => '0',
|
||||||
|
]];
|
||||||
|
|
||||||
|
$newUnpaidAmount = [[
|
||||||
|
'id' => $this->nativeCurrency->id,
|
||||||
|
'name' => $this->nativeCurrency->name,
|
||||||
|
'symbol' => $this->nativeCurrency->symbol,
|
||||||
|
'code' => $this->nativeCurrency->code,
|
||||||
|
'decimal_places' => $this->nativeCurrency->decimal_places,
|
||||||
|
'sum' => '0',
|
||||||
|
]];
|
||||||
|
foreach ([$paidAmount, $unpaidAmount] as $index => $array) {
|
||||||
|
foreach ($array as $item) {
|
||||||
|
$currencyId = (int) $item['id'];
|
||||||
|
if (0 === $index) {
|
||||||
|
// paid amount
|
||||||
|
if ($currencyId === $this->nativeCurrency->id) {
|
||||||
|
$newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], (string) $item['sum']);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||||
|
$convertedAmount = $converter->convert($currencies[$currencyId], $this->nativeCurrency, $start, $item['sum']);
|
||||||
|
$newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], $convertedAmount);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// unpaid amount
|
||||||
|
if ($currencyId === $this->nativeCurrency->id) {
|
||||||
|
$newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], (string) $item['sum']);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||||
|
$convertedAmount = $converter->convert($currencies[$currencyId], $this->nativeCurrency, $start, $item['sum']);
|
||||||
|
$newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], $convertedAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$paidAmount = $newPaidAmount;
|
||||||
|
$unpaidAmount = $newUnpaidAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// var_dump($paidAmount);
|
||||||
|
// var_dump($unpaidAmount);
|
||||||
|
// exit;
|
||||||
|
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
@@ -233,7 +397,7 @@ class BasicController extends Controller
|
|||||||
* @var array $info
|
* @var array $info
|
||||||
*/
|
*/
|
||||||
foreach ($paidAmount as $info) {
|
foreach ($paidAmount as $info) {
|
||||||
$amount = bcmul($info['sum'], '-1');
|
$amount = bcmul((string) $info['sum'], '-1');
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('bills-paid-in-%s', $info['code']),
|
'key' => sprintf('bills-paid-in-%s', $info['code']),
|
||||||
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
|
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
|
||||||
@@ -252,7 +416,7 @@ class BasicController extends Controller
|
|||||||
* @var array $info
|
* @var array $info
|
||||||
*/
|
*/
|
||||||
foreach ($unpaidAmount as $info) {
|
foreach ($unpaidAmount as $info) {
|
||||||
$amount = bcmul($info['sum'], '-1');
|
$amount = bcmul((string) $info['sum'], '-1');
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('bills-unpaid-in-%s', $info['code']),
|
'key' => sprintf('bills-unpaid-in-%s', $info['code']),
|
||||||
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
|
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
|
||||||
@@ -266,7 +430,38 @@ class BasicController extends Controller
|
|||||||
'sub_title' => '',
|
'sub_title' => '',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
app('log')->debug(sprintf('Done with getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
Log::debug(sprintf('Done with getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
||||||
|
|
||||||
|
if (0 === count($return)) {
|
||||||
|
$currency = $this->nativeCurrency;
|
||||||
|
unset($info, $amount);
|
||||||
|
|
||||||
|
$return[] = [
|
||||||
|
'key' => sprintf('bills-paid-in-%s', $currency->code),
|
||||||
|
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $currency->symbol]),
|
||||||
|
'monetary_value' => '0',
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
'value_parsed' => app('amount')->formatFlat($currency->symbol, $currency->decimal_places, '0', false),
|
||||||
|
'local_icon' => 'check',
|
||||||
|
'sub_title' => '',
|
||||||
|
];
|
||||||
|
$return[] = [
|
||||||
|
'key' => sprintf('bills-unpaid-in-%s', $currency->code),
|
||||||
|
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $currency->symbol]),
|
||||||
|
'monetary_value' => '0',
|
||||||
|
'currency_id' => (string) $currency->id,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
'value_parsed' => app('amount')->formatFlat($currency->symbol, $currency->decimal_places, '0', false),
|
||||||
|
'local_icon' => 'calendar-o',
|
||||||
|
'sub_title' => '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@@ -276,30 +471,60 @@ class BasicController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
|
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
|
||||||
$return = [];
|
|
||||||
$today = today(config('app.timezone'));
|
|
||||||
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
|
||||||
$budgets = $this->budgetRepository->getActiveBudgets();
|
|
||||||
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
|
||||||
$days = (int) $today->diffInDays($end, true) + 1;
|
|
||||||
|
|
||||||
|
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||||
|
$return = [];
|
||||||
|
$today = today(config('app.timezone'));
|
||||||
|
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
||||||
|
$budgets = $this->budgetRepository->getActiveBudgets();
|
||||||
|
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
||||||
|
$days = (int) $today->diffInDays($end, true) + 1;
|
||||||
|
$currencies = [];
|
||||||
|
|
||||||
|
// first, create an entry for each entry in the "available" array.
|
||||||
|
/** @var array $availableBudget */
|
||||||
|
foreach ($available as $currencyId => $availableBudget) {
|
||||||
|
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||||
|
$return[$currencyId] = [
|
||||||
|
'key' => sprintf('left-to-spend-in-%s', $currencies[$currencyId]->code),
|
||||||
|
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currencies[$currencyId]->symbol]),
|
||||||
|
'no_available_budgets' => false,
|
||||||
|
'monetary_value' => $availableBudget,
|
||||||
|
'currency_id' => (string) $currencies[$currencyId]->id,
|
||||||
|
'currency_code' => $currencies[$currencyId]->code,
|
||||||
|
'currency_symbol' => $currencies[$currencyId]->symbol,
|
||||||
|
'currency_decimal_places' => $currencies[$currencyId]->decimal_places,
|
||||||
|
'value_parsed' => app('amount')->formatFlat($currencies[$currencyId]->symbol, $currencies[$currencyId]->decimal_places, $availableBudget, false),
|
||||||
|
'local_icon' => 'money',
|
||||||
|
'sub_title' => app('amount')->formatFlat(
|
||||||
|
$currencies[$currencyId]->symbol,
|
||||||
|
$currencies[$currencyId]->decimal_places,
|
||||||
|
$availableBudget,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
foreach ($spent as $row) {
|
foreach ($spent as $row) {
|
||||||
// either an amount was budgeted or 0 is available.
|
// either an amount was budgeted or 0 is available.
|
||||||
$currencyId = $row['currency_id'];
|
$currencyId = (int) $row['currency_id'];
|
||||||
$amount = (string) ($available[$currencyId] ?? '0');
|
$amount = (string) ($available[$currencyId] ?? '0');
|
||||||
$spentInCurrency = $row['sum'];
|
if (0 === bccomp($amount, '0')) {
|
||||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
// #9858 skip over currencies with no available budget.
|
||||||
$perDay = '0';
|
continue;
|
||||||
|
}
|
||||||
|
$spentInCurrency = $row['sum'];
|
||||||
|
$leftToSpend = bcadd($amount, (string) $spentInCurrency);
|
||||||
|
$perDay = '0';
|
||||||
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
||||||
$perDay = bcdiv($leftToSpend, (string) $days);
|
$perDay = bcdiv($leftToSpend, (string) $days);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
|
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
|
||||||
|
|
||||||
$return[] = [
|
$return[$currencyId] = [
|
||||||
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
||||||
|
'no_available_budgets' => false,
|
||||||
'monetary_value' => $leftToSpend,
|
'monetary_value' => $leftToSpend,
|
||||||
'currency_id' => (string) $row['currency_id'],
|
'currency_id' => (string) $row['currency_id'],
|
||||||
'currency_code' => $row['currency_code'],
|
'currency_code' => $row['currency_code'],
|
||||||
@@ -315,8 +540,66 @@ class BasicController extends Controller
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
unset($leftToSpend);
|
||||||
|
if (0 === count($return)) {
|
||||||
|
// a small trick to get every expense in this period, regardless of budget.
|
||||||
|
$spent = $this->opsRepository->sumExpenses($start, $end, null, new Collection());
|
||||||
|
foreach ($spent as $row) {
|
||||||
|
// either an amount was budgeted or 0 is available.
|
||||||
|
$currencyId = (int) $row['currency_id'];
|
||||||
|
$spentInCurrency = $row['sum'];
|
||||||
|
$perDay = '0';
|
||||||
|
if (0 !== $days && -1 === bccomp((string) $spentInCurrency, '0')) {
|
||||||
|
$perDay = bcdiv((string) $spentInCurrency, (string) $days);
|
||||||
|
}
|
||||||
|
|
||||||
return $return;
|
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
|
||||||
|
|
||||||
|
$return[$currencyId] = [
|
||||||
|
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||||
|
'title' => trans('firefly.spent'),
|
||||||
|
'no_available_budgets' => true,
|
||||||
|
'monetary_value' => $spentInCurrency,
|
||||||
|
'currency_id' => (string) $row['currency_id'],
|
||||||
|
'currency_code' => $row['currency_code'],
|
||||||
|
'currency_symbol' => $row['currency_symbol'],
|
||||||
|
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||||
|
'value_parsed' => app('amount')->formatFlat($row['currency_symbol'], $row['currency_decimal_places'], $spentInCurrency, false),
|
||||||
|
'local_icon' => 'money',
|
||||||
|
'sub_title' => app('amount')->formatFlat(
|
||||||
|
$row['currency_symbol'],
|
||||||
|
$row['currency_decimal_places'],
|
||||||
|
$perDay,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// $amount = '0';
|
||||||
|
// // $days
|
||||||
|
// // fill in by money spent, just count it.
|
||||||
|
// $currency = $this->nativeCurrency;
|
||||||
|
// $return[$currency->id] = [
|
||||||
|
// 'key' => sprintf('left-to-spend-in-%s', $currency->code),
|
||||||
|
// 'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currency->symbol]),
|
||||||
|
// 'monetary_value' => '0',
|
||||||
|
// 'no_available_budgets' => true,
|
||||||
|
// 'currency_id' => (string) $currency->id,
|
||||||
|
// 'currency_code' => $currency->code,
|
||||||
|
// 'currency_symbol' => $currency->symbol,
|
||||||
|
// 'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
// 'value_parsed' => app('amount')->formatFlat($currency->symbol, $currency->decimal_places, '0', false),
|
||||||
|
// 'local_icon' => 'money',
|
||||||
|
// 'sub_title' => app('amount')->formatFlat(
|
||||||
|
// $currency->symbol,
|
||||||
|
// $currency->decimal_places,
|
||||||
|
// '0',
|
||||||
|
// false
|
||||||
|
// ),
|
||||||
|
// ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getNetWorthInfo(Carbon $end): array
|
private function getNetWorthInfo(Carbon $end): array
|
||||||
@@ -348,7 +631,7 @@ class BasicController extends Controller
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$amount = $data['balance'];
|
$amount = $data['balance'];
|
||||||
if (0 === bccomp($amount, '0')) {
|
if (0 === bccomp((string) $amount, '0')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// return stuff
|
// return stuff
|
||||||
|
91
app/Api/V1/Requests/Chart/ChartRequest.php
Normal file
91
app/Api/V1/Requests/Chart/ChartRequest.php
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DashboardChartRequest.php
|
||||||
|
* Copyright (c) 2023 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Requests\Chart;
|
||||||
|
|
||||||
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ChartRequest
|
||||||
|
*/
|
||||||
|
class ChartRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use ChecksLogin;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
|
|
||||||
|
public function getParameters(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'start' => $this->convertDateTime('start')?->startOfDay(),
|
||||||
|
'end' => $this->convertDateTime('end')?->endOfDay(),
|
||||||
|
'preselected' => $this->convertString('preselected', 'empty'),
|
||||||
|
'period' => $this->convertString('period', '1M'),
|
||||||
|
'accounts' => $this->arrayFromValue($this->get('accounts')),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rules that the incoming request must be matched against.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before_or_equal:end',
|
||||||
|
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after_or_equal:start',
|
||||||
|
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
|
||||||
|
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
||||||
|
'accounts.*' => 'exists:accounts,id',
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withValidator(Validator $validator): void
|
||||||
|
{
|
||||||
|
$validator->after(
|
||||||
|
static function (Validator $validator): void {
|
||||||
|
// validate transaction query data.
|
||||||
|
$data = $validator->getData();
|
||||||
|
if (!array_key_exists('accounts', $data)) {
|
||||||
|
// $validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!is_array($data['accounts'])) {
|
||||||
|
$validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -74,7 +74,7 @@ class MoveTransactionsRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,6 +33,8 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
|
|
||||||
|
use function Safe\json_decode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TransactionRequest
|
* Class TransactionRequest
|
||||||
*/
|
*/
|
||||||
@@ -74,7 +76,7 @@ class TransactionRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -49,9 +49,9 @@ class DestroyRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'.
|
$valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'
|
||||||
',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'.
|
.',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'
|
||||||
',not_assets_liabilities';
|
.',not_assets_liabilities';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'objects' => sprintf('required|max:255|min:1|string|in:%s', $valid),
|
'objects' => sprintf('required|max:255|min:1|string|in:%s', $valid),
|
||||||
|
62
app/Api/V1/Requests/Generic/DateRequest.php
Normal file
62
app/Api/V1/Requests/Generic/DateRequest.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DateRequest.php
|
||||||
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Requests\Generic;
|
||||||
|
|
||||||
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request class for end points that require date parameters.
|
||||||
|
*
|
||||||
|
* Class DateRequest
|
||||||
|
*/
|
||||||
|
class DateRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use ChecksLogin;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all data from the request.
|
||||||
|
*/
|
||||||
|
public function getAll(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'start' => $this->getCarbonDate('start')->startOfDay(),
|
||||||
|
'end' => $this->getCarbonDate('end')->endOfDay(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rules that the incoming request must be matched against.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||||
|
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
59
app/Api/V1/Requests/Generic/SingleDateRequest.php
Normal file
59
app/Api/V1/Requests/Generic/SingleDateRequest.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DateRequest.php
|
||||||
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V1\Requests\Generic;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request class for end points that require a date parameter.
|
||||||
|
*
|
||||||
|
* Class SingleDateRequest
|
||||||
|
*/
|
||||||
|
class SingleDateRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use ChecksLogin;
|
||||||
|
use ConvertsDataTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all data from the request.
|
||||||
|
*/
|
||||||
|
public function getDate(): Carbon
|
||||||
|
{
|
||||||
|
return $this->getCarbonDate('date');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rules that the incoming request must be matched against.
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@@ -144,7 +144,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -58,9 +58,7 @@ class StoreRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$models = config('firefly.valid_attachment_models');
|
$models = config('firefly.valid_attachment_models');
|
||||||
$models = array_map(
|
$models = array_map(
|
||||||
static function (string $className) {
|
static fn (string $className) => str_replace('FireflyIII\Models\\', '', $className),
|
||||||
return str_replace('FireflyIII\Models\\', '', $className);
|
|
||||||
},
|
|
||||||
$models
|
$models
|
||||||
);
|
);
|
||||||
$models = implode(',', $models);
|
$models = implode(',', $models);
|
||||||
|
@@ -60,9 +60,7 @@ class UpdateRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$models = config('firefly.valid_attachment_models');
|
$models = config('firefly.valid_attachment_models');
|
||||||
$models = array_map(
|
$models = array_map(
|
||||||
static function (string $className) {
|
static fn (string $className) => str_replace('FireflyIII\Models\\', '', $className),
|
||||||
return str_replace('FireflyIII\Models\\', '', $className);
|
|
||||||
},
|
|
||||||
$models
|
$models
|
||||||
);
|
);
|
||||||
$models = implode(',', $models);
|
$models = implode(',', $models);
|
||||||
|
@@ -90,7 +90,7 @@ class Request extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -129,7 +129,7 @@ class StoreRequest extends FormRequest
|
|||||||
$failed = false;
|
$failed = false;
|
||||||
}
|
}
|
||||||
if ($failed) {
|
if ($failed) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -110,7 +110,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,7 @@ class StoreRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -106,7 +106,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -96,7 +96,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,7 @@ class DestroyRequest extends FormRequest
|
|||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,16 +40,16 @@ class StoreRequest extends FormRequest
|
|||||||
return $this->getCarbonDate('date');
|
return $this->getCarbonDate('date');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRate(): string
|
|
||||||
{
|
|
||||||
return (string) $this->get('rate');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFromCurrency(): TransactionCurrency
|
public function getFromCurrency(): TransactionCurrency
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('code', $this->get('from'))->first();
|
return TransactionCurrency::where('code', $this->get('from'))->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRate(): string
|
||||||
|
{
|
||||||
|
return (string) $this->get('rate');
|
||||||
|
}
|
||||||
|
|
||||||
public function getToCurrency(): TransactionCurrency
|
public function getToCurrency(): TransactionCurrency
|
||||||
{
|
{
|
||||||
return TransactionCurrency::where('code', $this->get('to'))->first();
|
return TransactionCurrency::where('code', $this->get('to'))->first();
|
||||||
|
@@ -50,8 +50,8 @@ class UpdateRequest extends FormRequest
|
|||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||||
'rate' => 'required|numeric|gt:0',
|
'rate' => 'required|numeric|gt:0',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -126,7 +126,7 @@ class StoreRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -82,7 +82,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'accounts' => 'required',
|
'accounts' => 'required',
|
||||||
'accounts.*' => 'array|required',
|
'accounts.*' => 'array|required',
|
||||||
'accounts.*.account_id' => ['required', 'numeric', 'belongsToUser:accounts,id'],
|
'accounts.*.account_id' => ['required', 'numeric', 'belongsToUser:accounts,id'],
|
||||||
'accounts.*.current_amount' => ['numeric', new IsValidZeroOrMoreAmount()],
|
'accounts.*.current_amount' => ['numeric', 'nullable', new IsValidZeroOrMoreAmount(true)],
|
||||||
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
||||||
'object_group_title' => ['min:1', 'max:255'],
|
'object_group_title' => ['min:1', 'max:255'],
|
||||||
'transaction_currency_id' => 'exists:transaction_currencies,id|nullable',
|
'transaction_currency_id' => 'exists:transaction_currencies,id|nullable',
|
||||||
|
@@ -193,7 +193,7 @@ class StoreRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -208,7 +208,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -148,7 +148,7 @@ class StoreRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -168,7 +168,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -83,87 +83,87 @@ class StoreRequest extends FormRequest
|
|||||||
foreach ($this->get('transactions') as $transaction) {
|
foreach ($this->get('transactions') as $transaction) {
|
||||||
$object = new NullArrayObject($transaction);
|
$object = new NullArrayObject($transaction);
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'type' => $this->clearString($object['type']),
|
'type' => $this->clearString($object['type']),
|
||||||
'date' => $this->dateFromValue($object['date']),
|
'date' => $this->dateFromValue($object['date']),
|
||||||
'order' => $this->integerFromValue((string) $object['order']),
|
'order' => $this->integerFromValue((string) $object['order']),
|
||||||
|
|
||||||
'currency_id' => $this->integerFromValue((string) $object['currency_id']),
|
'currency_id' => $this->integerFromValue((string) $object['currency_id']),
|
||||||
'currency_code' => $this->clearString((string) $object['currency_code']),
|
'currency_code' => $this->clearString((string) $object['currency_code']),
|
||||||
|
|
||||||
// location
|
// location
|
||||||
'latitude' => $this->floatFromValue((string) $object['latitude']),
|
'latitude' => $this->floatFromValue((string) $object['latitude']),
|
||||||
'longitude' => $this->floatFromValue((string) $object['longitude']),
|
'longitude' => $this->floatFromValue((string) $object['longitude']),
|
||||||
'zoom_level' => $this->integerFromValue((string) $object['zoom_level']),
|
'zoom_level' => $this->integerFromValue((string) $object['zoom_level']),
|
||||||
|
|
||||||
// foreign currency info:
|
// foreign currency info:
|
||||||
'foreign_currency_id' => $this->integerFromValue((string) $object['foreign_currency_id']),
|
'foreign_currency_id' => $this->integerFromValue((string) $object['foreign_currency_id']),
|
||||||
'foreign_currency_code' => $this->clearString((string) $object['foreign_currency_code']),
|
'foreign_currency_code' => $this->clearString((string) $object['foreign_currency_code']),
|
||||||
|
|
||||||
// amount and foreign amount. Cannot be 0.
|
// amount and foreign amount. Cannot be 0.
|
||||||
'amount' => $this->clearString((string) $object['amount']),
|
'amount' => $this->clearString((string) $object['amount']),
|
||||||
'foreign_amount' => $this->clearString((string) $object['foreign_amount']),
|
'foreign_amount' => $this->clearString((string) $object['foreign_amount']),
|
||||||
|
|
||||||
// description.
|
// description.
|
||||||
'description' => $this->clearString($object['description']),
|
'description' => $this->clearString($object['description']),
|
||||||
|
|
||||||
// source of transaction. If everything is null, assume cash account.
|
// source of transaction. If everything is null, assume cash account.
|
||||||
'source_id' => $this->integerFromValue((string) $object['source_id']),
|
'source_id' => $this->integerFromValue((string) $object['source_id']),
|
||||||
'source_name' => $this->clearString((string) $object['source_name']),
|
'source_name' => $this->clearString((string) $object['source_name']),
|
||||||
'source_iban' => $this->clearIban((string) $object['source_iban']),
|
'source_iban' => $this->clearIban((string) $object['source_iban']),
|
||||||
'source_number' => $this->clearString((string) $object['source_number']),
|
'source_number' => $this->clearString((string) $object['source_number']),
|
||||||
'source_bic' => $this->clearString((string) $object['source_bic']),
|
'source_bic' => $this->clearString((string) $object['source_bic']),
|
||||||
|
|
||||||
// destination of transaction. If everything is null, assume cash account.
|
// destination of transaction. If everything is null, assume cash account.
|
||||||
'destination_id' => $this->integerFromValue((string) $object['destination_id']),
|
'destination_id' => $this->integerFromValue((string) $object['destination_id']),
|
||||||
'destination_name' => $this->clearString((string) $object['destination_name']),
|
'destination_name' => $this->clearString((string) $object['destination_name']),
|
||||||
'destination_iban' => $this->clearIban((string) $object['destination_iban']),
|
'destination_iban' => $this->clearIban((string) $object['destination_iban']),
|
||||||
'destination_number' => $this->clearString((string) $object['destination_number']),
|
'destination_number' => $this->clearString((string) $object['destination_number']),
|
||||||
'destination_bic' => $this->clearString((string) $object['destination_bic']),
|
'destination_bic' => $this->clearString((string) $object['destination_bic']),
|
||||||
|
|
||||||
// budget info
|
// budget info
|
||||||
'budget_id' => $this->integerFromValue((string) $object['budget_id']),
|
'budget_id' => $this->integerFromValue((string) $object['budget_id']),
|
||||||
'budget_name' => $this->clearString((string) $object['budget_name']),
|
'budget_name' => $this->clearString((string) $object['budget_name']),
|
||||||
|
|
||||||
// category info
|
// category info
|
||||||
'category_id' => $this->integerFromValue((string) $object['category_id']),
|
'category_id' => $this->integerFromValue((string) $object['category_id']),
|
||||||
'category_name' => $this->clearString((string) $object['category_name']),
|
'category_name' => $this->clearString((string) $object['category_name']),
|
||||||
|
|
||||||
// journal bill reference. Optional. Will only work for withdrawals
|
// journal bill reference. Optional. Will only work for withdrawals
|
||||||
'bill_id' => $this->integerFromValue((string) $object['bill_id']),
|
'bill_id' => $this->integerFromValue((string) $object['bill_id']),
|
||||||
'bill_name' => $this->clearString((string) $object['bill_name']),
|
'bill_name' => $this->clearString((string) $object['bill_name']),
|
||||||
|
|
||||||
// piggy bank reference. Optional. Will only work for transfers
|
// piggy bank reference. Optional. Will only work for transfers
|
||||||
'piggy_bank_id' => $this->integerFromValue((string) $object['piggy_bank_id']),
|
'piggy_bank_id' => $this->integerFromValue((string) $object['piggy_bank_id']),
|
||||||
'piggy_bank_name' => $this->clearString((string) $object['piggy_bank_name']),
|
'piggy_bank_name' => $this->clearString((string) $object['piggy_bank_name']),
|
||||||
|
|
||||||
// some other interesting properties
|
// some other interesting properties
|
||||||
'reconciled' => $this->convertBoolean((string) $object['reconciled']),
|
'reconciled' => $this->convertBoolean((string) $object['reconciled']),
|
||||||
'notes' => $this->clearStringKeepNewlines((string) $object['notes']),
|
'notes' => $this->clearStringKeepNewlines((string) $object['notes']),
|
||||||
'tags' => $this->arrayFromValue($object['tags']),
|
'tags' => $this->arrayFromValue($object['tags']),
|
||||||
|
|
||||||
// all custom fields:
|
// all custom fields:
|
||||||
'internal_reference' => $this->clearString((string) $object['internal_reference']),
|
'internal_reference' => $this->clearString((string) $object['internal_reference']),
|
||||||
'external_id' => $this->clearString((string) $object['external_id']),
|
'external_id' => $this->clearString((string) $object['external_id']),
|
||||||
'original_source' => sprintf('ff3-v%s', config('firefly.version')),
|
'original_source' => sprintf('ff3-v%s', config('firefly.version')),
|
||||||
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
||||||
'bunq_payment_id' => $this->clearString((string) $object['bunq_payment_id']),
|
'bunq_payment_id' => $this->clearString((string) $object['bunq_payment_id']),
|
||||||
'external_url' => $this->clearString((string) $object['external_url']),
|
'external_url' => $this->clearString((string) $object['external_url']),
|
||||||
|
|
||||||
'sepa_cc' => $this->clearString((string) $object['sepa_cc']),
|
'sepa_cc' => $this->clearString((string) $object['sepa_cc']),
|
||||||
'sepa_ct_op' => $this->clearString((string) $object['sepa_ct_op']),
|
'sepa_ct_op' => $this->clearString((string) $object['sepa_ct_op']),
|
||||||
'sepa_ct_id' => $this->clearString((string) $object['sepa_ct_id']),
|
'sepa_ct_id' => $this->clearString((string) $object['sepa_ct_id']),
|
||||||
'sepa_db' => $this->clearString((string) $object['sepa_db']),
|
'sepa_db' => $this->clearString((string) $object['sepa_db']),
|
||||||
'sepa_country' => $this->clearString((string) $object['sepa_country']),
|
'sepa_country' => $this->clearString((string) $object['sepa_country']),
|
||||||
'sepa_ep' => $this->clearString((string) $object['sepa_ep']),
|
'sepa_ep' => $this->clearString((string) $object['sepa_ep']),
|
||||||
'sepa_ci' => $this->clearString((string) $object['sepa_ci']),
|
'sepa_ci' => $this->clearString((string) $object['sepa_ci']),
|
||||||
'sepa_batch_id' => $this->clearString((string) $object['sepa_batch_id']),
|
'sepa_batch_id' => $this->clearString((string) $object['sepa_batch_id']),
|
||||||
// custom date fields. Must be Carbon objects. Presence is optional.
|
// custom date fields. Must be Carbon objects. Presence is optional.
|
||||||
'interest_date' => $this->dateFromValue($object['interest_date']),
|
'interest_date' => $this->dateFromValue($object['interest_date']),
|
||||||
'book_date' => $this->dateFromValue($object['book_date']),
|
'book_date' => $this->dateFromValue($object['book_date']),
|
||||||
'process_date' => $this->dateFromValue($object['process_date']),
|
'process_date' => $this->dateFromValue($object['process_date']),
|
||||||
'due_date' => $this->dateFromValue($object['due_date']),
|
'due_date' => $this->dateFromValue($object['due_date']),
|
||||||
'payment_date' => $this->dateFromValue($object['payment_date']),
|
'payment_date' => $this->dateFromValue($object['payment_date']),
|
||||||
'invoice_date' => $this->dateFromValue($object['invoice_date']),
|
'invoice_date' => $this->dateFromValue($object['invoice_date']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ class StoreRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -359,7 +359,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -80,7 +80,7 @@ class StoreRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -80,7 +80,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -99,7 +99,7 @@ class UserUpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,7 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountBalance;
|
use FireflyIII\Models\AccountBalance;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -69,7 +69,7 @@ class AccountController extends Controller
|
|||||||
public function accounts(AutocompleteRequest $request): JsonResponse
|
public function accounts(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$params = $request->getParameters();
|
$params = $request->getParameters();
|
||||||
$result = $this->repository->searchAccount($params['query'], $params['account_types'], $params['page'], $params['size']);
|
$result = $this->repository->searchAccount($params['query'], $params['account_types'], $params['size']);
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V2\Controllers\Autocomplete;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Repositories\UserGroups\Category\CategoryRepositoryInterface;
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,13 +61,11 @@ class CategoryController extends Controller
|
|||||||
$queryParameters = $request->getParameters();
|
$queryParameters = $request->getParameters();
|
||||||
$result = $this->repository->searchCategory($queryParameters['query'], $queryParameters['size']);
|
$result = $this->repository->searchCategory($queryParameters['query'], $queryParameters['size']);
|
||||||
$filtered = $result->map(
|
$filtered = $result->map(
|
||||||
static function (Category $item) {
|
static fn (Category $item) => [
|
||||||
return [
|
'id' => (string) $item->id,
|
||||||
'id' => (string) $item->id,
|
'title' => $item->name,
|
||||||
'title' => $item->name,
|
'meta' => [],
|
||||||
'meta' => [],
|
]
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->json($filtered);
|
return response()->json($filtered);
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V2\Controllers\Autocomplete;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Repositories\UserGroups\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,17 +59,15 @@ class TagController extends Controller
|
|||||||
public function tags(AutocompleteRequest $request): JsonResponse
|
public function tags(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$queryParameters = $request->getParameters();
|
$queryParameters = $request->getParameters();
|
||||||
$result = $this->repository->searchTag($queryParameters['query'], $queryParameters['size']);
|
$result = $this->repository->searchTag($queryParameters['query']);
|
||||||
$filtered = $result->map(
|
$filtered = $result->map(
|
||||||
static function (Tag $item) {
|
static fn (Tag $item) => [
|
||||||
return [
|
'id' => (string) $item->id,
|
||||||
'id' => (string) $item->id,
|
'title' => $item->tag,
|
||||||
'title' => $item->tag,
|
'value' => (string) $item->id,
|
||||||
'value' => (string) $item->id,
|
'label' => $item->tag,
|
||||||
'label' => $item->tag,
|
'meta' => [],
|
||||||
'meta' => [],
|
]
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->json($filtered);
|
return response()->json($filtered);
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V2\Controllers\Autocomplete;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\UserGroups\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -29,7 +29,7 @@ use FireflyIII\Api\V2\Request\Chart\ChartRequest;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Chart\ChartData;
|
use FireflyIII\Support\Chart\ChartData;
|
||||||
use FireflyIII\Support\Facades\Steam;
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
|
@@ -30,7 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Chart\ChartData;
|
use FireflyIII\Support\Chart\ChartData;
|
||||||
use FireflyIII\Support\Http\Api\AccountBalanceGrouped;
|
use FireflyIII\Support\Http\Api\AccountBalanceGrouped;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
|
@@ -32,8 +32,8 @@ use FireflyIII\Models\Budget;
|
|||||||
use FireflyIII\Models\BudgetLimit;
|
use FireflyIII\Models\BudgetLimit;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
@@ -212,13 +212,13 @@ class BudgetController extends Controller
|
|||||||
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
||||||
// convert the amount to the native currency.
|
// convert the amount to the native currency.
|
||||||
$rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']);
|
$rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']);
|
||||||
$convertedAmount = bcmul($journal['amount'], $rate);
|
$convertedAmount = bcmul((string) $journal['amount'], $rate);
|
||||||
if ($journal['foreign_currency_id'] === $this->currency->id) {
|
if ($journal['foreign_currency_id'] === $this->currency->id) {
|
||||||
$convertedAmount = $journal['foreign_amount'];
|
$convertedAmount = $journal['foreign_amount'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']);
|
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string) $journal['amount']);
|
||||||
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount);
|
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], (string) $convertedAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$converter->summarize();
|
$converter->summarize();
|
||||||
@@ -275,15 +275,15 @@ class BudgetController extends Controller
|
|||||||
}
|
}
|
||||||
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||||
if (1 === count($result)) {
|
if (1 === count($result)) {
|
||||||
$compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent']));
|
$compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||||
if (1 === $compare) {
|
if (1 === $compare) {
|
||||||
// convert this amount into the native currency:
|
// convert this amount into the native currency:
|
||||||
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']);
|
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']);
|
||||||
$result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']);
|
$result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, (string) $result[$limitCurrencyId]['native_spent']);
|
||||||
}
|
}
|
||||||
if ($compare <= 0) {
|
if ($compare <= 0) {
|
||||||
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent']));
|
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']));
|
||||||
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']));
|
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, (string) $result[$limitCurrencyId]['native_spent']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$converter->summarize();
|
$converter->summarize();
|
||||||
|
@@ -31,8 +31,8 @@ use FireflyIII\Enums\AccountTypeEnum;
|
|||||||
use FireflyIII\Enums\TransactionTypeEnum;
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
@@ -100,7 +100,7 @@ class CategoryController extends Controller
|
|||||||
$currencyId = (int) $journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||||
$currencies[$currencyId] = $currency;
|
$currencies[$currencyId] = $currency;
|
||||||
$categoryName = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name'];
|
$categoryName = $journal['category_name'] ?? (string) trans('firefly.no_category');
|
||||||
$amount = app('steam')->positive($journal['amount']);
|
$amount = app('steam')->positive($journal['amount']);
|
||||||
$nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
|
$nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
|
||||||
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
||||||
@@ -128,15 +128,13 @@ class CategoryController extends Controller
|
|||||||
];
|
];
|
||||||
|
|
||||||
// add monies
|
// add monies
|
||||||
$return[$key]['amount'] = bcadd($return[$key]['amount'], $amount);
|
$return[$key]['amount'] = bcadd($return[$key]['amount'], (string) $amount);
|
||||||
$return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], $nativeAmount);
|
$return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], (string) $nativeAmount);
|
||||||
}
|
}
|
||||||
$return = array_values($return);
|
$return = array_values($return);
|
||||||
|
|
||||||
// order by native amount
|
// order by native amount
|
||||||
usort($return, static function (array $a, array $b) {
|
usort($return, static fn (array $a, array $b) => (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1);
|
||||||
return (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1;
|
|
||||||
});
|
|
||||||
$converter->summarize();
|
$converter->summarize();
|
||||||
|
|
||||||
return response()->json($this->clean($return));
|
return response()->json($this->clean($return));
|
||||||
|
@@ -29,11 +29,10 @@ use Carbon\Exceptions\InvalidDateException;
|
|||||||
use Carbon\Exceptions\InvalidFormatException;
|
use Carbon\Exceptions\InvalidFormatException;
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\AbstractTransformer;
|
use FireflyIII\Transformers\AbstractTransformer;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
@@ -56,8 +55,8 @@ class Controller extends BaseController
|
|||||||
|
|
||||||
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
||||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||||
protected ParameterBag $parameters;
|
|
||||||
protected bool $convertToNative = false;
|
protected bool $convertToNative = false;
|
||||||
|
protected ParameterBag $parameters;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -167,7 +166,7 @@ class Controller extends BaseController
|
|||||||
|
|
||||||
// the transformer, at this point, needs to collect information that ALL items in the collection
|
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||||
// require, like meta-data and stuff like that, and save it for later.
|
// require, like meta-data and stuff like that, and save it for later.
|
||||||
$objects = $transformer->collectMetaData($objects);
|
// $objects = $transformer->collectMetaData($objects);
|
||||||
$paginator->setCollection($objects);
|
$paginator->setCollection($objects);
|
||||||
|
|
||||||
$resource = new FractalCollection($objects, $transformer, $key);
|
$resource = new FractalCollection($objects, $transformer, $key);
|
||||||
@@ -188,7 +187,7 @@ class Controller extends BaseController
|
|||||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
||||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
$transformer->collectMetaData(new Collection([$object]));
|
// $transformer->collectMetaData(new Collection([$object]));
|
||||||
|
|
||||||
$resource = new Item($object, $transformer, $key);
|
$resource = new Item($object, $transformer, $key);
|
||||||
|
|
||||||
|
@@ -27,8 +27,8 @@ namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Model\Account\IndexRequest;
|
use FireflyIII\Api\V2\Request\Model\Account\IndexRequest;
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -67,7 +67,7 @@ class IndexController extends Controller
|
|||||||
$types = $request->getAccountTypes();
|
$types = $request->getAccountTypes();
|
||||||
$sorting = $request->getSortInstructions('accounts');
|
$sorting = $request->getSortInstructions('accounts');
|
||||||
$filters = $request->getFilterInstructions('accounts');
|
$filters = $request->getFilterInstructions('accounts');
|
||||||
$accounts = $this->repository->getAccountsByType($types, $sorting, $filters);
|
$accounts = $this->repository->getAccountsByType($types, $sorting);
|
||||||
$pageSize = $this->parameters->get('limit');
|
$pageSize = $this->parameters->get('limit');
|
||||||
$count = $accounts->count();
|
$count = $accounts->count();
|
||||||
|
|
||||||
|
@@ -27,8 +27,8 @@ namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -27,8 +27,8 @@ namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Model\Account\UpdateRequest;
|
use FireflyIII\Api\V2\Request\Model\Account\UpdateRequest;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
class UpdateController extends Controller
|
class UpdateController extends Controller
|
||||||
|
@@ -25,9 +25,9 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\BillTransformer;
|
use FireflyIII\Transformers\BillTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -26,9 +26,9 @@ namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
|||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\BillTransformer;
|
use FireflyIII\Transformers\BillTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -26,7 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
|||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Budget;
|
|||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\BudgetTransformer;
|
use FireflyIII\Transformers\BudgetTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ use FireflyIII\Api\V2\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\BudgetTransformer;
|
use FireflyIII\Transformers\BudgetTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\BudgetLimit;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\BudgetLimitTransformer;
|
use FireflyIII\Transformers\BudgetLimitTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -25,8 +25,8 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V2\Controllers\Model\Currency;
|
namespace FireflyIII\Api\V2\Controllers\Model\Currency;
|
||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -25,9 +25,9 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V2\Controllers\Model\PiggyBank;
|
namespace FireflyIII\Api\V2\Controllers\Model\PiggyBank;
|
||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface;
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use FireflyIII\Transformers\V2\PiggyBankTransformer;
|
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Transaction;
|
|||||||
|
|
||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
class ShowController extends Controller
|
class ShowController extends Controller
|
||||||
|
@@ -32,7 +32,7 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||||
use FireflyIII\Rules\IsDuplicateTransaction;
|
use FireflyIII\Rules\IsDuplicateTransaction;
|
||||||
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
@@ -31,7 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
@@ -27,8 +27,8 @@ namespace FireflyIII\Api\V2\Controllers\Model\TransactionCurrency;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Api\V2\Request\Model\TransactionCurrency\IndexRequest;
|
use FireflyIII\Api\V2\Request\Model\TransactionCurrency\IndexRequest;
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
@@ -27,8 +27,8 @@ namespace FireflyIII\Api\V2\Controllers\Model\TransactionCurrency;
|
|||||||
use FireflyIII\Api\V2\Controllers\Controller;
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -34,12 +34,12 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|||||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Budget\AvailableBudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use FireflyIII\Support\Http\Api\SummaryBalanceGrouped;
|
use FireflyIII\Support\Http\Api\SummaryBalanceGrouped;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
@@ -174,8 +174,8 @@ class BasicController extends Controller
|
|||||||
* @var array $info
|
* @var array $info
|
||||||
*/
|
*/
|
||||||
foreach ($paidAmount as $info) {
|
foreach ($paidAmount as $info) {
|
||||||
$amount = bcmul($info['sum'], '-1');
|
$amount = bcmul((string) $info['sum'], '-1');
|
||||||
$nativeAmount = bcmul($info['native_sum'], '-1');
|
$nativeAmount = bcmul((string) $info['native_sum'], '-1');
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('bills-paid-in-%s', $info['currency_code']),
|
'key' => sprintf('bills-paid-in-%s', $info['currency_code']),
|
||||||
'value' => $amount,
|
'value' => $amount,
|
||||||
@@ -198,8 +198,8 @@ class BasicController extends Controller
|
|||||||
* @var array $info
|
* @var array $info
|
||||||
*/
|
*/
|
||||||
foreach ($unpaidAmount as $info) {
|
foreach ($unpaidAmount as $info) {
|
||||||
$amount = bcmul($info['sum'], '-1');
|
$amount = bcmul((string) $info['sum'], '-1');
|
||||||
$nativeAmount = bcmul($info['native_sum'], '-1');
|
$nativeAmount = bcmul((string) $info['native_sum'], '-1');
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']),
|
'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']),
|
||||||
'value' => $amount,
|
'value' => $amount,
|
||||||
@@ -279,8 +279,8 @@ class BasicController extends Controller
|
|||||||
if ((int) $journal['foreign_currency_id'] === $default->id) {
|
if ((int) $journal['foreign_currency_id'] === $default->id) {
|
||||||
$amountNative = $journal['foreign_amount'];
|
$amountNative = $journal['foreign_amount'];
|
||||||
}
|
}
|
||||||
$spent = bcadd($spent, $amount);
|
$spent = bcadd($spent, (string) $amount);
|
||||||
$spentNative = bcadd($spentNative, $amountNative);
|
$spentNative = bcadd($spentNative, (string) $amountNative);
|
||||||
}
|
}
|
||||||
app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent));
|
app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent));
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ use FireflyIII\Api\V2\Request\Generic\SingleDateRequest;
|
|||||||
use FireflyIII\Enums\AccountTypeEnum;
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user