mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-26 13:36:15 +00:00
Compare commits
2542 Commits
v6.0.22
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f94c21446a | ||
|
|
1ef1873016 | ||
|
|
32e4e29e7c | ||
|
|
65ca0dd9e0 | ||
|
|
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 | ||
|
|
d41f5b1090 | ||
|
|
40322813c9 | ||
|
|
4a98927e32 | ||
|
|
193e529803 | ||
|
|
fbf20ef2c2 | ||
|
|
54de829c8a | ||
|
|
131b987561 | ||
|
|
dce6754c62 | ||
|
|
f4bca90080 | ||
|
|
b2960b1ed9 | ||
|
|
33f87bce23 | ||
|
|
23aa45609b | ||
|
|
b098952f82 | ||
|
|
68c3e14b0c | ||
|
|
19d08137a5 | ||
|
|
73776e7869 | ||
|
|
bf04ca12c1 | ||
|
|
a4637debe9 | ||
|
|
48c1b525be | ||
|
|
56470bfbba | ||
|
|
0f732ca874 | ||
|
|
e452ba938d | ||
|
|
9921c5a925 | ||
|
|
58fab75681 | ||
|
|
54990308f6 | ||
|
|
f95758ff47 | ||
|
|
8d830e178f | ||
|
|
334a521ca1 | ||
|
|
12629a1955 | ||
|
|
2e3669a32f | ||
|
|
ea337607c4 | ||
|
|
f7f317a3b2 | ||
|
|
adbf6defe5 | ||
|
|
e0709f2975 | ||
|
|
30007b05cb | ||
|
|
13fc7f0d8d | ||
|
|
7c85138115 | ||
|
|
2c25f65f7f | ||
|
|
7eaba962e8 | ||
|
|
7c38393cde | ||
|
|
153fd2ae74 | ||
|
|
c0204c810c | ||
|
|
944c107e26 | ||
|
|
18e05c06fd | ||
|
|
fb79dbf17c | ||
|
|
31a8163c61 | ||
|
|
8bcd729250 | ||
|
|
80c4e69528 | ||
|
|
7f6d8fdb87 | ||
|
|
c8e301326e | ||
|
|
4820ef6580 | ||
|
|
4cb775cf4b | ||
|
|
c371662c51 | ||
|
|
ffaa164aa5 | ||
|
|
344bfbe059 | ||
|
|
6c38b87ec5 | ||
|
|
dfcd5d79be | ||
|
|
07631eea28 | ||
|
|
26c4fe36cc | ||
|
|
90fc4b44f2 | ||
|
|
f755dd2d48 | ||
|
|
d2647f96e7 | ||
|
|
9f94ec067a | ||
|
|
a795755618 | ||
|
|
8457a1c881 | ||
|
|
fc9429bf3e | ||
|
|
b6e8b66035 | ||
|
|
7504b21c3e | ||
|
|
b7dad8166d | ||
|
|
2da1b43c37 | ||
|
|
a606315884 | ||
|
|
295feedd77 | ||
|
|
d3b2748c8f | ||
|
|
1b4655fd70 | ||
|
|
05f67ef584 | ||
|
|
04ab7ba07d | ||
|
|
5806323970 | ||
|
|
ee260a3df7 | ||
|
|
7cb41fb333 | ||
|
|
d38adbfdc2 | ||
|
|
e6a6766ef1 | ||
|
|
a1e596491c | ||
|
|
9c920908a6 | ||
|
|
0014bffeb8 | ||
|
|
63c17f99b2 | ||
|
|
ec1e0e2807 | ||
|
|
2f16419a7b | ||
|
|
02c13859e7 | ||
|
|
57ec9b8e36 | ||
|
|
41ad35880d | ||
|
|
3aa946e028 | ||
|
|
53e46895aa | ||
|
|
c61389037d | ||
|
|
6172d60e00 | ||
|
|
f909f1d9ff | ||
|
|
55018ca046 | ||
|
|
19c746a865 | ||
|
|
503d2aa786 | ||
|
|
70d83ab501 | ||
|
|
edab602bb7 | ||
|
|
f9bcc4b1fa | ||
|
|
f3fe86167c | ||
|
|
2189fb46a2 | ||
|
|
7ff4178c8b | ||
|
|
fffd695ef8 | ||
|
|
ee592de035 | ||
|
|
7394e50ae2 | ||
|
|
f42fcff04a | ||
|
|
4eb3ce7c14 | ||
|
|
a977c567ce | ||
|
|
785bd7e905 | ||
|
|
df19f699d4 | ||
|
|
5e6e932e7e | ||
|
|
5bc397f01a | ||
|
|
42209e367f | ||
|
|
d53b1670d3 | ||
|
|
a6d450ba18 | ||
|
|
e8c1a95128 | ||
|
|
edb201f210 | ||
|
|
fe57367a8c | ||
|
|
134194a95b | ||
|
|
41c0e6fe2d | ||
|
|
c07914e733 | ||
|
|
52e2302f4f | ||
|
|
0a6b34b4f2 | ||
|
|
1e06b4dd0b | ||
|
|
5701f95e0b | ||
|
|
60d3572d37 | ||
|
|
ffa6e6a571 | ||
|
|
d6453cd735 | ||
|
|
fd79f9df44 | ||
|
|
4587340293 | ||
|
|
90bfdc7573 | ||
|
|
eca12f661f | ||
|
|
f85878b843 | ||
|
|
6499b5eaab | ||
|
|
7e4fece63d | ||
|
|
512eddf8be | ||
|
|
f0fa93a811 | ||
|
|
3c8de21709 | ||
|
|
81173e8340 | ||
|
|
35a8fa5f02 | ||
|
|
443036936d | ||
|
|
ac88007593 | ||
|
|
2297589dca | ||
|
|
6ada5fa560 | ||
|
|
8f6eefb5e7 | ||
|
|
b36a50381b | ||
|
|
51f84b3060 | ||
|
|
72132a19b0 | ||
|
|
065d165211 | ||
|
|
cabedf39b2 | ||
|
|
5d3806fcd4 | ||
|
|
01695b3342 | ||
|
|
71fb5fe077 | ||
|
|
3bec106840 | ||
|
|
fb01c36be1 | ||
|
|
26d851e69e | ||
|
|
28c18c046b | ||
|
|
318cef7e3b | ||
|
|
e8dc8f25be | ||
|
|
10ccc30240 | ||
|
|
5adc877d5e | ||
|
|
30923afb2b | ||
|
|
4eb6813b43 | ||
|
|
7521a31619 | ||
|
|
fc05beb452 | ||
|
|
1103428a83 | ||
|
|
d06d521bf0 | ||
|
|
8f64f1c0eb | ||
|
|
d11c232171 | ||
|
|
93c73248de | ||
|
|
5bed081ab9 | ||
|
|
c5188c503e | ||
|
|
98ffcac7b6 | ||
|
|
df1e81d611 | ||
|
|
9711170b08 | ||
|
|
e43264bdce | ||
|
|
e0643bed7a | ||
|
|
7f0eb3b064 | ||
|
|
f38e510526 | ||
|
|
25f99b23b2 | ||
|
|
44281fc8a0 | ||
|
|
eed3902cb7 | ||
|
|
94a3bb0443 | ||
|
|
8dcc36880e | ||
|
|
695bb31894 | ||
|
|
f8ded66869 | ||
|
|
8e4bdbc584 | ||
|
|
f7b14b01bc | ||
|
|
705b9bf0f2 | ||
|
|
f0226dbc54 | ||
|
|
1b1dfb0d7b | ||
|
|
8ed5092a76 | ||
|
|
d609821be6 | ||
|
|
cd0201074c | ||
|
|
1d8feec7bc | ||
|
|
d941472c84 | ||
|
|
674a118fac | ||
|
|
1334d793f6 | ||
|
|
60354c0202 | ||
|
|
22081d3f0a | ||
|
|
4b3f8fc78d | ||
|
|
4bd1aab86d | ||
|
|
60362cb60c | ||
|
|
27f740bf98 | ||
|
|
5e15747a5b | ||
|
|
8a6eaad2bb | ||
|
|
5ab52d9f66 | ||
|
|
21a327bf08 | ||
|
|
15dd175394 | ||
|
|
3f35305beb | ||
|
|
768d8b1515 | ||
|
|
1c19428a12 | ||
|
|
c204533195 | ||
|
|
6d89485792 | ||
|
|
949d818bad | ||
|
|
a12e200a0a | ||
|
|
b4039b1f13 | ||
|
|
32921e15b1 | ||
|
|
4f7cc7d53b | ||
|
|
0986bfbc34 | ||
|
|
663202bfc6 | ||
|
|
6f63ddf5b0 | ||
|
|
a9805b144a | ||
|
|
e1b8b9b3ae | ||
|
|
d57327fd11 | ||
|
|
15ac69bfad | ||
|
|
a5bd28f8d4 | ||
|
|
b2516ca1b4 | ||
|
|
053b46ae63 | ||
|
|
6e836aceec | ||
|
|
0e8bcd2e79 | ||
|
|
bd1f8b2497 | ||
|
|
19dfcf7139 | ||
|
|
ef7a3287bb | ||
|
|
2900049498 | ||
|
|
04d1e8fd59 | ||
|
|
9d2f57e40a | ||
|
|
ae366341cc | ||
|
|
3766128cb8 | ||
|
|
950c60d55c | ||
|
|
4b2807de48 | ||
|
|
649736cb31 | ||
|
|
6a121a8a78 | ||
|
|
f69b9ac9da | ||
|
|
23d70a2fac | ||
|
|
d178ff9de0 | ||
|
|
3ecad3457f | ||
|
|
fa6c621968 | ||
|
|
df863b6cff | ||
|
|
9316ff3e51 | ||
|
|
bfd91f8ee6 | ||
|
|
13e5d25cfe | ||
|
|
b13030420b | ||
|
|
44d1e8181c | ||
|
|
63b34c1853 | ||
|
|
facd0144cb | ||
|
|
115e3435af | ||
|
|
d44cd50768 | ||
|
|
1afcaea4c6 | ||
|
|
2bd1b37717 | ||
|
|
2d37177316 | ||
|
|
abb25e2015 | ||
|
|
d08d075e30 | ||
|
|
b4c67c02a7 | ||
|
|
04fb6a953e | ||
|
|
5dce0bec8e | ||
|
|
481bb3fb0a | ||
|
|
b6960dc299 | ||
|
|
73104aae1f | ||
|
|
10a284848b | ||
|
|
fd6560bdd0 | ||
|
|
0810f617c7 | ||
|
|
c3ffd39450 | ||
|
|
0f69e0d672 | ||
|
|
1aa8ebe57f | ||
|
|
23178614d5 | ||
|
|
d2b6829574 | ||
|
|
5602715c96 | ||
|
|
54d0433dd4 | ||
|
|
f4bc313d0b | ||
|
|
5617de3a79 | ||
|
|
2d62f0ff06 | ||
|
|
1c79f6b1b6 | ||
|
|
bf01153c6b | ||
|
|
c43b37baef | ||
|
|
d4942efd8e | ||
|
|
ea9f635b1a | ||
|
|
7eaa0e16b3 | ||
|
|
1b97d8fd48 | ||
|
|
89a29b9b10 | ||
|
|
2baac1a6d7 | ||
|
|
cd296aa9ac | ||
|
|
959d168352 | ||
|
|
6cd60951ba | ||
|
|
3898c0c0ef | ||
|
|
fe4d139817 | ||
|
|
d95f3ca59f | ||
|
|
7f6c03ce17 | ||
|
|
394d0eabef | ||
|
|
a8ae496fda | ||
|
|
1787f4421b | ||
|
|
36351a5dd9 | ||
|
|
d009ce31ca | ||
|
|
44eafeeae5 | ||
|
|
21165eb3e0 | ||
|
|
2ef3a33fbf | ||
|
|
f74be0402f | ||
|
|
a60cb366b2 | ||
|
|
58e2ef187d | ||
|
|
ae80fd8578 | ||
|
|
c17f2efca6 | ||
|
|
4a185639b9 | ||
|
|
dae7e7d507 | ||
|
|
e33e3cc40f | ||
|
|
36ec1daf3a | ||
|
|
50aff9cfb6 | ||
|
|
058a0f9fb2 | ||
|
|
0c955efa8b | ||
|
|
a62916a63d | ||
|
|
af7a4b5d3d | ||
|
|
2ae3929dd6 | ||
|
|
ebd30f4861 | ||
|
|
afc9ea08f3 | ||
|
|
78f9f7e2dd | ||
|
|
c44b827922 | ||
|
|
fb30f7ec8f | ||
|
|
e878d5ce07 | ||
|
|
f727a38b69 | ||
|
|
c11a5384da | ||
|
|
ed92cbd4b8 | ||
|
|
a9ea32772f | ||
|
|
92f5cca65b | ||
|
|
57b064f590 | ||
|
|
9729434926 | ||
|
|
9d9dffee74 | ||
|
|
b3f374f4ea | ||
|
|
50e07d422f | ||
|
|
631ed4956a | ||
|
|
0eca1c8d03 | ||
|
|
e38e4574ad | ||
|
|
be2d3f3637 | ||
|
|
0e3d779e24 | ||
|
|
4d25336d87 | ||
|
|
74f76a2835 | ||
|
|
84560a6f44 | ||
|
|
6fde693e7a | ||
|
|
2e46d9ba33 | ||
|
|
e36f8deb08 | ||
|
|
1631b422f1 | ||
|
|
b58d809063 | ||
|
|
9e34314dbc | ||
|
|
e4aa218b5f | ||
|
|
31722477d4 | ||
|
|
ec82105433 | ||
|
|
146e164f04 | ||
|
|
7d37c93988 | ||
|
|
73dffacd9a | ||
|
|
d37304fa68 | ||
|
|
62f4da6063 | ||
|
|
760da08ab7 | ||
|
|
e68c4d4408 | ||
|
|
46a200aa1f | ||
|
|
c422039335 | ||
|
|
0579c8565d | ||
|
|
9f25880a59 | ||
|
|
05f1819f7d | ||
|
|
fa2149f957 | ||
|
|
c21a79e029 | ||
|
|
03e31ebb5e | ||
|
|
3c20e5f3af | ||
|
|
9a9dd9e075 | ||
|
|
7189986c03 | ||
|
|
b407d8d315 | ||
|
|
41fa2a6208 | ||
|
|
fe00c4c373 | ||
|
|
7248a76c63 | ||
|
|
ee3c618797 | ||
|
|
a1241ebedb | ||
|
|
af78d998db | ||
|
|
d96c235ffe | ||
|
|
79ca1b5f4e | ||
|
|
0f68735e1c | ||
|
|
82abee37de | ||
|
|
507040f1fd | ||
|
|
42dc8486e9 | ||
|
|
6c655634bc | ||
|
|
f2166b97b8 | ||
|
|
da88e02be0 | ||
|
|
0d56b7d251 | ||
|
|
0a089efcac | ||
|
|
89ab360391 | ||
|
|
2bd97d9a99 | ||
|
|
103b9056e4 | ||
|
|
23c4352c18 | ||
|
|
2dddaa36d5 | ||
|
|
8ab7cf2388 | ||
|
|
f191086adb | ||
|
|
68b446db18 | ||
|
|
3d49d81856 | ||
|
|
96493425d1 | ||
|
|
419975285c | ||
|
|
aa5bde122e | ||
|
|
0fa3c2bd8d | ||
|
|
b9249a4d96 | ||
|
|
6638ca270f | ||
|
|
9bfef892f8 | ||
|
|
32e5efec7c | ||
|
|
36457455ca | ||
|
|
062c148e43 | ||
|
|
2314ce8004 | ||
|
|
a3ff73903a | ||
|
|
7c8445707e | ||
|
|
291e73da4b | ||
|
|
286a29ca3e | ||
|
|
71cf6c6a5e | ||
|
|
1e8f0adaf8 | ||
|
|
33531244aa | ||
|
|
06049a9a28 | ||
|
|
d313f5fdf5 | ||
|
|
f4868126c1 | ||
|
|
00147e98dd | ||
|
|
6d22663ca2 | ||
|
|
756bb9cf5e | ||
|
|
399d7968f5 | ||
|
|
966b68f42e | ||
|
|
134c551c12 | ||
|
|
9aeca15355 | ||
|
|
6c6d31830b | ||
|
|
e8cc321898 | ||
|
|
e73fe06f7e | ||
|
|
98b579c042 | ||
|
|
7b3a5c1afd | ||
|
|
7e2e49e129 | ||
|
|
e8ef630424 | ||
|
|
8805bcf6f6 | ||
|
|
ff5c9a3aa0 | ||
|
|
3a274dcaa7 | ||
|
|
ddfededf02 | ||
|
|
e1785898ba | ||
|
|
ae09200f42 | ||
|
|
847984f678 | ||
|
|
5971d155ef | ||
|
|
42305672ac | ||
|
|
25a56d9f72 | ||
|
|
cea52c0ac7 | ||
|
|
1b33ff9c25 | ||
|
|
8f9f08b96f | ||
|
|
594ba205bb | ||
|
|
3c65b46aa5 | ||
|
|
1cf9c76329 | ||
|
|
495f5c71c3 | ||
|
|
7e80f607b7 | ||
|
|
d93732e451 | ||
|
|
1b57bc7889 | ||
|
|
c0499df4ec | ||
|
|
d90ac519f7 | ||
|
|
a0e92b6969 | ||
|
|
df49dd23e2 | ||
|
|
d4525da6bc | ||
|
|
25b11bd20b | ||
|
|
9e373a9b0d | ||
|
|
705aac419a | ||
|
|
4fb61646b4 | ||
|
|
f6e642f72e | ||
|
|
565bd87959 | ||
|
|
5751f7e5a3 | ||
|
|
f5a755d4fc | ||
|
|
a500de8ab1 | ||
|
|
303548a5fe | ||
|
|
68de905698 | ||
|
|
9240b9868b | ||
|
|
0e2e155cc6 | ||
|
|
bffa0088b4 | ||
|
|
2e993857e8 | ||
|
|
117a376fc3 | ||
|
|
1daffedde0 | ||
|
|
0e8fdd76a6 | ||
|
|
7ff4f29bcb | ||
|
|
9e4cff2b23 | ||
|
|
4aaea89f2c | ||
|
|
4fbf7b38fb | ||
|
|
76075401f9 | ||
|
|
e2a20dd63d | ||
|
|
b52a1f3eb1 | ||
|
|
7fd5a88122 | ||
|
|
1a1baa5cda | ||
|
|
577d671a0c | ||
|
|
380029ffd8 | ||
|
|
e2f1fc307f | ||
|
|
76cc27a267 | ||
|
|
e8a6f30e4e | ||
|
|
fe6021a3d6 | ||
|
|
563c54702b | ||
|
|
4d67d27ba0 | ||
|
|
edf3876a57 | ||
|
|
2d10f255c2 | ||
|
|
ee76cc6761 | ||
|
|
f197e6623b | ||
|
|
42a9809450 | ||
|
|
444f80a933 | ||
|
|
4b985c818a | ||
|
|
2e62fe7b72 | ||
|
|
ccd182aed9 | ||
|
|
615eef3fdd | ||
|
|
d4e4907363 | ||
|
|
c205e93876 | ||
|
|
3b24bb99bb | ||
|
|
2814cd1b2a | ||
|
|
5285e1ac14 | ||
|
|
48a999cf91 | ||
|
|
3117c8846e | ||
|
|
6bb297e76f | ||
|
|
bc698f67ea | ||
|
|
f1c859aaa3 | ||
|
|
2d0aa207d4 | ||
|
|
4a75e9c262 | ||
|
|
ee7c4b8863 | ||
|
|
f782979d6c | ||
|
|
53cce6510c | ||
|
|
53252b84fd | ||
|
|
8f3cf38f77 | ||
|
|
f33766a062 | ||
|
|
ac5e62c65d | ||
|
|
e2289ce1e6 | ||
|
|
f0e2913802 | ||
|
|
1fa928b98f | ||
|
|
1c691cca33 | ||
|
|
69e1eb3eff | ||
|
|
90794cb515 | ||
|
|
28d7e24d30 | ||
|
|
6a62f781e9 | ||
|
|
fb6c67fa04 | ||
|
|
03e9e3dbdb | ||
|
|
5520992861 | ||
|
|
5f1502eea7 | ||
|
|
b3560ff525 | ||
|
|
8030167ffc | ||
|
|
fd2c1615cf | ||
|
|
b976239580 | ||
|
|
7d8d773f8f | ||
|
|
b930ad4da7 | ||
|
|
abad7cdf16 | ||
|
|
0e5eb036b0 | ||
|
|
d995bfc081 | ||
|
|
c920070ce2 | ||
|
|
277f5e538f | ||
|
|
89f197b9d4 | ||
|
|
c35ff3174a | ||
|
|
94085ee940 | ||
|
|
c841fa3620 | ||
|
|
69b2c1f4d2 | ||
|
|
2f7a1c941e | ||
|
|
c06fb8daf6 | ||
|
|
26948a058a | ||
|
|
1220564f30 | ||
|
|
ea4be9dd0c | ||
|
|
1ccda0b598 | ||
|
|
eb3b67ffd6 | ||
|
|
4819b5ac5d | ||
|
|
591b795aa3 | ||
|
|
ac21ed7d18 | ||
|
|
d9c66a2db0 | ||
|
|
d740814f88 | ||
|
|
cdf1ebf3f7 | ||
|
|
f2fab5d4ee | ||
|
|
21a6927279 | ||
|
|
92190bbc54 | ||
|
|
9ad005e31f | ||
|
|
f5c56e02da | ||
|
|
6f02eff020 | ||
|
|
c25c0d37c5 | ||
|
|
4ba1c5bcfc | ||
|
|
64aefe5848 | ||
|
|
73f2f71b03 | ||
|
|
12ee37d700 | ||
|
|
9679c22a27 | ||
|
|
1395c95353 | ||
|
|
4d1fd43c8c | ||
|
|
71c208c4fb | ||
|
|
91a2a1afc3 | ||
|
|
25c1ca2f5d | ||
|
|
6f0bb82f59 | ||
|
|
22a5184ebe | ||
|
|
17b0b1f43f | ||
|
|
b61df5ec19 | ||
|
|
1ac7275f83 | ||
|
|
cd10d04907 | ||
|
|
f9b76fcb8b | ||
|
|
093fa067e6 | ||
|
|
fa655f065b | ||
|
|
c8f2244912 | ||
|
|
f3a20e14a6 | ||
|
|
33ad47b115 | ||
|
|
775424d3b7 | ||
|
|
c9c86bbd1d | ||
|
|
f76a6ad85c | ||
|
|
2138b14d89 | ||
|
|
1bf61f57f5 | ||
|
|
07b55bd71f | ||
|
|
8d2d3d4002 | ||
|
|
d182b4b4a6 | ||
|
|
60f6a91fe4 | ||
|
|
ec89a2f956 | ||
|
|
87113d7181 | ||
|
|
59fae290e5 | ||
|
|
1a8ba2ce53 | ||
|
|
dddaa25d86 | ||
|
|
f28341587a | ||
|
|
5593bf3e08 | ||
|
|
92574a7a9d | ||
|
|
e049266f5d | ||
|
|
5b3e6fcb07 | ||
|
|
b0bfb556db | ||
|
|
484acbcb45 | ||
|
|
cdc802cfb8 | ||
|
|
582671ca84 | ||
|
|
22498b5804 | ||
|
|
87f277a482 | ||
|
|
ae0d74f57a | ||
|
|
0ae5593dde | ||
|
|
0d11769590 | ||
|
|
b7d8daf013 | ||
|
|
a9c0126b05 | ||
|
|
6bc5a57d10 | ||
|
|
2714ee96f1 | ||
|
|
524d382b7a | ||
|
|
2723e05d2a | ||
|
|
6dd9bda6b4 | ||
|
|
44449bc716 | ||
|
|
b17d8edb50 | ||
|
|
578072238a | ||
|
|
b4edd3dcc4 | ||
|
|
068094caac | ||
|
|
deb58e617d | ||
|
|
baca0c1120 | ||
|
|
02543438a4 | ||
|
|
d507e59038 | ||
|
|
9d0fd7ef1b | ||
|
|
dbef5e2143 | ||
|
|
04eca755d2 | ||
|
|
7883692196 | ||
|
|
8f64977cb9 | ||
|
|
f94fdc4979 | ||
|
|
a0a0e28447 | ||
|
|
f6f7783b94 | ||
|
|
d233cc1de8 | ||
|
|
37671499c8 | ||
|
|
c83b79998d | ||
|
|
ed842c2b42 | ||
|
|
8c5f114339 | ||
|
|
8b2f1d0b4f | ||
|
|
591a1b3050 | ||
|
|
42ec3fe02b | ||
|
|
370a398b5e | ||
|
|
554d89b6e9 | ||
|
|
cb049f5dda | ||
|
|
0728668d41 | ||
|
|
dfc187874e | ||
|
|
225588f3e7 | ||
|
|
06cc6c29aa | ||
|
|
b2d4469908 | ||
|
|
c398383905 | ||
|
|
7af9dce33b | ||
|
|
038790a5d6 | ||
|
|
fb3295bde1 | ||
|
|
43a4fd2ecb | ||
|
|
899c72d068 | ||
|
|
d118c0d886 | ||
|
|
6d4004d1ed | ||
|
|
ae60cd5b28 | ||
|
|
ab31a72199 | ||
|
|
2c1b9534f3 | ||
|
|
7028cb1546 | ||
|
|
dc1ecf6a42 | ||
|
|
3a27f9d02c | ||
|
|
4b27ab38f8 | ||
|
|
40de147611 | ||
|
|
df5756dc86 | ||
|
|
bb4f90d730 | ||
|
|
d89d46aaec | ||
|
|
304d720c4c | ||
|
|
7eff160190 | ||
|
|
8b2e18ed9d | ||
|
|
7001051833 | ||
|
|
b4b9752c05 | ||
|
|
acadc89eaa | ||
|
|
6ff84b8e90 | ||
|
|
7f3e3fc3bf | ||
|
|
02233fd7a4 | ||
|
|
50d3db0643 | ||
|
|
3751831779 | ||
|
|
14a24e47fb | ||
|
|
b7e78cb0e6 | ||
|
|
a8f65f42fc | ||
|
|
d3385a116d | ||
|
|
e0c446dd13 | ||
|
|
33d11b4780 | ||
|
|
07c49d1d04 | ||
|
|
9463285ac9 | ||
|
|
b41fc43e64 | ||
|
|
562763c938 | ||
|
|
ec60194110 | ||
|
|
1e472ee095 | ||
|
|
5597327448 | ||
|
|
cdd5baf5be | ||
|
|
7b5978059b | ||
|
|
da0b41e45c | ||
|
|
d0be2afba5 | ||
|
|
d99851231a | ||
|
|
7e02c141f9 | ||
|
|
d03960e379 | ||
|
|
16d3984ffc | ||
|
|
856a194988 | ||
|
|
1bff966bfe | ||
|
|
1948b6118b | ||
|
|
20c25d3ca2 | ||
|
|
a153735ac3 | ||
|
|
62509f7c18 | ||
|
|
9b48b67158 | ||
|
|
cbd50634a4 | ||
|
|
f475393bc1 | ||
|
|
abcddb09bf | ||
|
|
cf71a0fc55 | ||
|
|
78253f9e1e | ||
|
|
ebd0848c7f | ||
|
|
c8461eb0b5 | ||
|
|
a4cbdeaeac | ||
|
|
3e1ce69d52 | ||
|
|
08a26b976e | ||
|
|
5fc55381a2 | ||
|
|
dbf3d24ae7 | ||
|
|
cc7c6e02c5 | ||
|
|
b45aa85853 | ||
|
|
e7526ac5e3 | ||
|
|
441ada70b8 | ||
|
|
dedc06a46b | ||
|
|
b0adf1b277 | ||
|
|
28f65e9f44 | ||
|
|
a013af5f0d | ||
|
|
9552701662 | ||
|
|
ef52f0aad1 | ||
|
|
0b6f04905a | ||
|
|
cdb36357d4 | ||
|
|
8938622bd9 | ||
|
|
b210294aa9 | ||
|
|
5b02f20775 | ||
|
|
fac382a5df | ||
|
|
88d88bebc9 | ||
|
|
755fb9c29b | ||
|
|
51a835ab51 | ||
|
|
c9895ab182 | ||
|
|
e71d46a4e5 | ||
|
|
8d1d5f37c1 | ||
|
|
525a68682d | ||
|
|
715648d0d8 | ||
|
|
9452e93f22 | ||
|
|
a6aa145471 | ||
|
|
25aa6dcb59 | ||
|
|
bb2270b274 | ||
|
|
d7f6b4143e | ||
|
|
0cf0e26fa8 | ||
|
|
cc23197d60 | ||
|
|
bc1721d95e | ||
|
|
0d19173da6 | ||
|
|
1983f07d3c | ||
|
|
aad1b91cc2 | ||
|
|
8cb1057a33 | ||
|
|
b178032985 | ||
|
|
561213e95d | ||
|
|
44fa7c4306 | ||
|
|
e2169563e2 | ||
|
|
845344e003 | ||
|
|
cdb48453e8 | ||
|
|
9669cef518 | ||
|
|
f962f71ed7 | ||
|
|
94ed4021fb | ||
|
|
1765855c57 | ||
|
|
55cf3e7d44 | ||
|
|
9f1840dc05 | ||
|
|
78dab2e5f9 | ||
|
|
103b9d5005 | ||
|
|
1b75b778d8 | ||
|
|
7e665dbdfc | ||
|
|
b6897ec3a9 | ||
|
|
660260174a | ||
|
|
78d32865b5 | ||
|
|
edfa92c1aa | ||
|
|
63012f269c | ||
|
|
7d0e7f779f | ||
|
|
b8e18f80f4 | ||
|
|
481b01e4f7 | ||
|
|
edf2030251 | ||
|
|
bd1cfffb61 | ||
|
|
629f70d27d | ||
|
|
57f5ebc0f9 | ||
|
|
b4f51e7b47 | ||
|
|
d78d254e86 | ||
|
|
eb0c113699 | ||
|
|
23045ebd59 | ||
|
|
2e5931f304 | ||
|
|
a620b07c00 | ||
|
|
cb724145f2 | ||
|
|
8ef17f6686 | ||
|
|
debfd9160c | ||
|
|
f2482e4ace | ||
|
|
d98d757f8b | ||
|
|
0c9a41a929 | ||
|
|
e26f78bf50 | ||
|
|
ed265f68ba | ||
|
|
d2e9b64bf5 | ||
|
|
3811aff206 | ||
|
|
762d898fee | ||
|
|
5e6034fc86 | ||
|
|
9da10459d6 | ||
|
|
ff80cedd6b | ||
|
|
b213148ae8 | ||
|
|
c8646e20cb | ||
|
|
76a41fec50 | ||
|
|
0e705bd038 | ||
|
|
f33ffb98ff | ||
|
|
faa0d59340 | ||
|
|
5af0219884 | ||
|
|
dafd99f155 | ||
|
|
3560f0388c | ||
|
|
b2954658d8 | ||
|
|
44581d9983 | ||
|
|
02dcfeb227 | ||
|
|
d8bafb349d | ||
|
|
889598a4c8 | ||
|
|
7e37d10016 | ||
|
|
ebaebb09d1 | ||
|
|
531a3a4b6c | ||
|
|
b3e313821b | ||
|
|
51958af422 | ||
|
|
e3b21ccdba | ||
|
|
31bb208835 | ||
|
|
8c97e805a2 | ||
|
|
ac8a43bb37 | ||
|
|
2df4b40a28 | ||
|
|
e06736c254 | ||
|
|
ec367e94ce | ||
|
|
1515dea9fa | ||
|
|
adedf9c17d | ||
|
|
0b52fb84f1 | ||
|
|
16e742ae73 | ||
|
|
1b4471dfae | ||
|
|
ae152ce0a4 | ||
|
|
2aa023f140 | ||
|
|
6e2e4c6f08 | ||
|
|
1c8c038735 | ||
|
|
4d339a6da8 | ||
|
|
b7edd4407a | ||
|
|
a679a1e94a | ||
|
|
180451d32f | ||
|
|
7396f22bca | ||
|
|
058019aa84 | ||
|
|
695f83d1d8 | ||
|
|
ac4dfb3baf | ||
|
|
427001b223 | ||
|
|
3117d8b30d | ||
|
|
d19dd2a8b2 | ||
|
|
de3dcc3fc2 | ||
|
|
077f3e095b | ||
|
|
ad3b0bb320 | ||
|
|
8538741341 | ||
|
|
a0aef5d579 | ||
|
|
fdd93427aa | ||
|
|
ac3f6557de | ||
|
|
b0a909150c | ||
|
|
913f163fe4 | ||
|
|
3126b07b33 | ||
|
|
08ca90cf75 | ||
|
|
540ac2a277 | ||
|
|
ed80bed066 | ||
|
|
41d2541c6a | ||
|
|
5dedf63498 | ||
|
|
09bc4f41d2 | ||
|
|
cebf0b5c57 | ||
|
|
1632a57e3e | ||
|
|
744c4be7d1 | ||
|
|
bd99ef3eff | ||
|
|
8a86f13a5d | ||
|
|
7418b2f0ee | ||
|
|
a0e9de9312 | ||
|
|
7e23a6f5e8 | ||
|
|
44589f8744 | ||
|
|
d24531030f | ||
|
|
25bdab1346 | ||
|
|
41af1c863a | ||
|
|
76b3b18cfb | ||
|
|
e6fb2958a9 | ||
|
|
15b75b322f | ||
|
|
86149d1032 | ||
|
|
ded142cd9e | ||
|
|
7923eb9ec9 | ||
|
|
132553c108 | ||
|
|
c2269fc9a4 | ||
|
|
aed30d1499 | ||
|
|
84a1a876e1 | ||
|
|
dc675707f9 | ||
|
|
d5667c7ef6 | ||
|
|
cba1213dd1 | ||
|
|
7219c90957 | ||
|
|
af13bd991e | ||
|
|
48e548eb52 | ||
|
|
1a19e27f0e | ||
|
|
0cbd22426d | ||
|
|
d5e52e99e0 | ||
|
|
f52978e71f | ||
|
|
3a3358124d | ||
|
|
929808c633 | ||
|
|
a78df574f3 | ||
|
|
875cad16b6 | ||
|
|
7bc30192ca | ||
|
|
a1a8968e98 | ||
|
|
6abb74a038 | ||
|
|
2d7d05e985 | ||
|
|
d426e09474 | ||
|
|
72d55cb953 | ||
|
|
73ad865581 | ||
|
|
fefb52beb7 | ||
|
|
abd503543b | ||
|
|
e3eb550581 | ||
|
|
46b780758e | ||
|
|
b2c3ee9779 | ||
|
|
dca899bcee | ||
|
|
9667b8a948 | ||
|
|
661f225fe7 | ||
|
|
4c6fe0c8de | ||
|
|
78f457950e | ||
|
|
d831cc8df2 | ||
|
|
7056406afc | ||
|
|
c85cfcf3e6 | ||
|
|
db06d06789 | ||
|
|
a28b990cd1 | ||
|
|
dab4bfa7a6 | ||
|
|
6575236f2b | ||
|
|
ad582c8806 | ||
|
|
452e9cb953 | ||
|
|
a64f137b39 | ||
|
|
c067d6aab0 | ||
|
|
119b9920a6 | ||
|
|
99ed54fce8 | ||
|
|
2ea57cdd38 | ||
|
|
bb94bdfdaf | ||
|
|
4de8398cc2 | ||
|
|
e6e8cd5d8a | ||
|
|
0b200309ba | ||
|
|
a184548912 | ||
|
|
c987191212 | ||
|
|
7009b444d9 | ||
|
|
06551d5367 | ||
|
|
a20622ac0c | ||
|
|
ca38117fca | ||
|
|
9478f78d4f | ||
|
|
5c2397bbae | ||
|
|
92fefef816 | ||
|
|
d3ced65524 | ||
|
|
29eb748831 | ||
|
|
76df3d5f33 | ||
|
|
252076ec1f | ||
|
|
bbec28591f | ||
|
|
075a360ba6 | ||
|
|
477524a8ae | ||
|
|
dfe055732d | ||
|
|
78b611a18d | ||
|
|
367bdf65e6 | ||
|
|
3fc9caa31a | ||
|
|
95a41fcab7 | ||
|
|
58b409fc00 | ||
|
|
3eaaac09ad | ||
|
|
bcb672920c | ||
|
|
79b91e25c2 | ||
|
|
7170931464 | ||
|
|
c1b5a1a13e | ||
|
|
a6265ce8ab | ||
|
|
90109917df | ||
|
|
0acd54c2b7 | ||
|
|
c96226b9b4 | ||
|
|
6d143f1624 | ||
|
|
93324d1154 | ||
|
|
a39f0e1891 | ||
|
|
822f609a22 | ||
|
|
cd7ddd1c61 | ||
|
|
0b63ba26bb | ||
|
|
94d70cdb62 | ||
|
|
acb3831c8b | ||
|
|
c9d9ecede4 | ||
|
|
4eb5873353 | ||
|
|
7ca39fdb21 | ||
|
|
b8d1d7a8c0 | ||
|
|
1af79eab30 | ||
|
|
03be2704ce | ||
|
|
34baea66a7 | ||
|
|
0638d109d0 | ||
|
|
561e228a2d | ||
|
|
cb5d856769 | ||
|
|
04fe5d1fc4 | ||
|
|
45e9d4f8de | ||
|
|
73fdbb6202 | ||
|
|
e49dbefddd | ||
|
|
fc5143337a | ||
|
|
4b3eb6dace | ||
|
|
c741b2a819 | ||
|
|
cebfaa32bf | ||
|
|
d356d39d43 | ||
|
|
7d9f22d3f4 | ||
|
|
c6c8f282e2 | ||
|
|
6a64420721 | ||
|
|
fcde4e2488 | ||
|
|
aa5c4c20e9 | ||
|
|
794e31e487 | ||
|
|
16bf186312 | ||
|
|
45c722e786 | ||
|
|
36d9e5c3fe | ||
|
|
8d614de67f | ||
|
|
d17da670ab | ||
|
|
5bf4df9ad8 | ||
|
|
07db6b59ce | ||
|
|
e16f1cf4ee | ||
|
|
4c80d929ca | ||
|
|
16364d9859 | ||
|
|
c24f6acb2c | ||
|
|
4bd19e0627 | ||
|
|
69d839997a | ||
|
|
c02c027f4f | ||
|
|
b14606625e | ||
|
|
222d7b56c7 | ||
|
|
b7f7bf42b2 | ||
|
|
0cbd64d31a | ||
|
|
60bdae47c4 | ||
|
|
ca4b38d905 | ||
|
|
3674465f53 | ||
|
|
b951d4130c | ||
|
|
7992b810fd | ||
|
|
c1c0afa40b | ||
|
|
56c9026299 | ||
|
|
021ddfc36b | ||
|
|
5bd72f6428 | ||
|
|
feabfe54f0 | ||
|
|
565409b486 | ||
|
|
f57366da5f | ||
|
|
064217ccb0 | ||
|
|
fa3ccbda33 | ||
|
|
f43aadf02d | ||
|
|
3b8a4d3e9b | ||
|
|
3d410556ef | ||
|
|
f15ca1d0a1 | ||
|
|
7002463c54 | ||
|
|
649f876437 | ||
|
|
3cfd178cbd | ||
|
|
cefbaafa19 | ||
|
|
a8c88800c4 | ||
|
|
9d1a127200 | ||
|
|
3fdde2d1c8 | ||
|
|
cdc0b8dd2c | ||
|
|
1a1e06e6e8 | ||
|
|
6d39b8468c | ||
|
|
bdee3947b2 | ||
|
|
2317037655 | ||
|
|
dcea6b757b | ||
|
|
bd7fe92818 | ||
|
|
850e47d8db | ||
|
|
96fe62400f | ||
|
|
5d07fcdcb6 | ||
|
|
fd5d2d57a8 | ||
|
|
8e7d42201f | ||
|
|
f26bd3cb31 | ||
|
|
36915cdace | ||
|
|
8a5cecd2a0 | ||
|
|
78da1b22bb | ||
|
|
6d970a9794 | ||
|
|
8bb7739f05 | ||
|
|
7788bb4b33 | ||
|
|
2ecb4bb3b7 | ||
|
|
4a783d3c3c | ||
|
|
e16645ae87 | ||
|
|
9d3189be7e | ||
|
|
07fca78293 | ||
|
|
82080501c7 | ||
|
|
d93d6bfc66 | ||
|
|
a41326ef94 | ||
|
|
90b77845c3 | ||
|
|
57af80d820 | ||
|
|
fc4d5a1dfd | ||
|
|
8ab9ab8d21 | ||
|
|
75674b5793 | ||
|
|
a7d6f26051 | ||
|
|
eb540ce148 | ||
|
|
a3077fe43b | ||
|
|
63bb84d375 | ||
|
|
e5f5aa628e | ||
|
|
c54f84dc8e | ||
|
|
c2e562623c | ||
|
|
c8d5e8a9dc | ||
|
|
963f017be3 | ||
|
|
0e0eeb736f | ||
|
|
e8d9b8fa49 | ||
|
|
c166b9242e | ||
|
|
8ff8efced2 | ||
|
|
0b4fb9a806 | ||
|
|
ba9fef9410 | ||
|
|
f7d94d17cd | ||
|
|
1fea9c6817 | ||
|
|
a88c8bedbe | ||
|
|
fbf3468053 | ||
|
|
2a3ba9799e | ||
|
|
d121aad28f | ||
|
|
dc808fa807 | ||
|
|
a1be6ff62b | ||
|
|
20dc5b0256 | ||
|
|
edd54e23c5 | ||
|
|
1238df8784 | ||
|
|
b8c62652b0 | ||
|
|
54b2d02f63 | ||
|
|
47faf89a5c | ||
|
|
b7fb5a3854 | ||
|
|
a384b4202a | ||
|
|
99ecac0ce4 | ||
|
|
6102982456 | ||
|
|
b88e981b4b | ||
|
|
827263b03e | ||
|
|
d44e74d334 | ||
|
|
911f46c590 | ||
|
|
7d42c4ee5d | ||
|
|
ea89f6177f | ||
|
|
74291b3870 | ||
|
|
2c4f2082fe | ||
|
|
d8d58cc29b | ||
|
|
85b17e4035 | ||
|
|
83de5667b3 | ||
|
|
5fffe873c6 | ||
|
|
78c09c82d6 | ||
|
|
704abc315d | ||
|
|
86b4965458 | ||
|
|
d2dc0c2bf0 | ||
|
|
9f4894bbb5 | ||
|
|
76a8675a34 | ||
|
|
6988301da1 | ||
|
|
109cd37211 | ||
|
|
284ff4d1b0 | ||
|
|
bc0ab7af99 | ||
|
|
a17bc7258f | ||
|
|
87911c2438 | ||
|
|
746f1fd300 | ||
|
|
9e5faf919f | ||
|
|
cc6cbe6605 | ||
|
|
dc6d708897 | ||
|
|
6189d24b98 | ||
|
|
f6e28dc88f | ||
|
|
75ea035630 | ||
|
|
4cdb14301d | ||
|
|
9f95221ba3 | ||
|
|
e3a67be412 | ||
|
|
5749b642ce | ||
|
|
baff7c67f9 | ||
|
|
ccc005942f | ||
|
|
5b83c33039 | ||
|
|
cc32578c5f | ||
|
|
80f410835b | ||
|
|
b537a3145d | ||
|
|
bfa1fcbaf8 | ||
|
|
56243907c4 | ||
|
|
5928dd72e6 | ||
|
|
c6bf0ff1cd | ||
|
|
19d1cf192b | ||
|
|
37d7dc7e3e | ||
|
|
95a3a194b8 | ||
|
|
3542387188 | ||
|
|
da1b002a64 | ||
|
|
46daee28e7 | ||
|
|
9ade5635d4 | ||
|
|
e14e80f33c | ||
|
|
0c824e21c8 | ||
|
|
fab1c68569 | ||
|
|
c1534657f2 | ||
|
|
39841de680 | ||
|
|
43a720b62b | ||
|
|
5ec54de29e | ||
|
|
397e37f344 | ||
|
|
b6f84c2b99 | ||
|
|
843f86fc66 | ||
|
|
0e8e364074 | ||
|
|
bbccbef578 | ||
|
|
ee11a8e3a0 | ||
|
|
e8618047bd | ||
|
|
f104b76f73 | ||
|
|
cb701d8506 | ||
|
|
70a334c56e | ||
|
|
e6b2db1e29 | ||
|
|
e8dffa0052 | ||
|
|
c4f0512f39 | ||
|
|
3268019d0c | ||
|
|
a0ef6a1fc8 | ||
|
|
99d0098b20 | ||
|
|
a7a54c042c | ||
|
|
c44e48a793 | ||
|
|
53b501ca73 | ||
|
|
322f70bcca | ||
|
|
35559c077b | ||
|
|
590ffe7c76 | ||
|
|
8a2d8f148e | ||
|
|
4f0e15e07d | ||
|
|
7463861e0c | ||
|
|
1e70fa28be | ||
|
|
26c6ca470b | ||
|
|
5e54034e0e | ||
|
|
25873ef734 | ||
|
|
1092b04b22 | ||
|
|
01ce74dd72 | ||
|
|
41430d8386 | ||
|
|
01eb19169c | ||
|
|
cfaa7d7c68 | ||
|
|
14d3312a10 | ||
|
|
87be478dd8 | ||
|
|
0b6877a20e | ||
|
|
7186f0ef60 | ||
|
|
538933691e | ||
|
|
46c49ddbd8 | ||
|
|
bcfb134b6e | ||
|
|
57981f1cf9 | ||
|
|
0310186fb7 | ||
|
|
4dcb38290e | ||
|
|
2f5c37048b | ||
|
|
370c8b16ae | ||
|
|
af0555592a | ||
|
|
9c07ddaed6 | ||
|
|
bb7355a566 | ||
|
|
1d48347f8c | ||
|
|
060b76ca9c | ||
|
|
2b2b9b6f7a | ||
|
|
f3dd05a0c0 | ||
|
|
47a91aa273 | ||
|
|
41bc236603 | ||
|
|
65349451ea | ||
|
|
e77b6a55a4 | ||
|
|
2379bcff11 | ||
|
|
7133156fa1 | ||
|
|
a59176689d | ||
|
|
bc2d8f3dfb | ||
|
|
ddf89a9d5a | ||
|
|
7daaba17f6 | ||
|
|
9cb5b1384f | ||
|
|
7d13263482 | ||
|
|
d9ff252915 | ||
|
|
51ba550251 | ||
|
|
fd21c467ad | ||
|
|
9aa90650b4 | ||
|
|
d892257e8b | ||
|
|
db0dbcfcf1 | ||
|
|
f591996f04 | ||
|
|
b08d385586 | ||
|
|
20ef22f67e | ||
|
|
c888baf542 | ||
|
|
8b0af3f666 | ||
|
|
7043e1e7c0 | ||
|
|
c5854eba23 | ||
|
|
ddf1a8cebb | ||
|
|
7dcaf167e9 | ||
|
|
b359d51d3a | ||
|
|
3913fa5086 | ||
|
|
ab2772abe0 | ||
|
|
bc7875b17b | ||
|
|
4938fa9990 | ||
|
|
84df2c80ee | ||
|
|
dc17060754 | ||
|
|
e2fa81dddc | ||
|
|
182dfc95fe | ||
|
|
c8979b6c33 | ||
|
|
ab872e8912 | ||
|
|
d36b94fabf | ||
|
|
e3d4ceaecb | ||
|
|
e3a6e5b788 | ||
|
|
57235c0e00 | ||
|
|
2298c3ddaf | ||
|
|
7224f1be6f | ||
|
|
1bd3019c16 | ||
|
|
f0fa21dead | ||
|
|
845eaed8d7 | ||
|
|
b3649cd4d0 | ||
|
|
55f14c587b | ||
|
|
441a8a8408 | ||
|
|
060c9648f1 | ||
|
|
7680c8733f | ||
|
|
5a0af5c93b | ||
|
|
f4b066add1 | ||
|
|
9ecb414b02 | ||
|
|
ad4f908c24 | ||
|
|
025f739442 | ||
|
|
6df7354c48 | ||
|
|
3f77c845ca | ||
|
|
d4771f7a5c | ||
|
|
ec4e2bfa4f | ||
|
|
dfdbfae4b5 | ||
|
|
349d38b956 | ||
|
|
2267aa3ac4 | ||
|
|
2323aa454e | ||
|
|
8b3317b665 | ||
|
|
15f893c343 | ||
|
|
309b3e765e | ||
|
|
d3fad06e00 | ||
|
|
834f24c99c | ||
|
|
35291e1298 | ||
|
|
ac4e9dcbc5 | ||
|
|
d57806f2ba | ||
|
|
3b005c317d | ||
|
|
e91903fed2 | ||
|
|
fee2002b0f | ||
|
|
f12e502eb8 | ||
|
|
24e62b1cee | ||
|
|
f559ec73e0 | ||
|
|
530b501fcf | ||
|
|
d5ea78025e | ||
|
|
3413b9b5b5 | ||
|
|
0b45c1aa76 | ||
|
|
5718d1690a | ||
|
|
67b16cc070 | ||
|
|
5746ac3247 | ||
|
|
8a2c520b11 | ||
|
|
f46c14df8c | ||
|
|
009fbba491 | ||
|
|
53d84347c2 | ||
|
|
1961487055 | ||
|
|
c9ce5df74b | ||
|
|
1371b6773e | ||
|
|
b9f1baf150 | ||
|
|
66b322e844 | ||
|
|
487b65b669 | ||
|
|
9078781d61 | ||
|
|
1ec830521a | ||
|
|
c4bf2aae7d | ||
|
|
69ca88d9f8 | ||
|
|
b38b7b2534 | ||
|
|
f19bfc3b4b | ||
|
|
d22f9c09d7 | ||
|
|
fc2da9eb42 | ||
|
|
f2c9e20aef | ||
|
|
16b8ca2746 | ||
|
|
46ea074821 | ||
|
|
d2c89781e2 | ||
|
|
e54d711891 | ||
|
|
84d3ad4764 | ||
|
|
b908951a2d | ||
|
|
8b87deea58 | ||
|
|
0d7325b3dc | ||
|
|
a3fd99a498 | ||
|
|
0ff405d1e0 | ||
|
|
46a60af966 | ||
|
|
591c9e3b39 | ||
|
|
c30461b20b | ||
|
|
2c3f86d9bc | ||
|
|
34349e4475 | ||
|
|
6acd5be5dc | ||
|
|
55a2b4e789 | ||
|
|
f41397eb43 | ||
|
|
41fc1e8f82 | ||
|
|
bee219ebf7 | ||
|
|
438f602961 | ||
|
|
429e72e681 | ||
|
|
7a134781f2 | ||
|
|
b572c1dcd3 | ||
|
|
95593f847b | ||
|
|
b82fcbd97b | ||
|
|
daddee7806 | ||
|
|
930a08ec90 | ||
|
|
fd2edf3b23 | ||
|
|
0597255c08 | ||
|
|
955ab38a85 | ||
|
|
1311a0db8b | ||
|
|
0ce9ee6a6c | ||
|
|
3a339382d4 | ||
|
|
a5b15bbc16 | ||
|
|
fbf89fd514 | ||
|
|
b3223feba2 | ||
|
|
88a9bc379e | ||
|
|
b442b91b7c | ||
|
|
9fadbbe087 | ||
|
|
1ef7239276 | ||
|
|
ea573e9434 | ||
|
|
34fa24e4a8 | ||
|
|
a1be4a4d8a | ||
|
|
b8e8af1e2a | ||
|
|
c13a3fb30c | ||
|
|
cb8fa4e1f4 | ||
|
|
bf7f4f9887 | ||
|
|
af48548e81 | ||
|
|
90d58ec8fa | ||
|
|
e92dd7f464 | ||
|
|
3bdf9eeed2 | ||
|
|
558ac7b0da | ||
|
|
9d0488ffbc | ||
|
|
d7fa8b283e | ||
|
|
a0097bd613 | ||
|
|
ffc2156e5f | ||
|
|
e0a89bb5fe | ||
|
|
647179cd3c | ||
|
|
5106ccdbd7 | ||
|
|
7103098fe7 | ||
|
|
f8072f0bfc | ||
|
|
96ac3a95c8 | ||
|
|
cd713dc40f | ||
|
|
d9fba39d80 | ||
|
|
2564470197 | ||
|
|
9222c82af0 | ||
|
|
243f283bfd | ||
|
|
5b60aaecc0 | ||
|
|
20a4caec60 | ||
|
|
99cc096b71 | ||
|
|
5626d1c56d | ||
|
|
68c9c4ec3c | ||
|
|
f9d4a43e05 | ||
|
|
92e7f344e0 | ||
|
|
89ce2838d5 | ||
|
|
356b217692 | ||
|
|
950e39b753 | ||
|
|
8f14979717 | ||
|
|
aa2afd162e | ||
|
|
fe33352ec1 | ||
|
|
65c5249815 | ||
|
|
b1afaea1aa | ||
|
|
997dc3814b | ||
|
|
b37b5b86d4 | ||
|
|
b13a4e1016 | ||
|
|
7897ebc4d5 | ||
|
|
ac17b82d85 | ||
|
|
1b1712d998 | ||
|
|
a2c0d9f7d0 | ||
|
|
5b68b25c85 | ||
|
|
d3a215b575 | ||
|
|
5c352a0d3e | ||
|
|
fded058ea6 | ||
|
|
99f041b114 | ||
|
|
283b594995 | ||
|
|
723aa65e7a | ||
|
|
64d315ad51 | ||
|
|
d0844356cb | ||
|
|
ba8d65835a | ||
|
|
fa3343f437 | ||
|
|
c5b8a951d2 | ||
|
|
20b1fc05cb | ||
|
|
ab441d7d0c | ||
|
|
b621d14bdf | ||
|
|
94730e998b | ||
|
|
23c2f76e52 | ||
|
|
40196d48b2 | ||
|
|
ef3c2eb701 | ||
|
|
4f994a2795 | ||
|
|
807e575dac | ||
|
|
04b1465eb7 | ||
|
|
6f79ab2a70 | ||
|
|
c1469f016e | ||
|
|
373ec934df | ||
|
|
abd34ba1dc | ||
|
|
89b7596caf | ||
|
|
3543548ba0 | ||
|
|
a932965908 | ||
|
|
9056126328 | ||
|
|
0e85a5123d | ||
|
|
d3f19db42d | ||
|
|
9894d16d26 | ||
|
|
0b069bcb58 | ||
|
|
36d54c3fac | ||
|
|
530e48f16e | ||
|
|
9763f9f922 | ||
|
|
bbd4d7a8ef | ||
|
|
bafe2ece8c | ||
|
|
b2449eb726 | ||
|
|
353c345d9a | ||
|
|
e2461ba839 | ||
|
|
e199fdd2b6 | ||
|
|
592a89d6a5 | ||
|
|
7a7b629225 | ||
|
|
21a4774561 | ||
|
|
5be97bb18f | ||
|
|
a12ff10550 | ||
|
|
c808294ca1 | ||
|
|
9dcf264658 | ||
|
|
e0bbd3a810 | ||
|
|
2886a22f4e | ||
|
|
6f783f7662 | ||
|
|
992fdc9e27 | ||
|
|
73529c31e0 | ||
|
|
d9fc91a432 | ||
|
|
6a432e7931 | ||
|
|
26f7575ba2 | ||
|
|
b1c1bbd6c0 | ||
|
|
d40643af54 | ||
|
|
11cfefd908 | ||
|
|
ff2b2eec9b | ||
|
|
4f1187bf6e | ||
|
|
642539e410 | ||
|
|
1f774e0d71 | ||
|
|
1da19cde6f | ||
|
|
ac5973833e | ||
|
|
40b0e31d27 | ||
|
|
f56f8d72df | ||
|
|
b47bb13558 | ||
|
|
b4133b6512 | ||
|
|
fb20095502 | ||
|
|
cfc23c4cb9 | ||
|
|
44701f1633 | ||
|
|
fadf799b9c | ||
|
|
c22a9784ee | ||
|
|
a6512d3d74 | ||
|
|
cea2ca7532 | ||
|
|
e322069bb4 | ||
|
|
da7a976c4e | ||
|
|
300dba7257 | ||
|
|
ec59f80fe3 | ||
|
|
37aa5bcc60 | ||
|
|
e50d2cb481 | ||
|
|
468709c092 | ||
|
|
11ced9216c | ||
|
|
cfa9151f45 | ||
|
|
6577224a55 | ||
|
|
b4209f2e72 | ||
|
|
f045e4ea69 | ||
|
|
4a37152aea | ||
|
|
2907db1380 | ||
|
|
80a35692c5 | ||
|
|
1a6fe5ca3c | ||
|
|
13ec3493bd | ||
|
|
bf55e8df72 | ||
|
|
775504d812 | ||
|
|
8d6c45b68e | ||
|
|
db9094956e | ||
|
|
25d02e92f4 | ||
|
|
81cb0a38f3 | ||
|
|
e07a9d6162 | ||
|
|
2ccbc16dfa | ||
|
|
e00addc0b0 | ||
|
|
da7a2cf0c0 | ||
|
|
2368788405 | ||
|
|
f603415931 | ||
|
|
523fa42998 | ||
|
|
e449395f3f | ||
|
|
d8d8002f1e | ||
|
|
2570ca9573 | ||
|
|
e5fdc2cbfd | ||
|
|
0349cdbc1b | ||
|
|
122f0309a6 | ||
|
|
09bff5ea4e | ||
|
|
7ea112c5e7 | ||
|
|
44df07a5f5 | ||
|
|
66b0d9d309 | ||
|
|
6ac3d3e62c | ||
|
|
925450f84c | ||
|
|
62f59c6a19 | ||
|
|
7db21612a0 | ||
|
|
2c0da2cf26 | ||
|
|
79484cc194 | ||
|
|
6f18748c72 | ||
|
|
577824930f | ||
|
|
d614519ee7 | ||
|
|
ae31041f7f | ||
|
|
62c4d0cf86 | ||
|
|
c2ddabbad2 | ||
|
|
458402aaff | ||
|
|
5c81e98218 | ||
|
|
37a46b02f4 | ||
|
|
b3e1ecdd02 | ||
|
|
1780e6dc61 | ||
|
|
50f346d092 | ||
|
|
ccc851090a | ||
|
|
4605d84cc8 | ||
|
|
8c7ab50325 | ||
|
|
908539836b | ||
|
|
9f71cf966c | ||
|
|
02ed47c578 | ||
|
|
1ddbaf0884 | ||
|
|
d3ed8c6f0f | ||
|
|
4f1ac2ac6f | ||
|
|
1e733f4c8b | ||
|
|
8e2546da9d | ||
|
|
3a8162d3c5 | ||
|
|
f7ceb75316 | ||
|
|
744e193faa | ||
|
|
12b0e11592 | ||
|
|
717f3a9e3d | ||
|
|
b9f0682f04 | ||
|
|
8792465fd5 | ||
|
|
6fbf9a119d | ||
|
|
0dfa21a92e | ||
|
|
136fe8e8eb | ||
|
|
d510c4e31d | ||
|
|
c066bcc4ce | ||
|
|
c9e7ae1f08 | ||
|
|
6a9b4f4d55 | ||
|
|
2b5054b905 | ||
|
|
0a45a2485b | ||
|
|
fcc0294d07 | ||
|
|
ad981c2bf0 | ||
|
|
75a32b2f94 | ||
|
|
70b60f756b | ||
|
|
0d2ae8ae23 | ||
|
|
8043c86942 | ||
|
|
4c30a7bc55 | ||
|
|
f615b9c252 | ||
|
|
c19b36a391 | ||
|
|
935634e487 | ||
|
|
2c3f032a2b | ||
|
|
7e62b75b12 | ||
|
|
de57ab0874 | ||
|
|
6fb4aaecd3 | ||
|
|
45fdbf5a11 | ||
|
|
c6615a7b17 | ||
|
|
0efb3d2dcf | ||
|
|
b8a58f83ee | ||
|
|
110228e65e | ||
|
|
8ad27e0eda | ||
|
|
2e0d90c685 | ||
|
|
bd2ecb13b8 | ||
|
|
5725570dbb | ||
|
|
11f77685e4 | ||
|
|
0521c46d27 | ||
|
|
50d6225590 | ||
|
|
df55f7de79 | ||
|
|
5152ae9622 | ||
|
|
075d0da63d | ||
|
|
d804df2a2f | ||
|
|
ff0f8beb81 | ||
|
|
c00be92f97 | ||
|
|
88f6221424 | ||
|
|
f9463e02a2 | ||
|
|
25a23801be | ||
|
|
fe7bb02dc5 | ||
|
|
68edcfc4e8 | ||
|
|
5f8a24a684 | ||
|
|
0a5d62605a | ||
|
|
1873be8d95 | ||
|
|
01892c3828 | ||
|
|
b87e60c72f | ||
|
|
3a083f88b5 | ||
|
|
566bb2f097 | ||
|
|
1ba7847d84 | ||
|
|
c32044a8eb | ||
|
|
72a2d417af | ||
|
|
09c18d6d44 | ||
|
|
84ae6a633e | ||
|
|
82749cea07 | ||
|
|
23aa0e3ba3 | ||
|
|
8be27a2201 | ||
|
|
ff98f3cc3e | ||
|
|
01c4d25646 | ||
|
|
292b9ac9d0 | ||
|
|
6bdae03961 | ||
|
|
7426c6aac3 | ||
|
|
211526c032 | ||
|
|
e6fe08dd61 | ||
|
|
7bba67130a | ||
|
|
7186d8ddfd | ||
|
|
1a6bc6decd | ||
|
|
5b11c86113 | ||
|
|
98b95ab891 | ||
|
|
c3068d10bf | ||
|
|
fa1a1b084b | ||
|
|
387e44b8b9 | ||
|
|
6dafa89a15 | ||
|
|
5b5b8008b0 | ||
|
|
38a955e663 | ||
|
|
62921df702 | ||
|
|
c7c2b85882 | ||
|
|
bc26ee5cde | ||
|
|
9eca31529c | ||
|
|
25e3abeeb8 | ||
|
|
53d6281ba4 | ||
|
|
4b9fd949ad | ||
|
|
786b4c18a1 | ||
|
|
97b65ac44c | ||
|
|
102da7b21e | ||
|
|
85bde79fd1 | ||
|
|
09a25957d0 | ||
|
|
fd7a2181a4 | ||
|
|
2ede3b420b | ||
|
|
4bed30347d | ||
|
|
ffdcab3220 | ||
|
|
956108399b | ||
|
|
61c38f2a99 | ||
|
|
f3773ebfc2 | ||
|
|
f963ac63f1 | ||
|
|
1368aafe5f | ||
|
|
657262f179 | ||
|
|
8b9dce70bb | ||
|
|
30bbd0b3a4 | ||
|
|
d4488f041b | ||
|
|
fa8dc1ae4b | ||
|
|
c2b60edca3 | ||
|
|
949ca4f79e | ||
|
|
ab0b03dd14 | ||
|
|
5b41e58025 | ||
|
|
88bf76fa27 | ||
|
|
3ad155882a | ||
|
|
4747e28621 | ||
|
|
5664695a92 | ||
|
|
fdcd31652a | ||
|
|
e5397b6659 | ||
|
|
51e5b9a994 | ||
|
|
dc95632834 | ||
|
|
3e888382c9 | ||
|
|
de8d6f8439 | ||
|
|
60543b8f1d | ||
|
|
268cec6d08 | ||
|
|
94aea91927 | ||
|
|
135a6993aa | ||
|
|
16079f496a | ||
|
|
e318e8e9cf | ||
|
|
51ca8277bb | ||
|
|
a49cf1fd3d | ||
|
|
81a11ee5b4 | ||
|
|
b778424b7e | ||
|
|
d408d7cc20 | ||
|
|
228870ceac | ||
|
|
ae1939cd1b | ||
|
|
f7a4bd5d12 | ||
|
|
eec1888f87 | ||
|
|
a42470e5b4 | ||
|
|
098f1fe0f6 | ||
|
|
2e5bc750d1 | ||
|
|
d777a1f2b8 | ||
|
|
5178e19cea | ||
|
|
be8aaa68af | ||
|
|
1e31a1184a | ||
|
|
c269be7f07 | ||
|
|
6bf42ba237 | ||
|
|
1901648a05 | ||
|
|
789a6cebcd | ||
|
|
4230349c07 | ||
|
|
33b95b9371 | ||
|
|
e47110607c | ||
|
|
1e3665e54f | ||
|
|
47147066d2 | ||
|
|
5b8f67e992 | ||
|
|
fb1a66d872 | ||
|
|
e594b9304a | ||
|
|
0d7fd36c38 | ||
|
|
bdba786322 | ||
|
|
507e0fb54c | ||
|
|
e4d91aa337 | ||
|
|
4e6fc8e2a2 | ||
|
|
244ffb2450 | ||
|
|
7aa3aef508 | ||
|
|
c16f7d214f | ||
|
|
c08d44ea48 | ||
|
|
6381d04e2b | ||
|
|
ec43d10e35 | ||
|
|
b32d9aab34 | ||
|
|
de5cb4c165 | ||
|
|
609edb9dff | ||
|
|
636b3921fa | ||
|
|
a391d731ff | ||
|
|
c743b0c66b | ||
|
|
ef09f88816 | ||
|
|
ffeada037d | ||
|
|
4723d9dd30 | ||
|
|
b84604a4db | ||
|
|
1bd1a9cba3 | ||
|
|
d0c830c560 | ||
|
|
06d3cc3506 | ||
|
|
2b90c20db8 | ||
|
|
ebe1fd6142 | ||
|
|
ca8f153c6a | ||
|
|
581e5d7330 | ||
|
|
067d160c13 | ||
|
|
e8890ada7c | ||
|
|
c5fbf6ec55 | ||
|
|
5cd9793edf | ||
|
|
c60b5e5c21 | ||
|
|
b2bd9301b6 | ||
|
|
4864ecc0c7 | ||
|
|
58dea55d38 | ||
|
|
34e22e0747 | ||
|
|
7c9f74f550 | ||
|
|
f0517aee53 | ||
|
|
f69072d293 | ||
|
|
669aedeea3 | ||
|
|
8a4985261a | ||
|
|
337d14e71e | ||
|
|
ebf4b00288 | ||
|
|
a445bc53cd | ||
|
|
1f7ceb6df6 | ||
|
|
135b9fc010 | ||
|
|
655d03bec4 | ||
|
|
bc50d25468 | ||
|
|
e40bb81d80 | ||
|
|
53e972fbba | ||
|
|
51d244cfe6 | ||
|
|
3842552256 | ||
|
|
c9d5d74662 | ||
|
|
4961b1f715 | ||
|
|
680012056b | ||
|
|
64ec0cf62e | ||
|
|
c4f6366642 | ||
|
|
28021aa711 | ||
|
|
bf5a15077d | ||
|
|
9506b37200 | ||
|
|
ee41eadcd9 | ||
|
|
5ecc1929f9 | ||
|
|
1186359898 | ||
|
|
aabf73d3e9 | ||
|
|
da4e813d9a | ||
|
|
cbcadb6706 | ||
|
|
9f0b4564cf | ||
|
|
327b0b4a37 | ||
|
|
77695409f6 | ||
|
|
92cdec2877 | ||
|
|
4804f419ef | ||
|
|
0c52c85e25 | ||
|
|
5ca1367a7c | ||
|
|
68acd52c86 | ||
|
|
bd221a59d6 | ||
|
|
b91a938a60 | ||
|
|
698c1f6c7e | ||
|
|
2f110ab9a8 | ||
|
|
a1dfb3a99e | ||
|
|
b2a301bf94 | ||
|
|
3b3f9ee497 | ||
|
|
0b22b056bc | ||
|
|
ce239a5bb1 | ||
|
|
ce023f2580 | ||
|
|
46e130fdfe | ||
|
|
c2b22a2bac | ||
|
|
9a807fc215 | ||
|
|
8ef74e9fd2 | ||
|
|
abd123b1c8 | ||
|
|
7e72003984 | ||
|
|
69f653d0c9 | ||
|
|
e6e9535509 | ||
|
|
45787a30de | ||
|
|
18e4c2ab33 | ||
|
|
c063bcf80d | ||
|
|
eb8b7af7aa | ||
|
|
c60fb0c68c | ||
|
|
84e99a065f | ||
|
|
369e980466 | ||
|
|
963d4b7345 | ||
|
|
eaf6bd3fa0 | ||
|
|
9b4a30565c | ||
|
|
c37a877f34 | ||
|
|
d2a895ddda | ||
|
|
2660dc5bf7 | ||
|
|
40083bf2b4 | ||
|
|
3136bccb24 | ||
|
|
a5c370c70e | ||
|
|
01a897b5e1 | ||
|
|
722ae91c02 | ||
|
|
6df7f1f762 | ||
|
|
7aacd1f945 | ||
|
|
b02a61dfbd | ||
|
|
2b0a3ec818 | ||
|
|
00410c8486 | ||
|
|
8e0f0b03d8 | ||
|
|
7c3f2dd83a | ||
|
|
d2f0eab4c4 | ||
|
|
a8ade914ac | ||
|
|
ef08b7eb93 | ||
|
|
726ed3292a | ||
|
|
5883dfbed8 | ||
|
|
271e4271eb | ||
|
|
627db2c2df | ||
|
|
b9feb0aa71 | ||
|
|
155084084d | ||
|
|
1c3cb85a46 | ||
|
|
b0a39c00ba | ||
|
|
7cb919e9c2 | ||
|
|
cbecacd652 | ||
|
|
14e9d73768 | ||
|
|
8604b05d07 | ||
|
|
b66bac497e | ||
|
|
6ad38b38b8 | ||
|
|
53f31f17d2 | ||
|
|
a7bfdbe31f | ||
|
|
72ead65d9c | ||
|
|
846c60fb85 | ||
|
|
938446ede3 | ||
|
|
68f01d932e | ||
|
|
a6c355c7b8 | ||
|
|
5e49e149b1 | ||
|
|
06fd8dc5e0 | ||
|
|
43c79af293 | ||
|
|
3355645cb4 | ||
|
|
bac0710a9c | ||
|
|
47d8ab685d | ||
|
|
9fd4d29fda | ||
|
|
0126669fa8 | ||
|
|
1e01eb7bc2 | ||
|
|
ed28102aff | ||
|
|
6c91ca5463 | ||
|
|
9ab926f9ab | ||
|
|
29132b18ab | ||
|
|
28307edf81 | ||
|
|
7310e7a3e5 | ||
|
|
ff7219a955 | ||
|
|
97d739e254 | ||
|
|
8f26bbdaa0 | ||
|
|
67ef185a72 | ||
|
|
76954f4a13 | ||
|
|
afb9e6ef71 | ||
|
|
28112a2283 | ||
|
|
c5db6c9201 | ||
|
|
64813d4ba7 | ||
|
|
67e2c061ab | ||
|
|
d149cf01bd | ||
|
|
590c3cf6f8 | ||
|
|
93b25842e2 | ||
|
|
fa240c0e00 | ||
|
|
1b489385b2 | ||
|
|
bac0f99b9b | ||
|
|
8a66249b3d | ||
|
|
77bbe1e213 | ||
|
|
9973fd2970 | ||
|
|
64ea59e4ec | ||
|
|
80b8e676d0 | ||
|
|
867d932e59 | ||
|
|
57fb0d7f3b | ||
|
|
97cc2405a9 | ||
|
|
0022201c4f | ||
|
|
6f6b8d9b3e | ||
|
|
1d2e95f5af | ||
|
|
a0564751d6 | ||
|
|
4edd9fe3da | ||
|
|
5b05fb07ae | ||
|
|
998fed7782 | ||
|
|
c0cc896102 | ||
|
|
2d5790c417 | ||
|
|
1b978d41e0 | ||
|
|
9002365e6d | ||
|
|
c1cc71f85c | ||
|
|
ff599795d3 | ||
|
|
688f50ee3f | ||
|
|
e51fef3037 | ||
|
|
0f6f4e1a50 | ||
|
|
fe0a205a05 | ||
|
|
1059da8a2a | ||
|
|
e41236495f | ||
|
|
7436f94feb | ||
|
|
bcf1e4dc13 | ||
|
|
ba0843d0bb | ||
|
|
5a35960434 | ||
|
|
6eabe5fa8c | ||
|
|
8cb72d8d7d | ||
|
|
f81b5bea9d | ||
|
|
fa45076e48 | ||
|
|
08c07352ae | ||
|
|
94b0028254 | ||
|
|
b77b3e3fc8 | ||
|
|
4db6933c17 | ||
|
|
88160df2e8 | ||
|
|
0220cf9784 | ||
|
|
ef428a0226 | ||
|
|
dc45131f73 | ||
|
|
633d84449a | ||
|
|
c3a779df12 | ||
|
|
280c941899 | ||
|
|
d653bb24cb | ||
|
|
9879378566 | ||
|
|
7b4eb9f1df | ||
|
|
101bcc250e | ||
|
|
dedc1e8131 | ||
|
|
3b4b074bae | ||
|
|
4ee3c7d83e | ||
|
|
d36feebb71 | ||
|
|
6790c318e2 | ||
|
|
e9ef7d4144 | ||
|
|
a3a412d553 | ||
|
|
d0d7a0befc | ||
|
|
6b2e3dcb2a | ||
|
|
ab6d05cac3 | ||
|
|
c46962306e | ||
|
|
821bf6d657 | ||
|
|
f3df1d0a04 | ||
|
|
d7ff7c633d | ||
|
|
06629b0b89 | ||
|
|
ee9ab3d548 | ||
|
|
feb171171d | ||
|
|
21fede0dd0 | ||
|
|
12675dd950 | ||
|
|
5e32878d01 | ||
|
|
9a17a11b37 | ||
|
|
4f2159b54d | ||
|
|
075d459b7c | ||
|
|
e65d0eef6e | ||
|
|
91b7d20f9b | ||
|
|
59d96f2893 | ||
|
|
aa1a521cf0 | ||
|
|
4bb171128e | ||
|
|
a28f561e0c | ||
|
|
3b6c727916 | ||
|
|
447ec63299 | ||
|
|
f1a8d3cc81 | ||
|
|
4d7909e23d | ||
|
|
6f13600fb5 | ||
|
|
c9fefcd8f4 | ||
|
|
fa31483b02 | ||
|
|
e7be0eae8a | ||
|
|
86c70cf232 | ||
|
|
a3490e97c0 | ||
|
|
85b1768908 | ||
|
|
6ab462a795 | ||
|
|
70f46338db | ||
|
|
461b5ad859 | ||
|
|
6af62c6be0 | ||
|
|
78153c2aa4 | ||
|
|
62458885ce | ||
|
|
83d64262c8 | ||
|
|
0133a7c5db | ||
|
|
fa920fed4e | ||
|
|
1d138eed8d | ||
|
|
9e94b9e57e | ||
|
|
c4c690f44f | ||
|
|
902cc21ff0 | ||
|
|
106471877f | ||
|
|
ccaace707e | ||
|
|
cc14a4ac57 | ||
|
|
3ca1e6d197 | ||
|
|
531a6c17de | ||
|
|
4b7e1fcdb0 | ||
|
|
5f35bc5ee6 | ||
|
|
8100f68020 | ||
|
|
32a36bbb12 | ||
|
|
64b9234207 | ||
|
|
a9d490263b | ||
|
|
8c5a3c9b3e | ||
|
|
dd2f8d4404 | ||
|
|
ea82cff0ce | ||
|
|
66ef9a919a | ||
|
|
73b912ee8b | ||
|
|
5960258a89 | ||
|
|
ea7d1f481a | ||
|
|
d81a0ebba4 | ||
|
|
e90fb98613 | ||
|
|
2c34bd36a5 | ||
|
|
a86a582d0f | ||
|
|
c7778ce8cb | ||
|
|
5eaf1f4438 | ||
|
|
691682bc0c | ||
|
|
8627ee391a | ||
|
|
41089a0a0a | ||
|
|
2072a3dd94 | ||
|
|
8eec325e0a | ||
|
|
7ae88b42cf | ||
|
|
24e0839c34 | ||
|
|
c3398d4d51 | ||
|
|
80237d8bc3 | ||
|
|
4cec0a9f97 | ||
|
|
a810eb2cb5 | ||
|
|
7feb4b4aaf | ||
|
|
840fd61b04 | ||
|
|
5425dac180 | ||
|
|
0d65e396d4 | ||
|
|
704fc24d20 | ||
|
|
9b22c16f14 | ||
|
|
2923d1b449 | ||
|
|
9d5b028a5f | ||
|
|
97dfdd5c5d | ||
|
|
eb5ee4d147 | ||
|
|
d97581325d | ||
|
|
2a1e53f32a | ||
|
|
b5e4ac0038 | ||
|
|
b032210a33 | ||
|
|
24a1d61560 | ||
|
|
d632c1c7fc | ||
|
|
9c5b3fc030 | ||
|
|
90e407b9d0 | ||
|
|
dc0a2a2a10 | ||
|
|
b6aa76477e | ||
|
|
068191e08c | ||
|
|
533cd1dbed | ||
|
|
028ef63f6e | ||
|
|
127b6ea515 | ||
|
|
ab546865a8 | ||
|
|
d6a2f2959d | ||
|
|
58848caf30 | ||
|
|
c1107fe854 | ||
|
|
c3debb1a17 | ||
|
|
0c841a12d2 | ||
|
|
64ed9376fe | ||
|
|
1966e12703 | ||
|
|
289ccc7d89 | ||
|
|
590c33c0af | ||
|
|
4e7236a338 | ||
|
|
63b7626aab | ||
|
|
78b88949d8 | ||
|
|
40a7abf9e8 | ||
|
|
cd62dfd8f4 | ||
|
|
4445ad8fe5 | ||
|
|
ed29721677 | ||
|
|
e587f6ec37 | ||
|
|
f98f4b00ba | ||
|
|
78bbcb324b | ||
|
|
d646ab0232 | ||
|
|
1fe36044f1 | ||
|
|
2ea9369f99 | ||
|
|
802e1dbf2d | ||
|
|
b6aca26d8c | ||
|
|
ef653f7b00 | ||
|
|
8e183d8cad | ||
|
|
0ce34048cd | ||
|
|
d46041f22e | ||
|
|
94cf424bbd | ||
|
|
778d700ba8 | ||
|
|
8c1cbd77dd | ||
|
|
954bf779eb | ||
|
|
7fbed452bb | ||
|
|
e32023bb97 | ||
|
|
664a08d42f | ||
|
|
854c7f090b | ||
|
|
a29d056a9b | ||
|
|
7d3ee9f0c4 | ||
|
|
e26d39ab63 | ||
|
|
ecf465958f | ||
|
|
8fa6030341 | ||
|
|
1f6f6dadfa | ||
|
|
ed81eb4edf | ||
|
|
06ff4b808a | ||
|
|
fe5999d5b8 | ||
|
|
9331796dc3 | ||
|
|
0a18c948bc | ||
|
|
595a1fbe34 | ||
|
|
f12db3b8d9 | ||
|
|
2c1da7af31 | ||
|
|
0f9535bfd5 | ||
|
|
961d3c26fc | ||
|
|
bd8e003db8 | ||
|
|
619eb60dd1 | ||
|
|
15948303ec | ||
|
|
ccec203910 | ||
|
|
78122a7d4b | ||
|
|
272c73054e | ||
|
|
aa629523a0 | ||
|
|
3e6aca4cd1 | ||
|
|
891883c8c2 | ||
|
|
98ba392016 | ||
|
|
d49ee83748 | ||
|
|
88cdb1811f | ||
|
|
94c190668c | ||
|
|
eef0f4bd4e | ||
|
|
dad58fa362 | ||
|
|
40585469f2 | ||
|
|
d06035071a | ||
|
|
e81565d36a | ||
|
|
f66dd259f0 | ||
|
|
e003dcd596 | ||
|
|
d4ecf44b08 | ||
|
|
f4426eb830 | ||
|
|
7c86ce3977 | ||
|
|
1665335525 | ||
|
|
14bce014a3 | ||
|
|
75e5115aa3 | ||
|
|
de7638c502 | ||
|
|
126e378399 | ||
|
|
45e9c999b8 | ||
|
|
62bba0d33b | ||
|
|
0b220f3288 | ||
|
|
7dbdf0c4ff | ||
|
|
417b7c3f86 | ||
|
|
724a16944a | ||
|
|
c3bc1af7b5 | ||
|
|
38b7daf3b6 | ||
|
|
7bf7bb529e | ||
|
|
6b5774a66d | ||
|
|
0e3ebb9f1a | ||
|
|
1c41b6753d | ||
|
|
549f3c038a | ||
|
|
edbac66576 | ||
|
|
c788395508 | ||
|
|
35b0c20f88 | ||
|
|
518712d9e8 | ||
|
|
241ad25e2f | ||
|
|
7cf7c5fcef | ||
|
|
fbb9de64c3 | ||
|
|
88c145ac3e | ||
|
|
4aba842624 | ||
|
|
936c2b8888 | ||
|
|
c3e971c419 | ||
|
|
19fee6a8fb | ||
|
|
477eebdbe7 | ||
|
|
093bff750c | ||
|
|
92e679a9ea | ||
|
|
43232ae45c | ||
|
|
1fb13d8697 | ||
|
|
9ac28b93ca | ||
|
|
067c01ca06 | ||
|
|
82040c2a5d | ||
|
|
62502c746c | ||
|
|
6ab79a87fe | ||
|
|
04ee3b4dc1 | ||
|
|
9c9af79ad5 | ||
|
|
dd794e409f | ||
|
|
67d29b8416 | ||
|
|
5ee80dd046 | ||
|
|
f62e93b487 | ||
|
|
a7cc70b975 | ||
|
|
60f0d8074a | ||
|
|
ed1fdf9382 | ||
|
|
9ea3c4224e | ||
|
|
cdb041e647 |
30
.ci/all.sh
Executable file
30
.ci/all.sh
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# all.sh
|
||||||
|
# Copyright (c) 2024 james@firefly-iii.org
|
||||||
|
#
|
||||||
|
# This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
|
echo "Running PHP CS Fixer"
|
||||||
|
$SCRIPT_DIR/phpcs.sh
|
||||||
|
echo "Running PHPStan"
|
||||||
|
$SCRIPT_DIR/phpstan.sh
|
||||||
|
echo "Running PHPMD"
|
||||||
|
$SCRIPT_DIR/phpmd.sh
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
|
||||||
|
|
||||||
$current = __DIR__;
|
$current = __DIR__;
|
||||||
|
|
||||||
$paths = [
|
$paths = [
|
||||||
@@ -27,7 +29,7 @@ $paths = [
|
|||||||
$current . '/../../database',
|
$current . '/../../database',
|
||||||
$current . '/../../routes',
|
$current . '/../../routes',
|
||||||
$current . '/../../tests',
|
$current . '/../../tests',
|
||||||
$current . '/../../resources/lang',
|
$current . '/../../resources/lang/en_US',
|
||||||
];
|
];
|
||||||
|
|
||||||
$finder = PhpCsFixer\Finder::create()
|
$finder = PhpCsFixer\Finder::create()
|
||||||
@@ -35,10 +37,41 @@ $finder = PhpCsFixer\Finder::create()
|
|||||||
|
|
||||||
|
|
||||||
$config = new PhpCsFixer\Config();
|
$config = new PhpCsFixer\Config();
|
||||||
return $config->setRules([
|
$config->setParallelConfig(ParallelConfigFactory::detect());
|
||||||
'@PSR12' => true,
|
return $config->setRules(
|
||||||
'declare_strict_types' => true,
|
[
|
||||||
'strict_param' => true,
|
// rule sets
|
||||||
'array_syntax' => ['syntax' => 'short'],
|
'@PHP83Migration' => true,
|
||||||
])
|
'@PhpCsFixer' => true,
|
||||||
|
'@PhpCsFixer:risky' => true,
|
||||||
|
'@PSR12' => true,
|
||||||
|
'@PSR12:risky' => true,
|
||||||
|
'declare_strict_types' => true,
|
||||||
|
'strict_param' => true,
|
||||||
|
'no_unused_imports' => true,
|
||||||
|
'single_space_around_construct' => true,
|
||||||
|
'statement_indentation' => true,
|
||||||
|
'void_return' => true,
|
||||||
|
|
||||||
|
// disabled rules
|
||||||
|
'native_function_invocation' => false, // annoying
|
||||||
|
'php_unit_data_provider_name' => false, // bloody annoying long test names
|
||||||
|
'static_lambda' => false, // breaks the Response macro for API's.
|
||||||
|
'phpdoc_summary' => false, // annoying.
|
||||||
|
'comment_to_phpdoc' => false, // breaks phpstan lines in combination with PHPStorm.
|
||||||
|
'type_declaration_spaces' => false,
|
||||||
|
'cast_spaces' => false,
|
||||||
|
'phpdoc_to_comment' => false, // do not overrule single line comment style, breaks phpstan.
|
||||||
|
|
||||||
|
// complex rules
|
||||||
|
'array_syntax' => ['syntax' => 'short'],
|
||||||
|
'binary_operator_spaces' => [
|
||||||
|
'default' => 'at_least_single_space',
|
||||||
|
'operators' => [
|
||||||
|
'=>' => 'align_single_space_by_scope',
|
||||||
|
'=' => 'align_single_space_minimal_by_scope',
|
||||||
|
'??=' => 'align_single_space_minimal_by_scope',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
])
|
||||||
->setFinder($finder);
|
->setFinder($finder);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.12"
|
"friendsofphp/php-cs-fixer": "^3.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1256
.ci/php-cs-fixer/composer.lock
generated
1256
.ci/php-cs-fixer/composer.lock
generated
File diff suppressed because it is too large
Load Diff
18
.ci/phpcs.sh
18
.ci/phpcs.sh
@@ -20,19 +20,21 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# 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="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
# enable test .env file.
|
|
||||||
# cp .ci/.env.ci .env
|
|
||||||
|
|
||||||
# clean up php code
|
# clean up php code
|
||||||
cd $SCRIPT_DIR/php-cs-fixer
|
cd $SCRIPT_DIR/php-cs-fixer
|
||||||
composer update --quiet
|
composer update --quiet
|
||||||
rm -f .php-cs-fixer.cache
|
rm -f .php-cs-fixer.cache
|
||||||
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php --allow-risky=yes
|
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
|
||||||
|
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
|
||||||
|
--format=txt -v \
|
||||||
|
--allow-risky=yes
|
||||||
|
|
||||||
|
EXIT_CODE=$?
|
||||||
|
|
||||||
|
echo "Exit code for CS fixer is $EXIT_CODE."
|
||||||
|
|
||||||
cd $SCRIPT_DIR/..
|
cd $SCRIPT_DIR/..
|
||||||
|
|
||||||
exit 0
|
exit $EXIT_CODE
|
||||||
|
|||||||
19
.ci/phpmd.sh
Normal file → Executable file
19
.ci/phpmd.sh
Normal file → Executable file
@@ -22,16 +22,29 @@
|
|||||||
|
|
||||||
|
|
||||||
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
OUTPUT_FORMAT=text
|
||||||
|
|
||||||
|
if [[ $GITHUB_ACTIONS = "true" ]]
|
||||||
|
then
|
||||||
|
OUTPUT_FORMAT=github
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
cd $SCRIPT_DIR/phpmd
|
cd $SCRIPT_DIR/phpmd
|
||||||
composer update --quiet
|
composer update --quiet
|
||||||
./vendor/bin/phpmd \
|
./vendor/bin/phpmd \
|
||||||
$SCRIPT_DIR/../app text phpmd.xml \
|
$SCRIPT_DIR/../app,$SCRIPT_DIR/../database,$SCRIPT_DIR/../routes,$SCRIPT_DIR/../config \
|
||||||
|
$OUTPUT_FORMAT phpmd.xml \
|
||||||
--exclude $SCRIPT_DIR/../app/resources/** \
|
--exclude $SCRIPT_DIR/../app/resources/** \
|
||||||
--exclude $SCRIPT_DIR/../app/frontend/** \
|
--exclude $SCRIPT_DIR/../app/frontend/** \
|
||||||
--exclude $SCRIPT_DIR/../app/public/** \
|
--exclude $SCRIPT_DIR/../app/public/** \
|
||||||
--exclude $SCRIPT_DIR/../app/vendor/** \
|
--exclude $SCRIPT_DIR/../app/vendor/**
|
||||||
|
|
||||||
|
EXIT_CODE=$?
|
||||||
|
|
||||||
cd $SCRIPT_DIR/..
|
cd $SCRIPT_DIR/..
|
||||||
|
|
||||||
exit 0
|
echo "Exit code is $EXIT_CODE."
|
||||||
|
|
||||||
|
# for the time being, exit 0
|
||||||
|
exit $EXIT_CODE
|
||||||
|
|||||||
203
.ci/phpmd/composer.lock
generated
203
.ci/phpmd/composer.lock
generated
@@ -9,16 +9,16 @@
|
|||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "composer/pcre",
|
"name": "composer/pcre",
|
||||||
"version": "3.1.0",
|
"version": "3.1.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/pcre.git",
|
"url": "https://github.com/composer/pcre.git",
|
||||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
|
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
"url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/composer/pcre/issues",
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
"source": "https://github.com/composer/pcre/tree/3.1.0"
|
"source": "https://github.com/composer/pcre/tree/3.1.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -76,20 +76,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-17T09:50:14+00:00"
|
"time": "2024-03-19T10:26:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/xdebug-handler",
|
"name": "composer/xdebug-handler",
|
||||||
"version": "3.0.3",
|
"version": "3.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/xdebug-handler.git",
|
"url": "https://github.com/composer/xdebug-handler.git",
|
||||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c"
|
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
|
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c",
|
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.0",
|
"phpstan/phpstan": "^1.0",
|
||||||
"phpstan/phpstan-strict-rules": "^1.1",
|
"phpstan/phpstan-strict-rules": "^1.1",
|
||||||
"symfony/phpunit-bridge": "^6.0"
|
"phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -124,9 +124,9 @@
|
|||||||
"performance"
|
"performance"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/composer",
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
|
"source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -142,32 +142,32 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-02-25T21:32:43+00:00"
|
"time": "2024-03-26T18:29:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pdepend/pdepend",
|
"name": "pdepend/pdepend",
|
||||||
"version": "2.14.0",
|
"version": "2.16.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/pdepend/pdepend.git",
|
"url": "https://github.com/pdepend/pdepend.git",
|
||||||
"reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1"
|
"reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/1121d4b04af06e33e9659bac3a6741b91cab1de1",
|
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
|
||||||
"reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1",
|
"reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.7",
|
"php": ">=5.3.7",
|
||||||
"symfony/config": "^2.3.0|^3|^4|^5|^6.0",
|
"symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||||
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0",
|
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||||
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0"
|
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||||
|
"symfony/polyfill-mbstring": "^1.19"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"easy-doc/easy-doc": "0.0.0|^1.2.3",
|
"easy-doc/easy-doc": "0.0.0|^1.2.3",
|
||||||
"gregwar/rst": "^1.0",
|
"gregwar/rst": "^1.0",
|
||||||
"phpunit/phpunit": "^4.8.36|^5.7.27",
|
|
||||||
"squizlabs/php_codesniffer": "^2.0.0"
|
"squizlabs/php_codesniffer": "^2.0.0"
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/pdepend/pdepend/issues",
|
"issues": "https://github.com/pdepend/pdepend/issues",
|
||||||
"source": "https://github.com/pdepend/pdepend/tree/2.14.0"
|
"source": "https://github.com/pdepend/pdepend/tree/2.16.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -205,26 +205,26 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-05-26T13:15:18+00:00"
|
"time": "2023-12-17T18:09:59+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpmd/phpmd",
|
"name": "phpmd/phpmd",
|
||||||
"version": "2.13.0",
|
"version": "2.15.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpmd/phpmd.git",
|
"url": "https://github.com/phpmd/phpmd.git",
|
||||||
"reference": "dad0228156856b3ad959992f9748514fa943f3e3"
|
"reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpmd/phpmd/zipball/dad0228156856b3ad959992f9748514fa943f3e3",
|
"url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0",
|
||||||
"reference": "dad0228156856b3ad959992f9748514fa943f3e3",
|
"reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
|
"composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
|
||||||
"ext-xml": "*",
|
"ext-xml": "*",
|
||||||
"pdepend/pdepend": "^2.12.1",
|
"pdepend/pdepend": "^2.16.1",
|
||||||
"php": ">=5.3.9"
|
"php": ">=5.3.9"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@@ -233,8 +233,7 @@
|
|||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"gregwar/rst": "^1.0",
|
"gregwar/rst": "^1.0",
|
||||||
"mikey179/vfsstream": "^1.6.8",
|
"mikey179/vfsstream": "^1.6.8",
|
||||||
"phpunit/phpunit": "^4.8.36 || ^5.7.27",
|
"squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2"
|
||||||
"squizlabs/php_codesniffer": "^2.0"
|
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
"src/bin/phpmd"
|
"src/bin/phpmd"
|
||||||
@@ -271,6 +270,7 @@
|
|||||||
"description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
|
"description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
|
||||||
"homepage": "https://phpmd.org/",
|
"homepage": "https://phpmd.org/",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
"dev",
|
||||||
"mess detection",
|
"mess detection",
|
||||||
"mess detector",
|
"mess detector",
|
||||||
"pdepend",
|
"pdepend",
|
||||||
@@ -280,7 +280,7 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/phpmd",
|
"irc": "irc://irc.freenode.org/phpmd",
|
||||||
"issues": "https://github.com/phpmd/phpmd/issues",
|
"issues": "https://github.com/phpmd/phpmd/issues",
|
||||||
"source": "https://github.com/phpmd/phpmd/tree/2.13.0"
|
"source": "https://github.com/phpmd/phpmd/tree/2.15.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -288,7 +288,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-09-10T08:44:15+00:00"
|
"time": "2023-12-11T08:22:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@@ -395,34 +395,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/config",
|
"name": "symfony/config",
|
||||||
"version": "v6.3.0",
|
"version": "v7.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/config.git",
|
"url": "https://github.com/symfony/config.git",
|
||||||
"reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae"
|
"reference": "44deeba7233f08f383185ffa37dace3b3bc87364"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/config/zipball/a5e00dec161b08c946a2c16eed02adbeedf827ae",
|
"url": "https://api.github.com/repos/symfony/config/zipball/44deeba7233f08f383185ffa37dace3b3bc87364",
|
||||||
"reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae",
|
"reference": "44deeba7233f08f383185ffa37dace3b3bc87364",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1",
|
"php": ">=8.2",
|
||||||
"symfony/deprecation-contracts": "^2.5|^3",
|
"symfony/deprecation-contracts": "^2.5|^3",
|
||||||
"symfony/filesystem": "^5.4|^6.0",
|
"symfony/filesystem": "^6.4|^7.0",
|
||||||
"symfony/polyfill-ctype": "~1.8"
|
"symfony/polyfill-ctype": "~1.8"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/finder": "<5.4",
|
"symfony/finder": "<6.4",
|
||||||
"symfony/service-contracts": "<2.5"
|
"symfony/service-contracts": "<2.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/event-dispatcher": "^5.4|^6.0",
|
"symfony/event-dispatcher": "^6.4|^7.0",
|
||||||
"symfony/finder": "^5.4|^6.0",
|
"symfony/finder": "^6.4|^7.0",
|
||||||
"symfony/messenger": "^5.4|^6.0",
|
"symfony/messenger": "^6.4|^7.0",
|
||||||
"symfony/service-contracts": "^2.5|^3",
|
"symfony/service-contracts": "^2.5|^3",
|
||||||
"symfony/yaml": "^5.4|^6.0"
|
"symfony/yaml": "^6.4|^7.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -450,7 +450,7 @@
|
|||||||
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/config/tree/v6.3.0"
|
"source": "https://github.com/symfony/config/tree/v7.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -466,44 +466,43 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-04-25T10:46:17+00:00"
|
"time": "2024-02-26T07:52:39+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/dependency-injection",
|
"name": "symfony/dependency-injection",
|
||||||
"version": "v6.3.1",
|
"version": "v7.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/dependency-injection.git",
|
"url": "https://github.com/symfony/dependency-injection.git",
|
||||||
"reference": "7abf242af21f196b65f20ab00ff251fdf3889b8d"
|
"reference": "47f37af245df8457ea63409fc242b3cc825ce5eb"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7abf242af21f196b65f20ab00ff251fdf3889b8d",
|
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/47f37af245df8457ea63409fc242b3cc825ce5eb",
|
||||||
"reference": "7abf242af21f196b65f20ab00ff251fdf3889b8d",
|
"reference": "47f37af245df8457ea63409fc242b3cc825ce5eb",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1",
|
"php": ">=8.2",
|
||||||
"psr/container": "^1.1|^2.0",
|
"psr/container": "^1.1|^2.0",
|
||||||
"symfony/deprecation-contracts": "^2.5|^3",
|
"symfony/deprecation-contracts": "^2.5|^3",
|
||||||
"symfony/service-contracts": "^2.5|^3.0",
|
"symfony/service-contracts": "^3.3",
|
||||||
"symfony/var-exporter": "^6.2.10"
|
"symfony/var-exporter": "^6.4|^7.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"ext-psr": "<1.1|>=2",
|
"ext-psr": "<1.1|>=2",
|
||||||
"symfony/config": "<6.1",
|
"symfony/config": "<6.4",
|
||||||
"symfony/finder": "<5.4",
|
"symfony/finder": "<6.4",
|
||||||
"symfony/proxy-manager-bridge": "<6.3",
|
"symfony/yaml": "<6.4"
|
||||||
"symfony/yaml": "<5.4"
|
|
||||||
},
|
},
|
||||||
"provide": {
|
"provide": {
|
||||||
"psr/container-implementation": "1.1|2.0",
|
"psr/container-implementation": "1.1|2.0",
|
||||||
"symfony/service-implementation": "1.1|2.0|3.0"
|
"symfony/service-implementation": "1.1|2.0|3.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/config": "^6.1",
|
"symfony/config": "^6.4|^7.0",
|
||||||
"symfony/expression-language": "^5.4|^6.0",
|
"symfony/expression-language": "^6.4|^7.0",
|
||||||
"symfony/yaml": "^5.4|^6.0"
|
"symfony/yaml": "^6.4|^7.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -531,7 +530,7 @@
|
|||||||
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/dependency-injection/tree/v6.3.1"
|
"source": "https://github.com/symfony/dependency-injection/tree/v7.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -547,11 +546,11 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-06-24T11:51:27+00:00"
|
"time": "2024-02-22T20:27:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
"version": "v3.3.0",
|
"version": "v3.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||||
@@ -598,7 +597,7 @@
|
|||||||
"description": "A generic function and convention to trigger deprecation notices",
|
"description": "A generic function and convention to trigger deprecation notices",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
|
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -618,20 +617,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/filesystem",
|
"name": "symfony/filesystem",
|
||||||
"version": "v6.3.1",
|
"version": "v7.0.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/filesystem.git",
|
"url": "https://github.com/symfony/filesystem.git",
|
||||||
"reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae"
|
"reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
|
"url": "https://api.github.com/repos/symfony/filesystem/zipball/2890e3a825bc0c0558526c04499c13f83e1b6b12",
|
||||||
"reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
|
"reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1",
|
"php": ">=8.2",
|
||||||
"symfony/polyfill-ctype": "~1.8",
|
"symfony/polyfill-ctype": "~1.8",
|
||||||
"symfony/polyfill-mbstring": "~1.8"
|
"symfony/polyfill-mbstring": "~1.8"
|
||||||
},
|
},
|
||||||
@@ -661,7 +660,7 @@
|
|||||||
"description": "Provides basic utilities for the filesystem",
|
"description": "Provides basic utilities for the filesystem",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/filesystem/tree/v6.3.1"
|
"source": "https://github.com/symfony/filesystem/tree/v7.0.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -677,20 +676,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-06-01T08:30:39+00:00"
|
"time": "2024-01-23T15:02:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
|
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
|
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -704,9 +703,6 @@
|
|||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
@@ -743,7 +739,7 @@
|
|||||||
"portable"
|
"portable"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -759,20 +755,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
|
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -786,9 +782,6 @@
|
|||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
@@ -826,7 +819,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -842,25 +835,25 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
"version": "v3.3.0",
|
"version": "v3.4.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/service-contracts.git",
|
"url": "https://github.com/symfony/service-contracts.git",
|
||||||
"reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
|
"reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
|
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
|
||||||
"reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
|
"reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1",
|
"php": ">=8.1",
|
||||||
"psr/container": "^2.0"
|
"psr/container": "^1.1|^2.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"ext-psr": "<1.1|>=2"
|
"ext-psr": "<1.1|>=2"
|
||||||
@@ -908,7 +901,7 @@
|
|||||||
"standards"
|
"standards"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
|
"source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -924,27 +917,27 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-05-23T14:45:45+00:00"
|
"time": "2023-12-26T14:02:43+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/var-exporter",
|
"name": "symfony/var-exporter",
|
||||||
"version": "v6.3.0",
|
"version": "v7.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/var-exporter.git",
|
"url": "https://github.com/symfony/var-exporter.git",
|
||||||
"reference": "db5416d04269f2827d8c54331ba4cfa42620d350"
|
"reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/db5416d04269f2827d8c54331ba4cfa42620d350",
|
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
|
||||||
"reference": "db5416d04269f2827d8c54331ba4cfa42620d350",
|
"reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1"
|
"php": ">=8.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": "^5.4|^6.0"
|
"symfony/var-dumper": "^6.4|^7.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -982,7 +975,7 @@
|
|||||||
"serialize"
|
"serialize"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/var-exporter/tree/v6.3.0"
|
"source": "https://github.com/symfony/var-exporter/tree/v7.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -998,7 +991,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-04-21T08:48:44+00:00"
|
"time": "2024-02-26T10:35:24+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
@@ -1008,5 +1001,5 @@
|
|||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": [],
|
"platform": [],
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.3.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,54 +19,76 @@
|
|||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<ruleset name="pcsg-generated-ruleset"
|
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
name="pcsg-generated-ruleset"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||||
<description>Bla bla</description>
|
<description>Firefly III ruleset.</description>
|
||||||
|
<!-- Import the entire controversial code rule set -->
|
||||||
|
<rule ref="rulesets/controversial.xml">
|
||||||
|
<exclude name="CamelCasePropertyName"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
<!--
|
<!-- clean code -->
|
||||||
Commando vanuit firefly directory:
|
<!-- <rule ref="rulesets/codesize.xml" /> -->
|
||||||
phpmd database,app,tests html /gdrive-all/development/phpmd/phpmd.xml > public/report.html
|
<rule ref="rulesets/unusedcode.xml"/>
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Import the entire controversial code rule set -->
|
|
||||||
<rule ref="rulesets/controversial.xml">
|
|
||||||
<exclude name="CamelCasePropertyName" />
|
|
||||||
</rule>
|
|
||||||
|
|
||||||
<!-- clean code -->
|
<rule ref="rulesets/design.xml/NumberOfChildren">
|
||||||
<rule ref="rulesets/codesize.xml" />
|
<properties>
|
||||||
<rule ref="rulesets/design.xml" />
|
<!-- This is now at 32, which excludes the controllers but should prevent more monoliths. -->
|
||||||
<rule ref="rulesets/naming.xml" />
|
<property name="minimum" value="32"/>
|
||||||
<rule ref="rulesets/unusedcode.xml" />
|
</properties>
|
||||||
|
</rule>
|
||||||
|
<rule ref="rulesets/design.xml/CouplingBetweenObjects">
|
||||||
|
<properties>
|
||||||
|
<!-- Leaving this at 28 excuses most current code but it can't get worse than that. -->
|
||||||
|
<property name="maximum" value="28"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
|
|
||||||
<properties>
|
|
||||||
<property name="reportLevel" value="5"/>
|
|
||||||
</properties>
|
|
||||||
</rule>
|
|
||||||
<rule ref="rulesets/codesize.xml/NPathComplexity">
|
|
||||||
<properties>
|
|
||||||
<property name="minimum" value="128"/>
|
|
||||||
</properties>
|
|
||||||
</rule>
|
|
||||||
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength">
|
|
||||||
<properties>
|
|
||||||
<property name="minimum" value="40"/>
|
|
||||||
</properties>
|
|
||||||
</rule>
|
|
||||||
<rule ref="rulesets/codesize.xml/ExcessiveParameterList">
|
|
||||||
<properties>
|
|
||||||
<property name="minimum" value="5"/>
|
|
||||||
</properties>
|
|
||||||
</rule>
|
|
||||||
|
|
||||||
<!-- include clean code manually -->
|
<rule ref="rulesets/naming.xml/ShortMethodName">
|
||||||
<rule ref="rulesets/cleancode.xml/BooleanArgumentFlag" />
|
<properties>
|
||||||
<rule ref="rulesets/cleancode.xml/ElseExpression" />
|
<property name="minimum" value="3"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
<!-- no this one -->
|
<!-- code size -->
|
||||||
<!--<rule ref="rulesets/cleancode.xml/StaticAccess" />-->
|
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
|
||||||
|
<properties>
|
||||||
|
<!-- Leave at 20. This means methods will be pretty complex before the system starts complaining. -->
|
||||||
|
<property name="reportLevel" value="20"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
<rule ref="rulesets/codesize.xml/NPathComplexity">
|
||||||
|
<properties>
|
||||||
|
<!-- 2000 results in some pretty complex methods, but it's OK. -->
|
||||||
|
<!-- They should not be much more complex than that though -->
|
||||||
|
<property name="minimum" value="2000"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength">
|
||||||
|
<properties>
|
||||||
|
<!-- 75 seems like a nice number. Shorter isn't always feasible and there are a few exceptions already -->
|
||||||
|
<property name="minimum" value="75"/>
|
||||||
|
<property name="ignore-whitespace" value="true"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
<rule ref="rulesets/codesize.xml/ExcessiveParameterList">
|
||||||
|
<properties>
|
||||||
|
<!-- 5 is fine. 6 is excessive, but I have just one of those. At the end of the day, I still need all params. -->
|
||||||
|
<property name="minimum" value="5"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- include clean code manually -->
|
||||||
|
<rule ref="rulesets/cleancode.xml/BooleanArgumentFlag"/>
|
||||||
|
<rule ref="rulesets/cleancode.xml/ElseExpression"/>
|
||||||
|
<rule ref="rulesets/cleancode.xml/MissingImport"/>
|
||||||
|
<rule ref="rulesets/cleancode.xml/UndefinedVariable"/>
|
||||||
|
<rule ref="rulesets/cleancode.xml/IfStatementAssignment"/>
|
||||||
|
<rule ref="rulesets/cleancode.xml/DuplicatedArrayKey"/>
|
||||||
|
<rule ref="rulesets/cleancode.xml/ErrorControlOperator"/>
|
||||||
</ruleset>
|
</ruleset>
|
||||||
|
|||||||
@@ -1,70 +1,38 @@
|
|||||||
includes:
|
|
||||||
- ../vendor/nunomaduro/larastan/extension.neon
|
|
||||||
- ../vendor/ergebnis/phpstan-rules/rules.neon
|
|
||||||
- ../vendor/phpstan/phpstan-deprecation-rules/rules.neon
|
|
||||||
- ../vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
|
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
ignoreErrors:
|
scanFiles:
|
||||||
- '#is not allowed to extend#'
|
- ../_ide_helper
|
||||||
- '#is neither abstract nor final#'
|
|
||||||
- '#has a nullable return type declaration#'
|
|
||||||
- '#with a nullable type declaration#'
|
|
||||||
- '#with null as default value#'
|
|
||||||
- '#is not covariant with PHPDoc type array#'
|
|
||||||
-
|
|
||||||
message: '#but containers should not be injected#'
|
|
||||||
paths:
|
|
||||||
- ../app/Support/Authentication/RemoteUserGuard.php
|
|
||||||
-
|
|
||||||
message: '#Control structures using switch should not be used.#'
|
|
||||||
paths:
|
|
||||||
- ../app/Api/V1/Controllers/Data/DestroyController.php
|
|
||||||
- ../app/Console/Commands/Correction/FixAccountTypes.php
|
|
||||||
- ../app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php
|
|
||||||
- ../app/Exceptions/GracefulNotFoundHandler.php
|
|
||||||
- ../app/Generator/Webhook/StandardMessageGenerator.php
|
|
||||||
- ../app/Support/Amount.php
|
|
||||||
- ../app/Support/Navigation.php
|
|
||||||
- ../app/Support/ParseDateString.php
|
|
||||||
- ../app/Support/Search/AccountSearch.php
|
|
||||||
- ../app/Support/Search/OperatorQuerySearch.php
|
|
||||||
- ../app/Support/Twig/General.php
|
|
||||||
- ../app/Transformers/RecurrenceTransformer.php
|
|
||||||
- ../app/Validation/AccountValidator.php
|
|
||||||
- ../app/Validation/RecurrenceValidation.php
|
|
||||||
- ../app/Validation/TransactionValidation.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: '#Function compact\(\) should not be used#'
|
|
||||||
paths:
|
|
||||||
- ../app/Generator/Report/Account/MonthReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Audit/MonthReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Budget/MonthReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Category/MonthReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Standard/MonthReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Standard/MultiYearReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Standard/YearReportGenerator.php
|
|
||||||
- ../app/Generator/Report/Tag/MonthReportGenerator.php
|
|
||||||
- ../app/Http/Controllers/Account/*.php
|
|
||||||
- ../app/Http/Controllers/Admin/*.php
|
|
||||||
- ../app/Http/Controllers/*.php
|
|
||||||
- ../app/Support/ExpandedForm.php
|
|
||||||
- ../app/Support/Form/AccountForm.php
|
|
||||||
- ../app/Support/Form/CurrencyForm.php
|
|
||||||
- ../app/Support/Form/FormSupport.php
|
|
||||||
-
|
|
||||||
message: '#Either catch a more specific exception#'
|
|
||||||
paths:
|
|
||||||
- ../app/Support/Form/FormSupport.php
|
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
- ../app
|
- ../app
|
||||||
- ../database
|
- ../database
|
||||||
- ../routes
|
- ../routes
|
||||||
- ../config
|
- ../config
|
||||||
- ../bootstrap/app.php
|
- ../bootstrap/app.php
|
||||||
|
universalObjectCratesClasses:
|
||||||
|
- Illuminate\Database\Eloquent\Model
|
||||||
|
# TODO: slowly remove these parameters and fix the issues found.
|
||||||
|
reportUnmatchedIgnoredErrors: true
|
||||||
|
ignoreErrors:
|
||||||
|
# TODO: slowly remove these exceptions and fix the issues found.
|
||||||
|
- '#Dynamic call to static method#' # all the Laravel ORM things depend on this.
|
||||||
|
- identifier: varTag.nativeType
|
||||||
|
- identifier: varTag.type
|
||||||
|
-
|
||||||
|
identifier: larastan.noEnvCallsOutsideOfConfig
|
||||||
|
path: ../app/Console/Commands/System/CreatesDatabase.php
|
||||||
|
- identifier: missingType.iterableValue # not interesting enough to fix.
|
||||||
|
- identifier: missingType.generics # not interesting enough to fix.
|
||||||
|
- "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
|
||||||
|
- '#expects view-string, string given#'
|
||||||
|
- '#expects view-string\|null, string given#'
|
||||||
|
|
||||||
|
# phpstan can't handle this so we ignore them.
|
||||||
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#'
|
||||||
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#'
|
||||||
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#'
|
||||||
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#'
|
||||||
|
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#'
|
||||||
|
|
||||||
# The level 8 is the highest level. original was 5
|
# The level 8 is the highest level. original was 5
|
||||||
level: 4
|
# 7 is more than enough, higher just leaves NULL things.
|
||||||
|
level: 7
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,20 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|||||||
# cp .ci/.env.ci .env
|
# cp .ci/.env.ci .env
|
||||||
|
|
||||||
# Do static code analysis.
|
# Do static code analysis.
|
||||||
# ./vendor/bin/phpstan analyse -c .ci/phpstan.neon --no-progress
|
if [[ $GITHUB_ACTIONS = "" ]]
|
||||||
./vendor/bin/phpstan analyse -c .ci/phpstan.neon --xdebug --error-format=table > phpstan-report.txt
|
then
|
||||||
|
./vendor/bin/phpstan analyse -c .ci/phpstan.neon --error-format=table > phpstan-report.txt
|
||||||
|
EXIT_CODE=$?
|
||||||
|
echo "The PHPstan report can be found in phpstan-report.txt. Exit code is $EXIT_CODE."
|
||||||
|
fi
|
||||||
|
|
||||||
echo 'The PHPstan report can be found in phpstan-report.txt'
|
if [[ $GITHUB_ACTIONS = "true" ]]
|
||||||
|
then
|
||||||
|
./vendor/bin/phpstan analyse -c .ci/phpstan.neon --no-progress --error-format=github
|
||||||
|
EXIT_CODE=$?
|
||||||
|
|
||||||
|
# temporary exit code 0
|
||||||
|
# EXIT_CODE=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $EXIT_CODE
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# phpunit.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/>.
|
|
||||||
#
|
|
||||||
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
|
||||||
# enable test .env file.
|
|
||||||
cp $SCRIPT_DIR/../.env $SCRIPT_DIR/../.env.backup
|
|
||||||
cp $SCRIPT_DIR/.env.ci $SCRIPT_DIR/../.env
|
|
||||||
|
|
||||||
COVERAGE=false
|
|
||||||
RESET=false
|
|
||||||
FILE=storage/database/database.sqlite
|
|
||||||
|
|
||||||
while getopts "cr" o; do
|
|
||||||
case "${o}" in
|
|
||||||
c) COVERAGE=true;;
|
|
||||||
r) RESET=true;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# reset if necessary.
|
|
||||||
if [ $RESET = "true" ] ; then
|
|
||||||
rm -f $FILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
# download test database
|
|
||||||
if [ -f "$FILE" ]; then
|
|
||||||
echo 'DB exists, will use it'
|
|
||||||
else
|
|
||||||
echo 'Download new DB'
|
|
||||||
wget --quiet https://github.com/firefly-iii/test-fixtures/raw/main/test-database.sqlite -O $FILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
# run phpunit
|
|
||||||
if [ $COVERAGE = "true" ] ; then
|
|
||||||
echo 'Run with coverage'
|
|
||||||
XDEBUG_MODE=coverage ./vendor/bin/phpunit --configuration phpunit.xml --coverage-html $SCRIPT_DIR/coverage
|
|
||||||
else
|
|
||||||
echo 'Run without coverage'
|
|
||||||
./vendor/bin/phpunit --configuration phpunit.xml
|
|
||||||
fi
|
|
||||||
|
|
||||||
# restore .env file
|
|
||||||
mv $SCRIPT_DIR/../.env.backup $SCRIPT_DIR/../.env
|
|
||||||
|
|
||||||
cd $SCRIPT_DIR/..
|
|
||||||
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
|
||||||
95
.env.example
95
.env.example
@@ -1,6 +1,6 @@
|
|||||||
# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
|
# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
|
||||||
# Never set it to "testing".
|
# Never set it to "testing".
|
||||||
APP_ENV=local
|
APP_ENV=production
|
||||||
|
|
||||||
# Set to true if you want to see debug information in error screens.
|
# Set to true if you want to see debug information in error screens.
|
||||||
APP_DEBUG=false
|
APP_DEBUG=false
|
||||||
@@ -19,7 +19,7 @@ SITE_OWNER=mail@example.com
|
|||||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||||
|
|
||||||
# Firefly III will launch using this language (for new users and unauthenticated visitors)
|
# Firefly III will launch using this language (for new users and unauthenticated visitors)
|
||||||
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/main/resources/lang
|
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/blob/main/config/firefly.php#L123
|
||||||
#
|
#
|
||||||
# If text is still in English, remember that not everything may have been translated.
|
# If text is still in English, remember that not everything may have been translated.
|
||||||
DEFAULT_LANGUAGE=en_US
|
DEFAULT_LANGUAGE=en_US
|
||||||
@@ -78,7 +78,7 @@ PAPERTRAIL_HOST=
|
|||||||
PAPERTRAIL_PORT=
|
PAPERTRAIL_PORT=
|
||||||
|
|
||||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
|
# For other database types, please see the FAQ: https://docs.firefly-iii.org/references/faq/install/#i-want-to-use-sqlite
|
||||||
# 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
|
||||||
# Use "pgsql" for PostgreSQL
|
# Use "pgsql" for PostgreSQL
|
||||||
# Use "mysql" for MySQL and MariaDB.
|
# Use "mysql" for MySQL and MariaDB.
|
||||||
@@ -111,7 +111,10 @@ PGSQL_SSL_CERT=null
|
|||||||
PGSQL_SSL_KEY=null
|
PGSQL_SSL_KEY=null
|
||||||
PGSQL_SSL_CRL_FILE=null
|
PGSQL_SSL_CRL_FILE=null
|
||||||
|
|
||||||
# more PostgreSQL settings
|
# For postgresql 15 and up, setting this to public will no longer work as expected, becasuse the
|
||||||
|
# 'public' schema is without grants. This can be worked around by having a super user grant those
|
||||||
|
# necessary privileges, but in security conscious setups that's not viable.
|
||||||
|
# You will need to set this to the schema you want to use.
|
||||||
PGSQL_SCHEMA=public
|
PGSQL_SCHEMA=public
|
||||||
|
|
||||||
# If you're looking for performance improvements, you could install memcached or redis
|
# If you're looking for performance improvements, you could install memcached or redis
|
||||||
@@ -122,7 +125,7 @@ SESSION_DRIVER=file
|
|||||||
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
|
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
|
||||||
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
|
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
|
||||||
|
|
||||||
# can be tcp, unix or http
|
# can be tcp or unix. http is not supported
|
||||||
REDIS_SCHEME=tcp
|
REDIS_SCHEME=tcp
|
||||||
|
|
||||||
# use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
|
# use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
|
||||||
@@ -150,7 +153,7 @@ COOKIE_SECURE=false
|
|||||||
COOKIE_SAMESITE=lax
|
COOKIE_SAMESITE=lax
|
||||||
|
|
||||||
# If you want Firefly III to email you, update these settings
|
# If you want Firefly III to email you, update these settings
|
||||||
# For instructions, see: https://docs.firefly-iii.org/firefly-iii/advanced-installation/email/#email
|
# For instructions, see: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/notifications/#email
|
||||||
# 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
|
||||||
MAIL_MAILER=log
|
MAIL_MAILER=log
|
||||||
MAIL_HOST=null
|
MAIL_HOST=null
|
||||||
@@ -161,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=
|
||||||
@@ -173,6 +183,7 @@ MAILGUN_ENDPOINT=api.mailgun.net
|
|||||||
# 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
|
||||||
MANDRILL_SECRET=
|
MANDRILL_SECRET=
|
||||||
SPARKPOST_SECRET=
|
SPARKPOST_SECRET=
|
||||||
|
MAILERSEND_API_KEY=
|
||||||
|
|
||||||
# Firefly III can send you the following messages.
|
# Firefly III can send you the following messages.
|
||||||
SEND_ERROR_MESSAGE=true
|
SEND_ERROR_MESSAGE=true
|
||||||
@@ -184,6 +195,11 @@ SEND_REPORT_JOURNALS=true
|
|||||||
# Since this involves an external service, it's optional and disabled by default.
|
# Since this involves an external service, it's optional and disabled by default.
|
||||||
ENABLE_EXTERNAL_MAP=false
|
ENABLE_EXTERNAL_MAP=false
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable or disable exchange rate conversion.
|
||||||
|
#
|
||||||
|
ENABLE_EXCHANGE_RATES=false
|
||||||
|
|
||||||
# Set this value to true if you want Firefly III to download currency exchange rates
|
# Set this value to true if you want Firefly III to download currency exchange rates
|
||||||
# from the internet. These rates are hosted by the creator of Firefly III inside
|
# from the internet. These rates are hosted by the creator of Firefly III inside
|
||||||
# an Azure Storage Container.
|
# an Azure Storage Container.
|
||||||
@@ -195,6 +211,16 @@ MAP_DEFAULT_LAT=51.983333
|
|||||||
MAP_DEFAULT_LONG=5.916667
|
MAP_DEFAULT_LONG=5.916667
|
||||||
MAP_DEFAULT_ZOOM=6
|
MAP_DEFAULT_ZOOM=6
|
||||||
|
|
||||||
|
#
|
||||||
|
# Some objects have room for an URL, like transactions and webhooks.
|
||||||
|
# By default, the following protocols are allowed:
|
||||||
|
# http, https, ftp, ftps, mailto
|
||||||
|
#
|
||||||
|
# To change this, set your preferred comma separated set below.
|
||||||
|
# Be sure to include http, https and other default ones if you need to.
|
||||||
|
#
|
||||||
|
VALID_URL_PROTOCOLS=
|
||||||
|
|
||||||
#
|
#
|
||||||
# Firefly III authentication settings
|
# Firefly III authentication settings
|
||||||
#
|
#
|
||||||
@@ -204,7 +230,7 @@ MAP_DEFAULT_ZOOM=6
|
|||||||
# - 'web' (default, uses built in DB)
|
# - 'web' (default, uses built in DB)
|
||||||
# - 'remote_user_guard' for Authelia etc
|
# - 'remote_user_guard' for Authelia etc
|
||||||
# Read more about these settings in the documentation.
|
# Read more about these settings in the documentation.
|
||||||
# https://docs.firefly-iii.org/firefly-iii/advanced-installation/authentication
|
# https://docs.firefly-iii.org/how-to/firefly-iii/advanced/authentication/
|
||||||
#
|
#
|
||||||
# LDAP is no longer supported :(
|
# LDAP is no longer supported :(
|
||||||
#
|
#
|
||||||
@@ -259,7 +285,7 @@ ALLOW_WEBHOOKS=false
|
|||||||
# 1. Set this token to any 32-character value (this is important!).
|
# 1. Set this token to any 32-character value (this is important!).
|
||||||
# 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
|
# 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
|
||||||
#
|
#
|
||||||
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
|
# For more info: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/cron/
|
||||||
#
|
#
|
||||||
# You can set this variable from a file by appending it with _FILE
|
# You can set this variable from a file by appending it with _FILE
|
||||||
#
|
#
|
||||||
@@ -270,38 +296,10 @@ 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
|
||||||
|
|
||||||
# Run database creation and migration commands. Disable this only if you're 100% sure the DB exists
|
|
||||||
# and is up to date.
|
|
||||||
DKR_RUN_MIGRATION=true
|
|
||||||
|
|
||||||
# Run database upgrade commands. Disable this only when you're 100% sure your DB is up-to-date
|
|
||||||
# with the latest fixes (outside of migrations!)
|
|
||||||
DKR_RUN_UPGRADE=true
|
|
||||||
|
|
||||||
# Verify database integrity. Includes all data checks and verifications.
|
|
||||||
# Disabling this makes Firefly III assume your DB is intact.
|
|
||||||
DKR_RUN_VERIFY=true
|
|
||||||
|
|
||||||
# Run database reporting commands. When disabled, Firefly III won't go over your data to report current state.
|
|
||||||
# Disabling this should have no impact on data integrity or safety but it won't warn you of possible issues.
|
|
||||||
DKR_RUN_REPORT=true
|
|
||||||
|
|
||||||
# Generate OAuth2 keys.
|
|
||||||
# When disabled, Firefly III won't attempt to generate OAuth2 Passport keys. This won't be an issue, IFF (if and only if)
|
|
||||||
# you had previously generated keys already and they're stored in your database for restoration.
|
|
||||||
DKR_RUN_PASSPORT_INSTALL=true
|
|
||||||
|
|
||||||
# Leave the following configuration vars as is.
|
# Leave the following configuration vars as is.
|
||||||
# Unless you like to tinker and know what you're doing.
|
# Unless you like to tinker and know what you're doing.
|
||||||
APP_NAME=FireflyIII
|
APP_NAME=FireflyIII
|
||||||
@@ -314,18 +312,27 @@ PUSHER_SECRET=
|
|||||||
PUSHER_ID=
|
PUSHER_ID=
|
||||||
DEMO_USERNAME=
|
DEMO_USERNAME=
|
||||||
DEMO_PASSWORD=
|
DEMO_PASSWORD=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Disable or enable the running balance column data
|
||||||
|
# Please disable this. It's a very experimental feature.
|
||||||
|
#
|
||||||
|
USE_RUNNING_BALANCE=false
|
||||||
|
|
||||||
|
#
|
||||||
|
# The v2 layout is very experimental. If it breaks you get to keep both parts.
|
||||||
|
# Be wary of data loss.
|
||||||
|
#
|
||||||
FIREFLY_III_LAYOUT=v1
|
FIREFLY_III_LAYOUT=v1
|
||||||
|
|
||||||
#
|
#
|
||||||
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
|
# Which Query Parser implementation to use for the search engine and rules
|
||||||
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
|
# 'new' is experimental, 'legacy' is the classic one
|
||||||
# This configuration value WILL NOT HELP.
|
|
||||||
#
|
#
|
||||||
# Notable exception to this rule is Synology, which, according to some users, will use APP_URL to rewrite stuff.
|
QUERY_PARSER_IMPLEMENTATION=legacy
|
||||||
|
|
||||||
#
|
#
|
||||||
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
|
# Please make sure this URL matches the external URL of your Firefly III installation.
|
||||||
# So when configuring anything WEB related this variable doesn't do anything. Nothing
|
# It is used to validate specific requests and to generate URLs in emails.
|
||||||
#
|
|
||||||
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
|
|
||||||
#
|
#
|
||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
|
|||||||
26
.env.testing
Normal file
26
.env.testing
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
APP_ENV=testing
|
||||||
|
APP_DEBUG=true
|
||||||
|
SITE_OWNER=mail@example.com
|
||||||
|
APP_KEY=TestTestTestTestTestTestTestTest
|
||||||
|
DEFAULT_LANGUAGE=en_US
|
||||||
|
DEFAULT_LOCALE=equal
|
||||||
|
TZ=Europe/Amsterdam
|
||||||
|
LOG_CHANNEL=stdout
|
||||||
|
APP_LOG_LEVEL=debug
|
||||||
|
AUDIT_LOG_LEVEL=info
|
||||||
|
AUDIT_LOG_CHANNEL=audit_stdout
|
||||||
|
DB_CONNECTION=sqlite
|
||||||
|
CACHE_DRIVER=array
|
||||||
|
SESSION_DRIVER=array
|
||||||
|
MAIL_MAILER=log
|
||||||
|
SEND_ERROR_MESSAGE=true
|
||||||
|
ENABLE_EXTERNAL_MAP=false
|
||||||
|
ENABLE_EXTERNAL_RATES=true
|
||||||
|
AUTHENTICATION_GUARD=web
|
||||||
|
ALLOW_WEBHOOKS=true
|
||||||
|
APP_NAME=FireflyIII
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
QUEUE_DRIVER=sync
|
||||||
|
CACHE_PREFIX=firefly
|
||||||
|
FIREFLY_III_LAYOUT=v1
|
||||||
|
APP_URL=http://localhost
|
||||||
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# code owners for this Firefly III related repository
|
||||||
|
* @JC5 @SDx3
|
||||||
2
.github/ISSUE_TEMPLATE/fr.yml
vendored
2
.github/ISSUE_TEMPLATE/fr.yml
vendored
@@ -8,7 +8,7 @@ body:
|
|||||||
options:
|
options:
|
||||||
- label: I've read the [support guidelines](https://github.com/firefly-iii/firefly-iii/blob/main/.github/support.md)
|
- label: I've read the [support guidelines](https://github.com/firefly-iii/firefly-iii/blob/main/.github/support.md)
|
||||||
required: true
|
required: true
|
||||||
- label: My request is not listed as [a very good idea, but unfortunately...](https://docs.firefly-iii.org/firefly-iii/more-information/what-its-not/)
|
- label: My request is not listed as [a very good idea, but unfortunately...](https://docs.firefly-iii.org/explanation/more-information/what-its-not/)
|
||||||
required: true
|
required: true
|
||||||
- label: I've used [the search](https://github.com/firefly-iii/firefly-iii/issues?q=is%3Aissue) and this has not been requested before.
|
- label: I've used [the search](https://github.com/firefly-iii/firefly-iii/issues?q=is%3Aissue) and this has not been requested before.
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
4
.github/contributing.md
vendored
4
.github/contributing.md
vendored
@@ -1,3 +1,3 @@
|
|||||||
# [Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
|
# [Contributing guidelines](https://docs.firefly-iii.org/explanation/support/#contributing-code)
|
||||||
|
|
||||||
[Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
|
[Contributing guidelines](https://docs.firefly-iii.org/explanation/support/#contributing-code)
|
||||||
|
|||||||
19
.github/dependabot.yml
vendored
19
.github/dependabot.yml
vendored
@@ -1,11 +1,18 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
|
|
||||||
|
# Check for updates to GitHub Actions every week
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
labels: []
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
|
||||||
# composer updates
|
# composer updates
|
||||||
- package-ecosystem: "composer"
|
- package-ecosystem: "composer"
|
||||||
directory: "/" # Location of package manifests
|
directory: "/" # Location of package manifests
|
||||||
target-branch: develop
|
target-branch: develop
|
||||||
labels: [ "bug" ]
|
labels: []
|
||||||
versioning-strategy: increase
|
versioning-strategy: increase
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
@@ -13,16 +20,8 @@ updates:
|
|||||||
# yarn / JS updates
|
# yarn / JS updates
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
|
labels: []
|
||||||
target-branch: develop
|
target-branch: develop
|
||||||
labels: [ "bug" ]
|
|
||||||
versioning-strategy: increase
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
target-branch: develop
|
|
||||||
labels: [ "bug" ]
|
|
||||||
versioning-strategy: increase
|
versioning-strategy: increase
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
|||||||
4
.github/funding.yml
vendored
4
.github/funding.yml
vendored
@@ -1,4 +1,6 @@
|
|||||||
# These are supported funding model platforms
|
# Firefly III sponsor options
|
||||||
|
|
||||||
github: jc5
|
github: jc5
|
||||||
patreon: JC5
|
patreon: JC5
|
||||||
|
ko_fi: jamesc5
|
||||||
|
liberapay: JC5
|
||||||
|
|||||||
126
.github/label-actions.yml
vendored
Normal file
126
.github/label-actions.yml
vendored
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# Configuration for Label Actions - https://github.com/dessant/label-actions
|
||||||
|
|
||||||
|
# The `feature` label is added to issues
|
||||||
|
fixed:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as fixed. Thanks for reporting! A new version will be released in due time. Unfortunately, [I cannot give an estimate](https://docs.firefly-iii.org/references/faq/firefly-iii/general/#when-will-you-release-version-the-next-version), but [the roadmap](https://roadmap.firefly-iii.org/) is available for your reading pleasure.
|
||||||
|
|
||||||
|
There is no need to close the issue. It will be closed automatically.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
feature:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
unlabel: feature
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as a feature request.
|
||||||
|
|
||||||
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
epic:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as an epic. In epics, large amounts of works are collected that will be part of a major new feature. If you have more ideas that could be a part of this epic, feel free to reply.
|
||||||
|
|
||||||
|
*However*, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted.
|
||||||
|
|
||||||
|
If you are merely interested in this epic's progress, you can subscribe to this issue to get updates.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
enhancement:
|
||||||
|
unlabel: enhancement
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as an enhancement.
|
||||||
|
|
||||||
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
triage:
|
||||||
|
issues:
|
||||||
|
# Post a comment, `{issue-author}` is an optional placeholder
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been marked as being in triage. The root cause is not known yet, or the issue needs more investigation. You can help by sharing debug information (from `/debug`) if you also have this issue or when you haven't already done so.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
|
||||||
|
needs-moar-debug:
|
||||||
|
issues:
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
To learn more about this issue, please make sure you share at least:
|
||||||
|
|
||||||
|
1. The table you can find on the `/debug` page
|
||||||
|
2. Firefly III version
|
||||||
|
2. Docker, self-hosted, or hosted by a third party?
|
||||||
|
3. Operating system and browser
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
unlabel: needs-moar-debug
|
||||||
|
|
||||||
|
|
||||||
|
needs-moar-logs:
|
||||||
|
issues:
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
To learn more about this issue, please share the relevant log files from your Firefly III or data importer installation.
|
||||||
|
|
||||||
|
The relevant instructions can be found in the documentation: [How to debug Firefly III?](https://docs.firefly-iii.org/how-to/general/debug/) Once debug mode is activated per these instructions, you can repeat your action and find the logs, depending on your method of installation. All is explained on the page.
|
||||||
|
|
||||||
|
Please share the relevant log lines in your issue, either inline or as an attachment. If you feel the logs contain sensitive information, you may also send them to [james@firefly-iii.org](mailto:james@firefly-iii.org). Without these logs, it may not be possible to properly investigate this issue.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
unlabel: needs-moar-logs
|
||||||
|
|
||||||
|
v2-layout-issue:
|
||||||
|
issues:
|
||||||
|
comment: |
|
||||||
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
It seems your issue is about the new v2-layout that is currently in development for Firefly III.
|
||||||
|
|
||||||
|
These issues are collected in [a GitHub discussion](https://github.com/firefly-iii/firefly-iii/issues/8361).
|
||||||
|
|
||||||
|
Please note that the v2 layout is still very much in development.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
close: true
|
||||||
|
close-reason: completed
|
||||||
|
lock: false
|
||||||
|
unlabel: v2-layout-issue
|
||||||
61
.github/mergify.yml
vendored
61
.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
|
||||||
@@ -8,56 +14,3 @@ pull_request_rules:
|
|||||||
close:
|
close:
|
||||||
message: Please do not open PR's on the `main` branch, but on the `develop`
|
message: Please do not open PR's on the `main` branch, but on the `develop`
|
||||||
branch only. Thank you!
|
branch only. Thank you!
|
||||||
- name: No translations
|
|
||||||
conditions:
|
|
||||||
- -author~=^dependabot(|-preview)\[bot\]$
|
|
||||||
- base=develop
|
|
||||||
- or:
|
|
||||||
- files~=^resources/lang/bg_BG
|
|
||||||
- files~=^resources/lang/ca_ES
|
|
||||||
- files~=^resources/lang/cs_CZ
|
|
||||||
- files~=^resources/lang/da_DK
|
|
||||||
- files~=^resources/lang/de_DE
|
|
||||||
- files~=^resources/lang/el_GR
|
|
||||||
- files~=^resources/lang/en_GB
|
|
||||||
- files~=^resources/lang/es_ES
|
|
||||||
- files~=^resources/lang/et_EE
|
|
||||||
- files~=^resources/lang/fa_IR
|
|
||||||
- files~=^resources/lang/fi_FI
|
|
||||||
- files~=^resources/lang/fr_FR
|
|
||||||
- files~=^resources/lang/he_IL
|
|
||||||
- files~=^resources/lang/hu_HU
|
|
||||||
- files~=^resources/lang/id_ID
|
|
||||||
- files~=^resources/lang/is_IS
|
|
||||||
- files~=^resources/lang/it_IT
|
|
||||||
- files~=^resources/lang/ja_JP
|
|
||||||
- files~=^resources/lang/ko_KR
|
|
||||||
- files~=^resources/lang/lt_LT
|
|
||||||
- files~=^resources/lang/nb_NO
|
|
||||||
- files~=^resources/lang/nl_NL
|
|
||||||
- files~=^resources/lang/pl_PL
|
|
||||||
- files~=^resources/lang/pt_BR
|
|
||||||
- files~=^resources/lang/pt_PT
|
|
||||||
- files~=^resources/lang/ro_RO
|
|
||||||
- files~=^resources/lang/ru_RU
|
|
||||||
- files~=^resources/lang/si_LK
|
|
||||||
- files~=^resources/lang/sk_SK
|
|
||||||
- files~=^resources/lang/sl_SI
|
|
||||||
- files~=^resources/lang/sr_CS
|
|
||||||
- files~=^resources/lang/sv_SE
|
|
||||||
- files~=^resources/lang/th_TH
|
|
||||||
- files~=^resources/lang/tlh_AA
|
|
||||||
- files~=^resources/lang/tr_TR
|
|
||||||
- files~=^resources/lang/uk_UA
|
|
||||||
- files~=^resources/lang/vi_VN
|
|
||||||
- files~=^resources/lang/zh_CN
|
|
||||||
- files~=^resources/lang/zh_TW
|
|
||||||
actions:
|
|
||||||
comment:
|
|
||||||
message: >
|
|
||||||
Please do not submit translated strings in your PR. If you need new
|
|
||||||
sentences to be translated, add them to the `en_US` language strings.
|
|
||||||
New or changed translations for other languages can be submitted at
|
|
||||||
https://crowdin.com/project/firefly-iii
|
|
||||||
|
|
||||||
Thank you!
|
|
||||||
|
|||||||
21
.github/pull_request_template.md
vendored
21
.github/pull_request_template.md
vendored
@@ -1,18 +1,23 @@
|
|||||||
<!--
|
<!--
|
||||||
Before you create a new PR, please consider:
|
Thank you for submitting new code to Firefly III, or any of the related projects. Please read the following rules carefully.
|
||||||
|
|
||||||
1) Pull requests for the MAIN branch will be closed.
|
- Please do not submit solutions for problems that are not already reported in an issue.
|
||||||
2) DO NOT include translations in your PR. Only English US sentences.
|
- Unfortunately, Firefly III can't be your learning experience. If you're new to all of this, please open an issue first.
|
||||||
|
- Please do not open PRs to "discuss" possible solutions or to "get feedback" on your code. I simply don't have time for that.
|
||||||
|
- Pull requests for the MAIN branch will be closed.
|
||||||
|
- DO NOT include translated strings in your PR.
|
||||||
|
- PRs (or parts thereof) that only fix issues inside code comments will not be accepted.
|
||||||
|
|
||||||
|
If it feels necessary to open an issue first, please do so, before you open a PR.
|
||||||
|
|
||||||
|
See also: https://docs.firefly-iii.org/explanation/support/#contributing-code
|
||||||
|
|
||||||
Thanks.
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Fixes issue # (if relevant)
|
This PR fixes issue # (if relevant).
|
||||||
|
|
||||||
Changes in this pull request:
|
Changes in this pull request:
|
||||||
|
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
|
|
||||||
@JC5
|
|
||||||
|
|||||||
58
.github/stale.yml
vendored
58
.github/stale.yml
vendored
@@ -1,58 +0,0 @@
|
|||||||
# Configuration for probot-stale - https://github.com/probot/stale
|
|
||||||
|
|
||||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
|
||||||
daysUntilStale: 14
|
|
||||||
|
|
||||||
# Number of days of inactivity before a stale Issue or Pull Request is closed.
|
|
||||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
|
||||||
daysUntilClose: 14
|
|
||||||
|
|
||||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
|
||||||
# - "[Status] Maybe Later"
|
|
||||||
exemptLabels:
|
|
||||||
- enhancement
|
|
||||||
- feature
|
|
||||||
- bug
|
|
||||||
- announcement
|
|
||||||
- "layout-v3"
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a project (defaults to false)
|
|
||||||
exemptProjects: false
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a milestone (defaults to false)
|
|
||||||
exemptMilestones: false
|
|
||||||
|
|
||||||
# Label to use when marking as stale
|
|
||||||
staleLabel: stale
|
|
||||||
|
|
||||||
# Comment to post when marking as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue has been automatically marked as stale because it has not had
|
|
||||||
recent activity. It will be closed if no further activity occurs. Thank you
|
|
||||||
for your contributions.
|
|
||||||
|
|
||||||
# Comment to post when removing the stale label.
|
|
||||||
# unmarkComment: >
|
|
||||||
# Your comment here.
|
|
||||||
|
|
||||||
# Comment to post when closing a stale Issue or Pull Request.
|
|
||||||
# closeComment: >
|
|
||||||
# Your comment here.
|
|
||||||
|
|
||||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
|
||||||
limitPerRun: 30
|
|
||||||
|
|
||||||
# Limit to only `issues` or `pulls`
|
|
||||||
# only: issues
|
|
||||||
|
|
||||||
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
|
||||||
# pulls:
|
|
||||||
# daysUntilStale: 30
|
|
||||||
# markComment: >
|
|
||||||
# This pull request has been automatically marked as stale because it has not had
|
|
||||||
# recent activity. It will be closed if no further activity occurs. Thank you
|
|
||||||
# for your contributions.
|
|
||||||
|
|
||||||
# issues:
|
|
||||||
# exemptLabels:
|
|
||||||
# - confirmed
|
|
||||||
2
.github/support.md
vendored
2
.github/support.md
vendored
@@ -27,7 +27,7 @@ Only then [create a new issue](https://github.com/firefly-iii/firefly-iii/issues
|
|||||||
|
|
||||||
- Issues can be converted into discussions if it's not a bug or feature request.
|
- Issues can be converted into discussions if it's not a bug or feature request.
|
||||||
- Features that won't be implemented will be labelled "
|
- Features that won't be implemented will be labelled "
|
||||||
wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/what-its-not/).
|
wontfix". [This isn't personal](https://docs.firefly-iii.org/explanation/more-information/what-its-not/).
|
||||||
- Issues can be closed if they're duplicates of other issues.
|
- Issues can be closed if they're duplicates of other issues.
|
||||||
- Issues can be closed if the answer is in the FAQ.
|
- Issues can be closed if the answer is in the FAQ.
|
||||||
- Issues will be closed automatically after 14 days.
|
- Issues will be closed automatically after 14 days.
|
||||||
|
|||||||
39
.github/workflows/cleanup.yml
vendored
39
.github/workflows/cleanup.yml
vendored
@@ -1,10 +1,13 @@
|
|||||||
# This workflow prunes old workflow runs for an entire repository.
|
# This workflow prunes old workflow runs for an entire repository.
|
||||||
|
|
||||||
name: Prune old builds
|
name: "Chore - Prune old builds"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
actions: write
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 1 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
prune:
|
prune:
|
||||||
@@ -12,9 +15,9 @@ jobs:
|
|||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- name: Prune cancelled/skipped runs
|
- name: Prune cancelled/skipped runs
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
const cancelled = await github.rest.actions.listWorkflowRunsForRepo({
|
const cancelled = await github.rest.actions.listWorkflowRunsForRepo({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
@@ -22,14 +25,14 @@ jobs:
|
|||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
status: 'cancelled',
|
status: 'cancelled',
|
||||||
});
|
});
|
||||||
|
|
||||||
const skipped = await github.rest.actions.listWorkflowRunsForRepo({
|
const skipped = await github.rest.actions.listWorkflowRunsForRepo({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
per_page: 100,
|
per_page: 100,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
status: 'skipped',
|
status: 'skipped',
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const response of [cancelled, skipped]) {
|
for (const response of [cancelled, skipped]) {
|
||||||
for (const run of response.data.workflow_runs) {
|
for (const run of response.data.workflow_runs) {
|
||||||
console.log(`Run id ${run.id} of '${run.name}' is a cancelled/skipped run. Deleting...`);
|
console.log(`Run id ${run.id} of '${run.name}' is a cancelled/skipped run. Deleting...`);
|
||||||
@@ -42,31 +45,33 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
- name: Prune runs older than 3 days
|
- name: Prune runs older than 3 days
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
const days_to_expiration = 3;
|
const days_to_expiration = 3;
|
||||||
const ms_in_day = 86400000;
|
const ms_in_day = 86400000;
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const pages = 5;
|
const pages = 5;
|
||||||
|
|
||||||
// we don't want to prune old runs from test.yml
|
// we don't want to prune old runs from test.yml
|
||||||
// because we track the duration of runs over time
|
// because we track the duration of runs over time
|
||||||
|
|
||||||
const workflows = [
|
const workflows = [
|
||||||
'cleanup.yml',
|
'cleanup.yml',
|
||||||
|
'close-duplicates.yml',
|
||||||
'closed-issues.yml',
|
'closed-issues.yml',
|
||||||
'depsreview.yaml',
|
'debug-info-actions.yml',
|
||||||
'laravel.yml',
|
'depsreview.yml',
|
||||||
|
'label-actions.yml',
|
||||||
'lock.yml',
|
'lock.yml',
|
||||||
'qodana.yml',
|
'release.yml',
|
||||||
'sonarcloud.yml',
|
'sonarcloud.yml',
|
||||||
'stale.yml'
|
'stale.yml'
|
||||||
]
|
]
|
||||||
|
|
||||||
let runs_to_delete = [];
|
let runs_to_delete = [];
|
||||||
|
|
||||||
for (const workflow of workflows) {
|
for (const workflow of workflows) {
|
||||||
for (let page = 0; page < pages; page += 1) {
|
for (let page = 0; page < pages; page += 1) {
|
||||||
let response = await github.rest.actions.listWorkflowRuns({
|
let response = await github.rest.actions.listWorkflowRuns({
|
||||||
@@ -76,7 +81,7 @@ jobs:
|
|||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
workflow_id: workflow
|
workflow_id: workflow
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.data.workflow_runs.length > 0) {
|
if (response.data.workflow_runs.length > 0) {
|
||||||
for (const run of response.data.workflow_runs) {
|
for (const run of response.data.workflow_runs) {
|
||||||
if (now - Date.parse(run.created_at) > ms_in_day * days_to_expiration) {
|
if (now - Date.parse(run.created_at) > ms_in_day * days_to_expiration) {
|
||||||
@@ -86,7 +91,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const run of runs_to_delete) {
|
for (const run of runs_to_delete) {
|
||||||
console.log(`Run id ${run[0]} of '${run[1]}' is older than ${days_to_expiration} days. Deleting...`);
|
console.log(`Run id ${run[0]} of '${run[1]}' is older than ${days_to_expiration} days. Deleting...`);
|
||||||
try {
|
try {
|
||||||
|
|||||||
39
.github/workflows/close-duplicates.yml
vendored
Normal file
39
.github/workflows/close-duplicates.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
name: "Issues - Command to close duplicate issues"
|
||||||
|
|
||||||
|
# the workflow to execute on is comments that are newly created
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [ created ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
checks: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close_duplicates:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: github/command@v2.0.0
|
||||||
|
id: command
|
||||||
|
with:
|
||||||
|
allowed_contexts: "issue"
|
||||||
|
command: ".duplicate"
|
||||||
|
- name: reply
|
||||||
|
if: ${{ steps.command.outputs.continue == 'true' }}
|
||||||
|
run: |
|
||||||
|
|
||||||
|
ISSUE_TITLE=$(gh issue view ${{ steps.command.outputs.params }} --json title --jq '.title')
|
||||||
|
|
||||||
|
gh issue comment "$NUMBER" --body "Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. \`Share and enjoy\`.
|
||||||
|
|
||||||
|
Your issue is probably a duplicate of issue <span>#</span>${{ steps.command.outputs.params }}: [$ISSUE_TITLE](https://github.com/firefly-iii/firefly-iii/issues/${{ steps.command.outputs.params }}). Please refer to issue #${{ steps.command.outputs.params }} for support.
|
||||||
|
|
||||||
|
You can close this issue now. If you believe this is not in fact a duplicate, please reply and let us know. Otherwise, this issue will be automatically closed in a few days time.
|
||||||
|
|
||||||
|
Thank you for your contributions."
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GH_REPO: ${{ github.repository }}
|
||||||
|
NUMBER: ${{ github.event.issue.number }}
|
||||||
23
.github/workflows/closed-issues.yml
vendored
23
.github/workflows/closed-issues.yml
vendored
@@ -1,22 +1,25 @@
|
|||||||
name: "Reply to closed issue"
|
---
|
||||||
|
name: Issues - Reply to closed issue
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types:
|
types:
|
||||||
- closed
|
- closed
|
||||||
jobs:
|
jobs:
|
||||||
auto_comment:
|
command_and_close:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: aws-actions/closed-issue-message@v1
|
- uses: aws-actions/closed-issue-message@v2
|
||||||
with:
|
with:
|
||||||
message: |
|
message: |
|
||||||
Hi there! This is an automatic reply. `Share and enjoy`
|
Hi there! This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
This issue is now 🔒 closed. Please be aware that closed issues are **not** watched.
|
This issue is now 🔒 closed. Please be aware that closed issues are not monitored by the developer of Firefly III.
|
||||||
|
|
||||||
- If the original bug is not actually fixed, please feel free to open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose). Please refer to this issue for clarity.
|
- If the original bug is not actually fixed, please open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose). Refer to this issue for clarity.
|
||||||
- Follow-up questions must be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/)
|
- Follow-up questions must be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/)
|
||||||
- Further replies to this issue will get **no response**.
|
- Further replies to this issue may get no response.
|
||||||
|
|
||||||
|
If there is more to discuss, please open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose) or [discussion](https://github.com/firefly-iii/firefly-iii/discussions/).
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
32
.github/workflows/debug-info-actions.yml
vendored
Normal file
32
.github/workflows/debug-info-actions.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: 'Issues - Respond to hidden commands'
|
||||||
|
|
||||||
|
# the workflow to execute on is comments that are newly created
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [ opened, edited ]
|
||||||
|
issue_comment:
|
||||||
|
types: [ created ]
|
||||||
|
|
||||||
|
# permissions needed for reacting to IssueOps commands on issues and PRs
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
|
checks: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
respond:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: |
|
||||||
|
ISSUE_BODY=$(gh issue view $NUMBER --json body)
|
||||||
|
if [[ $ISSUE_BODY == *".eOxNZAmyGz6CXMyf"* ]]; then
|
||||||
|
gh issue comment "$NUMBER" --body "$V2_ISSUE_REPLY_BODY"
|
||||||
|
gh issue close "$NUMBER" --reason completed
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GH_REPO: ${{ github.repository }}
|
||||||
|
NUMBER: ${{ github.event.issue.number }}
|
||||||
|
V2_ISSUE_REPLY_BODY: ${{ secrets.V2_ISSUE_REPLY_BODY }}
|
||||||
|
LABELS: v2-layout-issue
|
||||||
14
.github/workflows/depsreview.yaml
vendored
14
.github/workflows/depsreview.yaml
vendored
@@ -1,14 +0,0 @@
|
|||||||
name: 'Dependency Review'
|
|
||||||
on: [ pull_request ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
dependency-review:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: 'Checkout Repository'
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: 'Dependency Review'
|
|
||||||
uses: actions/dependency-review-action@v3
|
|
||||||
16
.github/workflows/depsreview.yml
vendored
Normal file
16
.github/workflows/depsreview.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: 'Code - Dependency review'
|
||||||
|
on: [ pull_request ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependency-review:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 'Checkout repository'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: 'Dependency review'
|
||||||
|
uses: actions/dependency-review-action@v4
|
||||||
21
.github/workflows/label-actions.yml
vendored
Normal file
21
.github/workflows/label-actions.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: 'Issues - Reply to specific labels'
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [ labeled, unlabeled ]
|
||||||
|
pull_request_target:
|
||||||
|
types: [ labeled, unlabeled ]
|
||||||
|
discussion:
|
||||||
|
types: [ labeled, unlabeled ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
action:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: dessant/label-actions@v4
|
||||||
146
.github/workflows/laravel.yml
vendored
146
.github/workflows/laravel.yml
vendored
@@ -1,146 +0,0 @@
|
|||||||
name: Firefly III
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- '**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
prepare:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Copy .env
|
|
||||||
run: test -f .env || cp .ci/.env.ci .env
|
|
||||||
- name: Prepare dependencies
|
|
||||||
run: |
|
|
||||||
set -euxo pipefail
|
|
||||||
export PATH=$PATH:$HOME/.composer/vendor/bin/
|
|
||||||
composer global require hirak/prestissimo --no-plugins --no-scripts
|
|
||||||
composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
|
|
||||||
|
|
||||||
touch ./storage/database/database.sqlite
|
|
||||||
- name: Prepare Firefly III
|
|
||||||
run: |
|
|
||||||
chmod -R 777 storage bootstrap/cache
|
|
||||||
php artisan migrate --seed
|
|
||||||
php artisan firefly-iii:upgrade-database
|
|
||||||
- name: Upload database
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: database
|
|
||||||
path: storage/database/database.sqlite
|
|
||||||
- name: Upload cache
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: cache
|
|
||||||
path: bootstrap/cache/
|
|
||||||
- name: Upload composer cache
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: composer
|
|
||||||
path: ~/.composer
|
|
||||||
|
|
||||||
laravel-tests:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs:
|
|
||||||
- prepare
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Copy .env
|
|
||||||
run: test -f .env || cp .ci/.env.ci .env
|
|
||||||
- name: Download database
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: database
|
|
||||||
path: storage/database/database.sqlite
|
|
||||||
- name: Download cache
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: cache
|
|
||||||
path: bootstrap/cache/
|
|
||||||
- name: Download vendor
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: composer
|
|
||||||
path: ~/.composer
|
|
||||||
- name: Install composer
|
|
||||||
run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
|
|
||||||
|
|
||||||
- name: PHPUnit tests
|
|
||||||
uses: php-actions/phpunit@v1
|
|
||||||
with:
|
|
||||||
config: phpunit.xml
|
|
||||||
memory: 512M
|
|
||||||
|
|
||||||
coding-standards:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs:
|
|
||||||
- prepare
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Copy .env
|
|
||||||
run: test -f .env || cp .ci/.env.ci .env
|
|
||||||
- name: Download database
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: database
|
|
||||||
path: storage/database/database.sqlite
|
|
||||||
- name: Download cache
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: cache
|
|
||||||
path: bootstrap/cache/
|
|
||||||
- name: Download vendor
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: composer
|
|
||||||
path: ~/.composer
|
|
||||||
- name: install depenencies
|
|
||||||
run: |
|
|
||||||
composer global require nette/coding-standard
|
|
||||||
composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
|
|
||||||
|
|
||||||
- name: Execute code standard
|
|
||||||
run: /home/runner/.composer/vendor/bin/ecs check app tests --config ./.ci/firefly-iii-standard.yml
|
|
||||||
|
|
||||||
phpstan:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs:
|
|
||||||
- prepare
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Copy .env
|
|
||||||
run: test -f .env || cp .ci/.env.ci .env
|
|
||||||
- name: Download database
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: database
|
|
||||||
path: storage/database/database.sqlite
|
|
||||||
- name: Download cache
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: cache
|
|
||||||
path: bootstrap/cache/
|
|
||||||
- name: Download vendor
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: composer
|
|
||||||
path: ~/.composer
|
|
||||||
- name: Install depenencies
|
|
||||||
run: |
|
|
||||||
composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
|
|
||||||
|
|
||||||
- name: Execute PHPStan
|
|
||||||
run: vendor/bin/phpstan analyse -c .ci/phpstan.neon
|
|
||||||
22
.github/workflows/lock.yml
vendored
22
.github/workflows/lock.yml
vendored
@@ -1,19 +1,29 @@
|
|||||||
name: Lock old issues
|
name: 'Issues - Lock old issues'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 2 * * *'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: lock-threads
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lock:
|
lock:
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: JC5/lock-threads@main
|
- uses: dessant/lock-threads@v5
|
||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
issue-inactive-days: 21
|
||||||
issue-inactive-days: 90
|
pr-inactive-days: 21
|
||||||
pr-inactive-days: 90
|
discussion-inactive-days: 21
|
||||||
|
log-output: true
|
||||||
|
|||||||
35
.github/workflows/qodana.yml
vendored
35
.github/workflows/qodana.yml
vendored
@@ -1,35 +0,0 @@
|
|||||||
name: Qodana
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- develop
|
|
||||||
jobs:
|
|
||||||
qodana:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: 'Qodana Scan'
|
|
||||||
steps:
|
|
||||||
- name: Setup PHP with no coverage driver
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: '8.2'
|
|
||||||
coverage: none
|
|
||||||
extensions: bcmath, intl
|
|
||||||
env:
|
|
||||||
update: true
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
composer install --no-scripts
|
|
||||||
cp .env.example .env
|
|
||||||
php artisan key:generate
|
|
||||||
php artisan clear-compiled
|
|
||||||
php artisan ide-helper:generate;
|
|
||||||
|
|
||||||
- name: 'Qodana Scan'
|
|
||||||
uses: JetBrains/qodana-action@main
|
|
||||||
env:
|
|
||||||
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
|
|
||||||
493
.github/workflows/release.yml
vendored
Normal file
493
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,493 @@
|
|||||||
|
name: 'Code - Create new release'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'Release "v1.2.3" or "develop" or "branch-abc"'
|
||||||
|
required: true
|
||||||
|
default: 'develop'
|
||||||
|
phpversion:
|
||||||
|
description: 'PHP version'
|
||||||
|
required: true
|
||||||
|
default: '8.4'
|
||||||
|
schedule:
|
||||||
|
- cron: '0 3 * * MON'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Import GPG key
|
||||||
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||||
|
passphrase: ${{ secrets.PASSPHRASE }}
|
||||||
|
git_user_signingkey: true
|
||||||
|
git_commit_gpgsign: true
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ github.event.inputs.phpversion }}
|
||||||
|
extensions: mbstring, intl, zip, bcmath
|
||||||
|
- 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
|
||||||
|
with:
|
||||||
|
upload_sources: true
|
||||||
|
download_translations: true
|
||||||
|
push_translations: false
|
||||||
|
push_sources: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
CROWDIN_PROJECT_NR: ${{ secrets.CROWDIN_PROJECT_NR }}
|
||||||
|
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
|
||||||
|
- name: Cleanup changelog
|
||||||
|
id: cleanup-changelog
|
||||||
|
uses: JC5/firefly-iii-dev@main
|
||||||
|
with:
|
||||||
|
action: 'ff3:changelog'
|
||||||
|
output: ''
|
||||||
|
env:
|
||||||
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
|
GH_TOKEN: ${{ secrets.CHANGELOG_TOKEN }}
|
||||||
|
- name: "Create THANKS.md"
|
||||||
|
id: thank-you
|
||||||
|
uses: JC5/firefly-iii-dev@main
|
||||||
|
with:
|
||||||
|
action: 'ff3:thank-you'
|
||||||
|
output: ''
|
||||||
|
env:
|
||||||
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
|
GH_TOKEN: ''
|
||||||
|
- name: Replace version
|
||||||
|
id: replace-version
|
||||||
|
uses: JC5/firefly-iii-dev@main
|
||||||
|
with:
|
||||||
|
action: 'ff3:version'
|
||||||
|
output: ''
|
||||||
|
env:
|
||||||
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
|
GH_TOKEN: ""
|
||||||
|
FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- name: Generate JSON v1
|
||||||
|
id: json-v1
|
||||||
|
uses: JC5/firefly-iii-dev@main
|
||||||
|
with:
|
||||||
|
action: 'ff3:json-translations v1'
|
||||||
|
output: ''
|
||||||
|
env:
|
||||||
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
|
GH_TOKEN: ''
|
||||||
|
- name: Generate JSON v2
|
||||||
|
id: json-v2
|
||||||
|
uses: JC5/firefly-iii-dev@main
|
||||||
|
with:
|
||||||
|
action: 'ff3:json-translations v2'
|
||||||
|
output: ''
|
||||||
|
env:
|
||||||
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
|
GH_TOKEN: ''
|
||||||
|
- name: Code cleanup
|
||||||
|
id: code-cleanup
|
||||||
|
uses: JC5/firefly-iii-dev@main
|
||||||
|
with:
|
||||||
|
action: 'ff3:code'
|
||||||
|
output: ''
|
||||||
|
env:
|
||||||
|
FIREFLY_III_ROOT: /github/workspace
|
||||||
|
GH_TOKEN: ''
|
||||||
|
- name: Build JS
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run prod --workspace=v1
|
||||||
|
npm run build --workspace=v2
|
||||||
|
npm update
|
||||||
|
- name: Run CI
|
||||||
|
run: |
|
||||||
|
rm -rf vendor composer.lock
|
||||||
|
composer update --no-dev --no-scripts --no-plugins -q
|
||||||
|
sudo chown -R runner:docker resources/lang
|
||||||
|
.ci/phpcs.sh || true
|
||||||
|
- name: Calculate variables
|
||||||
|
run: |
|
||||||
|
|
||||||
|
# set some variables
|
||||||
|
releaseName=$version
|
||||||
|
originalName=$version
|
||||||
|
zipName=FireflyIII-$version.zip
|
||||||
|
tarName=FireflyIII-$version.tar.gz
|
||||||
|
|
||||||
|
# if this is a develop build, slightly different variable names.
|
||||||
|
if [[ "develop" == "$version" ]]; then
|
||||||
|
#[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||||
|
releaseName=$version-$(date +'%Y%m%d')
|
||||||
|
originalName=$releaseName
|
||||||
|
zipName=FireflyIII-develop.zip
|
||||||
|
tarName=FireflyIII-develop.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if this is a branch build, also slightly different variable names.
|
||||||
|
if [[ "$version" == branch* ]]; then
|
||||||
|
#[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||||
|
# branch builds overrule develop
|
||||||
|
releaseName=$version-$(date +'%Y%m%d')
|
||||||
|
originalName=$releaseName
|
||||||
|
zipName=FireflyIII-$version.zip
|
||||||
|
tarName=FireflyIII-$version.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
# in both cases, if the release or tag already exists, add ".1" until it no longer exists.
|
||||||
|
tagFound=true
|
||||||
|
tagCount=1
|
||||||
|
while [ "$tagFound" = true ]
|
||||||
|
do
|
||||||
|
if [ $(git tag -l "$releaseName") ]; then
|
||||||
|
echo "Tag $releaseName exists already."
|
||||||
|
releaseName="$originalName"."$tagCount"
|
||||||
|
echo "Tag for release is now $releaseName"
|
||||||
|
tagCount=$((tagCount+1))
|
||||||
|
else
|
||||||
|
echo "Tag $releaseName does not exist, can continue"
|
||||||
|
tagFound=false
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
echo 'Add all'
|
||||||
|
git add -A
|
||||||
|
# push to a new branch.
|
||||||
|
echo "Auto commit on branch '$(git branch --show-current)'."
|
||||||
|
git commit -m "🤖 Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
|
||||||
|
git push
|
||||||
|
env:
|
||||||
|
version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||||
|
- 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: Describe new release
|
||||||
|
run: |
|
||||||
|
|
||||||
|
# describe the development release.
|
||||||
|
if [[ "develop" == "$version" ]]; then
|
||||||
|
echo 'Describe the latest develop release'
|
||||||
|
rm -f output.txt
|
||||||
|
touch output.txt
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo ":warning: Please be careful with this pre-release, as it may not work as expected." >> output.txt
|
||||||
|
fi
|
||||||
|
# describe a branch release
|
||||||
|
if [[ "$version" == branch* ]]; then
|
||||||
|
echo 'Describe a branch release'
|
||||||
|
rm -f output.txt
|
||||||
|
touch output.txt
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "" >> output.txt
|
||||||
|
echo ":warning: Please be careful with this branch pre-release, as it may not work as expected." >> output.txt
|
||||||
|
fi
|
||||||
|
# describe the main release
|
||||||
|
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
||||||
|
echo 'Describe the latest release'
|
||||||
|
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 '### Instructions' >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "* 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
|
||||||
|
|
||||||
|
# describe alpha release
|
||||||
|
if [[ "$version" == *alpha* ]]; then
|
||||||
|
echo 'Describe an ALPHA release'
|
||||||
|
rm -f output.txt
|
||||||
|
touch output.txt
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo '### Instructions' >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "* 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
|
||||||
|
|
||||||
|
# describe beta release
|
||||||
|
if [[ "$version" == *beta* ]]; then
|
||||||
|
echo 'Describe a BETA release'
|
||||||
|
rm -f output.txt
|
||||||
|
touch output.txt
|
||||||
|
sudo chown -R runner:docker output.txt
|
||||||
|
echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo '### Instructions' >> output.txt
|
||||||
|
echo '' >> output.txt
|
||||||
|
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||||
|
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||||
|
echo "* 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
|
||||||
|
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:
|
||||||
|
if [[ "develop" == "$version" ]]; then
|
||||||
|
# pull the changes from the develop branch.
|
||||||
|
git checkout develop
|
||||||
|
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
|
||||||
|
|
||||||
|
gh release create $releaseName -p --verify-tag \
|
||||||
|
-t "Development release for $(date +'%Y-%m-%d')" \
|
||||||
|
--latest=false \
|
||||||
|
-F output.txt
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create a branch release:
|
||||||
|
if [[ "$version" == branch* ]]; then
|
||||||
|
|
||||||
|
# pull the changes from the branch-* branch.
|
||||||
|
git checkout $version
|
||||||
|
git merge origin/$version
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# create the release:
|
||||||
|
echo "Create branch release."
|
||||||
|
git tag -a $releaseName -m "Branch release '$version' on $(date +'%Y-%m-%d')"
|
||||||
|
git push origin $releaseName
|
||||||
|
|
||||||
|
gh release create $releaseName -p --verify-tag \
|
||||||
|
-t "Branch release for $(date +'%Y-%m-%d')" \
|
||||||
|
--latest=false \
|
||||||
|
-F output.txt
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create a production release.
|
||||||
|
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]]; then
|
||||||
|
git checkout main
|
||||||
|
git merge origin/main
|
||||||
|
git pull
|
||||||
|
git status
|
||||||
|
|
||||||
|
echo "Create prod release."
|
||||||
|
git tag -a $releaseName -m "Release $version"
|
||||||
|
git push origin $releaseName
|
||||||
|
|
||||||
|
# do not tag as latest when alpha or beta.
|
||||||
|
if [[ "$version" == *alpha* ]] || [[ "$version" == *beta* ]]; then
|
||||||
|
echo 'Mark alpha or beta as NOT the latest.'
|
||||||
|
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag --latest=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# tag as latest when NOT alpha or beta.
|
||||||
|
if [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
||||||
|
echo 'Mark prod as the latest.'
|
||||||
|
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag --latest=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
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 }}
|
||||||
52
.github/workflows/sonarcloud.yml
vendored
52
.github/workflows/sonarcloud.yml
vendored
@@ -1,38 +1,60 @@
|
|||||||
name: Sonarcloud
|
name: 'Code - Run Sonarcloud'
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- develop
|
- develop
|
||||||
|
env:
|
||||||
|
DB_CONNECTION: sqlite
|
||||||
|
APP_KEY: TestTestTestTestTestTestTestTest
|
||||||
jobs:
|
jobs:
|
||||||
sonarcloud:
|
sonarcloud:
|
||||||
name: SonarCloud
|
name: SonarCloud
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup PHP with Xdebug
|
- name: Setup PHP with Xdebug
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: '8.2'
|
php-version: '8.4'
|
||||||
coverage: xdebug
|
coverage: xdebug
|
||||||
|
extensions: >-
|
||||||
|
bcmath
|
||||||
|
curl
|
||||||
|
fileinfo
|
||||||
|
iconv
|
||||||
|
intl
|
||||||
|
json
|
||||||
|
sqlite3
|
||||||
|
mbstring
|
||||||
|
openssl
|
||||||
|
pdo
|
||||||
|
session
|
||||||
|
simplexml
|
||||||
|
sodium
|
||||||
|
tokenizer
|
||||||
|
xml
|
||||||
|
xmlwriter
|
||||||
|
|
||||||
|
- name: Copy standard configuration
|
||||||
|
run: cp .env.testing .env
|
||||||
|
|
||||||
- name: Install Composer dependencies
|
- name: Install Composer dependencies
|
||||||
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
|
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
|
||||||
|
|
||||||
- name: Copy environment file
|
- name: "Create database file"
|
||||||
run: cp .env.example .env
|
run: |
|
||||||
|
touch storage/database/database.sqlite
|
||||||
|
wget -q https://github.com/firefly-iii/test-fixtures/raw/refs/heads/main/test-database.sqlite -O storage/database/database.sqlite
|
||||||
|
|
||||||
- name: Generate app key
|
- name: "Upgrades the database to the latest version"
|
||||||
run: php artisan key:generate
|
run: php artisan firefly-iii:upgrade-database
|
||||||
|
|
||||||
|
- name: "Integrity Database Report"
|
||||||
|
run: php artisan firefly-iii:report-integrity
|
||||||
|
|
||||||
- name: "Run tests with coverage"
|
- name: "Run tests with coverage"
|
||||||
run: composer coverage
|
run: composer coverage
|
||||||
|
|||||||
28
.github/workflows/stale.yml
vendored
28
.github/workflows/stale.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
name: "Close stale issues"
|
name: "Issues - Mark and close stale issues"
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "30 1 * * *"
|
- cron: "0 4 * * *"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -12,23 +12,29 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
issues: write # for actions/stale to close stale issues
|
issues: write # for actions/stale to close stale issues
|
||||||
pull-requests: write # for actions/stale to close stale PRs
|
pull-requests: write # for actions/stale to close stale PRs
|
||||||
|
actions: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v6
|
- uses: actions/stale@v9
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
stale-issue-message: >
|
stale-issue-message: |
|
||||||
Hi there! This is an automatic reply. `Share and enjoy`
|
Hi there!
|
||||||
|
|
||||||
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||||
|
|
||||||
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
stale-pr-message: >
|
stale-pr-message: |
|
||||||
Hi there! This is an automatic reply. `Share and enjoy`
|
Hi there!
|
||||||
|
|
||||||
This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
|
This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
days-before-stale: 14
|
days-before-stale: 14
|
||||||
days-before-close: 7
|
days-before-close: 7
|
||||||
exempt-issue-labels: 'enhancement,feature,bug,announcement,epic'
|
exempt-all-milestones: true
|
||||||
|
exempt-issue-labels: 'triage'
|
||||||
|
|||||||
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,10 +1,30 @@
|
|||||||
/node_modules
|
/node_modules
|
||||||
/frontend/node_modules
|
|
||||||
/storage/*.key
|
/storage/*.key
|
||||||
/vendor
|
/vendor
|
||||||
/.vagrant
|
public/hot
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
.env
|
.env
|
||||||
/.ci/php-cs-fixer/vendor
|
/.ci/php-cs-fixer/vendor
|
||||||
coverage.xml
|
coverage.xml
|
||||||
|
output.txt
|
||||||
|
|
||||||
|
# ignore generated files.
|
||||||
|
public/build
|
||||||
|
|
||||||
|
# ignore v1 build files
|
||||||
|
resources/assets/v1/node_modules
|
||||||
|
resources/assets/v1/build
|
||||||
|
public/v1/js/app.js*
|
||||||
|
public/v1/js/app_vue.js*
|
||||||
|
public/v1/js/create*
|
||||||
|
public/v1/js/edit*
|
||||||
|
public/v1/js/profile*
|
||||||
|
public/v1/js/administrations
|
||||||
|
public/v1/js/exchange-rates
|
||||||
|
public/v1/js/webhooks
|
||||||
|
|
||||||
|
# ignore v2 build files
|
||||||
|
resources/assets/v2/node_modules
|
||||||
|
resources/assets/v2/build
|
||||||
|
public/v2/i18n
|
||||||
|
|||||||
@@ -8,7 +8,5 @@
|
|||||||
# To hide directory listing
|
# To hide directory listing
|
||||||
Options All -Indexes
|
Options All -Indexes
|
||||||
|
|
||||||
# To prevent access to .env and other files
|
# To prevent access any file
|
||||||
<Files .*>
|
Deny from all
|
||||||
Deny from all
|
|
||||||
</Files>
|
|
||||||
|
|||||||
209
THANKS.md
Executable file
209
THANKS.md
Executable file
@@ -0,0 +1,209 @@
|
|||||||
|
# Thank you! :tada: :heart: :tada:
|
||||||
|
|
||||||
|
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
|
||||||
|
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
|
||||||
|
- Denis Iskandarov
|
||||||
|
- =
|
||||||
|
- Lompi
|
||||||
|
- Jose Diaz-Gonzalez
|
||||||
|
- SoftBrix
|
||||||
|
|
||||||
|
## 2024
|
||||||
|
- Sobuno
|
||||||
|
- TasneemTantawy
|
||||||
|
- Antônio Franco
|
||||||
|
- yparitcher
|
||||||
|
- Jhon Pedroza
|
||||||
|
- mzhubail
|
||||||
|
- tasnim
|
||||||
|
- withbest
|
||||||
|
- Steve Wasiura
|
||||||
|
- imlonghao
|
||||||
|
- Rahman Yusuf
|
||||||
|
- Michael Thomas
|
||||||
|
- WardenJakx
|
||||||
|
- kuilin
|
||||||
|
- Stevie Robinson
|
||||||
|
- luzpaz
|
||||||
|
- Lemuel Roberto Bonifácio
|
||||||
|
- maureenferreira
|
||||||
|
|
||||||
|
## 2023
|
||||||
|
- tieu1991
|
||||||
|
- Maxco10
|
||||||
|
- zqye
|
||||||
|
- Mateus Pereira
|
||||||
|
- josephbadow
|
||||||
|
- Christian Desktop
|
||||||
|
- Edgars
|
||||||
|
- Hannah K
|
||||||
|
- noxonad
|
||||||
|
- Kaijia Feng
|
||||||
|
- Marc Ordinas i Llopis
|
||||||
|
- Kuba Turek
|
||||||
|
- Julien Stébenne
|
||||||
|
|
||||||
|
## 2022
|
||||||
|
- Johannes Zellner
|
||||||
|
- Janne Heß
|
||||||
|
- charlesteets
|
||||||
|
- Nathan PERIER
|
||||||
|
- Jan Willhaus
|
||||||
|
- canoine
|
||||||
|
- Rick Cuddy
|
||||||
|
- James
|
||||||
|
- Hugo Meyronneinc
|
||||||
|
- naveen
|
||||||
|
- neilnaveen
|
||||||
|
- naveensrinivasan
|
||||||
|
- Federico Micelli
|
||||||
|
- George Hahn
|
||||||
|
|
||||||
|
## 2021
|
||||||
|
- StillLoading
|
||||||
|
- Igor Rzegocki
|
||||||
|
- Lorenzo Breda
|
||||||
|
- Hosh
|
||||||
|
- Flightkick
|
||||||
|
- alex6480
|
||||||
|
- VREEdom
|
||||||
|
- Hamza FADIL
|
||||||
|
- Kasper Læssø Sørensen
|
||||||
|
- Alex
|
||||||
|
- Jeroen De Meerleer
|
||||||
|
- Ruben van Erk
|
||||||
|
- Fabian Zimmermann
|
||||||
|
- Mirko Berger
|
||||||
|
- KaihatsuOnline
|
||||||
|
- MihataBG
|
||||||
|
|
||||||
|
## 2020
|
||||||
|
- Hannes Körber
|
||||||
|
- Julien Cassagne
|
||||||
|
- bu4ak
|
||||||
|
- Viktor Yakovlev
|
||||||
|
- Oliver Kaufmann
|
||||||
|
- Arvind Chembarpu
|
||||||
|
- GrayStrider
|
||||||
|
- psychowood
|
||||||
|
- Hosh Sadiq
|
||||||
|
- emansih
|
||||||
|
- Aniruddha Maru
|
||||||
|
- johnny
|
||||||
|
- sephrat
|
||||||
|
- bpatath
|
||||||
|
- Florian Dupret
|
||||||
|
- Maxim Kurbatov
|
||||||
|
- Lucas Guima
|
||||||
|
- Sandro
|
||||||
|
- Ruben Verhoef
|
||||||
|
- Daniel Idzerda
|
||||||
|
- Calum Smith
|
||||||
|
- Agraphie
|
||||||
|
- Tomer Shvueli
|
||||||
|
- Tomer S
|
||||||
|
|
||||||
|
## 2019
|
||||||
|
- Pascal Jungblut
|
||||||
|
- Justyn Shull
|
||||||
|
- Timendum
|
||||||
|
- Nicolas Lœuillet
|
||||||
|
- Dominic Guhl
|
||||||
|
- Melroy van den Berg
|
||||||
|
- Henning Stein
|
||||||
|
- Jan Klepek
|
||||||
|
- Jonathan
|
||||||
|
- Geoffrey “Frogeye” Preud'homme
|
||||||
|
- Michael Fix
|
||||||
|
- Juraj Mlich
|
||||||
|
- Eddybrando Vásquez
|
||||||
|
- hulloanson
|
||||||
|
- Will Rouesnel
|
||||||
|
- lastlink
|
||||||
|
- Mr. Funk
|
||||||
|
- Simon Taddiken
|
||||||
|
- Joris
|
||||||
|
- Bastiaan Nijkamp
|
||||||
|
|
||||||
|
## 2018
|
||||||
|
- a1ex4
|
||||||
|
- Daniel Quah
|
||||||
|
- Marco Lourenço
|
||||||
|
- Dennis Enderink
|
||||||
|
- Luca Bognolo
|
||||||
|
- Mike Conway
|
||||||
|
- Ben
|
||||||
|
- Mathieu Post
|
||||||
|
- George Hertz
|
||||||
|
- HamuZ HamuZ
|
||||||
|
- David Meiseles
|
||||||
|
- Erik Gelderblom
|
||||||
|
- Luca Vallerini
|
||||||
|
- Clemens Wijnekus
|
||||||
|
- Jacob Weisz
|
||||||
|
- Mateusz Gozdek
|
||||||
|
- anmol26s
|
||||||
|
- Kevin Hellemun
|
||||||
|
- Shashank M Chakravarthy
|
||||||
|
- Nico Schreiner
|
||||||
|
- Paul Sohier
|
||||||
|
- Brenden Conte
|
||||||
|
- Ben Yanke
|
||||||
|
- Andrew Prokhorenkov
|
||||||
|
- devlearner
|
||||||
|
- Kelvin
|
||||||
|
- J'informatique
|
||||||
|
|
||||||
|
## 2017
|
||||||
|
- Victor Mosin
|
||||||
|
- Justin
|
||||||
|
- Hugo van Duijn
|
||||||
|
- Lukas Winkler
|
||||||
|
- Marcin Szymanski
|
||||||
|
- Jens Kat
|
||||||
|
- koziolek
|
||||||
|
- jleeong
|
||||||
|
- Simon Hanna
|
||||||
|
- richard & xeli.eu
|
||||||
|
- Sergey Besedin
|
||||||
|
- Welbert Serra
|
||||||
|
- Joris de Vries
|
||||||
|
- Patrick Kostjens
|
||||||
|
- Enrico Lamperti
|
||||||
|
- Christian Musa
|
||||||
|
- Enno Lohmeier
|
||||||
|
|
||||||
|
## 2016
|
||||||
|
- Sander
|
||||||
|
- Toon Schoenmakers
|
||||||
|
- Telyn
|
||||||
|
- Sander Kleykens
|
||||||
|
- Tom van der Werf
|
||||||
|
- Matthew Peck
|
||||||
|
- Sander Mulders
|
||||||
|
- Bonno Nachtegaal-Karels
|
||||||
|
- Niek Haarman
|
||||||
|
- Edwin
|
||||||
|
- Thijs Alkemade
|
||||||
|
- zjean
|
||||||
|
- Graham Miller
|
||||||
|
- Robert Horlings
|
||||||
|
- leander091
|
||||||
|
|
||||||
|
## 2015
|
||||||
|
- Antonio Spinelli
|
||||||
|
- Colin O'Dell
|
||||||
|
- RonaldvanMeer
|
||||||
|
- Richard Ebbers
|
||||||
|
- Balazs Varkonyi
|
||||||
|
- Niek van der Kooy
|
||||||
|
- Ilya Kil
|
||||||
|
|
||||||
|
## 2014
|
||||||
|
- Stewart Malik
|
||||||
|
- Graham Campbell
|
||||||
|
|
||||||
|
|
||||||
|
Thank you for all your support!
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController.php
|
* AccountController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -25,14 +26,16 @@ 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\Enums\AccountTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Debug\Timer;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use JsonException;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
@@ -41,6 +44,10 @@ class AccountController extends Controller
|
|||||||
{
|
{
|
||||||
use AccountFilter;
|
use AccountFilter;
|
||||||
|
|
||||||
|
// this array only exists to test if the constructor will use it properly.
|
||||||
|
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
private array $balanceTypes;
|
private array $balanceTypes;
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
@@ -60,71 +67,79 @@ class AccountController extends Controller
|
|||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE,];
|
$this->balanceTypes = [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Documentation for this endpoint:
|
* Documentation for this endpoint:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getAccountsAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getAccountsAC
|
||||||
*
|
*
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws JsonException
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function accounts(AutocompleteRequest $request): JsonResponse
|
public function accounts(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$types = $data['types'];
|
$types = $data['types'];
|
||||||
$query = $data['query'];
|
$query = $data['query'];
|
||||||
$date = $data['date'] ?? today(config('app.timezone'));
|
$date = $data['date'] ?? today(config('app.timezone'));
|
||||||
|
|
||||||
$return = [];
|
$return = [];
|
||||||
$result = $this->repository->searchAccount((string)$query, $types, $data['limit']);
|
Timer::start(sprintf('AC accounts "%s"', $query));
|
||||||
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
|
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
|
||||||
|
// set date to subday + end-of-day for account balance. so it is at $date 23:59:59
|
||||||
|
$date->endOfDay();
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($result as $account) {
|
foreach ($result as $account) {
|
||||||
$nameWithBalance = $account->name;
|
$nameWithBalance = $account->name;
|
||||||
$currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
|
||||||
|
$useCurrency = $currency;
|
||||||
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
||||||
$balance = app('steam')->balance($account, $date);
|
// this one is correct.
|
||||||
|
Log::debug(sprintf('accounts: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
|
||||||
|
$balance = Steam::finalAccountBalance($account, $date);
|
||||||
|
$key = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance';
|
||||||
|
$useCurrency = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? $this->nativeCurrency : $currency;
|
||||||
|
$amount = $balance[$key] ?? '0';
|
||||||
$nameWithBalance = sprintf(
|
$nameWithBalance = sprintf(
|
||||||
'%s (%s)',
|
'%s (%s)',
|
||||||
$account->name,
|
$account->name,
|
||||||
app('amount')->formatAnything($currency, $balance, false)
|
app('amount')->formatAnything($useCurrency, $amount, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'id' => (string)$account->id,
|
'id' => (string) $account->id,
|
||||||
'name' => $account->name,
|
'name' => $account->name,
|
||||||
'name_with_balance' => $nameWithBalance,
|
'name_with_balance' => $nameWithBalance,
|
||||||
'type' => $account->accountType->type,
|
'type' => $account->accountType->type,
|
||||||
'currency_id' => $currency->id,
|
'currency_id' => (string) $useCurrency->id,
|
||||||
'currency_name' => $currency->name,
|
'currency_name' => $useCurrency->name,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $useCurrency->code,
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $useCurrency->symbol,
|
||||||
'currency_decimal_places' => $currency->decimal_places,
|
'currency_decimal_places' => $useCurrency->decimal_places,
|
||||||
|
'account_currency_id' => (string) $currency->id,
|
||||||
|
'account_currency_name' => $currency->name,
|
||||||
|
'account_currency_code' => $currency->code,
|
||||||
|
'account_currency_symbol' => $currency->symbol,
|
||||||
|
'account_currency_decimal_places' => $currency->decimal_places,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom order.
|
// custom order.
|
||||||
usort(
|
usort(
|
||||||
$return,
|
$return,
|
||||||
function ($a, $b) {
|
static function (array $left, array $right) {
|
||||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
$order = [AccountTypeEnum::ASSET->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::EXPENSE->value];
|
||||||
$posA = array_search($a['type'], $order, true);
|
$posA = (int) array_search($left['type'], $order, true);
|
||||||
$posB = array_search($b['type'], $order, true);
|
$posB = (int) array_search($right['type'], $order, true);
|
||||||
|
|
||||||
return $posA - $posB;
|
return $posA - $posB;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Timer::stop(sprintf('AC accounts "%s"', $query));
|
||||||
|
|
||||||
return response()->json($return);
|
return response()->api($return);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BillController.php
|
* BillController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -58,26 +59,19 @@ class BillController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Documentation for this endpoint is at:
|
* Documentation for this endpoint is at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBillsAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBillsAC
|
||||||
* TODO expand API to add active field.
|
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function bills(AutocompleteRequest $request): JsonResponse
|
public function bills(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchBill($data['query'], $data['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()->json($filtered->toArray());
|
return response()->api($filtered->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BudgetController.php
|
* BudgetController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -58,24 +59,18 @@ class BudgetController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Documentation for this endpoint is at:
|
* Documentation for this endpoint is at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBudgetsAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBudgetsAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function budgets(AutocompleteRequest $request): JsonResponse
|
public function budgets(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchBudget($data['query'], $data['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()->json($filtered);
|
return response()->api($filtered->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CategoryController.php
|
* CategoryController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -58,24 +59,18 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Documentation for this endpoint is at:
|
* Documentation for this endpoint is at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCategoriesAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCategoriesAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function categories(AutocompleteRequest $request): JsonResponse
|
public function categories(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchCategory($data['query'], $data['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()->json($filtered);
|
return response()->api($filtered->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CurrencyController.php
|
* CurrencyController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -58,21 +59,17 @@ class CurrencyController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Documentation for this endpoint is at:
|
* Documentation for this endpoint is at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function currencies(AutocompleteRequest $request): JsonResponse
|
public function currencies(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$collection = $this->repository->searchCurrency($data['query'], $data['limit']);
|
$collection = $this->repository->searchCurrency($data['query'], $this->parameters->get('limit'));
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
/** @var TransactionCurrency $currency */
|
/** @var TransactionCurrency $currency */
|
||||||
foreach ($collection as $currency) {
|
foreach ($collection as $currency) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$currency->id,
|
'id' => (string) $currency->id,
|
||||||
'name' => $currency->name,
|
'name' => $currency->name,
|
||||||
'code' => $currency->code,
|
'code' => $currency->code,
|
||||||
'symbol' => $currency->symbol,
|
'symbol' => $currency->symbol,
|
||||||
@@ -80,28 +77,25 @@ class CurrencyController extends Controller
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($result);
|
return response()->api($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Documentation for this endpoint is at:
|
* Documentation for this endpoint is at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesCodeAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesCodeAC
|
||||||
*
|
*
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public function currenciesWithCode(AutocompleteRequest $request): JsonResponse
|
public function currenciesWithCode(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$collection = $this->repository->searchCurrency($data['query'], $data['limit']);
|
$collection = $this->repository->searchCurrency($data['query'], $this->parameters->get('limit'));
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
/** @var TransactionCurrency $currency */
|
/** @var TransactionCurrency $currency */
|
||||||
foreach ($collection as $currency) {
|
foreach ($collection as $currency) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$currency->id,
|
'id' => (string) $currency->id,
|
||||||
'name' => sprintf('%s (%s)', $currency->name, $currency->code),
|
'name' => sprintf('%s (%s)', $currency->name, $currency->code),
|
||||||
'code' => $currency->code,
|
'code' => $currency->code,
|
||||||
'symbol' => $currency->symbol,
|
'symbol' => $currency->symbol,
|
||||||
@@ -109,6 +103,6 @@ class CurrencyController extends Controller
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($result);
|
return response()->api($result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ObjectGroupController.php
|
* ObjectGroupController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -58,26 +59,22 @@ class ObjectGroupController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Documentation for this endpoint is at:
|
* Documentation for this endpoint is at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getObjectGroupsAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getObjectGroupsAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function objectGroups(AutocompleteRequest $request): JsonResponse
|
public function objectGroups(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$return = [];
|
$return = [];
|
||||||
$result = $this->repository->search($data['query'], $data['limit']);
|
$result = $this->repository->search($data['query'], $this->parameters->get('limit'));
|
||||||
|
|
||||||
/** @var ObjectGroup $objectGroup */
|
/** @var ObjectGroup $objectGroup */
|
||||||
foreach ($result as $objectGroup) {
|
foreach ($result as $objectGroup) {
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'id' => (string)$objectGroup->id,
|
'id' => (string) $objectGroup->id,
|
||||||
'name' => $objectGroup->title,
|
'name' => $objectGroup->title,
|
||||||
'title' => $objectGroup->title,
|
'title' => $objectGroup->title,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($return);
|
return response()->api($return);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PiggyBankController.php
|
* PiggyBankController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -62,76 +63,67 @@ class PiggyBankController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function piggyBanks(AutocompleteRequest $request): JsonResponse
|
public function piggyBanks(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $data['limit']);
|
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$response = [];
|
||||||
$response = [];
|
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($piggies as $piggy) {
|
foreach ($piggies as $piggy) {
|
||||||
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
|
$currency = $piggy->transactionCurrency;
|
||||||
$objectGroup = $piggy->objectGroups()->first();
|
$objectGroup = $piggy->objectGroups()->first();
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string)$piggy->id,
|
'id' => (string) $piggy->id,
|
||||||
'name' => $piggy->name,
|
'name' => $piggy->name,
|
||||||
'currency_id' => (string)$currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
'currency_name' => $currency->name,
|
'currency_name' => $currency->name,
|
||||||
'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,
|
||||||
'object_group_id' => null === $objectGroup ? null : (string)$objectGroup->id,
|
'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
|
||||||
'object_group_title' => $objectGroup?->title,
|
'object_group_title' => $objectGroup?->title,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($response);
|
return response()->api($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesBalanceAC
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesBalanceAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function piggyBanksWithBalance(AutocompleteRequest $request): JsonResponse
|
public function piggyBanksWithBalance(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $data['limit']);
|
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$response = [];
|
||||||
$response = [];
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($piggies as $piggy) {
|
foreach ($piggies as $piggy) {
|
||||||
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
|
$currency = $piggy->transactionCurrency;
|
||||||
$currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0';
|
$currentAmount = $this->piggyRepository->getCurrentAmount($piggy);
|
||||||
$objectGroup = $piggy->objectGroups()->first();
|
$objectGroup = $piggy->objectGroups()->first();
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string)$piggy->id,
|
'id' => (string) $piggy->id,
|
||||||
'name' => $piggy->name,
|
'name' => $piggy->name,
|
||||||
'name_with_balance' => sprintf(
|
'name_with_balance' => sprintf(
|
||||||
'%s (%s / %s)',
|
'%s (%s / %s)',
|
||||||
$piggy->name,
|
$piggy->name,
|
||||||
app('amount')->formatAnything($currency, $currentAmount, false),
|
app('amount')->formatAnything($currency, $currentAmount, false),
|
||||||
app('amount')->formatAnything($currency, $piggy->targetamount, false),
|
app('amount')->formatAnything($currency, $piggy->target_amount, false),
|
||||||
),
|
),
|
||||||
'currency_id' => (string)$currency->id,
|
'currency_id' => (string) $currency->id,
|
||||||
'currency_name' => $currency->name,
|
'currency_name' => $currency->name,
|
||||||
'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,
|
||||||
'object_group_id' => null === $objectGroup ? null : (string)$objectGroup->id,
|
'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
|
||||||
'object_group_title' => $objectGroup?->title,
|
'object_group_title' => $objectGroup?->title,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($response);
|
return response()->api($response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RecurrenceController.php
|
* RecurrenceController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -56,26 +57,22 @@ class RecurrenceController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRecurringAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRecurringAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function recurring(AutocompleteRequest $request): JsonResponse
|
public function recurring(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$recurrences = $this->repository->searchRecurrence($data['query'], $data['limit']);
|
$recurrences = $this->repository->searchRecurrence($data['query'], $this->parameters->get('limit'));
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var Recurrence $recurrence */
|
/** @var Recurrence $recurrence */
|
||||||
foreach ($recurrences as $recurrence) {
|
foreach ($recurrences as $recurrence) {
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string)$recurrence->id,
|
'id' => (string) $recurrence->id,
|
||||||
'name' => $recurrence->title,
|
'name' => $recurrence->title,
|
||||||
'description' => $recurrence->description,
|
'description' => $recurrence->description,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($response);
|
return response()->api($response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RuleController.php
|
* RuleController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -55,26 +56,22 @@ class RuleController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRulesAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRulesAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function rules(AutocompleteRequest $request): JsonResponse
|
public function rules(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$rules = $this->repository->searchRule($data['query'], $data['limit']);
|
$rules = $this->repository->searchRule($data['query'], $this->parameters->get('limit'));
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var Rule $rule */
|
/** @var Rule $rule */
|
||||||
foreach ($rules as $rule) {
|
foreach ($rules as $rule) {
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string)$rule->id,
|
'id' => (string) $rule->id,
|
||||||
'name' => $rule->title,
|
'name' => $rule->title,
|
||||||
'description' => $rule->description,
|
'description' => $rule->description,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($response);
|
return response()->api($response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RuleGroupController.php
|
* RuleGroupController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -55,26 +56,22 @@ class RuleGroupController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRuleGroupsAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRuleGroupsAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function ruleGroups(AutocompleteRequest $request): JsonResponse
|
public function ruleGroups(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$groups = $this->repository->searchRuleGroup($data['query'], $data['limit']);
|
$groups = $this->repository->searchRuleGroup($data['query'], $this->parameters->get('limit'));
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
/** @var RuleGroup $group */
|
/** @var RuleGroup $group */
|
||||||
foreach ($groups as $group) {
|
foreach ($groups as $group) {
|
||||||
$response[] = [
|
$response[] = [
|
||||||
'id' => (string)$group->id,
|
'id' => (string) $group->id,
|
||||||
'name' => $group->title,
|
'name' => $group->title,
|
||||||
'description' => $group->description,
|
'description' => $group->description,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($response);
|
return response()->api($response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TagController.php
|
* TagController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -58,26 +59,22 @@ class TagController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTagAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTagAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function tags(AutocompleteRequest $request): JsonResponse
|
public function tags(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
|
$result = $this->repository->searchTags($data['query'], $this->parameters->get('limit'));
|
||||||
$result = $this->repository->searchTags($data['query'], $data['limit']);
|
|
||||||
$array = [];
|
$array = [];
|
||||||
|
|
||||||
/** @var Tag $tag */
|
/** @var Tag $tag */
|
||||||
foreach ($result as $tag) {
|
foreach ($result as $tag) {
|
||||||
$array[] = [
|
$array[] = [
|
||||||
'id' => (string)$tag->id,
|
'id' => (string) $tag->id,
|
||||||
'name' => $tag->tag,
|
'name' => $tag->tag,
|
||||||
'tag' => $tag->tag,
|
'tag' => $tag->tag,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($array);
|
return response()->api($array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TransactionController.php
|
* TransactionController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -25,6 +26,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\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||||
@@ -37,6 +39,7 @@ 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;
|
||||||
|
|
||||||
@@ -50,10 +53,12 @@ class TransactionController extends Controller
|
|||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
$userGroup = $this->validateUserGroup($request);
|
||||||
$this->repository = app(JournalRepositoryInterface::class);
|
$this->repository = app(JournalRepositoryInterface::class);
|
||||||
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
|
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
|
||||||
$this->repository->setUser($user);
|
$this->repository->setUser($user);
|
||||||
$this->groupRepository->setUser($user);
|
$this->groupRepository->setUser($user);
|
||||||
|
$this->groupRepository->setUserGroup($userGroup);
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
@@ -63,15 +68,11 @@ class TransactionController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function transactions(AutocompleteRequest $request): JsonResponse
|
public function transactions(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$result = $this->repository->searchJournalDescriptions($data['query'], $data['limit']);
|
$result = $this->repository->searchJournalDescriptions($data['query'], $this->parameters->get('limit'));
|
||||||
|
|
||||||
// limit and unique
|
// limit and unique
|
||||||
$filtered = $result->unique('description');
|
$filtered = $result->unique('description');
|
||||||
@@ -80,23 +81,19 @@ class TransactionController extends Controller
|
|||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($filtered as $journal) {
|
foreach ($filtered as $journal) {
|
||||||
$array[] = [
|
$array[] = [
|
||||||
'id' => (string)$journal->id,
|
'id' => (string) $journal->id,
|
||||||
'transaction_group_id' => (string)$journal->transaction_group_id,
|
'transaction_group_id' => (string) $journal->transaction_group_id,
|
||||||
'name' => $journal->description,
|
'name' => $journal->description,
|
||||||
'description' => $journal->description,
|
'description' => $journal->description,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($array);
|
return response()->api($array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsIDAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsIDAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function transactionsWithID(AutocompleteRequest $request): JsonResponse
|
public function transactionsWithID(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -104,7 +101,7 @@ class TransactionController extends Controller
|
|||||||
$result = new Collection();
|
$result = new Collection();
|
||||||
if (is_numeric($data['query'])) {
|
if (is_numeric($data['query'])) {
|
||||||
// search for group, not journal.
|
// search for group, not journal.
|
||||||
$firstResult = $this->groupRepository->find((int)$data['query']);
|
$firstResult = $this->groupRepository->find((int) $data['query']);
|
||||||
if (null !== $firstResult) {
|
if (null !== $firstResult) {
|
||||||
// group may contain multiple journals, each a result:
|
// group may contain multiple journals, each a result:
|
||||||
foreach ($firstResult->transactionJournals as $journal) {
|
foreach ($firstResult->transactionJournals as $journal) {
|
||||||
@@ -113,22 +110,22 @@ class TransactionController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_numeric($data['query'])) {
|
if (!is_numeric($data['query'])) {
|
||||||
$result = $this->repository->searchJournalDescriptions($data['query'], $data['limit']);
|
$result = $this->repository->searchJournalDescriptions($data['query'], $this->parameters->get('limit'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// limit and unique
|
// limit and unique
|
||||||
$array = [];
|
$array = [];
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($result as $journal) {
|
foreach ($result as $journal) {
|
||||||
$array[] = [
|
$array[] = [
|
||||||
'id' => (string)$journal->id,
|
'id' => (string) $journal->id,
|
||||||
'transaction_group_id' => (string)$journal->transaction_group_id,
|
'transaction_group_id' => (string) $journal->transaction_group_id,
|
||||||
'name' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
|
'name' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
|
||||||
'description' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
|
'description' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($array);
|
return response()->api($array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TransactionTypeController.php
|
* TransactionTypeController.php
|
||||||
* Copyright (c) 2020 james@firefly-iii.org
|
* Copyright (c) 2020 james@firefly-iii.org
|
||||||
@@ -54,27 +55,23 @@ class TransactionTypeController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at
|
* This endpoint is documented at
|
||||||
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionTypesAC
|
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionTypesAC
|
||||||
*
|
|
||||||
* @param AutocompleteRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function transactionTypes(AutocompleteRequest $request): JsonResponse
|
public function transactionTypes(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getData();
|
$data = $request->getData();
|
||||||
$types = $this->repository->searchTypes($data['query'], $data['limit']);
|
$types = $this->repository->searchTypes($data['query'], $this->parameters->get('limit'));
|
||||||
$array = [];
|
$array = [];
|
||||||
|
|
||||||
/** @var TransactionType $type */
|
/** @var TransactionType $type */
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
// different key for consistency.
|
// different key for consistency.
|
||||||
$array[] = [
|
$array[] = [
|
||||||
'id' => (string)$type->id,
|
'id' => (string) $type->id,
|
||||||
'name' => $type->type,
|
'name' => $type->type,
|
||||||
'type' => $type->type,
|
'type' => $type->type,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($array);
|
return response()->api($array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,18 +26,19 @@ 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\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Support\Chart\ChartData;
|
||||||
|
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;
|
||||||
use JsonException;
|
|
||||||
use Psr\Container\ContainerExceptionInterface;
|
|
||||||
use Psr\Container\NotFoundExceptionInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
@@ -45,14 +46,13 @@ use Psr\Container\NotFoundExceptionInterface;
|
|||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
use ApiSupport;
|
use ApiSupport;
|
||||||
|
use CollectsAccountsFromFilter;
|
||||||
|
|
||||||
private CurrencyRepositoryInterface $currencyRepository;
|
private ChartData $chartData;
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -61,61 +61,122 @@ 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);
|
||||||
|
|
||||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
|
||||||
$this->currencyRepository->setUser($user);
|
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
*
|
*
|
||||||
* @param DateRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* @throws JsonException
|
|
||||||
* @throws ContainerExceptionInterface
|
|
||||||
* @throws NotFoundExceptionInterface
|
|
||||||
*/
|
*/
|
||||||
public function overview(DateRequest $request): JsonResponse
|
public function overview(DateRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
// parameters for chart:
|
// parameters for chart:
|
||||||
$dates = $request->getAll();
|
$dates = $request->getAll();
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = $dates['start'];
|
$start = $dates['start'];
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = $dates['end'];
|
$end = $dates['end'];
|
||||||
|
|
||||||
|
// set dates to end of day + start of day:
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
// user's preferences
|
// user's preferences
|
||||||
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
|
||||||
$default = app('amount')->getDefaultCurrency();
|
|
||||||
|
|
||||||
if (!(is_array($frontPage->data) && count($frontPage->data) > 0)) {
|
/** @var Preference $frontpage */
|
||||||
$frontPage->data = $defaultSet;
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
$frontPage->save();
|
|
||||||
|
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||||
|
$frontpage->data = $defaultSet;
|
||||||
|
$frontpage->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get accounts:
|
// get accounts:
|
||||||
$accounts = $this->repository->getAccountsById($frontPage->data);
|
$accounts = $this->repository->getAccountsById($frontpage->data);
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
$currency = $this->repository->getAccountCurrency($account);
|
$currency = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
|
||||||
if (null === $currency) {
|
$field = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance';
|
||||||
$currency = $default;
|
$currentSet = [
|
||||||
}
|
|
||||||
$currentSet = [
|
|
||||||
'label' => $account->name,
|
'label' => $account->name,
|
||||||
'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,
|
||||||
@@ -127,18 +188,17 @@ class AccountController extends Controller
|
|||||||
];
|
];
|
||||||
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
||||||
$currentStart = clone $start;
|
$currentStart = clone $start;
|
||||||
$range = app('steam')->balanceInRange($account, $start, clone $end);
|
$range = Steam::finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
||||||
// 2022-10-11 this method no longer converts to float.
|
$previous = array_values($range)[0][$field];
|
||||||
$previous = array_values($range)[0];
|
|
||||||
while ($currentStart <= $end) {
|
while ($currentStart <= $end) {
|
||||||
$format = $currentStart->format('Y-m-d');
|
$format = $currentStart->format('Y-m-d');
|
||||||
$label = $currentStart->toAtomString();
|
$label = $currentStart->toAtomString();
|
||||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
$balance = array_key_exists($format, $range) ? $range[$format][$field] : $previous;
|
||||||
$previous = $balance;
|
$previous = $balance;
|
||||||
$currentStart->addDay();
|
$currentStart->addDay();
|
||||||
$currentSet['entries'][$label] = $balance;
|
$currentSet['entries'][$label] = $balance;
|
||||||
}
|
}
|
||||||
$chartData[] = $currentSet;
|
$chartData[] = $currentSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($chartData);
|
return response()->json($chartData);
|
||||||
|
|||||||
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,34 +25,51 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V1\Controllers;
|
namespace FireflyIII\Api\V1\Controllers;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Carbon\Exceptions\InvalidDateException;
|
|
||||||
use Carbon\Exceptions\InvalidFormatException;
|
use Carbon\Exceptions\InvalidFormatException;
|
||||||
|
use FireflyIII\Exceptions\BadHttpHeaderException;
|
||||||
|
use FireflyIII\Models\Preference;
|
||||||
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
|
use FireflyIII\Transformers\AbstractTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
|
use League\Fractal\Resource\Item;
|
||||||
use League\Fractal\Serializer\JsonApiSerializer;
|
use League\Fractal\Serializer\JsonApiSerializer;
|
||||||
use Psr\Container\ContainerExceptionInterface;
|
|
||||||
use Psr\Container\NotFoundExceptionInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Controller.
|
* Class Controller.
|
||||||
*
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.CouplingBetweenObjects")
|
||||||
|
* @SuppressWarnings("PHPMD.NumberOfChildren")
|
||||||
*/
|
*/
|
||||||
abstract class Controller extends BaseController
|
abstract class Controller extends BaseController
|
||||||
{
|
{
|
||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
use DispatchesJobs;
|
use DispatchesJobs;
|
||||||
use ValidatesRequests;
|
use ValidatesRequests;
|
||||||
|
use ValidatesUserGroupTrait;
|
||||||
|
|
||||||
protected const CONTENT_TYPE = 'application/vnd.api+json';
|
protected const string CONTENT_TYPE = 'application/vnd.api+json';
|
||||||
protected array $allowedSort;
|
protected const string JSON_CONTENT_TYPE = 'application/json';
|
||||||
protected ParameterBag $parameters;
|
protected array $accepts = ['application/json', 'application/vnd.api+json'];
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
protected array $allowedSort;
|
||||||
|
protected bool $convertToNative = false;
|
||||||
|
protected TransactionCurrency $nativeCurrency;
|
||||||
|
protected ParameterBag $parameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller constructor.
|
* Controller constructor.
|
||||||
@@ -61,14 +78,23 @@ abstract class Controller extends BaseController
|
|||||||
{
|
{
|
||||||
// get global parameters
|
// get global parameters
|
||||||
$this->allowedSort = config('firefly.allowed_sort_parameters');
|
$this->allowedSort = config('firefly.allowed_sort_parameters');
|
||||||
$this->parameters = $this->getParameters();
|
|
||||||
$this->middleware(
|
$this->middleware(
|
||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
|
$this->parameters = $this->getParameters();
|
||||||
if (auth()->check()) {
|
if (auth()->check()) {
|
||||||
$language = app('steam')->getLanguage();
|
$language = Steam::getLanguage();
|
||||||
|
$this->convertToNative = Amount::convertToNative();
|
||||||
|
$this->nativeCurrency = Amount::getNativeCurrency();
|
||||||
app()->setLocale($language);
|
app()->setLocale($language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// filter down what this endpoint accepts.
|
||||||
|
if (!$request->accepts($this->accepts)) {
|
||||||
|
throw new BadHttpHeaderException(sprintf('Sorry, Accept header "%s" is not something this endpoint can provide.', $request->header('Accept')));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -76,45 +102,42 @@ abstract class Controller extends BaseController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to grab all parameters from the URL.
|
* Method to grab all parameters from the URL.
|
||||||
*
|
|
||||||
* @return ParameterBag
|
|
||||||
* @throws ContainerExceptionInterface
|
|
||||||
* @throws NotFoundExceptionInterface
|
|
||||||
*/
|
*/
|
||||||
private function getParameters(): ParameterBag
|
private function getParameters(): ParameterBag
|
||||||
{
|
{
|
||||||
$bag = new ParameterBag();
|
$bag = new ParameterBag();
|
||||||
$page = (int)request()->get('page');
|
$page = (int) request()->get('page');
|
||||||
if ($page < 1) {
|
if ($page < 1) {
|
||||||
$page = 1;
|
$page = 1;
|
||||||
}
|
}
|
||||||
if ($page > pow(2, 16)) {
|
if ($page > 2 ** 16) {
|
||||||
$page = pow(2, 16);
|
$page = 2 ** 16;
|
||||||
}
|
}
|
||||||
$bag->set('page', $page);
|
$bag->set('page', $page);
|
||||||
|
|
||||||
// some date fields:
|
// some date fields:
|
||||||
$dates = ['start', 'end', 'date'];
|
$dates = ['start', 'end', 'date'];
|
||||||
foreach ($dates as $field) {
|
foreach ($dates as $field) {
|
||||||
$date = null;
|
$date = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$date = request()->query->get($field);
|
$date = request()->query->get($field);
|
||||||
} catch (BadRequestException $e) {
|
} catch (BadRequestException $e) {
|
||||||
Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
|
app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
|
||||||
Log::error($e->getMessage());
|
app('log')->error($e->getMessage());
|
||||||
Log::error($e->getTraceAsString());
|
app('log')->error($e->getTraceAsString());
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
$obj = null;
|
$obj = null;
|
||||||
if (null !== $date) {
|
if (null !== $date) {
|
||||||
try {
|
try {
|
||||||
$obj = Carbon::parse($date);
|
$obj = Carbon::parse((string) $date);
|
||||||
} catch (InvalidDateException | InvalidFormatException $e) {
|
} catch (InvalidFormatException $e) {
|
||||||
// don't care
|
// don't care
|
||||||
app('log')->warning(
|
app('log')->warning(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Ignored invalid date "%s" in API controller parameter check: %s',
|
'Ignored invalid date "%s" in API controller parameter check: %s',
|
||||||
substr($date, 0, 20),
|
substr((string) $date, 0, 20),
|
||||||
$e->getMessage()
|
$e->getMessage()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -129,13 +152,32 @@ abstract class Controller extends BaseController
|
|||||||
try {
|
try {
|
||||||
$value = request()->query->get($integer);
|
$value = request()->query->get($integer);
|
||||||
} catch (BadRequestException $e) {
|
} catch (BadRequestException $e) {
|
||||||
Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
|
app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
|
||||||
Log::error($e->getMessage());
|
app('log')->error($e->getMessage());
|
||||||
Log::error($e->getTraceAsString());
|
app('log')->error($e->getTraceAsString());
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
if (null !== $value) {
|
if (null !== $value) {
|
||||||
$bag->set($integer, (int)$value);
|
$value = (int) $value;
|
||||||
|
if ($value < 1) {
|
||||||
|
$value = 1;
|
||||||
|
}
|
||||||
|
if ($value > 2 ** 16) {
|
||||||
|
$value = 2 ** 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bag->set($integer, $value);
|
||||||
|
}
|
||||||
|
if (null === $value
|
||||||
|
&& 'limit' === $integer // @phpstan-ignore-line
|
||||||
|
&& auth()->check()) {
|
||||||
|
// set default for user:
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
/** @var Preference $pageSize */
|
||||||
|
$pageSize = (int) app('preferences')->getForUser($user, 'listPageSize', 50)->data;
|
||||||
|
$bag->set($integer, $pageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,26 +185,22 @@ abstract class Controller extends BaseController
|
|||||||
return $this->getSortParameters($bag);
|
return $this->getSortParameters($bag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ParameterBag $bag
|
|
||||||
*
|
|
||||||
* @return ParameterBag
|
|
||||||
*/
|
|
||||||
private function getSortParameters(ParameterBag $bag): ParameterBag
|
private function getSortParameters(ParameterBag $bag): ParameterBag
|
||||||
{
|
{
|
||||||
$sortParameters = [];
|
$sortParameters = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$param = (string)request()->query->get('sort');
|
$param = (string) request()->query->get('sort');
|
||||||
} catch (BadRequestException $e) {
|
} catch (BadRequestException $e) {
|
||||||
Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.');
|
app('log')->error('Request field "sort" contains a non-scalar value. Value set to NULL.');
|
||||||
Log::error($e->getMessage());
|
app('log')->error($e->getMessage());
|
||||||
Log::error($e->getTraceAsString());
|
app('log')->error($e->getTraceAsString());
|
||||||
$param = '';
|
$param = '';
|
||||||
}
|
}
|
||||||
if ('' === $param) {
|
if ('' === $param) {
|
||||||
return $bag;
|
return $bag;
|
||||||
}
|
}
|
||||||
$parts = explode(',', $param);
|
$parts = explode(',', $param);
|
||||||
foreach ($parts as $part) {
|
foreach ($parts as $part) {
|
||||||
$part = trim($part);
|
$part = trim($part);
|
||||||
$direction = 'asc';
|
$direction = 'asc';
|
||||||
@@ -181,8 +219,6 @@ abstract class Controller extends BaseController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to help build URL's.
|
* Method to help build URL's.
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
final protected function buildParams(): string
|
final protected function buildParams(): string
|
||||||
{
|
{
|
||||||
@@ -194,24 +230,63 @@ abstract class Controller extends BaseController
|
|||||||
}
|
}
|
||||||
if ($value instanceof Carbon) {
|
if ($value instanceof Carbon) {
|
||||||
$params[$key] = $value->format('Y-m-d');
|
$params[$key] = $value->format('Y-m-d');
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$params[$key] = $value;
|
$params[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return . http_build_query($params);
|
return $return.http_build_query($params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Manager
|
|
||||||
*/
|
|
||||||
final protected function getManager(): Manager
|
final protected function getManager(): Manager
|
||||||
{
|
{
|
||||||
// create some objects:
|
// create some objects:
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
$baseUrl = request()->getSchemeAndHttpHost() . '/api/v1';
|
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
|
||||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
return $manager;
|
return $manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
|
||||||
|
{
|
||||||
|
$manager = new Manager();
|
||||||
|
$baseUrl = sprintf('%s/api/v1/', request()->getSchemeAndHttpHost());
|
||||||
|
|
||||||
|
// TODO add stuff to path?
|
||||||
|
|
||||||
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
|
$objects = $paginator->getCollection();
|
||||||
|
|
||||||
|
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||||
|
// require, like meta-data and stuff like that, and save it for later.
|
||||||
|
// $objects = $transformer->collectMetaData($objects);
|
||||||
|
$paginator->setCollection($objects);
|
||||||
|
|
||||||
|
$resource = new FractalCollection($objects, $transformer, $key);
|
||||||
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
|
return $manager->createData($resource)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a JSON API object and returns it.
|
||||||
|
*
|
||||||
|
* @param array<int, mixed>|Model $object
|
||||||
|
*/
|
||||||
|
final protected function jsonApiObject(string $key, array|Model $object, AbstractTransformer $transformer): array
|
||||||
|
{
|
||||||
|
// create some objects:
|
||||||
|
$manager = new Manager();
|
||||||
|
$baseUrl = sprintf('%s/api/v1', request()->getSchemeAndHttpHost());
|
||||||
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
|
// $transformer->collectMetaData(new Collection([$object]));
|
||||||
|
|
||||||
|
$resource = new Item($object, $transformer, $key);
|
||||||
|
|
||||||
|
return $manager->createData($resource)->toArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ class TransactionController extends Controller
|
|||||||
{
|
{
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@@ -63,10 +60,6 @@ class TransactionController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/bulkUpdateTransactions
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/bulkUpdateTransactions
|
||||||
*
|
|
||||||
* @param TransactionRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function update(TransactionRequest $request): JsonResponse
|
public function update(TransactionRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -76,12 +69,12 @@ class TransactionController extends Controller
|
|||||||
// this deserves better code, but for now a loop of basic if-statements
|
// this deserves better code, but for now a loop of basic if-statements
|
||||||
// to respond to what is in the $query.
|
// to respond to what is in the $query.
|
||||||
// this is OK because only one thing can be in the query at the moment.
|
// this is OK because only one thing can be in the query at the moment.
|
||||||
if ($this->updatesTransactionAccount($params)) {
|
if ($this->isUpdateTransactionAccount($params)) {
|
||||||
$original = $this->repository->find((int)$params['where']['account_id']);
|
$original = $this->repository->find((int) $params['where']['account_id']);
|
||||||
$destination = $this->repository->find((int)$params['update']['account_id']);
|
$destination = $this->repository->find((int) $params['update']['account_id']);
|
||||||
|
|
||||||
/** @var AccountDestroyService $service */
|
/** @var AccountDestroyService $service */
|
||||||
$service = app(AccountDestroyService::class);
|
$service = app(AccountDestroyService::class);
|
||||||
$service->moveTransactions($original, $destination);
|
$service->moveTransactions($original, $destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,11 +82,9 @@ class TransactionController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $params
|
* @param array<string, array<string, string>> $params
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function updatesTransactionAccount(array $params): bool
|
private function isUpdateTransactionAccount(array $params): bool
|
||||||
{
|
{
|
||||||
return array_key_exists('account_id', $params['where']) && array_key_exists('account_id', $params['update']);
|
return array_key_exists('account_id', $params['where']) && array_key_exists('account_id', $params['update']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DestroyController.php
|
* DestroyController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -25,11 +26,11 @@ namespace FireflyIII\Api\V1\Controllers\Data;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Data\DestroyRequest;
|
use FireflyIII\Api\V1\Requests\Data\DestroyRequest;
|
||||||
|
use FireflyIII\Enums\AccountTypeEnum;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||||
@@ -58,160 +59,53 @@ class DestroyController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/destroyData
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/destroyData
|
||||||
*
|
*
|
||||||
* @param DestroyRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function destroy(DestroyRequest $request): JsonResponse
|
public function destroy(DestroyRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$objects = $request->getObjects();
|
$objects = $request->getObjects();
|
||||||
$this->unused = $request->boolean('unused', false);
|
$this->unused = $request->boolean('unused', false);
|
||||||
switch ($objects) {
|
|
||||||
default:
|
$allExceptAssets = [AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::REVENUE->value];
|
||||||
throw new FireflyException(sprintf('200033: This endpoint can\'t handle object "%s"', $objects));
|
$all = [AccountTypeEnum::ASSET->value, AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::RECONCILIATION->value];
|
||||||
case 'budgets':
|
$liabilities = [AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CREDITCARD->value];
|
||||||
$this->destroyBudgets();
|
$transactions = [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value, TransactionTypeEnum::RECONCILIATION->value];
|
||||||
break;
|
|
||||||
case 'bills':
|
match ($objects) {
|
||||||
$this->destroyBills();
|
'budgets' => $this->destroyBudgets(),
|
||||||
break;
|
'bills' => $this->destroyBills(),
|
||||||
case 'piggy_banks':
|
'piggy_banks' => $this->destroyPiggyBanks(),
|
||||||
$this->destroyPiggyBanks();
|
'rules' => $this->destroyRules(),
|
||||||
break;
|
'recurring' => $this->destroyRecurringTransactions(),
|
||||||
case 'rules':
|
'categories' => $this->destroyCategories(),
|
||||||
$this->destroyRules();
|
'tags' => $this->destroyTags(),
|
||||||
break;
|
'object_groups' => $this->destroyObjectGroups(),
|
||||||
case 'recurring':
|
'not_assets_liabilities' => $this->destroyAccounts($allExceptAssets),
|
||||||
$this->destroyRecurringTransactions();
|
'accounts' => $this->destroyAccounts($all),
|
||||||
break;
|
'asset_accounts' => $this->destroyAccounts([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]),
|
||||||
case 'categories':
|
'expense_accounts' => $this->destroyAccounts([AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::EXPENSE->value]),
|
||||||
$this->destroyCategories();
|
'revenue_accounts' => $this->destroyAccounts([AccountTypeEnum::REVENUE->value]),
|
||||||
break;
|
'liabilities' => $this->destroyAccounts($liabilities),
|
||||||
case 'tags':
|
'transactions' => $this->destroyTransactions($transactions),
|
||||||
$this->destroyTags();
|
'withdrawals' => $this->destroyTransactions([TransactionTypeEnum::WITHDRAWAL->value]),
|
||||||
break;
|
'deposits' => $this->destroyTransactions([TransactionTypeEnum::DEPOSIT->value]),
|
||||||
case 'object_groups':
|
'transfers' => $this->destroyTransactions([TransactionTypeEnum::TRANSFER->value]),
|
||||||
$this->destroyObjectGroups();
|
default => throw new FireflyException(sprintf('200033: This endpoint can\'t handle object "%s"', $objects)),
|
||||||
break;
|
};
|
||||||
case 'not_assets_liabilities':
|
|
||||||
$this->destroyAccounts(
|
|
||||||
[
|
|
||||||
AccountType::BENEFICIARY,
|
|
||||||
AccountType::CASH,
|
|
||||||
AccountType::CREDITCARD,
|
|
||||||
AccountType::DEFAULT,
|
|
||||||
AccountType::EXPENSE,
|
|
||||||
AccountType::IMPORT,
|
|
||||||
AccountType::INITIAL_BALANCE,
|
|
||||||
AccountType::LIABILITY_CREDIT,
|
|
||||||
AccountType::RECONCILIATION,
|
|
||||||
AccountType::REVENUE,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'accounts':
|
|
||||||
$this->destroyAccounts(
|
|
||||||
[
|
|
||||||
AccountType::ASSET,
|
|
||||||
AccountType::BENEFICIARY,
|
|
||||||
AccountType::CASH,
|
|
||||||
AccountType::CREDITCARD,
|
|
||||||
AccountType::DEBT,
|
|
||||||
AccountType::DEFAULT,
|
|
||||||
AccountType::EXPENSE,
|
|
||||||
AccountType::IMPORT,
|
|
||||||
AccountType::INITIAL_BALANCE,
|
|
||||||
AccountType::LIABILITY_CREDIT,
|
|
||||||
AccountType::LOAN,
|
|
||||||
AccountType::MORTGAGE,
|
|
||||||
AccountType::RECONCILIATION,
|
|
||||||
AccountType::REVENUE,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'asset_accounts':
|
|
||||||
$this->destroyAccounts(
|
|
||||||
[
|
|
||||||
AccountType::ASSET,
|
|
||||||
AccountType::DEFAULT,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'expense_accounts':
|
|
||||||
$this->destroyAccounts(
|
|
||||||
[
|
|
||||||
AccountType::BENEFICIARY,
|
|
||||||
AccountType::EXPENSE,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'revenue_accounts':
|
|
||||||
$this->destroyAccounts(
|
|
||||||
[
|
|
||||||
AccountType::REVENUE,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'liabilities':
|
|
||||||
$this->destroyAccounts(
|
|
||||||
[
|
|
||||||
AccountType::DEBT,
|
|
||||||
AccountType::LOAN,
|
|
||||||
AccountType::MORTGAGE,
|
|
||||||
AccountType::CREDITCARD,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'transactions':
|
|
||||||
$this->destroyTransactions(
|
|
||||||
[
|
|
||||||
TransactionType::WITHDRAWAL,
|
|
||||||
TransactionType::DEPOSIT,
|
|
||||||
TransactionType::TRANSFER,
|
|
||||||
TransactionType::RECONCILIATION,
|
|
||||||
TransactionType::OPENING_BALANCE,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'withdrawals':
|
|
||||||
$this->destroyTransactions(
|
|
||||||
[
|
|
||||||
TransactionType::WITHDRAWAL,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'deposits':
|
|
||||||
$this->destroyTransactions(
|
|
||||||
[
|
|
||||||
TransactionType::DEPOSIT,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'transfers':
|
|
||||||
$this->destroyTransactions(
|
|
||||||
[
|
|
||||||
TransactionType::TRANSFER,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
return response()->json([], 204);
|
return response()->json([], 204);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyBudgets(): void
|
private function destroyBudgets(): void
|
||||||
{
|
{
|
||||||
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
||||||
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||||
$abRepository->destroyAll();
|
$abRepository->destroyAll();
|
||||||
|
|
||||||
/** @var BudgetLimitRepositoryInterface $blRepository */
|
/** @var BudgetLimitRepositoryInterface $blRepository */
|
||||||
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||||
$blRepository->destroyAll();
|
$blRepository->destroyAll();
|
||||||
|
|
||||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||||
@@ -219,9 +113,6 @@ class DestroyController extends Controller
|
|||||||
$budgetRepository->destroyAll();
|
$budgetRepository->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyBills(): void
|
private function destroyBills(): void
|
||||||
{
|
{
|
||||||
/** @var BillRepositoryInterface $repository */
|
/** @var BillRepositoryInterface $repository */
|
||||||
@@ -229,9 +120,6 @@ class DestroyController extends Controller
|
|||||||
$repository->destroyAll();
|
$repository->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyPiggyBanks(): void
|
private function destroyPiggyBanks(): void
|
||||||
{
|
{
|
||||||
/** @var PiggyBankRepositoryInterface $repository */
|
/** @var PiggyBankRepositoryInterface $repository */
|
||||||
@@ -239,9 +127,6 @@ class DestroyController extends Controller
|
|||||||
$repository->destroyAll();
|
$repository->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyRules(): void
|
private function destroyRules(): void
|
||||||
{
|
{
|
||||||
/** @var RuleGroupRepositoryInterface $repository */
|
/** @var RuleGroupRepositoryInterface $repository */
|
||||||
@@ -249,9 +134,6 @@ class DestroyController extends Controller
|
|||||||
$repository->destroyAll();
|
$repository->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyRecurringTransactions(): void
|
private function destroyRecurringTransactions(): void
|
||||||
{
|
{
|
||||||
/** @var RecurringRepositoryInterface $repository */
|
/** @var RecurringRepositoryInterface $repository */
|
||||||
@@ -259,9 +141,6 @@ class DestroyController extends Controller
|
|||||||
$repository->destroyAll();
|
$repository->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyCategories(): void
|
private function destroyCategories(): void
|
||||||
{
|
{
|
||||||
/** @var CategoryRepositoryInterface $categoryRepos */
|
/** @var CategoryRepositoryInterface $categoryRepos */
|
||||||
@@ -269,9 +148,6 @@ class DestroyController extends Controller
|
|||||||
$categoryRepos->destroyAll();
|
$categoryRepos->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function destroyTags(): void
|
private function destroyTags(): void
|
||||||
{
|
{
|
||||||
/** @var TagRepositoryInterface $tagRepository */
|
/** @var TagRepositoryInterface $tagRepository */
|
||||||
@@ -279,9 +155,6 @@ class DestroyController extends Controller
|
|||||||
$tagRepository->destroyAll();
|
$tagRepository->destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function destroyObjectGroups(): void
|
private function destroyObjectGroups(): void
|
||||||
{
|
{
|
||||||
/** @var ObjectGroupRepositoryInterface $repository */
|
/** @var ObjectGroupRepositoryInterface $repository */
|
||||||
@@ -290,7 +163,7 @@ class DestroyController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $types
|
* @param array<int, string> $types
|
||||||
*/
|
*/
|
||||||
private function destroyAccounts(array $types): void
|
private function destroyAccounts(array $types): void
|
||||||
{
|
{
|
||||||
@@ -303,19 +176,22 @@ class DestroyController extends Controller
|
|||||||
foreach ($collection as $account) {
|
foreach ($collection as $account) {
|
||||||
$count = $account->transactions()->count();
|
$count = $account->transactions()->count();
|
||||||
if (true === $this->unused && 0 === $count) {
|
if (true === $this->unused && 0 === $count) {
|
||||||
Log::info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
|
app('log')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
|
||||||
|
Log::channel('audit')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
|
||||||
$service->destroy($account, null);
|
$service->destroy($account, null);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (false === $this->unused) {
|
if (false === $this->unused) {
|
||||||
Log::info(sprintf('Deleting account #%d "%s"', $account->id, $account->name));
|
app('log')->info(sprintf('Deleting account #%d "%s"', $account->id, $account->name));
|
||||||
|
Log::channel('audit')->warning(sprintf('Deleted account #%d "%s"', $account->id, $account->name));
|
||||||
$service->destroy($account, null);
|
$service->destroy($account, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $types
|
* @param array<int, string> $types
|
||||||
*/
|
*/
|
||||||
private function destroyTransactions(array $types): void
|
private function destroyTransactions(array $types): void
|
||||||
{
|
{
|
||||||
@@ -323,6 +199,7 @@ class DestroyController extends Controller
|
|||||||
$repository = app(JournalRepositoryInterface::class);
|
$repository = app(JournalRepositoryInterface::class);
|
||||||
$journals = $repository->findByType($types);
|
$journals = $repository->findByType($types);
|
||||||
$service = app(JournalDestroyService::class);
|
$service = app(JournalDestroyService::class);
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$service->destroy($journal);
|
$service->destroy($journal);
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
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 Psr\Container\ContainerExceptionInterface;
|
|
||||||
use Psr\Container\NotFoundExceptionInterface;
|
use function Safe\date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ExportController
|
* Class ExportController
|
||||||
@@ -59,10 +59,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportAccounts
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportAccounts
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function accounts(ExportRequest $request): LaravelResponse
|
public function accounts(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -72,12 +71,7 @@ class ExportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $key
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* @throws ContainerExceptionInterface
|
|
||||||
* @throws NotFoundExceptionInterface
|
|
||||||
*/
|
*/
|
||||||
private function returnExport(string $key): LaravelResponse
|
private function returnExport(string $key): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -90,13 +84,14 @@ class ExportController extends Controller
|
|||||||
$response
|
$response
|
||||||
->header('Content-Description', 'File Transfer')
|
->header('Content-Description', 'File Transfer')
|
||||||
->header('Content-Type', 'application/octet-stream')
|
->header('Content-Type', 'application/octet-stream')
|
||||||
->header('Content-Disposition', 'attachment; filename=' . $fileName)
|
->header('Content-Disposition', 'attachment; filename='.$fileName)
|
||||||
->header('Content-Transfer-Encoding', 'binary')
|
->header('Content-Transfer-Encoding', 'binary')
|
||||||
->header('Connection', 'Keep-Alive')
|
->header('Connection', 'Keep-Alive')
|
||||||
->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;
|
||||||
}
|
}
|
||||||
@@ -105,10 +100,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function bills(ExportRequest $request): LaravelResponse
|
public function bills(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -121,10 +115,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBudgets
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBudgets
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function budgets(ExportRequest $request): LaravelResponse
|
public function budgets(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -137,10 +130,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportCategories
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportCategories
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function categories(ExportRequest $request): LaravelResponse
|
public function categories(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -153,10 +145,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportPiggies
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportPiggies
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function piggyBanks(ExportRequest $request): LaravelResponse
|
public function piggyBanks(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -169,10 +160,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRecurring
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRecurring
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function recurring(ExportRequest $request): LaravelResponse
|
public function recurring(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -185,10 +175,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRules
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRules
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function rules(ExportRequest $request): LaravelResponse
|
public function rules(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -201,10 +190,9 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTags
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTags
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
*
|
||||||
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*/
|
*/
|
||||||
public function tags(ExportRequest $request): LaravelResponse
|
public function tags(ExportRequest $request): LaravelResponse
|
||||||
{
|
{
|
||||||
@@ -217,9 +205,6 @@ class ExportController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTransactions
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTransactions
|
||||||
*
|
*
|
||||||
* @param ExportRequest $request
|
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function transactions(ExportRequest $request): LaravelResponse
|
public function transactions(ExportRequest $request): LaravelResponse
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PurgeController.php
|
* PurgeController.php
|
||||||
* Copyright (c) 2022 james@firefly-iii.org
|
* Copyright (c) 2022 james@firefly-iii.org
|
||||||
@@ -28,13 +29,14 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\PiggyBank;
|
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\Rule;
|
use FireflyIII\Models\Rule;
|
||||||
use FireflyIII\Models\RuleGroup;
|
use FireflyIII\Models\RuleGroup;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Models\TransactionGroup;
|
use FireflyIII\Models\TransactionGroup;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,12 +48,11 @@ class PurgeController extends Controller
|
|||||||
* TODO cleanup and use repositories.
|
* TODO cleanup and use repositories.
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/purgeData
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/purgeData
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function purge(): JsonResponse
|
public function purge(): JsonResponse
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
// some manual code, too lazy to call all repositories.
|
// some manual code, too lazy to call all repositories.
|
||||||
|
|
||||||
@@ -62,12 +63,17 @@ class PurgeController extends Controller
|
|||||||
Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
|
|
||||||
// piggies
|
// piggies
|
||||||
$set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
$repository = app(PiggyBankRepositoryInterface::class);
|
||||||
->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*']);
|
$repository->setUser($user);
|
||||||
/** @var PiggyBank $piggy */
|
$repository->purgeAll();
|
||||||
foreach ($set as $piggy) {
|
// $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
|
||||||
$piggy->forceDelete();
|
// ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
|
||||||
}
|
// ;
|
||||||
|
//
|
||||||
|
// /** @var PiggyBank $piggy */
|
||||||
|
// foreach ($set as $piggy) {
|
||||||
|
// $piggy->forceDelete();
|
||||||
|
// }
|
||||||
|
|
||||||
// rule group
|
// rule group
|
||||||
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
@@ -84,7 +90,6 @@ class PurgeController extends Controller
|
|||||||
// tags
|
// tags
|
||||||
Tag::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
Tag::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
|
|
||||||
|
|
||||||
// accounts
|
// accounts
|
||||||
Account::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
Account::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
|
||||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
*
|
*
|
||||||
* Shows expense information grouped or limited by date.
|
* Shows expense information grouped or limited by date.
|
||||||
@@ -43,27 +41,21 @@ class AccountController extends Controller
|
|||||||
{
|
{
|
||||||
use ApiSupport;
|
use ApiSupport;
|
||||||
|
|
||||||
private CurrencyRepositoryInterface $currencyRepository;
|
|
||||||
private OperationsRepositoryInterface $opsRepository;
|
private OperationsRepositoryInterface $opsRepository;
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->middleware(
|
$this->middleware(
|
||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$this->repository = app(AccountRepositoryInterface::class);
|
$this->repository = app(AccountRepositoryInterface::class);
|
||||||
$this->repository->setUser($user);
|
$this->repository->setUser($user);
|
||||||
|
|
||||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
|
||||||
$this->currencyRepository->setUser($user);
|
|
||||||
|
|
||||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||||
$this->opsRepository->setUser($user);
|
$this->opsRepository->setUser($user);
|
||||||
|
|
||||||
@@ -75,10 +67,6 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseAsset
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseAsset
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function asset(GenericRequest $request): JsonResponse
|
public function asset(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -91,11 +79,11 @@ class AccountController extends Controller
|
|||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$expense['id'],
|
'id' => (string) $expense['id'],
|
||||||
'name' => $expense['name'],
|
'name' => $expense['name'],
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // intentional float
|
'difference_float' => (float) $expense['sum'], // intentional float
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -106,10 +94,6 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseExpense
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseExpense
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function expense(GenericRequest $request): JsonResponse
|
public function expense(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -123,11 +107,11 @@ class AccountController extends Controller
|
|||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$expense['id'],
|
'id' => (string) $expense['id'],
|
||||||
'name' => $expense['name'],
|
'name' => $expense['name'],
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // intentional float
|
'difference_float' => (float) $expense['sum'], // intentional float
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BillController
|
* Class BillController
|
||||||
@@ -60,18 +62,16 @@ class BillController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBill
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBill
|
||||||
*
|
*
|
||||||
* Expenses per bill, possibly filtered by bill and account.
|
* Expenses per bill, possibly filtered by bill and account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function bill(GenericRequest $request): JsonResponse
|
public function bill(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$bills = $request->getBills();
|
$bills = $request->getBills();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
$response = [];
|
||||||
|
|
||||||
// get all bills:
|
// get all bills:
|
||||||
if (0 === $bills->count()) {
|
if (0 === $bills->count()) {
|
||||||
@@ -79,39 +79,42 @@ class BillController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||||
$collector->setBills($bills);
|
$collector->setBills($bills);
|
||||||
|
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$billId = (int)$journal['bill_id'];
|
$billId = (int) $journal['bill_id'];
|
||||||
$currencyId = (int)$journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyCode = $journal['currency_code'];
|
||||||
$key = sprintf('%d-%d', $billId, $currencyId);
|
$field = 'amount';
|
||||||
$foreignKey = sprintf('%d-%d', $billId, $foreignCurrencyId);
|
|
||||||
|
// use the native amount if the user wants to convert to native currency
|
||||||
|
if ($convertToNative && $currencyId !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
$field = 'native_amount';
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Journal #%d in bill #%d will use %s (%s %s)', $journal['transaction_group_id'], $billId, $field, $currencyCode, $journal[$field] ?? '0'));
|
||||||
|
|
||||||
|
$key = sprintf('%d-%d', $billId, $currencyId);
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$key] = $response[$key] ?? [
|
$response[$key] ??= [
|
||||||
'id' => (string)$billId,
|
'id' => (string) $billId,
|
||||||
'name' => $journal['bill_name'],
|
'name' => $journal['bill_name'],
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string)$currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
|
$response[$key]['difference'] = bcadd($response[$key]['difference'], (string) ($journal[$field] ?? '0'));
|
||||||
$response[$key]['difference_float'] = (float)$response[$key]['difference']; // intentional float
|
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // intentional float
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignKey] = $response[$foreignKey] ?? [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // intentional float
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,48 +126,49 @@ class BillController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBill
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBill
|
||||||
*
|
*
|
||||||
* Expenses for no bill filtered by account.
|
* Expenses for no bill filtered by account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noBill(GenericRequest $request): JsonResponse
|
public function noBill(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
$response = [];
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||||
$collector->withoutBill();
|
$collector->withoutBill();
|
||||||
|
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = 'amount';
|
||||||
|
|
||||||
|
// use the native amount if the user wants to convert to native currency
|
||||||
|
if ($convertToNative && $currencyId !== $default->id) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
$field = 'native_amount';
|
||||||
|
}
|
||||||
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
|
$field = 'foreign_amount';
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Journal #%d will use %s (%s %s)', $journal['transaction_group_id'], $field, $currencyCode, $journal[$field] ?? '0'));
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string)$currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) ($journal[$field] ?? '0'));
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BudgetController.php
|
* BudgetController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -43,8 +44,6 @@ class BudgetController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -67,10 +66,6 @@ class BudgetController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBudget
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function budget(GenericRequest $request): JsonResponse
|
public function budget(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -82,17 +77,19 @@ class BudgetController extends Controller
|
|||||||
if (0 === $budgets->count()) {
|
if (0 === $budgets->count()) {
|
||||||
$budgets = $this->repository->getActiveBudgets();
|
$budgets = $this->repository->getActiveBudgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Budget $budget */
|
/** @var Budget $budget */
|
||||||
foreach ($budgets as $budget) {
|
foreach ($budgets as $budget) {
|
||||||
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$budget]));
|
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$budget]));
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$budget->id,
|
'id' => (string) $budget->id,
|
||||||
'name' => $budget->name,
|
'name' => $budget->name,
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // intentional float
|
'difference_float' => (float) $expense['sum'], // intentional float
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -104,10 +101,6 @@ class BudgetController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBudget
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noBudget(GenericRequest $request): JsonResponse
|
public function noBudget(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -116,12 +109,13 @@ class BudgetController extends Controller
|
|||||||
$assetAccounts = $request->getAssetAccounts();
|
$assetAccounts = $request->getAssetAccounts();
|
||||||
$result = [];
|
$result = [];
|
||||||
$expenses = $this->noRepository->sumExpenses($start, $end, $assetAccounts);
|
$expenses = $this->noRepository->sumExpenses($start, $end, $assetAccounts);
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // intentional float
|
'difference_float' => (float) $expense['sum'], // intentional float
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -68,10 +66,6 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function category(GenericRequest $request): JsonResponse
|
public function category(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -83,17 +77,19 @@ class CategoryController extends Controller
|
|||||||
if (0 === $categories->count()) {
|
if (0 === $categories->count()) {
|
||||||
$categories = $this->repository->getCategories();
|
$categories = $this->repository->getCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Category $category */
|
/** @var Category $category */
|
||||||
foreach ($categories as $category) {
|
foreach ($categories as $category) {
|
||||||
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$category]));
|
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$category]));
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$category->id,
|
'id' => (string) $category->id,
|
||||||
'name' => $category->name,
|
'name' => $category->name,
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // intentional float
|
'difference_float' => (float) $expense['sum'], // intentional float
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -105,10 +101,6 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noCategory(GenericRequest $request): JsonResponse
|
public function noCategory(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -117,12 +109,13 @@ class CategoryController extends Controller
|
|||||||
$assetAccounts = $request->getAssetAccounts();
|
$assetAccounts = $request->getAssetAccounts();
|
||||||
$result = [];
|
$result = [];
|
||||||
$expenses = $this->noRepository->sumExpenses($start, $end, $assetAccounts);
|
$expenses = $this->noRepository->sumExpenses($start, $end, $assetAccounts);
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // intentional float
|
'difference_float' => (float) $expense['sum'], // intentional float
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PeriodController.php
|
* PeriodController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -25,9 +26,11 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PeriodController
|
* Class PeriodController
|
||||||
@@ -37,46 +40,52 @@ class PeriodController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTotal
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTotal
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function total(GenericRequest $request): JsonResponse
|
public function total(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type)
|
// collect all expenses in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// same code as many other sumExpense methods. I think this needs some kind of generic method.
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$amount = '0';
|
||||||
|
$currencyId = (int) $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
if ($convertToNative) {
|
||||||
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $journal['foreign_currency_id'];
|
||||||
|
$currencyCode = $journal['foreign_currency_code'];
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount));
|
||||||
|
}
|
||||||
|
if (!$convertToNative) {
|
||||||
|
// ignore the amount in foreign currency.
|
||||||
|
Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount']));
|
||||||
|
$amount = $journal['amount'];
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
$response[$currencyId] ??= [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string)$currencyId,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_code' => $journal['currency_code'],
|
'currency_code' => $currencyCode,
|
||||||
];
|
];
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $amount);
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TagController
|
* Class TagController
|
||||||
@@ -59,49 +61,54 @@ class TagController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoTag
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoTag
|
||||||
*
|
*
|
||||||
* Expenses for no tag filtered by account.
|
* Expenses for no tag filtered by account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noTag(GenericRequest $request): JsonResponse
|
public function noTag(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||||
$collector->withoutTags();
|
$collector->withoutTags();
|
||||||
|
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// same code as many other sumExpense methods. I think this needs some kind of generic method.
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$amount = '0';
|
||||||
|
$currencyId = (int) $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
if ($convertToNative) {
|
||||||
|
$amount = Amount::getAmountFromJournal($journal);
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $default->id;
|
||||||
|
$currencyCode = $default->code;
|
||||||
|
}
|
||||||
|
if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) {
|
||||||
|
$currencyId = $journal['foreign_currency_id'];
|
||||||
|
$currencyCode = $journal['foreign_currency_code'];
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount));
|
||||||
|
}
|
||||||
|
if (!$convertToNative) {
|
||||||
|
// ignore the amount in foreign currency.
|
||||||
|
Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount']));
|
||||||
|
$amount = $journal['amount'];
|
||||||
|
}
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
$response[$currencyId] ??= [
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
'difference' => '0',
|
||||||
'difference' => '0',
|
'difference_float' => 0,
|
||||||
'difference_float' => 0,
|
'currency_id' => (string) $currencyId,
|
||||||
'currency_id' => (string)$currencyId,
|
'currency_code' => $currencyCode,
|
||||||
'currency_code' => $journal['currency_code'],
|
];
|
||||||
];
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $amount);
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
|
|
||||||
}
|
|
||||||
if (0 !== $foreignCurrencyId) {
|
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
|
||||||
'difference' => '0',
|
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
@@ -112,18 +119,14 @@ class TagController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTag
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTag
|
||||||
*
|
*
|
||||||
* Expenses per tag, possibly filtered by tag and account.
|
* Expenses per tag, possibly filtered by tag and account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function tag(GenericRequest $request): JsonResponse
|
public function tag(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$tags = $request->getTags();
|
$tags = $request->getTags();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
// get all tags:
|
// get all tags:
|
||||||
if (0 === $tags->count()) {
|
if (0 === $tags->count()) {
|
||||||
@@ -131,14 +134,15 @@ class TagController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||||
$collector->setTags($tags);
|
$collector->setTags($tags);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
|
||||||
|
|
||||||
/** @var array $tag */
|
/** @var array $tag */
|
||||||
foreach ($journal['tags'] as $tag) {
|
foreach ($journal['tags'] as $tag) {
|
||||||
@@ -148,16 +152,16 @@ class TagController extends Controller
|
|||||||
|
|
||||||
// on currency ID
|
// on currency ID
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$key] = $response[$key] ?? [
|
$response[$key] ??= [
|
||||||
'id' => (string)$tagId,
|
'id' => (string) $tagId,
|
||||||
'name' => $tag['name'],
|
'name' => $tag['name'],
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'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.
|
||||||
}
|
}
|
||||||
|
|
||||||
// on foreign ID
|
// on foreign ID
|
||||||
@@ -165,11 +169,11 @@ class TagController extends Controller
|
|||||||
$response[$foreignKey] = $journal[$foreignKey] ?? [
|
$response[$foreignKey] = $journal[$foreignKey] ?? [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'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.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,12 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
|
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
|
||||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
*
|
*
|
||||||
* Shows income information grouped or limited by date.
|
* Shows income information grouped or limited by date.
|
||||||
@@ -43,27 +41,21 @@ class AccountController extends Controller
|
|||||||
{
|
{
|
||||||
use ApiSupport;
|
use ApiSupport;
|
||||||
|
|
||||||
private CurrencyRepositoryInterface $currencyRepository;
|
|
||||||
private OperationsRepositoryInterface $opsRepository;
|
private OperationsRepositoryInterface $opsRepository;
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->middleware(
|
$this->middleware(
|
||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$this->repository = app(AccountRepositoryInterface::class);
|
$this->repository = app(AccountRepositoryInterface::class);
|
||||||
$this->repository->setUser($user);
|
$this->repository->setUser($user);
|
||||||
|
|
||||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
|
||||||
$this->currencyRepository->setUser($user);
|
|
||||||
|
|
||||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||||
$this->opsRepository->setUser($user);
|
$this->opsRepository->setUser($user);
|
||||||
|
|
||||||
@@ -75,26 +67,24 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeAsset
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeAsset
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function asset(GenericRequest $request): JsonResponse
|
public function asset(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$assetAccounts = $request->getAssetAccounts();
|
$assetAccounts = $request->getAssetAccounts();
|
||||||
|
|
||||||
$income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
|
$income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
/** @var array $entry */
|
/** @var array $entry */
|
||||||
foreach ($income as $entry) {
|
foreach ($income as $entry) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$entry['id'],
|
'id' => (string) $entry['id'],
|
||||||
'name' => $entry['name'],
|
'name' => $entry['name'],
|
||||||
'difference' => $entry['sum'],
|
'difference' => $entry['sum'],
|
||||||
'difference_float' => (float)$entry['sum'], // float but on purpose.
|
'difference_float' => (float) $entry['sum'], // float but on purpose.
|
||||||
'currency_id' => (string)$entry['currency_id'],
|
'currency_id' => (string) $entry['currency_id'],
|
||||||
'currency_code' => $entry['currency_code'],
|
'currency_code' => $entry['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -105,10 +95,6 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeRevenue
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeRevenue
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function revenue(GenericRequest $request): JsonResponse
|
public function revenue(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -122,11 +108,11 @@ class AccountController extends Controller
|
|||||||
/** @var array $entry */
|
/** @var array $entry */
|
||||||
foreach ($income as $entry) {
|
foreach ($income as $entry) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$entry['id'],
|
'id' => (string) $entry['id'],
|
||||||
'name' => $entry['name'],
|
'name' => $entry['name'],
|
||||||
'difference' => $entry['sum'],
|
'difference' => $entry['sum'],
|
||||||
'difference_float' => (float)$entry['sum'], // float but on purpose.
|
'difference_float' => (float) $entry['sum'], // float but on purpose.
|
||||||
'currency_id' => (string)$entry['currency_id'],
|
'currency_id' => (string) $entry['currency_id'],
|
||||||
'currency_code' => $entry['currency_code'],
|
'currency_code' => $entry['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -68,10 +66,6 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeCategory
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeCategory
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function category(GenericRequest $request): JsonResponse
|
public function category(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -83,17 +77,19 @@ class CategoryController extends Controller
|
|||||||
if (0 === $categories->count()) {
|
if (0 === $categories->count()) {
|
||||||
$categories = $this->repository->getCategories();
|
$categories = $this->repository->getCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Category $category */
|
/** @var Category $category */
|
||||||
foreach ($categories as $category) {
|
foreach ($categories as $category) {
|
||||||
$expenses = $this->opsRepository->sumIncome($start, $end, $assetAccounts, new Collection([$category]));
|
$expenses = $this->opsRepository->sumIncome($start, $end, $assetAccounts, new Collection([$category]));
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$category->id,
|
'id' => (string) $category->id,
|
||||||
'name' => $category->name,
|
'name' => $category->name,
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // float but on purpose.
|
'difference_float' => (float) $expense['sum'], // float but on purpose.
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -105,10 +101,6 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoCategory
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoCategory
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noCategory(GenericRequest $request): JsonResponse
|
public function noCategory(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -117,12 +109,13 @@ class CategoryController extends Controller
|
|||||||
$assetAccounts = $request->getAssetAccounts();
|
$assetAccounts = $request->getAssetAccounts();
|
||||||
$result = [];
|
$result = [];
|
||||||
$expenses = $this->noRepository->sumIncome($start, $end, $assetAccounts);
|
$expenses = $this->noRepository->sumIncome($start, $end, $assetAccounts);
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'], // float but on purpose.
|
'difference_float' => (float) $expense['sum'], // float but on purpose.
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PeriodController.php
|
* PeriodController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -25,8 +26,9 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Income;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,49 +39,44 @@ class PeriodController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTotal
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTotal
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function total(GenericRequest $request): JsonResponse
|
public function total(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type)
|
// collect all expenses in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
// perhaps use default currency instead?
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
'difference' => '0',
|
$currencyId = $default->id;
|
||||||
'difference_float' => 0,
|
$currencyCode = $default->code;
|
||||||
'currency_id' => (string)$currencyId,
|
|
||||||
'currency_code' => $journal['currency_code'],
|
|
||||||
];
|
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
|
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
'difference' => '0',
|
$field = 'foreign_amount';
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response[$currencyId] ??= [
|
||||||
|
'difference' => '0',
|
||||||
|
'difference_float' => 0,
|
||||||
|
'currency_id' => (string) $currencyId,
|
||||||
|
'currency_code' => $currencyCode,
|
||||||
|
];
|
||||||
|
$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.
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
|||||||
@@ -26,9 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Income;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,52 +61,48 @@ class TagController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTag
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTag
|
||||||
*
|
*
|
||||||
* Expenses for no tag filtered by account.
|
* Expenses for no tag filtered by account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noTag(GenericRequest $request): JsonResponse
|
public function noTag(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$collector->withoutTags();
|
$collector->withoutTags();
|
||||||
|
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
// perhaps use default currency instead?
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
'difference' => '0',
|
$currencyId = $default->id;
|
||||||
'difference_float' => 0,
|
$currencyCode = $default->code;
|
||||||
'currency_id' => (string)$currencyId,
|
|
||||||
'currency_code' => $journal['currency_code'],
|
|
||||||
];
|
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
|
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
'difference' => '0',
|
$field = 'foreign_amount';
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response[$currencyId] ??= [
|
||||||
|
'difference' => '0',
|
||||||
|
'difference_float' => 0,
|
||||||
|
'currency_id' => (string) $currencyId,
|
||||||
|
'currency_code' => $currencyCode,
|
||||||
|
];
|
||||||
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
@@ -116,18 +113,14 @@ class TagController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoTag
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoTag
|
||||||
*
|
*
|
||||||
* Expenses per tag, possibly filtered by tag and account.
|
* Expenses per tag, possibly filtered by tag and account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function tag(GenericRequest $request): JsonResponse
|
public function tag(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$tags = $request->getTags();
|
$tags = $request->getTags();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
// get all tags:
|
// get all tags:
|
||||||
if (0 === $tags->count()) {
|
if (0 === $tags->count()) {
|
||||||
@@ -135,14 +128,15 @@ class TagController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$collector->setTags($tags);
|
$collector->setTags($tags);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
|
||||||
|
|
||||||
/** @var array $tag */
|
/** @var array $tag */
|
||||||
foreach ($journal['tags'] as $tag) {
|
foreach ($journal['tags'] as $tag) {
|
||||||
@@ -152,16 +146,16 @@ class TagController extends Controller
|
|||||||
|
|
||||||
// on currency ID
|
// on currency ID
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$key] = $response[$key] ?? [
|
$response[$key] ??= [
|
||||||
'id' => (string)$tagId,
|
'id' => (string) $tagId,
|
||||||
'name' => $tag['name'],
|
'name' => $tag['name'],
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'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'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// on foreign ID
|
// on foreign ID
|
||||||
@@ -169,14 +163,14 @@ class TagController extends Controller
|
|||||||
$response[$foreignKey] = $journal[$foreignKey] ?? [
|
$response[$foreignKey] = $journal[$foreignKey] ?? [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
'currency_id' => (string) $foreignCurrencyId,
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
'currency_code' => $journal['foreign_currency_code'],
|
||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd(
|
$response[$foreignKey]['difference'] = bcadd(
|
||||||
$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'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AccountController.php
|
* AccountController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -40,8 +41,6 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -60,10 +59,6 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransfers
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransfers
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function asset(GenericRequest $request): JsonResponse
|
public function asset(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CategoryController.php
|
* CategoryController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -43,8 +44,6 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -67,10 +66,6 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function category(GenericRequest $request): JsonResponse
|
public function category(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -82,17 +77,19 @@ class CategoryController extends Controller
|
|||||||
if (0 === $categories->count()) {
|
if (0 === $categories->count()) {
|
||||||
$categories = $this->repository->getCategories();
|
$categories = $this->repository->getCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Category $category */
|
/** @var Category $category */
|
||||||
foreach ($categories as $category) {
|
foreach ($categories as $category) {
|
||||||
$expenses = $this->opsRepository->sumTransfers($start, $end, $assetAccounts, new Collection([$category]));
|
$expenses = $this->opsRepository->sumTransfers($start, $end, $assetAccounts, new Collection([$category]));
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'id' => (string)$category->id,
|
'id' => (string) $category->id,
|
||||||
'name' => $category->name,
|
'name' => $category->name,
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'],
|
'difference_float' => (float) $expense['sum'],
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -104,10 +101,6 @@ class CategoryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noCategory(GenericRequest $request): JsonResponse
|
public function noCategory(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
@@ -116,12 +109,13 @@ class CategoryController extends Controller
|
|||||||
$assetAccounts = $request->getAssetAccounts();
|
$assetAccounts = $request->getAssetAccounts();
|
||||||
$result = [];
|
$result = [];
|
||||||
$expenses = $this->noRepository->sumTransfers($start, $end, $assetAccounts);
|
$expenses = $this->noRepository->sumTransfers($start, $end, $assetAccounts);
|
||||||
|
|
||||||
/** @var array $expense */
|
/** @var array $expense */
|
||||||
foreach ($expenses as $expense) {
|
foreach ($expenses as $expense) {
|
||||||
$result[] = [
|
$result[] = [
|
||||||
'difference' => $expense['sum'],
|
'difference' => $expense['sum'],
|
||||||
'difference_float' => (float)$expense['sum'],
|
'difference_float' => (float) $expense['sum'],
|
||||||
'currency_id' => (string)$expense['currency_id'],
|
'currency_id' => (string) $expense['currency_id'],
|
||||||
'currency_code' => $expense['currency_code'],
|
'currency_code' => $expense['currency_code'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PeriodController.php
|
* PeriodController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -25,8 +26,9 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Transfer;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,49 +39,45 @@ class PeriodController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTotal
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTotal
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function total(GenericRequest $request): JsonResponse
|
public function total(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type)
|
// collect all expenses in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
// perhaps use default currency instead?
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
'difference' => '0',
|
$currencyId = $default->id;
|
||||||
'difference_float' => 0,
|
$currencyCode = $default->code;
|
||||||
'currency_id' => (string)$currencyId,
|
|
||||||
'currency_code' => $journal['currency_code'],
|
|
||||||
];
|
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
|
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
'difference' => '0',
|
$field = 'foreign_amount';
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response[$currencyId] ??= [
|
||||||
|
'difference' => '0',
|
||||||
|
'difference_float' => 0,
|
||||||
|
'currency_id' => (string) $currencyId,
|
||||||
|
'currency_code' => $currencyCode,
|
||||||
|
];
|
||||||
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TagController.php
|
* TagController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -25,9 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Transfer;
|
|||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,52 +59,49 @@ class TagController extends Controller
|
|||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoTag
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoTag
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function noTag(GenericRequest $request): JsonResponse
|
public function noTag(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
$convertToNative = Amount::convertToNative();
|
||||||
|
$default = Amount::getNativeCurrency();
|
||||||
|
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$collector->withoutTags();
|
$collector->withoutTags();
|
||||||
|
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
// currency
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$currencyId = $journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||||
|
|
||||||
if (0 !== $currencyId) {
|
// perhaps use default currency instead?
|
||||||
$response[$currencyId] = $response[$currencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||||
'difference' => '0',
|
$currencyId = $default->id;
|
||||||
'difference_float' => 0,
|
$currencyCode = $default->code;
|
||||||
'currency_id' => (string)$currencyId,
|
|
||||||
'currency_code' => $journal['currency_code'],
|
|
||||||
];
|
|
||||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
|
|
||||||
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
|
|
||||||
}
|
}
|
||||||
if (0 !== $foreignCurrencyId) {
|
// use foreign amount when the foreign currency IS the default currency.
|
||||||
$response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
|
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||||
'difference' => '0',
|
$field = 'foreign_amount';
|
||||||
'difference_float' => 0,
|
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
|
||||||
];
|
|
||||||
$response[$foreignCurrencyId]['difference'] = bcadd(
|
|
||||||
$response[$foreignCurrencyId]['difference'],
|
|
||||||
app('steam')->positive($journal['foreign_amount'])
|
|
||||||
);
|
|
||||||
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response[$currencyId] ??= [
|
||||||
|
'difference' => '0',
|
||||||
|
'difference_float' => 0,
|
||||||
|
'currency_id' => (string) $currencyId,
|
||||||
|
'currency_code' => $currencyCode,
|
||||||
|
];
|
||||||
|
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
|
||||||
|
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(array_values($response));
|
return response()->json(array_values($response));
|
||||||
@@ -113,18 +112,14 @@ class TagController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTag
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTag
|
||||||
*
|
*
|
||||||
* Transfers per tag, possibly filtered by tag and account.
|
* Transfers per tag, possibly filtered by tag and account.
|
||||||
*
|
|
||||||
* @param GenericRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function tag(GenericRequest $request): JsonResponse
|
public function tag(GenericRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$accounts = $request->getAssetAccounts();
|
$accounts = $request->getAssetAccounts();
|
||||||
$tags = $request->getTags();
|
$tags = $request->getTags();
|
||||||
$start = $request->getStart();
|
$start = $request->getStart();
|
||||||
$end = $request->getEnd();
|
$end = $request->getEnd();
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
// get all tags:
|
// get all tags:
|
||||||
if (0 === $tags->count()) {
|
if (0 === $tags->count()) {
|
||||||
@@ -132,14 +127,15 @@ class TagController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
$collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||||
$collector->setTags($tags);
|
$collector->setTags($tags);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($genericSet as $journal) {
|
foreach ($genericSet as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
$currencyId = (int) $journal['currency_id'];
|
||||||
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
|
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
|
||||||
|
|
||||||
/** @var array $tag */
|
/** @var array $tag */
|
||||||
foreach ($journal['tags'] as $tag) {
|
foreach ($journal['tags'] as $tag) {
|
||||||
@@ -149,16 +145,16 @@ class TagController extends Controller
|
|||||||
|
|
||||||
// on currency ID
|
// on currency ID
|
||||||
if (0 !== $currencyId) {
|
if (0 !== $currencyId) {
|
||||||
$response[$key] = $response[$key] ?? [
|
$response[$key] ??= [
|
||||||
'id' => (string)$tagId,
|
'id' => (string) $tagId,
|
||||||
'name' => $tag['name'],
|
'name' => $tag['name'],
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'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'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// on foreign ID
|
// on foreign ID
|
||||||
@@ -166,14 +162,14 @@ class TagController extends Controller
|
|||||||
$response[$foreignKey] = $journal[$foreignKey] ?? [
|
$response[$foreignKey] = $journal[$foreignKey] ?? [
|
||||||
'difference' => '0',
|
'difference' => '0',
|
||||||
'difference_float' => 0,
|
'difference_float' => 0,
|
||||||
'currency_id' => (string)$foreignCurrencyId,
|
'currency_id' => (string) $foreignCurrencyId,
|
||||||
'currency_code' => $journal['foreign_currency_code'],
|
'currency_code' => $journal['foreign_currency_code'],
|
||||||
];
|
];
|
||||||
$response[$foreignKey]['difference'] = bcadd(
|
$response[$foreignKey]['difference'] = bcadd(
|
||||||
$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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController.php
|
* AccountController.php
|
||||||
* Copyright (c) 2019 james@firefly-iii.org
|
* Copyright (c) 2019 james@firefly-iii.org
|
||||||
@@ -33,14 +34,12 @@ use Illuminate\Http\JsonResponse;
|
|||||||
*/
|
*/
|
||||||
class DestroyController extends Controller
|
class DestroyController extends Controller
|
||||||
{
|
{
|
||||||
public const RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -60,10 +59,6 @@ class DestroyController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/deleteAccount
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/deleteAccount
|
||||||
*
|
*
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function destroy(Account $account): JsonResponse
|
public function destroy(Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController.php
|
* AccountController.php
|
||||||
* Copyright (c) 2019 james@firefly-iii.org
|
* Copyright (c) 2019 james@firefly-iii.org
|
||||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||||
use FireflyIII\Transformers\AttachmentTransformer;
|
use FireflyIII\Transformers\AttachmentTransformer;
|
||||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
@@ -47,14 +49,12 @@ class ListController extends Controller
|
|||||||
{
|
{
|
||||||
use TransactionFilter;
|
use TransactionFilter;
|
||||||
|
|
||||||
public const RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -73,29 +73,26 @@ class ListController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listAttachmentByAccount
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listAttachmentByAccount
|
||||||
*
|
*
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function attachments(Account $account): JsonResponse
|
public function attachments(Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$collection = $this->repository->getAttachments($account);
|
$collection = $this->repository->getAttachments($account);
|
||||||
|
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.accounts.attachments', [$account->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.accounts.attachments', [$account->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -105,33 +102,30 @@ class ListController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listPiggyBankByAccount
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listPiggyBankByAccount
|
||||||
*
|
*
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function piggyBanks(Account $account): JsonResponse
|
public function piggyBanks(Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
// create some objects:
|
// create some objects:
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// get list of budgets. Count it and split it.
|
// get list of piggy banks. Count it and split it.
|
||||||
$collection = $this->repository->getPiggyBanks($account);
|
$collection = $this->repository->getPiggyBanks($account);
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var PiggyBankTransformer $transformer */
|
/** @var PiggyBankTransformer $transformer */
|
||||||
$transformer = app(PiggyBankTransformer::class);
|
$transformer = app(PiggyBankTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
|
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -143,48 +137,46 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* Show all transaction groups related to the account.
|
* Show all transaction groups related to the account.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function transactions(Request $request, Account $account): JsonResponse
|
public function transactions(Request $request, Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$type = $request->get('type') ?? 'default';
|
$type = $request->get('type') ?? 'default';
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $type);
|
||||||
|
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
// user can overrule page size with limit parameter.
|
|
||||||
$limit = $this->parameters->get('limit');
|
|
||||||
if (null !== $limit && $limit > 0) {
|
|
||||||
$pageSize = $limit;
|
|
||||||
}
|
|
||||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
|
||||||
$manager = $this->getManager();
|
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
|
|
||||||
// use new group collector:
|
// use new group collector:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setUser($admin)->setAccounts(new Collection([$account]))
|
$collector->setUser($admin)->setAccounts(new Collection([$account]))
|
||||||
->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types);
|
->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types)
|
||||||
|
;
|
||||||
|
|
||||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
if (null !== $this->parameters->get('start')) {
|
||||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
$collector->setStart($this->parameters->get('start'));
|
||||||
|
}
|
||||||
|
if (null !== $this->parameters->get('end')) {
|
||||||
|
$collector->setEnd($this->parameters->get('end'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$paginator = $collector->getPaginatedGroups();
|
$paginator = $collector->getPaginatedGroups();
|
||||||
$paginator->setPath(route('api.v1.accounts.transactions', [$account->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.accounts.transactions', [$account->id]).$this->buildParams());
|
||||||
$groups = $paginator->getCollection();
|
|
||||||
|
// enrich
|
||||||
|
$enrichment = new TransactionGroupEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$transactions = $enrichment->enrich($paginator->getCollection());
|
||||||
|
|
||||||
/** @var TransactionGroupTransformer $transformer */
|
/** @var TransactionGroupTransformer $transformer */
|
||||||
$transformer = app(TransactionGroupTransformer::class);
|
$transformer = app(TransactionGroupTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($groups, $transformer, 'transactions');
|
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShowController.php
|
* ShowController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -28,7 +29,9 @@ 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\Http\Api\AccountFilter;
|
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
||||||
use FireflyIII\Transformers\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
@@ -43,14 +46,12 @@ class ShowController extends Controller
|
|||||||
{
|
{
|
||||||
use AccountFilter;
|
use AccountFilter;
|
||||||
|
|
||||||
public const RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -71,40 +72,43 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(Request $request): JsonResponse
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$type = $request->get('type') ?? 'all';
|
$type = $request->get('type') ?? 'all';
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $type);
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$types = $this->mapAccountTypes($this->parameters->get('type'));
|
$types = $this->mapAccountTypes($this->parameters->get('type'));
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// get list of accounts. Count it and split it.
|
// get list of accounts. Count it and split it.
|
||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
$collection = $this->repository->getAccountsByType($types, $this->parameters->get('sort') ?? []);
|
$collection = $this->repository->getAccountsByType($types, $this->parameters->get('sort') ?? []);
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
|
|
||||||
// continue sort:
|
// continue sort:
|
||||||
|
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
|
// enrich
|
||||||
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
|
$accounts = $enrichment->enrich($accounts);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.accounts.index') . $this->buildParams());
|
$paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
|
||||||
|
|
||||||
/** @var AccountTransformer $transformer */
|
/** @var AccountTransformer $transformer */
|
||||||
$transformer = app(AccountTransformer::class);
|
$transformer = app(AccountTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY);
|
$resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -115,22 +119,27 @@ class ShowController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/getAccount
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/getAccount
|
||||||
*
|
*
|
||||||
* Show single instance.
|
* Show single instance.
|
||||||
*
|
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function show(Account $account): JsonResponse
|
public function show(Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
// get list of accounts. Count it and split it.
|
// get list of accounts. Count it and split it.
|
||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
$account->refresh();
|
$account->refresh();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
|
|
||||||
/** @var AccountTransformer $transformer */
|
/** @var AccountTransformer $transformer */
|
||||||
$transformer = app(AccountTransformer::class);
|
$transformer = app(AccountTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController.php
|
* AccountController.php
|
||||||
* Copyright (c) 2019 james@firefly-iii.org
|
* Copyright (c) 2019 james@firefly-iii.org
|
||||||
@@ -26,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\Account;
|
|||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
use FireflyIII\Api\V1\Requests\Models\Account\StoreRequest;
|
use FireflyIII\Api\V1\Requests\Models\Account\StoreRequest;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
||||||
use FireflyIII\Transformers\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
|
|
||||||
@@ -35,14 +38,12 @@ use League\Fractal\Resource\Item;
|
|||||||
*/
|
*/
|
||||||
class StoreController extends Controller
|
class StoreController extends Controller
|
||||||
{
|
{
|
||||||
public const RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -62,23 +63,27 @@ class StoreController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/storeAccount
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/storeAccount
|
||||||
*
|
*
|
||||||
* Store a new instance.
|
* Store a new instance.
|
||||||
*
|
|
||||||
* @param StoreRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function store(StoreRequest $request): JsonResponse
|
public function store(StoreRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAllAccountData();
|
$data = $request->getAllAccountData();
|
||||||
$this->repository->resetAccountOrder();
|
$this->repository->resetAccountOrder();
|
||||||
$account = $this->repository->store($data);
|
$account = $this->repository->store($data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
/** @var AccountTransformer $transformer */
|
/** @var AccountTransformer $transformer */
|
||||||
$transformer = app(AccountTransformer::class);
|
$transformer = app(AccountTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController.php
|
* AccountController.php
|
||||||
* Copyright (c) 2019 james@firefly-iii.org
|
* Copyright (c) 2019 james@firefly-iii.org
|
||||||
@@ -27,25 +28,23 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
|||||||
use FireflyIII\Api\V1\Requests\Models\Account\UpdateRequest;
|
use FireflyIII\Api\V1\Requests\Models\Account\UpdateRequest;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
||||||
use FireflyIII\Transformers\AccountTransformer;
|
use FireflyIII\Transformers\AccountTransformer;
|
||||||
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
use Preferences;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UpdateController
|
* Class UpdateController
|
||||||
*/
|
*/
|
||||||
class UpdateController extends Controller
|
class UpdateController extends Controller
|
||||||
{
|
{
|
||||||
public const RESOURCE_KEY = 'accounts';
|
public const string RESOURCE_KEY = 'accounts';
|
||||||
|
|
||||||
private AccountRepositoryInterface $repository;
|
private AccountRepositoryInterface $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -65,26 +64,29 @@ class UpdateController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/updateAccount
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/updateAccount
|
||||||
*
|
*
|
||||||
* Update account.
|
* Update account.
|
||||||
*
|
|
||||||
* @param UpdateRequest $request
|
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function update(UpdateRequest $request, Account $account): JsonResponse
|
public function update(UpdateRequest $request, Account $account): JsonResponse
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||||
$data = $request->getUpdateData();
|
$data = $request->getUpdateData();
|
||||||
$data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type);
|
$data['type'] = config('firefly.shortNamesByFullName.'.$account->accountType->type);
|
||||||
$account = $this->repository->update($account, $data);
|
$account = $this->repository->update($account, $data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$account->refresh();
|
$account->refresh();
|
||||||
Preferences::mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
|
// enrich
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
$enrichment = new AccountEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
|
$account = $enrichment->enrichSingle($account);
|
||||||
|
|
||||||
/** @var AccountTransformer $transformer */
|
/** @var AccountTransformer $transformer */
|
||||||
$transformer = app(AccountTransformer::class);
|
$transformer = app(AccountTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DestroyController.php
|
* DestroyController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -29,6 +30,8 @@ use FireflyIII\Models\Attachment;
|
|||||||
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class DestroyController
|
* Class DestroyController
|
||||||
@@ -39,8 +42,6 @@ class DestroyController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DestroyController constructor.
|
* DestroyController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -63,14 +64,15 @@ class DestroyController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/deleteAttachment
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/deleteAttachment
|
||||||
*
|
*
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param Attachment $attachment
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function destroy(Attachment $attachment): JsonResponse
|
public function destroy(Attachment $attachment): JsonResponse
|
||||||
{
|
{
|
||||||
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
|
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
$this->repository->destroy($attachment);
|
$this->repository->destroy($attachment);
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShowController.php
|
* ShowController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -33,9 +34,11 @@ use FireflyIII\User;
|
|||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Response as LaravelResponse;
|
use Illuminate\Http\Response as LaravelResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ShowController
|
* Class ShowController
|
||||||
@@ -46,8 +49,6 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ShowController constructor.
|
* ShowController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -71,13 +72,15 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Download an attachment.
|
* Download an attachment.
|
||||||
*
|
*
|
||||||
* @param Attachment $attachment
|
* @throws FireflyException
|
||||||
*
|
|
||||||
* @return LaravelResponse
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
*/
|
||||||
public function download(Attachment $attachment): LaravelResponse
|
public function download(Attachment $attachment): LaravelResponse
|
||||||
{
|
{
|
||||||
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
|
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
if (false === $attachment->uploaded) {
|
if (false === $attachment->uploaded) {
|
||||||
throw new FireflyException('200000: File has not been uploaded (yet).');
|
throw new FireflyException('200000: File has not been uploaded (yet).');
|
||||||
}
|
}
|
||||||
@@ -85,27 +88,29 @@ class ShowController extends Controller
|
|||||||
throw new FireflyException('200000: File has not been uploaded (yet).');
|
throw new FireflyException('200000: File has not been uploaded (yet).');
|
||||||
}
|
}
|
||||||
if ($this->repository->exists($attachment)) {
|
if ($this->repository->exists($attachment)) {
|
||||||
$content = $this->repository->getContent($attachment);
|
$content = $this->repository->getContent($attachment);
|
||||||
if ('' === $content) {
|
if ('' === $content) {
|
||||||
throw new FireflyException('200002: File is empty (zero bytes).');
|
throw new FireflyException('200002: File is empty (zero bytes).');
|
||||||
}
|
}
|
||||||
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
|
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
|
||||||
|
|
||||||
/** @var LaravelResponse $response */
|
/** @var LaravelResponse $response */
|
||||||
$response = response($content);
|
$response = response($content);
|
||||||
$response
|
$response
|
||||||
->header('Content-Description', 'File Transfer')
|
->header('Content-Description', 'File Transfer')
|
||||||
->header('Content-Type', 'application/octet-stream')
|
->header('Content-Type', 'application/octet-stream')
|
||||||
->header('Content-Disposition', 'attachment; filename=' . $quoted)
|
->header('Content-Disposition', 'attachment; filename='.$quoted)
|
||||||
->header('Content-Transfer-Encoding', 'binary')
|
->header('Content-Transfer-Encoding', 'binary')
|
||||||
->header('Connection', 'Keep-Alive')
|
->header('Connection', 'Keep-Alive')
|
||||||
->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($content));
|
->header('Content-Length', (string) strlen($content))
|
||||||
|
;
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FireflyException('200003: File does not exist.');
|
throw new FireflyException('200003: File does not exist.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,15 +120,20 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
|
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// get list of attachments. Count it and split it.
|
// get list of attachments. Count it and split it.
|
||||||
$collection = $this->repository->get();
|
$collection = $this->repository->get();
|
||||||
@@ -131,14 +141,14 @@ class ShowController extends Controller
|
|||||||
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.attachments.index') . $this->buildParams());
|
$paginator->setPath(route('api.v1.attachments.index').$this->buildParams());
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -149,19 +159,21 @@ class ShowController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/getAttachment
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/getAttachment
|
||||||
*
|
*
|
||||||
* Display the specified resource.
|
* Display the specified resource.
|
||||||
*
|
|
||||||
* @param Attachment $attachment
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function show(Attachment $attachment): JsonResponse
|
public function show(Attachment $attachment): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
|
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($attachment, $transformer, 'attachments');
|
$resource = new Item($attachment, $transformer, 'attachments');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StoreController.php
|
* StoreController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -36,6 +37,7 @@ use Illuminate\Http\JsonResponse;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class StoreController
|
* Class StoreController
|
||||||
@@ -46,8 +48,6 @@ class StoreController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* StoreController constructor.
|
* StoreController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -71,47 +71,54 @@ class StoreController extends Controller
|
|||||||
*
|
*
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*
|
*
|
||||||
* @param StoreRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function store(StoreRequest $request): JsonResponse
|
public function store(StoreRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
$data = $request->getAll();
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
$attachment = $this->repository->store($data);
|
|
||||||
$manager = $this->getManager();
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||||
|
$data = $request->getAll();
|
||||||
|
$attachment = $this->repository->store($data);
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($attachment, $transformer, 'attachments');
|
$resource = new Item($attachment, $transformer, 'attachments');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload an attachment.
|
* Upload an attachment.
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param Attachment $attachment
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function upload(Request $request, Attachment $attachment): JsonResponse
|
public function upload(Request $request, Attachment $attachment): JsonResponse
|
||||||
{
|
{
|
||||||
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
|
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
/** @var AttachmentHelperInterface $helper */
|
/** @var AttachmentHelperInterface $helper */
|
||||||
$helper = app(AttachmentHelperInterface::class);
|
$helper = app(AttachmentHelperInterface::class);
|
||||||
$body = $request->getContent();
|
$body = $request->getContent();
|
||||||
if ('' === $body) {
|
if ('' === $body) {
|
||||||
Log::error('Body of attachment is empty.');
|
app('log')->error('Body of attachment is empty.');
|
||||||
|
|
||||||
|
return response()->json([], 422);
|
||||||
|
}
|
||||||
|
$result = $helper->saveAttachmentFromApi($attachment, $body);
|
||||||
|
if (false === $result) {
|
||||||
|
app('log')->error('Could not save attachment from API.');
|
||||||
|
|
||||||
return response()->json([], 422);
|
return response()->json([], 422);
|
||||||
}
|
}
|
||||||
$helper->saveAttachmentFromApi($attachment, $body);
|
|
||||||
|
|
||||||
return response()->json([], 204);
|
return response()->json([], 204);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UpdateController.php
|
* UpdateController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -31,7 +32,9 @@ use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
|||||||
use FireflyIII\Transformers\AttachmentTransformer;
|
use FireflyIII\Transformers\AttachmentTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UpdateController
|
* Class UpdateController
|
||||||
@@ -42,8 +45,6 @@ class UpdateController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateController constructor.
|
* UpdateController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -66,23 +67,23 @@ class UpdateController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/updateAttachment
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/updateAttachment
|
||||||
*
|
*
|
||||||
* Update the specified resource in storage.
|
* Update the specified resource in storage.
|
||||||
*
|
|
||||||
* @param UpdateRequest $request
|
|
||||||
* @param Attachment $attachment
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function update(UpdateRequest $request, Attachment $attachment): JsonResponse
|
public function update(UpdateRequest $request, Attachment $attachment): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAll();
|
if (true === auth()->user()->hasRole('demo')) {
|
||||||
|
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
|
||||||
|
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
$data = $request->getAll();
|
||||||
$this->repository->update($attachment, $data);
|
$this->repository->update($attachment, $data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($attachment, $transformer, 'attachments');
|
$resource = new Item($attachment, $transformer, 'attachments');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShowController.php
|
* ShowController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -44,8 +45,6 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AvailableBudgetController constructor.
|
* AvailableBudgetController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -68,18 +67,17 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
$start = $this->parameters->get('start');
|
$start = $this->parameters->get('start');
|
||||||
$end = $this->parameters->get('end');
|
$end = $this->parameters->get('end');
|
||||||
|
|
||||||
// get list of available budgets. Count it and split it.
|
// get list of available budgets. Count it and split it.
|
||||||
$collection = $this->abRepository->getAvailableBudgetsByDate($start, $end);
|
$collection = $this->abRepository->getAvailableBudgetsByDate($start, $end);
|
||||||
@@ -87,14 +85,14 @@ class ShowController extends Controller
|
|||||||
$availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.available-budgets.index') . $this->buildParams());
|
$paginator->setPath(route('api.v1.available-budgets.index').$this->buildParams());
|
||||||
|
|
||||||
/** @var AvailableBudgetTransformer $transformer */
|
/** @var AvailableBudgetTransformer $transformer */
|
||||||
$transformer = app(AvailableBudgetTransformer::class);
|
$transformer = app(AvailableBudgetTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
|
$resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -105,20 +103,16 @@ class ShowController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/available_budgets/getAvailableBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/available_budgets/getAvailableBudget
|
||||||
*
|
*
|
||||||
* Display the specified resource.
|
* Display the specified resource.
|
||||||
*
|
|
||||||
* @param AvailableBudget $availableBudget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function show(AvailableBudget $availableBudget): JsonResponse
|
public function show(AvailableBudget $availableBudget): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var AvailableBudgetTransformer $transformer */
|
/** @var AvailableBudgetTransformer $transformer */
|
||||||
$transformer = app(AvailableBudgetTransformer::class);
|
$transformer = app(AvailableBudgetTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($availableBudget, $transformer, 'available_budgets');
|
$resource = new Item($availableBudget, $transformer, 'available_budgets');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DestroyController.php
|
* DestroyController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -37,8 +38,6 @@ class DestroyController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BillController constructor.
|
* BillController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -58,10 +57,6 @@ class DestroyController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/deleteBill
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/deleteBill
|
||||||
*
|
*
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function destroy(Bill $bill): JsonResponse
|
public function destroy(Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ListController.php
|
* ListController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
|||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||||
use FireflyIII\Transformers\AttachmentTransformer;
|
use FireflyIII\Transformers\AttachmentTransformer;
|
||||||
use FireflyIII\Transformers\RuleTransformer;
|
use FireflyIII\Transformers\RuleTransformer;
|
||||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
@@ -50,8 +52,6 @@ class ListController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BillController constructor.
|
* BillController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -72,29 +72,26 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function attachments(Bill $bill): JsonResponse
|
public function attachments(Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$collection = $this->repository->getAttachments($bill);
|
$collection = $this->repository->getAttachments($bill);
|
||||||
|
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.bills.attachments', [$bill->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.bills.attachments', [$bill->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -106,31 +103,28 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* List all of them.
|
* List all of them.
|
||||||
*
|
*
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function rules(Bill $bill): JsonResponse
|
public function rules(Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// get list of budgets. Count it and split it.
|
// get list of budgets. Count it and split it.
|
||||||
$collection = $this->repository->getRulesForBill($bill);
|
$collection = $this->repository->getRulesForBill($bill);
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.bills.rules', [$bill->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.bills.rules', [$bill->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var RuleTransformer $transformer */
|
/** @var RuleTransformer $transformer */
|
||||||
$transformer = app(RuleTransformer::class);
|
$transformer = app(RuleTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
$resource = new FractalCollection($rules, $transformer, 'rules');
|
$resource = new FractalCollection($rules, $transformer, 'rules');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -142,28 +136,23 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* Show all transactions.
|
* Show all transactions.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function transactions(Request $request, Bill $bill): JsonResponse
|
public function transactions(Request $request, Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$type = $request->get('type') ?? 'default';
|
$type = $request->get('type') ?? 'default';
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $type);
|
||||||
|
|
||||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
|
|
||||||
// use new group collector:
|
// use new group collector:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector
|
$collector
|
||||||
->setUser($admin)
|
->setUser($admin)
|
||||||
// include source + destination account name and type.
|
// include source + destination account name and type.
|
||||||
@@ -175,23 +164,30 @@ class ListController extends Controller
|
|||||||
// set page to retrieve
|
// set page to retrieve
|
||||||
->setPage($this->parameters->get('page'))
|
->setPage($this->parameters->get('page'))
|
||||||
// set types of transactions to return.
|
// set types of transactions to return.
|
||||||
->setTypes($types);
|
->setTypes($types)
|
||||||
|
;
|
||||||
|
|
||||||
// do parameter stuff on new group collector.
|
if (null !== $this->parameters->get('start')) {
|
||||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
$collector->setStart($this->parameters->get('start'));
|
||||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
}
|
||||||
|
if (null !== $this->parameters->get('end')) {
|
||||||
|
$collector->setEnd($this->parameters->get('end'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// get paginator.
|
// get paginator.
|
||||||
$paginator = $collector->getPaginatedGroups();
|
$paginator = $collector->getPaginatedGroups();
|
||||||
$paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.bills.transactions', [$bill->id]).$this->buildParams());
|
||||||
$transactions = $paginator->getCollection();
|
|
||||||
|
// enrich
|
||||||
|
$enrichment = new TransactionGroupEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$transactions = $enrichment->enrich($paginator->getCollection());
|
||||||
|
|
||||||
/** @var TransactionGroupTransformer $transformer */
|
/** @var TransactionGroupTransformer $transformer */
|
||||||
$transformer = app(TransactionGroupTransformer::class);
|
$transformer = app(TransactionGroupTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShowController.php
|
* ShowController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -43,8 +44,6 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BillController constructor.
|
* BillController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -65,24 +64,23 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
{
|
{
|
||||||
$this->repository->correctOrder();
|
$this->repository->correctOrder();
|
||||||
$bills = $this->repository->getBills();
|
$bills = $this->repository->getBills();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$count = $bills->count();
|
$count = $bills->count();
|
||||||
$bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
||||||
|
|
||||||
/** @var BillTransformer $transformer */
|
/** @var BillTransformer $transformer */
|
||||||
$transformer = app(BillTransformer::class);
|
$transformer = app(BillTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($bills, $transformer, 'bills');
|
$resource = new FractalCollection($bills, $transformer, 'bills');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -93,19 +91,16 @@ class ShowController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/getBill
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/getBill
|
||||||
*
|
*
|
||||||
* Show the specified bill.
|
* Show the specified bill.
|
||||||
*
|
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function show(Bill $bill): JsonResponse
|
public function show(Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BillTransformer $transformer */
|
/** @var BillTransformer $transformer */
|
||||||
$transformer = app(BillTransformer::class);
|
$transformer = app(BillTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($bill, $transformer, 'bills');
|
$resource = new Item($bill, $transformer, 'bills');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StoreController.php
|
* StoreController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -43,8 +44,6 @@ class StoreController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BillController constructor.
|
* BillController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -65,22 +64,19 @@ class StoreController extends Controller
|
|||||||
*
|
*
|
||||||
* Store a bill.
|
* Store a bill.
|
||||||
*
|
*
|
||||||
* @param StoreRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function store(StoreRequest $request): JsonResponse
|
public function store(StoreRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAll();
|
$data = $request->getAll();
|
||||||
$bill = $this->repository->store($data);
|
$bill = $this->repository->store($data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BillTransformer $transformer */
|
/** @var BillTransformer $transformer */
|
||||||
$transformer = app(BillTransformer::class);
|
$transformer = app(BillTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($bill, $transformer, 'bills');
|
$resource = new Item($bill, $transformer, 'bills');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UpdateController.php
|
* UpdateController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -40,8 +41,6 @@ class UpdateController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BillController constructor.
|
* BillController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -61,23 +60,18 @@ class UpdateController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/updateBill
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/updateBill
|
||||||
*
|
*
|
||||||
* Update a bill.
|
* Update a bill.
|
||||||
*
|
|
||||||
* @param UpdateRequest $request
|
|
||||||
* @param Bill $bill
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function update(UpdateRequest $request, Bill $bill): JsonResponse
|
public function update(UpdateRequest $request, Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAll();
|
$data = $request->getAll();
|
||||||
$bill = $this->repository->update($bill, $data);
|
$bill = $this->repository->update($bill, $data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BillTransformer $transformer */
|
/** @var BillTransformer $transformer */
|
||||||
$transformer = app(BillTransformer::class);
|
$transformer = app(BillTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($bill, $transformer, 'bills');
|
$resource = new Item($bill, $transformer, 'bills');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DestroyController.php
|
* DestroyController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -37,8 +38,6 @@ class DestroyController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DestroyController constructor.
|
* DestroyController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -58,10 +57,6 @@ class DestroyController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/deleteBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/deleteBudget
|
||||||
*
|
*
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function destroy(Budget $budget): JsonResponse
|
public function destroy(Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ListController.php
|
* ListController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -24,12 +25,14 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Api\V1\Controllers\Models\Budget;
|
namespace FireflyIII\Api\V1\Controllers\Models\Budget;
|
||||||
|
|
||||||
use FireflyIII\Api\V1\Controllers\Controller;
|
use FireflyIII\Api\V1\Controllers\Controller;
|
||||||
|
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\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||||
use FireflyIII\Transformers\AttachmentTransformer;
|
use FireflyIII\Transformers\AttachmentTransformer;
|
||||||
use FireflyIII\Transformers\BudgetLimitTransformer;
|
use FireflyIII\Transformers\BudgetLimitTransformer;
|
||||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
@@ -40,9 +43,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
|||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
|
|
||||||
/***
|
// Class ListController
|
||||||
* Class ListController
|
|
||||||
*/
|
|
||||||
class ListController extends Controller
|
class ListController extends Controller
|
||||||
{
|
{
|
||||||
use TransactionFilter;
|
use TransactionFilter;
|
||||||
@@ -52,8 +53,6 @@ class ListController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ListController constructor.
|
* ListController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -74,29 +73,26 @@ class ListController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listAttachmentByBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listAttachmentByBudget
|
||||||
*
|
*
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function attachments(Budget $budget): JsonResponse
|
public function attachments(Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$collection = $this->repository->getAttachments($budget);
|
$collection = $this->repository->getAttachments($budget);
|
||||||
|
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var AttachmentTransformer $transformer */
|
/** @var AttachmentTransformer $transformer */
|
||||||
$transformer = app(AttachmentTransformer::class);
|
$transformer = app(AttachmentTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
$resource = new FractalCollection($attachments, $transformer, 'attachments');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -108,26 +104,23 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function budgetLimits(Budget $budget): JsonResponse
|
public function budgetLimits(Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$this->parameters->set('budget_id', $budget->id);
|
$this->parameters->set('budget_id', $budget->id);
|
||||||
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
|
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.budgets.budget-limits', [$budget->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.budget-limits', [$budget->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
$resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
|
$resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -139,35 +132,24 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* Show all transactions.
|
* Show all transactions.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function transactions(Request $request, Budget $budget): JsonResponse
|
public function transactions(Request $request, Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// user can overrule page size with limit parameter.
|
$type = $request->get('type') ?? 'default';
|
||||||
$limit = $this->parameters->get('limit');
|
|
||||||
if (null !== $limit && $limit > 0) {
|
|
||||||
$pageSize = $limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = $request->get('type') ?? 'default';
|
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $type);
|
||||||
|
|
||||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
|
|
||||||
// use new group collector:
|
// use new group collector:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector
|
$collector
|
||||||
->setUser($admin)
|
->setUser($admin)
|
||||||
// filter on budget.
|
// filter on budget.
|
||||||
@@ -179,20 +161,28 @@ class ListController extends Controller
|
|||||||
// set page to retrieve
|
// set page to retrieve
|
||||||
->setPage($this->parameters->get('page'))
|
->setPage($this->parameters->get('page'))
|
||||||
// set types of transactions to return.
|
// set types of transactions to return.
|
||||||
->setTypes($types);
|
->setTypes($types)
|
||||||
|
;
|
||||||
|
|
||||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
if (null !== $this->parameters->get('start')) {
|
||||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
$collector->setStart($this->parameters->get('start'));
|
||||||
|
}
|
||||||
|
if (null !== $this->parameters->get('end')) {
|
||||||
|
$collector->setEnd($this->parameters->get('end'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$paginator = $collector->getPaginatedGroups();
|
$paginator = $collector->getPaginatedGroups();
|
||||||
$paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]).$this->buildParams());
|
||||||
$transactions = $paginator->getCollection();
|
|
||||||
|
// enrich
|
||||||
|
$enrichment = new TransactionGroupEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$transactions = $enrichment->enrich($paginator->getCollection());
|
||||||
|
|
||||||
/** @var TransactionGroupTransformer $transformer */
|
/** @var TransactionGroupTransformer $transformer */
|
||||||
$transformer = app(TransactionGroupTransformer::class);
|
$transformer = app(TransactionGroupTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -204,35 +194,28 @@ class ListController extends Controller
|
|||||||
*
|
*
|
||||||
* Show all transactions.
|
* Show all transactions.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function withoutBudget(Request $request): JsonResponse
|
public function withoutBudget(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// user can overrule page size with limit parameter.
|
$type = $request->get('type') ?? 'default';
|
||||||
$limit = $this->parameters->get('limit');
|
|
||||||
if (null !== $limit && $limit > 0) {
|
|
||||||
$pageSize = $limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = $request->get('type') ?? 'default';
|
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $type);
|
||||||
|
|
||||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
|
|
||||||
// use new group collector:
|
// use new group collector:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector
|
$collector
|
||||||
->setUser($admin)
|
->setUser($admin)
|
||||||
|
// withdrawals only
|
||||||
|
->setTypes([TransactionTypeEnum::WITHDRAWAL->value])
|
||||||
// filter on budget.
|
// filter on budget.
|
||||||
->withoutBudget()
|
->withoutBudget()
|
||||||
// all info needed for the API:
|
// all info needed for the API:
|
||||||
@@ -242,20 +225,28 @@ class ListController extends Controller
|
|||||||
// set page to retrieve
|
// set page to retrieve
|
||||||
->setPage($this->parameters->get('page'))
|
->setPage($this->parameters->get('page'))
|
||||||
// set types of transactions to return.
|
// set types of transactions to return.
|
||||||
->setTypes($types);
|
->setTypes($types)
|
||||||
|
;
|
||||||
|
|
||||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
if (null !== $this->parameters->get('start')) {
|
||||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
$collector->setStart($this->parameters->get('start'));
|
||||||
|
}
|
||||||
|
if (null !== $this->parameters->get('end')) {
|
||||||
|
$collector->setEnd($this->parameters->get('end'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$paginator = $collector->getPaginatedGroups();
|
$paginator = $collector->getPaginatedGroups();
|
||||||
$paginator->setPath(route('api.v1.budgets.without-budget') . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.without-budget').$this->buildParams());
|
||||||
$transactions = $paginator->getCollection();
|
|
||||||
|
// enrich
|
||||||
|
$enrichment = new TransactionGroupEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$transactions = $enrichment->enrich($paginator->getCollection());
|
||||||
|
|
||||||
/** @var TransactionGroupTransformer $transformer */
|
/** @var TransactionGroupTransformer $transformer */
|
||||||
$transformer = app(TransactionGroupTransformer::class);
|
$transformer = app(TransactionGroupTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShowController.php
|
* ShowController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -45,8 +46,6 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ListController constructor.
|
* ListController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -69,30 +68,29 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
// types to get, page size:
|
// types to get, page size:
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
|
|
||||||
// get list of budgets. Count it and split it.
|
// get list of budgets. Count it and split it.
|
||||||
$collection = $this->repository->getBudgets();
|
$collection = $this->repository->getBudgets();
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$budgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$budgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
// make paginator:
|
// make paginator:
|
||||||
$paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.budgets.index') . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.index').$this->buildParams());
|
||||||
|
|
||||||
/** @var BudgetTransformer $transformer */
|
/** @var BudgetTransformer $transformer */
|
||||||
$transformer = app(BudgetTransformer::class);
|
$transformer = app(BudgetTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($budgets, $transformer, 'budgets');
|
$resource = new FractalCollection($budgets, $transformer, 'budgets');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -100,20 +98,16 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a budget.
|
* Show a budget.
|
||||||
*
|
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function show(Budget $budget): JsonResponse
|
public function show(Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BudgetTransformer $transformer */
|
/** @var BudgetTransformer $transformer */
|
||||||
$transformer = app(BudgetTransformer::class);
|
$transformer = app(BudgetTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($budget, $transformer, 'budgets');
|
$resource = new Item($budget, $transformer, 'budgets');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StoreController.php
|
* StoreController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -40,8 +41,6 @@ class StoreController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* StoreController constructor.
|
* StoreController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -62,23 +61,19 @@ class StoreController extends Controller
|
|||||||
*
|
*
|
||||||
* Store a budget.
|
* Store a budget.
|
||||||
*
|
*
|
||||||
* @param StoreRequest $request
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function store(StoreRequest $request): JsonResponse
|
public function store(StoreRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$budget = $this->repository->store($request->getAll());
|
$budget = $this->repository->store($request->getAll());
|
||||||
$budget->refresh();
|
$budget->refresh();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BudgetTransformer $transformer */
|
/** @var BudgetTransformer $transformer */
|
||||||
$transformer = app(BudgetTransformer::class);
|
$transformer = app(BudgetTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($budget, $transformer, 'budgets');
|
$resource = new Item($budget, $transformer, 'budgets');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UpdateController.php
|
* UpdateController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -40,8 +41,6 @@ class UpdateController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateController constructor.
|
* UpdateController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -61,23 +60,18 @@ class UpdateController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudget
|
||||||
*
|
*
|
||||||
* Update a budget.
|
* Update a budget.
|
||||||
*
|
|
||||||
* @param UpdateRequest $request
|
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function update(UpdateRequest $request, Budget $budget): JsonResponse
|
public function update(UpdateRequest $request, Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAll();
|
$data = $request->getAll();
|
||||||
$budget = $this->repository->update($budget, $data);
|
$budget = $this->repository->update($budget, $data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BudgetTransformer $transformer */
|
/** @var BudgetTransformer $transformer */
|
||||||
$transformer = app(BudgetTransformer::class);
|
$transformer = app(BudgetTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($budget, $transformer, 'budgets');
|
$resource = new Item($budget, $transformer, 'budgets');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DestroyController.php
|
* DestroyController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -40,8 +41,6 @@ class DestroyController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BudgetLimitController constructor.
|
* BudgetLimitController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -64,10 +63,6 @@ class DestroyController extends Controller
|
|||||||
*
|
*
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
*
|
||||||
* @param Budget $budget
|
|
||||||
* @param BudgetLimit $budgetLimit
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function destroy(Budget $budget, BudgetLimit $budgetLimit): JsonResponse
|
public function destroy(Budget $budget, BudgetLimit $budgetLimit): JsonResponse
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ListController.php
|
* ListController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -28,8 +29,8 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\BudgetLimit;
|
use FireflyIII\Models\BudgetLimit;
|
||||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
|
||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
|
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@@ -44,55 +45,28 @@ class ListController extends Controller
|
|||||||
{
|
{
|
||||||
use TransactionFilter;
|
use TransactionFilter;
|
||||||
|
|
||||||
private BudgetLimitRepositoryInterface $blRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BudgetLimitController constructor.
|
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->middleware(
|
|
||||||
function ($request, $next) {
|
|
||||||
/** @var User $user */
|
|
||||||
$user = auth()->user();
|
|
||||||
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
|
|
||||||
$this->blRepository->setUser($user);
|
|
||||||
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionByBudgetLimit
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionByBudgetLimit
|
||||||
* Show all transactions.
|
* Show all transactions.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
|
||||||
* @param Budget $budget
|
|
||||||
* @param BudgetLimit $budgetLimit
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function transactions(Request $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse
|
public function transactions(Request $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse
|
||||||
{
|
{
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$type = $request->get('type') ?? 'default';
|
$type = $request->get('type') ?? 'default';
|
||||||
$this->parameters->set('type', $type);
|
$this->parameters->set('type', $type);
|
||||||
|
|
||||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
|
|
||||||
// use new group collector:
|
// use new group collector:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector
|
$collector
|
||||||
->setUser($admin)
|
->setUser($admin)
|
||||||
// filter on budget.
|
// filter on budget.
|
||||||
@@ -104,19 +78,24 @@ class ListController extends Controller
|
|||||||
// set page to retrieve
|
// set page to retrieve
|
||||||
->setPage($this->parameters->get('page'))
|
->setPage($this->parameters->get('page'))
|
||||||
// set types of transactions to return.
|
// set types of transactions to return.
|
||||||
->setTypes($types);
|
->setTypes($types)
|
||||||
|
;
|
||||||
|
|
||||||
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
|
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
|
||||||
$collector->setTypes($types);
|
$collector->setTypes($types);
|
||||||
$paginator = $collector->getPaginatedGroups();
|
$paginator = $collector->getPaginatedGroups();
|
||||||
$paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]).$this->buildParams());
|
||||||
$transactions = $paginator->getCollection();
|
|
||||||
|
// enrich
|
||||||
|
$enrichment = new TransactionGroupEnrichment();
|
||||||
|
$enrichment->setUser($admin);
|
||||||
|
$transactions = $enrichment->enrich($paginator->getCollection());
|
||||||
|
|
||||||
/** @var TransactionGroupTransformer $transformer */
|
/** @var TransactionGroupTransformer $transformer */
|
||||||
$transformer = app(TransactionGroupTransformer::class);
|
$transformer = app(TransactionGroupTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShowController.php
|
* ShowController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -33,7 +34,6 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
|||||||
use FireflyIII\Transformers\BudgetLimitTransformer;
|
use FireflyIII\Transformers\BudgetLimitTransformer;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
@@ -49,8 +49,6 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BudgetLimitController constructor.
|
* BudgetLimitController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -74,29 +72,23 @@ class ShowController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listBudgetLimitByBudget
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listBudgetLimitByBudget
|
||||||
*
|
*
|
||||||
* Display a listing of the budget limits for this budget.
|
* Display a listing of the budget limits for this budget.
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, Budget $budget): JsonResponse
|
public function index(Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$manager->parseIncludes('budget');
|
$manager->parseIncludes('budget');
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
|
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]) . $this->buildParams());
|
$paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]).$this->buildParams());
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
|
$resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -108,27 +100,24 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* Display a listing of the budget limits for this budget.
|
* Display a listing of the budget limits for this budget.
|
||||||
*
|
*
|
||||||
* @param SameDateRequest $request
|
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
*/
|
||||||
public function indexAll(SameDateRequest $request): JsonResponse
|
public function indexAll(SameDateRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$manager->parseIncludes('budget');
|
$manager->parseIncludes('budget');
|
||||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = $this->parameters->get('limit');
|
||||||
$collection = $this->blRepository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end'));
|
$collection = $this->blRepository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end'));
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$paginator->setPath(route('api.v1.budget-limits.index') . $this->buildParams());
|
$paginator->setPath(route('api.v1.budget-limits.index').$this->buildParams());
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
|
$resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
@@ -138,26 +127,21 @@ class ShowController extends Controller
|
|||||||
* This endpoint is documented at:
|
* This endpoint is documented at:
|
||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/getBudgetLimit
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/getBudgetLimit
|
||||||
*
|
*
|
||||||
* @param Request $request
|
|
||||||
* @param Budget $budget
|
|
||||||
* @param BudgetLimit $budgetLimit
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function show(Request $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse
|
public function show(Budget $budget, BudgetLimit $budgetLimit): JsonResponse
|
||||||
{
|
{
|
||||||
if ((int)$budget->id !== (int)$budgetLimit->budget_id) {
|
if ($budget->id !== $budgetLimit->budget_id) {
|
||||||
throw new FireflyException('20028: The budget limit does not belong to the budget.');
|
throw new FireflyException('20028: The budget limit does not belong to the budget.');
|
||||||
}
|
}
|
||||||
// continue!
|
// continue!
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($budgetLimit, $transformer, 'budget_limits');
|
$resource = new Item($budgetLimit, $transformer, 'budget_limits');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StoreController.php
|
* StoreController.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
@@ -41,8 +42,6 @@ class StoreController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BudgetLimitController constructor.
|
* BudgetLimitController constructor.
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -64,26 +63,23 @@ class StoreController extends Controller
|
|||||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/storeBudgetLimit
|
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/storeBudgetLimit
|
||||||
*
|
*
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*
|
|
||||||
* @param StoreRequest $request
|
|
||||||
* @param Budget $budget
|
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function store(StoreRequest $request, Budget $budget): JsonResponse
|
public function store(StoreRequest $request, Budget $budget): JsonResponse
|
||||||
{
|
{
|
||||||
$data = $request->getAll();
|
$data = $request->getAll();
|
||||||
$data['start_date'] = $data['start'];
|
$data['start_date'] = $data['start'];
|
||||||
$data['end_date'] = $data['end'];
|
$data['end_date'] = $data['end'];
|
||||||
|
$data['notes'] = $data['notes'];
|
||||||
$data['budget_id'] = $budget->id;
|
$data['budget_id'] = $budget->id;
|
||||||
|
|
||||||
$budgetLimit = $this->blRepository->store($data);
|
$budgetLimit = $this->blRepository->store($data);
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
/** @var BudgetLimitTransformer $transformer */
|
/** @var BudgetLimitTransformer $transformer */
|
||||||
$transformer = app(BudgetLimitTransformer::class);
|
$transformer = app(BudgetLimitTransformer::class);
|
||||||
$transformer->setParameters($this->parameters);
|
$transformer->setParameters($this->parameters);
|
||||||
|
|
||||||
$resource = new Item($budgetLimit, $transformer, 'budget_limits');
|
$resource = new Item($budgetLimit, $transformer, 'budget_limits');
|
||||||
|
|
||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user