mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-16 19:04:36 +00:00
Compare commits
1335 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f8eb1fa44a | ||
|
afc794513f | ||
|
7e6d3c9d6b | ||
|
44960e8e42 | ||
|
41430c3bb2 | ||
|
2f435019e0 | ||
|
480e70dfac | ||
|
c4818334e7 | ||
|
a5d5f86aed | ||
|
78afb771b1 | ||
|
a74a646777 | ||
|
87f9ca3bb2 | ||
|
d54e264a91 | ||
|
99aea5ce7a | ||
|
e10d5e89e5 | ||
|
0105456828 | ||
|
5c7df5c04d | ||
|
563ede822f | ||
|
786cfc21c7 | ||
|
8f0856e31a | ||
|
bea075c74d | ||
|
5f82accb61 | ||
|
95f50ca2fd | ||
|
d8b76bdfd2 | ||
|
74a9edaaf7 | ||
|
7dd858be39 | ||
|
7d7ff71384 | ||
|
003177fa49 | ||
|
3c3a83330d | ||
|
724f423692 | ||
|
65b8882ed4 | ||
|
66d7fd7d4c | ||
|
782a6f289c | ||
|
70d936bb8f | ||
|
dda3082c7e | ||
|
ed948cc965 | ||
|
0347649f42 | ||
|
c66fe2b541 | ||
|
8c1ae76c7a | ||
|
04dee404c0 | ||
|
b22dd29835 | ||
|
536a5cd1c8 | ||
|
b7f1bcf7c9 | ||
|
5e590072dd | ||
|
d204b9b752 | ||
|
22d1121193 | ||
|
e23c6521b9 | ||
|
b0cb9663a6 | ||
|
95b7da89f0 | ||
|
b0a5b53abb | ||
|
ce78c8993f | ||
|
2538b4a885 | ||
|
109d96ad16 | ||
|
4cbb0d9716 | ||
|
65ecea3b1c | ||
|
495b80f5ef | ||
|
e113736887 | ||
|
042b7a4966 | ||
|
5ab8cb38d3 | ||
|
fc4ab29244 | ||
|
5a43e6cb9f | ||
|
4effc95c5f | ||
|
962965b5b7 | ||
|
260b611293 | ||
|
d2131c371b | ||
|
eedf6a07f0 | ||
|
5cd1e7c100 | ||
|
6a750a998f | ||
|
bd818b2dea | ||
|
4164ebcc69 | ||
|
60d732067b | ||
|
b7b52707fb | ||
|
f373c72679 | ||
|
ec2027b8db | ||
|
a84de5db77 | ||
|
5065b1ee03 | ||
|
a0aa114ee6 | ||
|
823839fbf6 | ||
|
1c93d8bf79 | ||
|
626404407e | ||
|
446ab62d38 | ||
|
0d39161ec3 | ||
|
29be16dcba | ||
|
b0bb790386 | ||
|
e64b40d58b | ||
|
4870945af2 | ||
|
a547a5f3f9 | ||
|
e5eabdf7e7 | ||
|
f78d56b149 | ||
|
771926c779 | ||
|
6090efe2df | ||
|
863227c55c | ||
|
5a6967cefd | ||
|
5166171e5d | ||
|
3e36a29c23 | ||
|
20e1e50032 | ||
|
36bc483edb | ||
|
aa59227786 | ||
|
2d8449ed68 | ||
|
d7ab482ae1 | ||
|
cfcc4ce88a | ||
|
eda44bbed0 | ||
|
988049061d | ||
|
ebb1c5ae25 | ||
|
ce7eebac5c | ||
|
b7c446f7db | ||
|
7c39a04c4b | ||
|
037d84b810 | ||
|
529bf50c85 | ||
|
d2b4bd78a9 | ||
|
e1c146a5c1 | ||
|
ed9acbdfde | ||
|
dc825d5a9c | ||
|
9f8faf15f1 | ||
|
934656c954 | ||
|
d233a2df3c | ||
|
7c7740d3ba | ||
|
cda6cfb4cd | ||
|
a90d095609 | ||
|
98e683329e | ||
|
3588bd881c | ||
|
0460811e6c | ||
|
27f5fe18df | ||
|
6d944ec98f | ||
|
adf6691470 | ||
|
dd8b500efd | ||
|
4e1ff8c4a3 | ||
|
e73d590ead | ||
|
5cc22f49cf | ||
|
eb3d2b1749 | ||
|
21a197ba46 | ||
|
0b74707638 | ||
|
16dc8b7d68 | ||
|
5a8abe004e | ||
|
b211d72c8b | ||
|
36f3eb8b2f | ||
|
cb1cb9f328 | ||
|
3344bb7263 | ||
|
5e1167b8ae | ||
|
b80db054e2 | ||
|
c66df3cb2c | ||
|
ac8ff4e565 | ||
|
bfa7ee90f4 | ||
|
77c9e37584 | ||
|
80350f8423 | ||
|
3c1ff4d21f | ||
|
55b8f03590 | ||
|
1fd7852309 | ||
|
9c5292962f | ||
|
c05c6e72c0 | ||
|
bdcd033952 | ||
|
4ec6bcc8c7 | ||
|
11ea4b6d47 | ||
|
e4f45b5370 | ||
|
9baadd3793 | ||
|
94a79876ce | ||
|
42c3d1fa68 | ||
|
0e3ccebd0b | ||
|
4af8272faa | ||
|
0ef3d0cf03 | ||
|
f266b92ef1 | ||
|
462c9fb3aa | ||
|
568186828c | ||
|
8bcc319b7d | ||
|
baff9780de | ||
|
d8b8f98738 | ||
|
b714eaac06 | ||
|
14b94a5bd2 | ||
|
ea014a6504 | ||
|
e28e66e8f1 | ||
|
b47a140c2f | ||
|
19d7e27fa9 | ||
|
2d368f226e | ||
|
75d81f8f18 | ||
|
e3437ba697 | ||
|
84f299c33b | ||
|
3d4489efe6 | ||
|
6aa50e3c00 | ||
|
b70498c337 | ||
|
f34aa77d1d | ||
|
3833a41acb | ||
|
b5a5a216cd | ||
|
d9da2a57b6 | ||
|
1591b61b77 | ||
|
66f2df9677 | ||
|
5199377113 | ||
|
da202317c0 | ||
|
1d2a4e707e | ||
|
edf9dbc6e8 | ||
|
dfbe6e5b6e | ||
|
d551333fa2 | ||
|
01cab599bb | ||
|
1c8834fffb | ||
|
22e6ea700f | ||
|
7f7d6cf893 | ||
|
a94d476b75 | ||
|
eb5e55a272 | ||
|
53c80aaef8 | ||
|
607d0115f0 | ||
|
b4f18dbe77 | ||
|
51d97cdca5 | ||
|
2cd593157f | ||
|
ec70fde557 | ||
|
950576d38b | ||
|
ce5304277d | ||
|
53760766a0 | ||
|
ed863986a7 | ||
|
89ff5a83b5 | ||
|
fe0b62b9b4 | ||
|
32c8ddbe1b | ||
|
2cfbfd8649 | ||
|
3f6c19dec4 | ||
|
93421b50f9 | ||
|
54e829173a | ||
|
4fe38bd31b | ||
|
fb0638e824 | ||
|
108794a6b6 | ||
|
9c16fc1380 | ||
|
99c219ed97 | ||
|
ec12238ea1 | ||
|
bdbd22f98b | ||
|
b8e1944d20 | ||
|
8883d185fe | ||
|
19e40e9976 | ||
|
fa85b2b5b2 | ||
|
5cf0131d75 | ||
|
3948cb8e6c | ||
|
f43938726a | ||
|
8c8bb7a930 | ||
|
3972882a33 | ||
|
0ef5eeeb55 | ||
|
ef48a79d0c | ||
|
2bb883219c | ||
|
23c0bb49c4 | ||
|
13e59105ec | ||
|
98c057c516 | ||
|
e293d69798 | ||
|
b097e29104 | ||
|
29fbd46e33 | ||
|
6a15afc723 | ||
|
c56a39a726 | ||
|
4b80e46d26 | ||
|
a6f3e61520 | ||
|
cce4ef19e5 | ||
|
1951491c04 | ||
|
87b72e4bcd | ||
|
2c6643d691 | ||
|
d02df46517 | ||
|
0c0cc417ee | ||
|
f0c03e8a3b | ||
|
345766f387 | ||
|
3fa659632c | ||
|
95b92b7d1e | ||
|
466e988627 | ||
|
dc3c967c9f | ||
|
1fc31b4d8f | ||
|
e4a4b0a4eb | ||
|
a9c026884d | ||
|
e893000ce9 | ||
|
32eeb3424d | ||
|
ab523b6102 | ||
|
b062222c45 | ||
|
2dddc843ce | ||
|
b74c1c8cf9 | ||
|
d5d4bb2c4b | ||
|
89ac27ad10 | ||
|
48b169c026 | ||
|
0715b7406e | ||
|
6e4991a34b | ||
|
8730af59bc | ||
|
bdcc2c6c9f | ||
|
6f0f6e86a1 | ||
|
3962d9da92 | ||
|
5ed53d5f04 | ||
|
ddb28b78c3 | ||
|
7699b6b4ea | ||
|
d783d05462 | ||
|
33bf373151 | ||
|
8116644526 | ||
|
dc4665e82a | ||
|
732a85e51d | ||
|
32190db8bb | ||
|
25d3a115e0 | ||
|
30e3ed6410 | ||
|
8b5a775dc5 | ||
|
2942c3a4be | ||
|
768d3bb3e8 | ||
|
250b2c2f53 | ||
|
c8440af9a5 | ||
|
37fe2d22b0 | ||
|
b0b5d90976 | ||
|
27b0c7f425 | ||
|
7c23571806 | ||
|
ea378c8d82 | ||
|
0fb45974ef | ||
|
6490f9c128 | ||
|
2d7f1af52c | ||
|
ac27659a59 | ||
|
11d59c8bd1 | ||
|
a6936cbd02 | ||
|
3be84d76ef | ||
|
9aed1f344f | ||
|
4fff264630 | ||
|
2e444da2a3 | ||
|
7a216f95ca | ||
|
f22a9799a1 | ||
|
90bdc40393 | ||
|
622a97c8d8 | ||
|
03691c81c2 | ||
|
885b56c465 | ||
|
23cc7be231 | ||
|
bb82b0eb79 | ||
|
2e05f640b8 | ||
|
697a02ffee | ||
|
ad402021ed | ||
|
67caf6ef1f | ||
|
3277858c5a | ||
|
3fbedf323f | ||
|
144a6130f2 | ||
|
fa38c975b6 | ||
|
c14fa1021c | ||
|
5e78cc02bd | ||
|
429ef80fb9 | ||
|
e4d93cad27 | ||
|
d9a4840e37 | ||
|
a93070b98d | ||
|
c05a942862 | ||
|
f9a7879c1e | ||
|
bdfbc6d6a7 | ||
|
21181d8d8e | ||
|
1c7a27b816 | ||
|
e953f58c74 | ||
|
9250cee9e7 | ||
|
bb075d15ff | ||
|
a31f16bba7 | ||
|
88a41c37f3 | ||
|
d21885ca98 | ||
|
d774f8e870 | ||
|
08b5e66628 | ||
|
6fdfec3967 | ||
|
ab4616a3ad | ||
|
cb34ff4c83 | ||
|
bdbead256c | ||
|
f200086d01 | ||
|
ef97c3b42d | ||
|
ed8b41e8ec | ||
|
aada3371b7 | ||
|
38a9782bdf | ||
|
c6ac81dcf6 | ||
|
2d3f3f0fde | ||
|
993a2c7823 | ||
|
87b36cf7e3 | ||
|
742f2c8d9f | ||
|
0d7ac5f1d8 | ||
|
3adccff611 | ||
|
08b8bd27f9 | ||
|
1059c7e2be | ||
|
3ebcd5f738 | ||
|
4627ea1dec | ||
|
7ed24e78d5 | ||
|
ae02e3fd8d | ||
|
cc88d5962e | ||
|
70c8a524cd | ||
|
9a8efc8a58 | ||
|
f0f67b87c4 | ||
|
1a3ec98896 | ||
|
efff44cba9 | ||
|
7227418c4c | ||
|
29f93a9b73 | ||
|
532aa2acd0 | ||
|
6aca410f37 | ||
|
f20656b516 | ||
|
bcd7866e10 | ||
|
c1b8d44209 | ||
|
50e947fbbe | ||
|
189d969ee6 | ||
|
201790ff8d | ||
|
cc26ce4143 | ||
|
745e0aa525 | ||
|
6602b1587a | ||
|
6698b57f52 | ||
|
628268d47c | ||
|
56a635212a | ||
|
7e67eb17e0 | ||
|
935d72d672 | ||
|
fccb510186 | ||
|
e7ea0dc842 | ||
|
a40d6b0649 | ||
|
b7429a358f | ||
|
cf8b4e2f76 | ||
|
48c865e57a | ||
|
059764cd23 | ||
|
c205eee6fd | ||
|
7b22099608 | ||
|
b56b42d6fb | ||
|
ef6ef57e67 | ||
|
47d3cf1d45 | ||
|
9cfac9a884 | ||
|
dc172476e1 | ||
|
6fc7763380 | ||
|
ce45f21dba | ||
|
2de713c946 | ||
|
3d1dfe20b3 | ||
|
0404735ccb | ||
|
83f200f5a2 | ||
|
a29eb9b993 | ||
|
c939be97fb | ||
|
f31e62a532 | ||
|
34c195159e | ||
|
322fef2db1 | ||
|
7aa2565e89 | ||
|
8f3572f2d3 | ||
|
fb165ef28b | ||
|
a26acf4a25 | ||
|
645400e17f | ||
|
ccad52b80f | ||
|
f6303deaa4 | ||
|
d3a3083b85 | ||
|
99452056ec | ||
|
fca21bab4d | ||
|
9c58b77f01 | ||
|
b5c5f67fcc | ||
|
0f17423465 | ||
|
f093e29bd1 | ||
|
fe9b8e834d | ||
|
64f273120e | ||
|
31c1dd466b | ||
|
99b369bf45 | ||
|
e2a1535c44 | ||
|
3dfa88020e | ||
|
a220094941 | ||
|
ababdacf89 | ||
|
114dd5fc2a | ||
|
c058629172 | ||
|
79d7f577e4 | ||
|
631bafc6ab | ||
|
be58da539e | ||
|
a508ac9dda | ||
|
538fd2cef0 | ||
|
42557446a1 | ||
|
b9586481fc | ||
|
a0434e3271 | ||
|
15a5bcc21a | ||
|
edb838045b | ||
|
41a2e657b1 | ||
|
18b80a69c2 | ||
|
ce80fb39e8 | ||
|
2f19ff314b | ||
|
a0fd4b505a | ||
|
919aa70251 | ||
|
1aea4045a3 | ||
|
4cded0bf57 | ||
|
cd0585c7c4 | ||
|
8281279452 | ||
|
8f1bf846fe | ||
|
c26bf557d0 | ||
|
499b92cdd1 | ||
|
3dce5e162f | ||
|
f9de65c035 | ||
|
6f95e9a3cb | ||
|
ce09da084c | ||
|
5d50f92dd3 | ||
|
d054e085d6 | ||
|
59cdfa6fe6 | ||
|
ee0e9011b2 | ||
|
654ebe0c48 | ||
|
a40859c0bb | ||
|
74e3f6dee5 | ||
|
e553bfb204 | ||
|
96caace068 | ||
|
5310ccebbe | ||
|
ccd55257cd | ||
|
583687f3a7 | ||
|
e06dc86bf7 | ||
|
8828aa0621 | ||
|
e472e105f2 | ||
|
6ad10f1772 | ||
|
fcf7d98834 | ||
|
90ad06c65c | ||
|
888e9beb4c | ||
|
69b338ca85 | ||
|
0c009445d4 | ||
|
c5fb734e42 | ||
|
d2c8475504 | ||
|
f38d99653f | ||
|
cdce43d226 | ||
|
89ab0a7e97 | ||
|
c7250bfcba | ||
|
4a9b693da8 | ||
|
fff35aa820 | ||
|
a9a542d68f | ||
|
35ff3f0cbf | ||
|
abf92b6df3 | ||
|
8517fc9f24 | ||
|
21b473108f | ||
|
d4367f73a2 | ||
|
7ff46c3cd6 | ||
|
4a88e241b5 | ||
|
8da0317b19 | ||
|
297c2e244d | ||
|
a51d752a35 | ||
|
7800b0a7f5 | ||
|
5ce4104644 | ||
|
b4f1bbf793 | ||
|
ca33bea6b7 | ||
|
42d20ff693 | ||
|
22a14416ad | ||
|
98bd9bdaa0 | ||
|
13bac92a24 | ||
|
d9eb14d6e5 | ||
|
6ec0471e8b | ||
|
8008311d9c | ||
|
fcf16051a2 | ||
|
3a236456cd | ||
|
2606d77c62 | ||
|
3d2f33c120 | ||
|
4f14969464 | ||
|
7234f011ec | ||
|
5b949d6e00 | ||
|
2fd476ada8 | ||
|
2e7703bc97 | ||
|
9b69a6addd | ||
|
500243b0b3 | ||
|
3ef84dc1fc | ||
|
b04d68d087 | ||
|
715c381eb2 | ||
|
ca32ae4561 | ||
|
6b277c5e67 | ||
|
1ac64fd0b3 | ||
|
f2c1dd41d0 | ||
|
869360f26c | ||
|
dbdc334931 | ||
|
b317d1a171 | ||
|
b00c7b0ce3 | ||
|
a61eafeac2 | ||
|
5978b1c421 | ||
|
9f16799453 | ||
|
74fe0ee4e4 | ||
|
e8880232b3 | ||
|
556e9f1df7 | ||
|
beb301e781 | ||
|
056c809754 | ||
|
fa47eac9ff | ||
|
bf4a7846dd | ||
|
b0cc6dd714 | ||
|
d6e2d8e4a2 | ||
|
bbfc962727 | ||
|
8ddb357e5a | ||
|
560c10898f | ||
|
04f5214bb7 | ||
|
4c35d52234 | ||
|
01be5e3e23 | ||
|
46dc4102e0 | ||
|
cf31049c51 | ||
|
c624c4342f | ||
|
701d7baca8 | ||
|
8e45959483 | ||
|
6858d67897 | ||
|
9b23cbd2c2 | ||
|
ec1bb300e2 | ||
|
69a8cad47b | ||
|
bcaca0eca3 | ||
|
a1f79e58db | ||
|
2cc5fdcf62 | ||
|
dd1b4e21f5 | ||
|
91eb052c22 | ||
|
ecefcfabc0 | ||
|
8e42e71528 | ||
|
a2275ae111 | ||
|
3976803d8f | ||
|
7921fc74fd | ||
|
1732acfee2 | ||
|
3a4fc65712 | ||
|
9ce9caba02 | ||
|
07f4995c8f | ||
|
8200c7248a | ||
|
bd9f1d5398 | ||
|
ce0ca23d79 | ||
|
35863c8d3a | ||
|
dad73ce9df | ||
|
f716692591 | ||
|
6387114a18 | ||
|
55ab39ca55 | ||
|
28a4f724d5 | ||
|
f2d06bcea1 | ||
|
4d1771614a | ||
|
61efabb3b5 | ||
|
b00458c2b9 | ||
|
594f9822c7 | ||
|
9b3131b95e | ||
|
d7ad32a8cc | ||
|
59127e4029 | ||
|
7edf70a77b | ||
|
3fd90a37fb | ||
|
356ec276bc | ||
|
ad8d945c1d | ||
|
a3bf30a77b | ||
|
3f829a3114 | ||
|
537b4ae003 | ||
|
08b4c9ea5c | ||
|
6b00f5a97d | ||
|
d259df9a47 | ||
|
aeaebd082f | ||
|
0c9c0f2032 | ||
|
155801ab2b | ||
|
deeeb06488 | ||
|
28fd719ce3 | ||
|
317075aa6d | ||
|
eaf2efc510 | ||
|
88555bbea2 | ||
|
a4d7bf4ebe | ||
|
50e5c21735 | ||
|
2ddacf48d4 | ||
|
cd66d2c7b0 | ||
|
2e7c26c539 | ||
|
f0f47530bf | ||
|
e7be4e3e49 | ||
|
7a7ce7fcea | ||
|
bd104a7ea8 | ||
|
31d6789ff0 | ||
|
bdcb7372a5 | ||
|
b8df2226ae | ||
|
106bae5c97 | ||
|
651297fa0b | ||
|
1b2873fc5f | ||
|
f82a2b3bc5 | ||
|
4cb616ebeb | ||
|
1bcc975d7b | ||
|
98fd5b8858 | ||
|
6f08482aaf | ||
|
f7d06b9759 | ||
|
a178fed0c6 | ||
|
ff342f6789 | ||
|
b1c2f8faa1 | ||
|
6f59e79b28 | ||
|
6c22bad77a | ||
|
1cf0125d1b | ||
|
49211482b0 | ||
|
b3aecec11d | ||
|
7cb86d0254 | ||
|
0ba9389ca2 | ||
|
1902787104 | ||
|
b3e32db073 | ||
|
01d53bdb85 | ||
|
51acc34a80 | ||
|
694447e66c | ||
|
05b7a610ef | ||
|
1e799402ee | ||
|
5f9c61c4b4 | ||
|
12b6791e8b | ||
|
8024ad123e | ||
|
2bd2f5a5aa | ||
|
37d79b2a1c | ||
|
cd057045e6 | ||
|
ddfbd69e8b | ||
|
28fa1264b7 | ||
|
a6c3189833 | ||
|
0d2fe08dc9 | ||
|
8cfe25bfac | ||
|
f9e2a677d9 | ||
|
2ef1c54417 | ||
|
f9c3c0c8ae | ||
|
44a15551ba | ||
|
732e181312 | ||
|
919187f7fd | ||
|
7840a5ea49 | ||
|
3a33ac1455 | ||
|
2eb7d8ba91 | ||
|
7ec5cce2c8 | ||
|
8fdc6c11e1 | ||
|
1a110de597 | ||
|
317aa591c3 | ||
|
0d44f82c86 | ||
|
9cac61dc33 | ||
|
52481a6e8b | ||
|
b3e18f4e56 | ||
|
aa25ac774e | ||
|
af7da586aa | ||
|
b671da900a | ||
|
d8bb83e8c4 | ||
|
bc3d64a2ff | ||
|
70e72c246d | ||
|
7c8c82edd7 | ||
|
5dc556f0af | ||
|
c8c69f1a66 | ||
|
985019e117 | ||
|
b9620b3a21 | ||
|
e7bb4a8ec6 | ||
|
bb5f935d7a | ||
|
17dad27610 | ||
|
ee960d76c7 | ||
|
dfb595193a | ||
|
0a91a40c1b | ||
|
12f4305691 | ||
|
dd865b0dfb | ||
|
7cbfa9fcd4 | ||
|
28d880a7c4 | ||
|
e83d45fce5 | ||
|
693ff3cc66 | ||
|
706b095f95 | ||
|
8e2e96d513 | ||
|
28bce44f69 | ||
|
53d88dfd50 | ||
|
42daf7ed32 | ||
|
e5402ea7c1 | ||
|
05e8d6b578 | ||
|
505f340917 | ||
|
46856c9394 | ||
|
c63a2ad39d | ||
|
68a7078614 | ||
|
2e15f1e2a3 | ||
|
a790838222 | ||
|
cd14360d62 | ||
|
74c94a60a6 | ||
|
56cbc7683e | ||
|
bf778d2fca | ||
|
6e5bca8306 | ||
|
7e8fea6ed3 | ||
|
43ff3e11ed | ||
|
f1750e3c35 | ||
|
8b1fe26c84 | ||
|
6ab09a3603 | ||
|
df45298c1f | ||
|
4a64dce737 | ||
|
27ad428b5e | ||
|
2da33bae43 | ||
|
3dab683a45 | ||
|
d08fa37ccf | ||
|
4cd7976f63 | ||
|
569e8b6180 | ||
|
9a443bd08e | ||
|
efb37ae709 | ||
|
4658ef9918 | ||
|
2b6a1c9cb1 | ||
|
c4606b1854 | ||
|
d47b946d00 | ||
|
a886e8087d | ||
|
d473455680 | ||
|
40245ef43b | ||
|
aa057d6a57 | ||
|
5c03e64f46 | ||
|
1d4d156749 | ||
|
4fc6da1fa1 | ||
|
9fac48fcea | ||
|
ff4fdd3740 | ||
|
da1cce035a | ||
|
49292bbb2d | ||
|
3e502db772 | ||
|
426351bb54 | ||
|
4d6e244100 | ||
|
71253b23d5 | ||
|
076ff7c7ba | ||
|
94b6c7975a | ||
|
0b08010221 | ||
|
bc67113d77 | ||
|
5974bdcc2a | ||
|
f9696287a4 | ||
|
807dede90a | ||
|
1f2b37b70e | ||
|
7288ba0fd7 | ||
|
f48c17cf88 | ||
|
fba9cc3739 | ||
|
e04388a230 | ||
|
fbe3be169d | ||
|
4e4ae0fca0 | ||
|
2f278c8618 | ||
|
905ae3437b | ||
|
7679721007 | ||
|
9f29a2e04f | ||
|
ff5bf0c6e5 | ||
|
0eb8c2b7ba | ||
|
deb140e3bc | ||
|
9a1710eb27 | ||
|
e478238d77 | ||
|
c9c9410908 | ||
|
42372cabd5 | ||
|
ab9c991530 | ||
|
9429d84cf8 | ||
|
b22774a599 | ||
|
ca3b0a2ab1 | ||
|
62f76d08ad | ||
|
92bff24d43 | ||
|
eddd3e508f | ||
|
649eb65bb1 | ||
|
8fb3348a7c | ||
|
6c2df1a783 | ||
|
55afc98108 | ||
|
b875eb31d2 | ||
|
060b031272 | ||
|
95c4c4a238 | ||
|
4424e48926 | ||
|
b8c7876454 | ||
|
8256f60340 | ||
|
1d0cb45e4c | ||
|
d1a184e3f2 | ||
|
aa38b31015 | ||
|
466067bd95 | ||
|
c9b56efaaa | ||
|
e56920edee | ||
|
0e0c475c83 | ||
|
241190c4da | ||
|
69d0c31ae5 | ||
|
c3993fd943 | ||
|
8a3b7d7c1a | ||
|
87f14617cc | ||
|
9f24f765ea | ||
|
48c802e5cc | ||
|
388d141d82 | ||
|
7fa93e97db | ||
|
030d241130 | ||
|
bac392d331 | ||
|
1542d5e386 | ||
|
f1b6b3386a | ||
|
7d05999ced | ||
|
d477feb930 | ||
|
9465a6d2b5 | ||
|
c3f78b698d | ||
|
a4e699f781 | ||
|
cd871e5aad | ||
|
c9b215684c | ||
|
82a4c706b0 | ||
|
082e6f5e99 | ||
|
b90c7c09b6 | ||
|
1ee72a6ce5 | ||
|
f72a8c5c06 | ||
|
ba5db2c15f | ||
|
f5b89ca783 | ||
|
4ef840e210 | ||
|
e2d0ee125f | ||
|
8e1dbc03d9 | ||
|
9c0893fa8c | ||
|
0dfb97c5f7 | ||
|
cb52af28e7 | ||
|
4b4384b1a8 | ||
|
62483e748b | ||
|
9b10984d81 | ||
|
c5e283a13e | ||
|
df918e8529 | ||
|
aa1193a9eb | ||
|
8f7f263a48 | ||
|
0bad227548 | ||
|
78bcd3e1bb | ||
|
554640c345 | ||
|
baecc256f6 | ||
|
10a2a4cf5b | ||
|
c5dc073d49 | ||
|
d48e4c66b2 | ||
|
d357142075 | ||
|
af17381e04 | ||
|
2e7d339d7e | ||
|
c6cddad13c | ||
|
54bd54b521 | ||
|
8cbbb970e1 | ||
|
fbbf7f75c3 | ||
|
5a23b95352 | ||
|
6f9675b6d6 | ||
|
bb8ce30552 | ||
|
581e2ad431 | ||
|
45deb493ba | ||
|
4531d0ee32 | ||
|
a26e8a5f83 | ||
|
be74fbd677 | ||
|
ee8c83bbd8 | ||
|
dbd32abdd1 | ||
|
f300287814 | ||
|
dd361bb9ad | ||
|
744205cb6e | ||
|
86c22c9fdd | ||
|
d7a66f6782 | ||
|
902f310eb0 | ||
|
3bb107e192 | ||
|
78f8b1454d | ||
|
70ba9a4db5 | ||
|
93d9c44585 | ||
|
f0bb462f1c | ||
|
151e8e8f17 | ||
|
23f474b003 | ||
|
15104de84c | ||
|
55e4875662 | ||
|
5c3165efa2 | ||
|
3690a53dc9 | ||
|
fb119cc208 | ||
|
7343304284 | ||
|
c1ecc62ac1 | ||
|
bd40615f8e | ||
|
0df8d096f0 | ||
|
749dd1e8e3 | ||
|
ade6558769 | ||
|
6303b172b1 | ||
|
636ae193a7 | ||
|
aff8493204 | ||
|
8f2d4494d5 | ||
|
7a2bb4eb96 | ||
|
4916c06797 | ||
|
a818ab0942 | ||
|
9aa89393c0 | ||
|
216b304fe1 | ||
|
cf8a687b4d | ||
|
d1d6ba4114 | ||
|
a5ac713310 | ||
|
6fa8c33672 | ||
|
dd2b019d3c | ||
|
3a12ad192f | ||
|
d669b75352 | ||
|
746d50d459 | ||
|
f741552d91 | ||
|
c38e4b86b4 | ||
|
b044d85e90 | ||
|
24d111f026 | ||
|
f50058e3c2 | ||
|
ce9445168c | ||
|
27b8b4b35a | ||
|
9ccb67db8a | ||
|
3d82afd4e6 | ||
|
5f9cb61160 | ||
|
7f54b70c24 | ||
|
a156dce281 | ||
|
c0b0e58720 | ||
|
170ffbae04 | ||
|
6755ec7eb0 | ||
|
c8bc9a096a | ||
|
dc7f5a562b | ||
|
3b5b51578d | ||
|
41188a1bd6 | ||
|
d9bafe34eb | ||
|
43dbba5378 | ||
|
168ed5ac56 | ||
|
e5b4a55d8e | ||
|
167c057e8a | ||
|
71bf054ab1 | ||
|
111fcd77c4 | ||
|
287c1c4ffa | ||
|
3d69dc786d | ||
|
57a3f20c13 | ||
|
eab2c57594 | ||
|
b019962f34 | ||
|
5c59c819b6 | ||
|
93b97b8d72 | ||
|
f1f922031a | ||
|
390cace775 | ||
|
28fdad9426 | ||
|
9155c13e08 | ||
|
e8776d44c5 | ||
|
5ee8d04800 | ||
|
eb31934fb7 | ||
|
000f86d318 | ||
|
d9b3ebc82f | ||
|
91b3ca047a | ||
|
08131e42af | ||
|
a013553a6c | ||
|
7b2fe8eb4a | ||
|
610f782054 | ||
|
94700f4064 | ||
|
0f12ebb31c | ||
|
00a8a9ac0e | ||
|
92616c6ae3 | ||
|
97db618cd8 | ||
|
2832d308f1 | ||
|
a7ecdf715f | ||
|
935dc3ff9f | ||
|
99d14e8cbe | ||
|
664fde2344 | ||
|
27c45eface | ||
|
f83bc3c8b3 | ||
|
0d5efb8d27 | ||
|
bf9c1c1875 | ||
|
049d866f62 | ||
|
d672f0c2ad | ||
|
7b040e8583 | ||
|
e1cf285272 | ||
|
53f7f13362 | ||
|
f710677cdc | ||
|
b5fbc8b632 | ||
|
1fdc0a196c | ||
|
559f429f5e | ||
|
ae4b198d3d | ||
|
e088ecbbad | ||
|
f6b7bd5b44 | ||
|
f5a21f64c0 | ||
|
f5cbed7c0c | ||
|
59fff8928b | ||
|
8743b49a17 | ||
|
19dc91937e | ||
|
4846cb7b14 | ||
|
54e0ac816b | ||
|
9ce960b3d7 | ||
|
cc9d1c4bfd | ||
|
d211555beb | ||
|
9350557d10 | ||
|
ea6c54cad0 | ||
|
81287602d7 | ||
|
441ba79ec7 | ||
|
c9e4a09da6 | ||
|
c84f4e2bc0 | ||
|
6938f8ab89 | ||
|
4fdd2c851f | ||
|
78b56712fc | ||
|
6dcdb0f9a0 | ||
|
cfab837b96 | ||
|
b8461cdeb6 | ||
|
e07d65ef6b | ||
|
80cbc35c89 | ||
|
2faf84780f | ||
|
ebdb1a8836 | ||
|
2dfa51652a | ||
|
1cf1ea230f | ||
|
86e127ebff | ||
|
a313265785 | ||
|
37693ad08d | ||
|
e8180d252b | ||
|
9957c95c68 | ||
|
3354d53a48 | ||
|
ddaa53b940 | ||
|
c2e04a11bf | ||
|
00d059b8df | ||
|
f3fff6f1c5 | ||
|
9360eb6a70 | ||
|
26fb03e6c8 | ||
|
eed3d021d9 | ||
|
48728e8418 | ||
|
f39f25760a | ||
|
10ea60daaf | ||
|
f2fa5e140b | ||
|
be5ff35b13 | ||
|
bd5d73d1e6 | ||
|
cc712b0c75 | ||
|
a5ac84e1b9 | ||
|
cbe1f762ca | ||
|
e6db49c20c | ||
|
4909fcc8b4 | ||
|
68cdfd00b0 | ||
|
323c16ebe1 | ||
|
c20a38b7b0 | ||
|
20993342a2 | ||
|
1b3198c143 | ||
|
173d0290ea | ||
|
ae4cd8da12 | ||
|
a494398332 | ||
|
c82bdd1f5a | ||
|
e6ac3ccfad | ||
|
b13b58a2b2 | ||
|
2b6790f83f | ||
|
fe30850568 | ||
|
493c71b89e | ||
|
deaebc373c | ||
|
e834489206 | ||
|
1b316e462e | ||
|
7bf75128a8 | ||
|
3857e8d49f | ||
|
b16149b842 | ||
|
32ed8a4d8d | ||
|
f949d2476b | ||
|
0620830b10 | ||
|
7ee25693aa | ||
|
7cb86add64 | ||
|
fbc9720f7a | ||
|
ffdd37ddd5 | ||
|
51062bc80b | ||
|
31533b5ef8 | ||
|
3649b595df | ||
|
83b7c9aa32 | ||
|
4e3c59a2da | ||
|
dcbfe90cf7 | ||
|
f69be86c74 | ||
|
820722f44e | ||
|
2ff806dedc | ||
|
a755badd5f | ||
|
4df1e5393b | ||
|
8c55bd179f | ||
|
ccfc5ece66 | ||
|
6c12f1bc86 | ||
|
88839e9610 | ||
|
4f6a733238 | ||
|
dc9083a764 | ||
|
6f231b840b | ||
|
61a703e605 | ||
|
8e0e9734a5 | ||
|
2afb455bac | ||
|
01792f91e2 | ||
|
651dff0750 | ||
|
9cbfbd41dc | ||
|
168d6f403c | ||
|
41f200e630 | ||
|
0809cfdc6d | ||
|
466d739da8 | ||
|
daf65cb387 | ||
|
2605f60983 | ||
|
fcf6cdb134 | ||
|
209258b507 | ||
|
f80bc214f9 | ||
|
f76990bb9b | ||
|
eef68c9b31 | ||
|
006c2ae186 | ||
|
8b66ff6afe | ||
|
4cc6d57e6e | ||
|
af1c6b22bb | ||
|
5958990ed5 | ||
|
cd4cbdc197 | ||
|
1f538be16e | ||
|
9703439a4c | ||
|
42203ba872 | ||
|
cd60b852a1 | ||
|
5b1d9e1a0d | ||
|
e02657a7c7 | ||
|
c352eb0c74 | ||
|
81b9d5da09 | ||
|
b9b0413510 | ||
|
97770da619 | ||
|
521623797e | ||
|
15d3414443 | ||
|
245f06c93a | ||
|
33899f0e2f | ||
|
4697fbdeef | ||
|
06174d6afb | ||
|
b2bb16c1e0 | ||
|
27aae279e6 | ||
|
e9ee93beb7 | ||
|
20941dedd3 | ||
|
5ac88623ed | ||
|
768508dd4b | ||
|
668633e764 | ||
|
3dbb1f034d | ||
|
1270e5d15c | ||
|
afec8480fb | ||
|
8720511046 | ||
|
a7a00ecf40 | ||
|
88bbafd3e8 | ||
|
ae3258b449 | ||
|
cf4d7cfeef | ||
|
46ee2a0568 | ||
|
ce250c85fc | ||
|
1087b9f5df | ||
|
0dc74d9d14 | ||
|
98b272383f | ||
|
e722daafd0 | ||
|
670ab059d1 | ||
|
09f826ceba | ||
|
df5e3c9be9 | ||
|
31c336b3b1 | ||
|
b3a419b2f3 | ||
|
11f63fa6ce | ||
|
4b35059140 | ||
|
7836feba63 | ||
|
1e54366f1f | ||
|
d039bb0e03 | ||
|
166d32f073 | ||
|
321890992e | ||
|
d644403d8a | ||
|
44e76f9518 | ||
|
f9703eca4c | ||
|
48551e8bf5 | ||
|
74b538805b | ||
|
35f493beff | ||
|
06d11c9133 | ||
|
da7eb615db | ||
|
5da5024ad3 | ||
|
c1346d4c86 | ||
|
c38a4a15ff | ||
|
bdec94ead6 | ||
|
69bebf202f | ||
|
38895afea6 | ||
|
70ed4188b6 | ||
|
d889094863 | ||
|
c96eb8753e | ||
|
5a7607f6c6 | ||
|
71bb88529a | ||
|
b26164a168 | ||
|
19444551e4 | ||
|
e0b2a6e627 | ||
|
2973765866 | ||
|
2a08a25064 | ||
|
a55e291908 | ||
|
2003d37a9a | ||
|
29145bf6cf | ||
|
caa1ff120a | ||
|
ef4e964c94 | ||
|
1f263f60a7 | ||
|
5fc7cafcbe | ||
|
397c4926eb | ||
|
a14544398b | ||
|
d439dceac1 | ||
|
af29b31ea8 | ||
|
b311ef70bc | ||
|
9f9d744406 | ||
|
e094871bc9 | ||
|
dfc95cee45 | ||
|
fdca234721 | ||
|
cf5cc626d7 | ||
|
358d9aac7d | ||
|
681bc580c4 | ||
|
4a2768f8d1 | ||
|
05f8773fa0 | ||
|
5e5fdfdd51 | ||
|
5e744390c0 | ||
|
cb5fa401cb | ||
|
2980860377 | ||
|
9ff0b282f3 | ||
|
4bc1c032bd | ||
|
9fcb00f10b | ||
|
723e461559 | ||
|
9b24e6d448 | ||
|
e622774775 | ||
|
84ce9bc94b | ||
|
a3a1bc30b1 | ||
|
b4c9a7698e | ||
|
8b2d7fc32f | ||
|
90e66cbd94 | ||
|
fd9a7080ea | ||
|
c0fad106f0 | ||
|
78c8243184 | ||
|
780abecd53 | ||
|
ea6896816d | ||
|
95a456860a | ||
|
b1b2fda155 | ||
|
5847f534c3 | ||
|
e8e8163fa7 | ||
|
6a21d82dcf | ||
|
d6b47656bc | ||
|
8c37ef3a95 | ||
|
35deed1d10 | ||
|
ba32a665f1 | ||
|
bbd19be554 | ||
|
c360cc6db6 | ||
|
7e4b9af315 | ||
|
9b03e6b124 | ||
|
013e16e15f | ||
|
180ec52798 | ||
|
c7b47b4453 | ||
|
4b00db7662 | ||
|
78a7b995d2 | ||
|
f7c50a123a | ||
|
9617d17aca | ||
|
d9884ddf73 | ||
|
8157f0a958 | ||
|
b7580a5f83 | ||
|
66703b30b3 | ||
|
53677e3c64 | ||
|
feef6a1756 | ||
|
5f299b895b | ||
|
4e1bb5fbac | ||
|
47ccc513ad | ||
|
cce1a01936 | ||
|
6f2b1a6a76 | ||
|
8526907f50 | ||
|
bc192a8e54 | ||
|
9ff6f8fc52 | ||
|
6573bd6b4b | ||
|
9dc3f614af | ||
|
3888b8cceb | ||
|
294df4a2b3 | ||
|
265dd37212 | ||
|
eb7c79ad27 | ||
|
de111c7100 | ||
|
e892c9a824 | ||
|
5eb0e18cae | ||
|
27cabb398e | ||
|
64dbb14241 | ||
|
bb4e2be9eb | ||
|
7d1de0da17 | ||
|
bf16c9a42b | ||
|
1a7b1ce499 | ||
|
efc9bc71a7 | ||
|
fc5b315af0 | ||
|
7a4a78628d | ||
|
d16fb30a62 | ||
|
2d177e660e | ||
|
2f131dc170 | ||
|
94810e371a | ||
|
59731878f6 | ||
|
54ede8aa18 | ||
|
b415b6b043 | ||
|
70c922cdc5 | ||
|
068fc32cb2 | ||
|
3dcdacc3b8 | ||
|
a6594358d8 | ||
|
f98921da46 | ||
|
25747fbcf2 | ||
|
aac5c2b13c | ||
|
cc810a5b6f | ||
|
1b3592d959 | ||
|
d75614e9a7 | ||
|
08703e282f | ||
|
2904baf44e | ||
|
f99e46bf75 | ||
|
9f87890ead | ||
|
638184cf66 | ||
|
03babfe75c | ||
|
238ed3c788 | ||
|
6a9d931ba3 | ||
|
a3d2a9e00b | ||
|
39b88e8207 | ||
|
449c6dfde5 | ||
|
7cc47ca0b1 | ||
|
95f4a83f41 | ||
|
35154dc7a3 | ||
|
0fd0d7d080 | ||
|
658265c938 | ||
|
38fe9e7e1c | ||
|
77056dcf8d | ||
|
026683a8e1 | ||
|
6ab6dd6ac3 | ||
|
83de3482ce | ||
|
919a35aed3 | ||
|
ad3defb071 | ||
|
9c929ecd1b | ||
|
f79c9f7cf1 | ||
|
8e75c345d9 | ||
|
44886d9aad | ||
|
c2d444347d | ||
|
5cb497596d | ||
|
1857469d2f | ||
|
ea71b4843d | ||
|
97727e2e3d | ||
|
f81e7da8bb | ||
|
8e827bf83b | ||
|
9e1fa284ca | ||
|
3bf800be6e | ||
|
635b9f9dba | ||
|
52a0d7cf7b | ||
|
a34516932b | ||
|
929a2a30a2 | ||
|
ffa88eeb08 | ||
|
51b45b4ed4 | ||
|
f263844793 | ||
|
18c46df9aa | ||
|
15846e157b | ||
|
bc59f2db0d | ||
|
cd2be8c1a4 | ||
|
f958115c50 | ||
|
e7d677bfb6 | ||
|
3e80ffc52b | ||
|
d0c7a5c076 | ||
|
f3f4e6b354 | ||
|
0b5ee1edfc | ||
|
5f6975a113 |
@@ -1,25 +1,50 @@
|
||||
# Save as .codeclimate.yml (note leading .) in project root directory
|
||||
languages:
|
||||
JavaScript: true
|
||||
PHP: true
|
||||
---
|
||||
engines:
|
||||
csslint:
|
||||
enabled: true
|
||||
duplication:
|
||||
enabled: true
|
||||
config:
|
||||
languages:
|
||||
- ruby
|
||||
- javascript
|
||||
- python
|
||||
- php
|
||||
eslint:
|
||||
enabled: true
|
||||
fixme:
|
||||
enabled: true
|
||||
phpmd:
|
||||
enabled: true
|
||||
ratings:
|
||||
paths:
|
||||
- "**.css"
|
||||
- "**.inc"
|
||||
- "**.js"
|
||||
- "**.jsx"
|
||||
- "**.module"
|
||||
- "**.php"
|
||||
- "**.py"
|
||||
- "**.rb"
|
||||
exclude_paths:
|
||||
- "public/packages/maximebf/php-debugbar/debugbar.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets.js"
|
||||
- "public/packages/maximebf/php-debugbar/openhandler.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js"
|
||||
- "public/js/bootstrap3-typeahead.min.js"
|
||||
- "public/js/bootstrap-sortable.js"
|
||||
- "public/js/bootstrap-tagsinput.min.js"
|
||||
- "public/js/bootstrap-tagsinput.min.js.map"
|
||||
- "public/js/daterangepicker.js"
|
||||
- "public/js/jquery-2.1.3.min.js"
|
||||
- "public/js/jquery-2.1.3.min.js.map"
|
||||
- "public/js/jquery-ui.min.js"
|
||||
- "public/js/metisMenu.js"
|
||||
- "public/js/moment.min.js"
|
||||
- "public/js/sb-admin-2.js"
|
||||
- "public/bootstrap/*"
|
||||
- "resources/lang/*"
|
||||
- "tests/*"
|
||||
- "database/*"
|
||||
- "storage/*"
|
||||
- gulpfile.js
|
||||
- public/packages/maximebf/php-debugbar/debugbar.js
|
||||
- public/packages/maximebf/php-debugbar/widgets.js
|
||||
- public/packages/maximebf/php-debugbar/openhandler.js
|
||||
- public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js
|
||||
- public/js/bootstrap3-typeahead.min.js
|
||||
- public/js/bootstrap-sortable.js
|
||||
- public/js/bootstrap-tagsinput.min.js
|
||||
- public/js/bootstrap-tagsinput.min.js.map
|
||||
- public/js/daterangepicker.js
|
||||
- public/js/jquery-2.1.3.min.js
|
||||
- public/js/jquery-2.1.3.min.js.map
|
||||
- public/js/jquery-ui.min.js
|
||||
- public/js/metisMenu.js
|
||||
- public/js/moment.min.js
|
||||
- public/js/sb-admin-2.js
|
||||
- public/bootstrap/*
|
||||
- resources/lang/*
|
||||
- tests/*
|
||||
- database/*
|
||||
- storage/*
|
||||
|
@@ -1 +0,0 @@
|
||||
src_dir: .
|
31
.env.example
Normal file → Executable file
31
.env.example
Normal file → Executable file
@@ -1,7 +1,8 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_FORCE_SSL=false
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
LOG_LEVEL=warning
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
@@ -11,23 +12,35 @@ DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
COOKIE_PATH="/"
|
||||
COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
DEFAULT_CURRENCY=EUR
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_DRIVER=smtp
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
EMAIL_PRETEND=false
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=enter_your_email_here
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
MUST_CONFIRM_ACCOUNT=false
|
||||
|
||||
SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
SHOW_DEMO_WARNING=false
|
||||
|
||||
ANALYTICS_ID=
|
||||
RUNCLEANUP=true
|
||||
SITE_OWNER=mail@example.com
|
||||
|
||||
SENDGRID_USERNAME=
|
||||
SENDGRID_PASSWORD=
|
||||
|
||||
BLOCKED_DOMAINS=
|
32
.env.testing
Normal file → Executable file
32
.env.testing
Normal file → Executable file
@@ -1,6 +1,8 @@
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_KEY=SomeRandomString
|
||||
APP_FORCE_SSL=false
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
DB_HOST=localhost
|
||||
@@ -10,9 +12,27 @@ DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=array
|
||||
SESSION_DRIVER=array
|
||||
QUEUE_DRIVER=array
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=ABC
|
||||
EMAIL_PRETEND=true
|
||||
DEFAULT_CURRENCY=EUR
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=your_address_here@example.com
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
|
||||
ANALYTICS_ID=abcde
|
||||
RUNCLEANUP=false
|
||||
SITE_OWNER=your_address_here@example.com
|
||||
|
||||
BLOCKED_DOMAINS=
|
2
.gitattributes
vendored
Normal file → Executable file
2
.gitattributes
vendored
Normal file → Executable file
@@ -1 +1,3 @@
|
||||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.less linguist-vendored
|
||||
|
35
.gitignore
vendored
35
.gitignore
vendored
@@ -1,36 +1,5 @@
|
||||
/bootstrap/compiled.php
|
||||
/vendor
|
||||
composer.phar
|
||||
Thumbs.db
|
||||
.idea/
|
||||
tests/_output/*
|
||||
_ide_helper.php
|
||||
/build/logs
|
||||
index.html*
|
||||
app/storage/firefly-export*
|
||||
.vagrant
|
||||
firefly-iii-import-*.json
|
||||
tests/_output/*
|
||||
testing.sqlite
|
||||
_ide_helper_models.php
|
||||
clean.sqlite
|
||||
tests/acceptance/AcceptanceTester.php
|
||||
tests/functional/FunctionalTester.php
|
||||
tests/unit/UnitTester.php
|
||||
pi.php
|
||||
tests/_data/db.sqlite
|
||||
tests/_data/dump.sql
|
||||
db.sqlite_snapshot
|
||||
c3.php
|
||||
db.sqlite-journal
|
||||
tests/_output/*
|
||||
/node_modules
|
||||
.env
|
||||
clover.xml
|
||||
node_modules/
|
||||
addNewLines.php
|
||||
.phpstorm.meta.php
|
||||
.env.backup
|
||||
_development
|
||||
.env.local
|
||||
|
||||
tests/_output/*
|
||||
tests/_output/*
|
||||
|
22
.jshintrc
22
.jshintrc
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"undef": true,
|
||||
"unused": false,
|
||||
"strict": true,
|
||||
"browser": true,
|
||||
"jquery": true,
|
||||
"devel": true,
|
||||
"globals": [
|
||||
"language",
|
||||
"token",
|
||||
"currencyCode",
|
||||
"$",
|
||||
"token",
|
||||
"accountID",
|
||||
"billID",
|
||||
"currentMonthName",
|
||||
"previousMonthName",
|
||||
"nextMonthName",
|
||||
"everything",
|
||||
"moment"
|
||||
]
|
||||
}
|
@@ -1,3 +1,6 @@
|
||||
# .scrutinizer.yml
|
||||
tools:
|
||||
external_code_coverage: false
|
||||
filter:
|
||||
excluded_paths:
|
||||
- app/Support/Migration/*
|
||||
|
18
.travis.yml
18
.travis.yml
@@ -1,18 +1,22 @@
|
||||
language: php
|
||||
sudo: false
|
||||
|
||||
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7
|
||||
|
||||
install:
|
||||
- composer update
|
||||
- phpenv config-rm xdebug.ini
|
||||
- composer selfupdate
|
||||
- rm composer.lock
|
||||
- composer update --no-scripts
|
||||
- php artisan clear-compiled
|
||||
- php artisan optimize
|
||||
- php artisan env
|
||||
- mv -v .env.testing .env
|
||||
- php artisan env
|
||||
- touch storage/upload/at-1.data
|
||||
- touch storage/upload/at-2.data
|
||||
- touch storage/database/testing.db
|
||||
- php artisan migrate --env=testing
|
||||
- php artisan migrate --seed --env=testing
|
||||
- php artisan migrate --seed
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
|
124
CHANGELOG.md
Normal file
124
CHANGELOG.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
- No unreleased changes yet.
|
||||
|
||||
[3.9.0]
|
||||
### Added
|
||||
- @zjean has added code that allows you to force "https://"-URL's.
|
||||
- @tonicospinelli has added Portuguese (Brazil) translations.
|
||||
- Firefly III supports the *splitting* of transactions:
|
||||
- A withdrawal (expense) can be split into multiple sub-transactions (with multiple destinations)
|
||||
- Likewise for deposits (incomes). You can set multiple sources.
|
||||
- Likewise for transfers.
|
||||
|
||||
### Changed
|
||||
- Update a lot of libraries.
|
||||
- Big improvement to test data generation.
|
||||
- Cleaned up many repositories.
|
||||
|
||||
### Removed
|
||||
- Front page boxes will no longer respond to credit card bills.
|
||||
|
||||
### Fixed
|
||||
- Many bugs
|
||||
|
||||
## [3.8.4] - 2016-04-24
|
||||
### Added
|
||||
- Lots of new translations.
|
||||
- Can now set page size.
|
||||
- Can now mass edit transactions.
|
||||
- Can now mass delete transactions.
|
||||
- Firefly will now attempt to verify the integrity of your database when updating.
|
||||
|
||||
### Changed
|
||||
- New version of Charts library.
|
||||
|
||||
### Fixed
|
||||
- Several CSV related bugs.
|
||||
- Several other bugs.
|
||||
- Bugs fixed by @Bonno.
|
||||
|
||||
## [3.8.3] - 2016-04-17
|
||||
### Added
|
||||
- New audit report to see what happened.
|
||||
|
||||
### Changed
|
||||
- New Chart JS release used.
|
||||
- Help function is more reliable.
|
||||
|
||||
### Fixed
|
||||
- Expected bill amount is now correct.
|
||||
- Upgrade will now invalidate cache.
|
||||
- Search was broken.
|
||||
- Queries run better
|
||||
|
||||
## [3.8.2] - 2016-04-03
|
||||
### Added
|
||||
- Small user administration at /admin.
|
||||
- Informational popups are working in reports.
|
||||
|
||||
### Changed
|
||||
- User activation emails are better
|
||||
|
||||
### Fixed
|
||||
- Some bugs related to accounts and rules.
|
||||
|
||||
|
||||
## [3.8.1] - 2016-03-29
|
||||
### Added
|
||||
- More translations
|
||||
- Extended cookie control.
|
||||
- User accounts can now be activated (disabled by default).
|
||||
- Bills can now take the source and destination account name into account.
|
||||
|
||||
### Changed
|
||||
- The pages related to rules have new URL's.
|
||||
|
||||
### Fixed
|
||||
- Spelling errors.
|
||||
- Problems related to the "account repository".
|
||||
- Some views showed empty (0.0) amounts.
|
||||
|
||||
## [3.8.0] - 2016-03-20
|
||||
### Added
|
||||
- Two factor authentication, thanks to the excellent work of [zjean](https://github.com/zjean).
|
||||
- A new chart showing your net worth in year and multi-year reports.
|
||||
- You can now see if your current or future rules actually match any transactions, thanks to the excellent work of @roberthorlings.
|
||||
- New date fields for transactions. They are not used yet in reports or anything, but they can be filled in.
|
||||
- New routine to export your data.
|
||||
- Firefly III will mail the site owner when blocked users try to login, or when blocked domains are used in registrations.
|
||||
|
||||
|
||||
### Changed
|
||||
- Firefly III now requires PHP 7.0 minimum.
|
||||
|
||||
|
||||
### Fixed
|
||||
- HTML fixes, thanks to [roberthorlings](https://github.com/roberthorlings) and [zjean](https://github.com/zjean)..
|
||||
- A bug fix in the ABN Amro importer, thanks to [roberthorlings](https://github.com/roberthorlings)
|
||||
- It was not possible to change the opening balance, once it had been set. Thanks to [xnyhps](https://github.com/xnyhps) and [marcoveeneman](https://github.com/marcoveeneman) for spotting this.
|
||||
- Various other bug fixes.
|
||||
|
||||
|
||||
|
||||
## [3.4.2] - 2015-05-25
|
||||
### Added
|
||||
- Initial release.
|
||||
|
||||
### Changed
|
||||
- Initial release.
|
||||
|
||||
### Deprecated
|
||||
- Initial release.
|
||||
|
||||
### Removed
|
||||
- Initial release.
|
||||
|
||||
### Fixed
|
||||
- Initial release.
|
||||
|
||||
### Security
|
||||
- Initial release.
|
7
LICENSE
Normal file
7
LICENSE
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
135
README.md
135
README.md
@@ -1,127 +1,30 @@
|
||||
# Firefly III
|
||||
# Firefly III [](https://secure.php.net/downloads.php#v7.0.4) [](https://packagist.org/packages/grumpydictator/firefly-iii) [](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
## A personal finances manager
|
||||
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
|
||||
[](https://i.nder.be/hhfv03hp) [](https://i.nder.be/hhmwmqw9)
|
||||
|
||||
## About
|
||||
[](https://i.nder.be/g63q05m0) [](https://i.nder.be/c2g30ngg)
|
||||
|
||||
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared
|
||||
household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
|
||||
|
||||
_Firefly is a system you'll have install yourself on webhosting of your choosing._
|
||||
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people
|
||||
make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase
|
||||
their current cashflow. There are tons of ways to save and earn money.
|
||||
## Installation
|
||||
|
||||
To install Firefly III, you'll need a web server (preferrably on Linux) and access to the command line. Then, please read the [installation guide](https://jc5.github.io/firefly-iii/installation-guide/).
|
||||
|
||||
## More about Firefly III
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase their current cashflow. There are tons of ways to save and earn money.
|
||||
|
||||
Firefly works on the principle that if you know where you're money is going, you can stop it from going there.
|
||||
|
||||
To get to know Firefly, and to see if it fits you, check out these resources:
|
||||
#### Some advantages of using Firefly
|
||||
|
||||
- The screenshots below on this very page.
|
||||
- The featurelist below, also on this very page.
|
||||
- The [full description](https://github.com/JC5/firefly-iii/wiki/full-description), which will tell you how Firefly works,
|
||||
and the philosophy behind it.
|
||||
- Firefly can import any CSV file, so migrating from other systems is easy.
|
||||
- Firefly runs on your own server, so you are fully in control of your data. Remember, there is no such thing as "the cloud", it’s just somebody else’s computer!
|
||||
- Firefly has lots of features without becoming fancy or bloated.
|
||||
- If you feel you're missing something you can just ask me and I'll add it!
|
||||
|
||||
Firefly is pretty awesome. [You can read more about Firefly III, and its features, on the Github Pages](https://jc5.github.io/firefly-iii/).
|
||||
|
||||
#### About the name (should you care)
|
||||
|
||||
It's III, or 3, because [version 2](https://github.com/JC5/Firefly) and version 1 (not online) preceded it. It has been growing steadily ever since.
|
||||
|
||||
## Current features
|
||||
|
||||
- [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system);
|
||||
- You can store, edit and remove [withdrawals, deposits and transfers](https://en.wikipedia.org/wiki/Financial_transaction). This allows you full financial management;
|
||||
- You can manage different types of accounts;
|
||||
- [Asset](https://en.wikipedia.org/wiki/Asset) accounts
|
||||
- Shared [asset accounts](https://en.wikipedia.org/wiki/Asset) ([household accounts](https://en.wikipedia.org/wiki/Household))
|
||||
- Saving accounts
|
||||
- Credit cards
|
||||
- It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_;
|
||||
- Organize transactions using categories;
|
||||
- Save towards a goal using [piggy banks](https://en.wikipedia.org/wiki/Piggy_bank);
|
||||
- Predict and anticipate [bills](https://en.wikipedia.org/wiki/Invoice);
|
||||
- View income / expense [reports](https://en.wikipedia.org/wiki/Financial_statement);
|
||||
- Organize expenses using tags;
|
||||
- Lots of help text in case you don't get it.
|
||||
|
||||
Everything is organised:
|
||||
|
||||
- Clear views that should show you how you're doing;
|
||||
- Easy navigation through your records;
|
||||
- Browse back and forth to see previous months or even years;
|
||||
- Lots of charts because we all love them;
|
||||
- Financial reporting showing you how well you are doing.
|
||||
|
||||
## Screenshots
|
||||
|
||||
_Please note that everything in these screenshots is fictional and may not be realistic._
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Running and installing
|
||||
|
||||
If you're still interested please read [the installation guide](https://github.com/JC5/firefly-iii/wiki/Installation),
|
||||
[the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable)
|
||||
and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**.
|
||||
|
||||
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
|
||||
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. Accounts on the demo sites will stop working after one month. It's a trial.
|
||||
|
||||
## Security
|
||||
|
||||
You should always run Firefly III on a site with TLS enabled (https://). Please note that although some parts of the
|
||||
database are encrypted (transaction descriptions, names, etc.) some parts are _not_ (amounts, dates, etc). If you need
|
||||
more security, you must enable transparent database encryption or a comparable technology. Please remember that this
|
||||
is open source software under active development, and it is in no way guaranteed to be safe or secure.
|
||||
|
||||
## Translations
|
||||
|
||||
Firefly III is currently available in Dutch and English. Support for other languages is being worked on. I can use
|
||||
your help. Checkout [Crowdin](https://crowdin.com/project/firefly-iii) for more information.
|
||||
|
||||
## Credits
|
||||
|
||||
Firefly III uses the following libraries and tools:
|
||||
|
||||
* The AdminLTE template by [Almsaseed Studio](https://almsaeedstudio.com/)
|
||||
* The [Google charts](https://developers.google.com/chart/) library.
|
||||
* [Chart.js](http://www.chartjs.org/)
|
||||
* [Bootstrap](http://getbootstrap.com/)
|
||||
* [Laravel](http://laravel.com/)
|
||||
* [Twig](http://twig.sensiolabs.org/)
|
||||
* For development, some of the excellent tools made by [Barry van den Heuvel](https://github.com/barryvdh)
|
||||
* [Bootstrap sortable](https://github.com/drvic10k/bootstrap-sortable) by [Matúš Brliť](https://github.com/drvic10k).
|
||||
* [Date range picker](https://github.com/dangrossman/bootstrap-daterangepicker/) by [Dan Grossman](https://github.com/dangrossman)
|
||||
* The [real favicon generator](http://realfavicongenerator.net/)
|
||||
* Various other open source components (see [composer.json](https://github.com/JC5/firefly-iii/blob/master/composer.json))
|
||||
|
||||
|
||||
## Current state
|
||||
|
||||
Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. Translations are a work in progress.
|
||||
|
||||
Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
|
||||
If you like this tool, feel free to [donate me some beer money](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2ZMV952UUSCLU&lc=NL&item_name=Development%20of%20Firefly¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted).
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||

|
||||
If you want to contact me, please open an issue or [email me](mailto:thegrumpydictator@gmail.com).
|
45
app/Bootstrap/ConfigureLogging.php
Normal file
45
app/Bootstrap/ConfigureLogging.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* ConfigureLogging.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Bootstrap;
|
||||
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Foundation\Bootstrap\ConfigureLogging as IlluminateConfigureLogging;
|
||||
use Illuminate\Log\Writer;
|
||||
|
||||
/**
|
||||
* Class ConfigureLogging
|
||||
*
|
||||
* @package FireflyIII\Bootstrap
|
||||
*/
|
||||
class ConfigureLogging extends IlluminateConfigureLogging
|
||||
{
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param Writer $log
|
||||
*/
|
||||
protected function configureDailyHandler(Application $app, Writer $log)
|
||||
{
|
||||
$log->useDailyFiles(
|
||||
$app->storagePath() . '/logs/firefly-iii.log',
|
||||
$app->make('config')->get('app.log_max_files', 5)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param Writer $log
|
||||
*/
|
||||
protected function configureSingleHandler(Application $app, Writer $log)
|
||||
{
|
||||
$log->useFiles($app->storagePath() . '/logs/firefly-iii.log');
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
<?php namespace FireflyIII\Commands;
|
||||
/**
|
||||
* Class Command
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Commands
|
||||
*/
|
||||
abstract class Command
|
||||
{
|
||||
|
||||
|
||||
}
|
76
app/Console/Commands/UpgradeFireflyInstructions.php
Normal file
76
app/Console/Commands/UpgradeFireflyInstructions.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* UpgradeFireflyInstructions.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeFireflyInstructions
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class UpgradeFireflyInstructions extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:upgrade-instructions';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//
|
||||
/** @var string $version */
|
||||
$version = config('firefly.version');
|
||||
$config = config('upgrade.text');
|
||||
$text = $config[$version] ?? null;
|
||||
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
$this->line('');
|
||||
|
||||
if (is_null($text)) {
|
||||
$this->line('Thank you for installing Firefly III, v' . $version);
|
||||
$this->line('If you are upgrading from a previous version,');
|
||||
$this->info('there are no extra upgrade instructions.');
|
||||
$this->line('Firefly III should be ready for use.');
|
||||
} else {
|
||||
$this->line('Thank you for installing Firefly III, v' . $version);
|
||||
$this->line('If you are upgrading from a previous version,');
|
||||
$this->line('please follow these upgrade instructions carefully:');
|
||||
$this->info(wordwrap($text));
|
||||
}
|
||||
|
||||
$this->line('');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
}
|
||||
}
|
307
app/Console/Commands/VerifyDatabase.php
Normal file
307
app/Console/Commands/VerifyDatabase.php
Normal file
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* VerifyDatabase.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Crypt;
|
||||
use DB;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class VerifyDatabase
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class VerifyDatabase extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Will verify your database.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:verify';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// accounts with no transactions.
|
||||
$this->reportAccounts();
|
||||
// budgets with no limits
|
||||
$this->reportBudgetLimits();
|
||||
// budgets with no transactions
|
||||
$this->reportBudgets();
|
||||
// categories with no transactions
|
||||
$this->reportCategories();
|
||||
// tags with no transactions
|
||||
$this->reportTags();
|
||||
// sum of transactions is not zero.
|
||||
$this->reportSum();
|
||||
// any deleted transaction journals that have transactions that are NOT deleted:
|
||||
$this->reportJournals();
|
||||
// deleted transactions that are connected to a not deleted journal.
|
||||
$this->reportTransactions();
|
||||
// deleted accounts that still have not deleted transactions or journals attached to them.
|
||||
$this->reportDeletedAccounts();
|
||||
|
||||
// report on journals with no transactions at all.
|
||||
$this->reportNoTransactions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on accounts with no transactions.
|
||||
*/
|
||||
private function reportAccounts()
|
||||
{
|
||||
$set = Account
|
||||
::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
|
||||
->groupBy('accounts.id')
|
||||
->having('transaction_count', '=', 0)
|
||||
->get(['accounts.id', 'accounts.name', 'accounts.user_id', 'users.email', DB::raw('COUNT(`transactions`.`id`) AS `transaction_count`')]);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$line = 'User #' . $entry->user_id . ' (' . $entry->email . ') has account #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
|
||||
. '") which has no transactions.';
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on budgets with no budget limits (which makes them pointless).
|
||||
*/
|
||||
private function reportBudgetLimits()
|
||||
{
|
||||
$set = Budget
|
||||
::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
|
||||
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
|
||||
->groupBy('budgets.id')
|
||||
->having('budget_limit_count', '=', 0)
|
||||
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email', DB::raw('COUNT(`budget_limits`.`id`) AS `budget_limit_count`')]);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has budget #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
|
||||
. '") which has no budget limits.';
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on budgets without any transactions.
|
||||
*/
|
||||
private function reportBudgets()
|
||||
{
|
||||
$set = Budget
|
||||
::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull('budget_transaction_journal.budget_id')
|
||||
->whereNull('budgets.deleted_at')
|
||||
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has budget #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
|
||||
. '") which has no transactions.';
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on categories without any transactions.
|
||||
*/
|
||||
private function reportCategories()
|
||||
{
|
||||
$set = Category
|
||||
::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')
|
||||
->leftJoin('users', 'categories.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull('category_transaction_journal.category_id')
|
||||
->whereNull('categories.deleted_at')
|
||||
->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has category #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
|
||||
. '") which has no transactions.';
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on deleted accounts that still have not deleted transactions or journals attached to them.
|
||||
*/
|
||||
private function reportDeletedAccounts()
|
||||
{
|
||||
$set = Account
|
||||
::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->whereNotNull('accounts.deleted_at')
|
||||
->whereNotNull('transactions.id')
|
||||
->where(
|
||||
function (Builder $q) {
|
||||
$q->whereNull('transactions.deleted_at');
|
||||
$q->orWhereNull('transaction_journals.deleted_at');
|
||||
}
|
||||
)
|
||||
->get(
|
||||
['accounts.id as account_id', 'accounts.deleted_at as account_deleted_at', 'transactions.id as transaction_id',
|
||||
'transactions.deleted_at as transaction_deleted_at', 'transaction_journals.id as journal_id',
|
||||
'transaction_journals.deleted_at as journal_deleted_at']
|
||||
);
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$date = is_null($entry->transaction_deleted_at) ? $entry->journal_deleted_at : $entry->transaction_deleted_at;
|
||||
$this->error(
|
||||
'Error: Account #' . $entry->account_id . ' should have been deleted, but has not.' .
|
||||
' Find it in the table called `accounts` and change the `deleted_at` field to: "' . $date . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Any deleted transaction journals that have transactions that are NOT deleted:
|
||||
*/
|
||||
private function reportJournals()
|
||||
{
|
||||
$set = TransactionJournal
|
||||
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNotNull('transaction_journals.deleted_at')// USE THIS
|
||||
->whereNull('transactions.deleted_at')
|
||||
->whereNotNull('transactions.id')
|
||||
->get(
|
||||
[
|
||||
'transaction_journals.id as journal_id',
|
||||
'transaction_journals.description',
|
||||
'transaction_journals.deleted_at as journal_deleted',
|
||||
'transactions.id as transaction_id',
|
||||
'transactions.deleted_at as transaction_deleted_at']
|
||||
);
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$this->error(
|
||||
'Error: Transaction #' . $entry->transaction_id . ' should have been deleted, but has not.' .
|
||||
' Find it in the table called `transactions` and change the `deleted_at` field to: "' . $entry->journal_deleted . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function reportNoTransactions()
|
||||
{
|
||||
/*
|
||||
* select transaction_journals.id, count(transactions.id) as transaction_count from transaction_journals
|
||||
left join transactions ON transaction_journals.id = transactions.transaction_journal_id
|
||||
group by transaction_journals.id
|
||||
having transaction_count = 0
|
||||
*/
|
||||
$set = TransactionJournal
|
||||
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->groupBy('transaction_journals.id')
|
||||
->having('transaction_count', '=', 0)
|
||||
->get(['transaction_journals.id', DB::raw('COUNT(`transactions`.`id`) as `transaction_count`')]);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$this->error(
|
||||
'Error: Journal #' . $entry->id . ' has zero transactions. Open table `transaction_journals` and delete the entry with id #' . $entry->id
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports for each user when the sum of their transactions is not zero.
|
||||
*/
|
||||
private function reportSum()
|
||||
{
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($userRepository->all() as $user) {
|
||||
$sum = strval($user->transactions()->sum('amount'));
|
||||
if (bccomp($sum, '0') !== 0) {
|
||||
$this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on tags without any transactions.
|
||||
*/
|
||||
private function reportTags()
|
||||
{
|
||||
$set = Tag
|
||||
::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
|
||||
->leftJoin('users', 'tags.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull('tag_transaction_journal.tag_id')
|
||||
->whereNull('tags.deleted_at')
|
||||
->get(['tags.id', 'tags.tag', 'tags.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has tag #' . $entry->id . ' ("' . $entry->tag
|
||||
. '") which has no transactions.';
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports on deleted transactions that are connected to a not deleted journal.
|
||||
*/
|
||||
private function reportTransactions()
|
||||
{
|
||||
$set = Transaction
|
||||
::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNotNull('transactions.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->get(
|
||||
['transactions.id as transaction_id', 'transactions.deleted_at as transaction_deleted', 'transaction_journals.id as journal_id',
|
||||
'transaction_journals.deleted_at']
|
||||
);
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$this->error(
|
||||
'Error: Transaction journal #' . $entry->journal_id . ' should have been deleted, but has not.' .
|
||||
' Find it in the table called `transaction_journals` and change the `deleted_at` field to: "' . $entry->transaction_deleted . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,17 +1,47 @@
|
||||
<?php namespace FireflyIII\Console;
|
||||
<?php
|
||||
/**
|
||||
* Kernel.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console;
|
||||
|
||||
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
|
||||
use FireflyIII\Console\Commands\VerifyDatabase;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
/**
|
||||
* Class Kernel
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Console
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The bootstrap classes for the application.
|
||||
*
|
||||
* This needs to be for with the next upgrade.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $bootstrappers
|
||||
= [
|
||||
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
|
||||
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
|
||||
'FireflyIII\Bootstrap\ConfigureLogging',
|
||||
'Illuminate\Foundation\Bootstrap\HandleExceptions',
|
||||
'Illuminate\Foundation\Bootstrap\RegisterFacades',
|
||||
'Illuminate\Foundation\Bootstrap\SetRequestForConsole',
|
||||
'Illuminate\Foundation\Bootstrap\RegisterProviders',
|
||||
'Illuminate\Foundation\Bootstrap\BootProviders',
|
||||
];
|
||||
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
@@ -19,19 +49,7 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected $commands
|
||||
= [
|
||||
UpgradeFireflyInstructions::class,
|
||||
VerifyDatabase::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
421
app/Crud/Account/AccountCrud.php
Normal file
421
app/Crud/Account/AccountCrud.php
Normal file
@@ -0,0 +1,421 @@
|
||||
<?php
|
||||
/**
|
||||
* AccountCrud.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Crud\Account;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AccountCrud
|
||||
*
|
||||
* @package FireflyIII\Crud\Account
|
||||
*/
|
||||
class AccountCrud implements AccountCrudInterface
|
||||
{
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
/** @var array */
|
||||
private $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber'];
|
||||
|
||||
/**
|
||||
* AccountCrud constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Account $moveTo
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function destroy(Account $account, Account $moveTo = null): bool
|
||||
{
|
||||
if (!is_null($moveTo)) {
|
||||
// update all transactions:
|
||||
DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]);
|
||||
}
|
||||
|
||||
$account->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $accountId
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function find(int $accountId): Account
|
||||
{
|
||||
$account = $this->user->accounts()->find($accountId);
|
||||
if (is_null($account)) {
|
||||
$account = new Account;
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $accountIds
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccountsById(array $accountIds): Collection
|
||||
{
|
||||
/** @var Collection $result */
|
||||
$query = $this->user->accounts()->with(
|
||||
['accountmeta' => function (HasMany $query) {
|
||||
$query->where('name', 'accountRole');
|
||||
}]
|
||||
);
|
||||
|
||||
if (count($accountIds) > 0) {
|
||||
$query->whereIn('accounts.id', $accountIds);
|
||||
}
|
||||
|
||||
$result = $query->get(['accounts.*']);
|
||||
|
||||
$result = $result->sortBy(
|
||||
function (Account $account) {
|
||||
return strtolower($account->name);
|
||||
}
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccountsByType(array $types): Collection
|
||||
{
|
||||
/** @var Collection $result */
|
||||
$query = $this->user->accounts()->with(
|
||||
['accountmeta' => function (HasMany $query) {
|
||||
$query->where('name', 'accountRole');
|
||||
}]
|
||||
);
|
||||
if (count($types) > 0) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
|
||||
$result = $query->get(['accounts.*']);
|
||||
|
||||
$result = $result->sortBy(
|
||||
function (Account $account) {
|
||||
return strtolower($account->name);
|
||||
}
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function store(array $data): Account
|
||||
{
|
||||
$newAccount = $this->storeAccount($data);
|
||||
if (!is_null($newAccount)) {
|
||||
$this->storeMetadata($newAccount, $data);
|
||||
}
|
||||
|
||||
// continue with the opposing account:
|
||||
if ($data['openingBalance'] != 0) {
|
||||
$opposingData = [
|
||||
'user' => $data['user'],
|
||||
'accountType' => 'initial',
|
||||
'virtualBalance' => 0,
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
'iban' => '',
|
||||
];
|
||||
$opposing = $this->storeAccount($opposingData);
|
||||
if (!is_null($opposing) && !is_null($newAccount)) {
|
||||
$this->storeInitialBalance($newAccount, $opposing, $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $newAccount;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $account
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return AccountMeta
|
||||
*/
|
||||
public function storeMeta(Account $account, string $name, $value): AccountMeta
|
||||
{
|
||||
return AccountMeta::create(['name' => $name, 'data' => $value, 'account_id' => $account->id,]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function update(Account $account, array $data): Account
|
||||
{
|
||||
// update the account:
|
||||
$account->name = $data['name'];
|
||||
$account->active = $data['active'] == '1' ? true : false;
|
||||
$account->virtual_balance = $data['virtualBalance'];
|
||||
$account->iban = $data['iban'];
|
||||
$account->save();
|
||||
|
||||
$this->updateMetadata($account, $data);
|
||||
$openingBalance = $this->openingBalanceTransaction($account);
|
||||
if ($data['openingBalance'] != 0) {
|
||||
if (!is_null($openingBalance->id)) {
|
||||
$this->updateInitialBalance($account, $openingBalance, $data);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
$type = $data['openingBalance'] < 0 ? 'expense' : 'revenue';
|
||||
$opposingData = [
|
||||
'user' => $data['user'],
|
||||
'accountType' => $type,
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
'iban' => '',
|
||||
'virtualBalance' => 0,
|
||||
];
|
||||
$opposing = $this->storeAccount($opposingData);
|
||||
if (!is_null($opposing)) {
|
||||
$this->storeInitialBalance($account, $opposing, $data);
|
||||
}
|
||||
|
||||
return $account;
|
||||
|
||||
}
|
||||
|
||||
if ($openingBalance) { // opening balance is zero, should we delete it?
|
||||
$openingBalance->delete(); // delete existing opening balance.
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
protected function storeAccount(array $data): Account
|
||||
{
|
||||
$type = config('firefly.accountTypeByIdentifier.' . $data['accountType']);
|
||||
$accountType = AccountType::whereType($type)->first();
|
||||
$newAccount = new Account(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'account_type_id' => $accountType->id,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => $data['virtualBalance'],
|
||||
'active' => $data['active'] === true ? true : false,
|
||||
'iban' => $data['iban'],
|
||||
]
|
||||
);
|
||||
|
||||
if (!$newAccount->isValid()) {
|
||||
// does the account already exist?
|
||||
$searchData = [
|
||||
'user_id' => $data['user'],
|
||||
'account_type_id' => $accountType->id,
|
||||
'virtual_balance' => $data['virtualBalance'],
|
||||
'name' => $data['name'],
|
||||
'iban' => $data['iban'],
|
||||
];
|
||||
$existingAccount = Account::firstOrNullEncrypted($searchData);
|
||||
if (!$existingAccount) {
|
||||
Log::error('Account create error: ' . $newAccount->getErrors()->toJson());
|
||||
abort(500);
|
||||
}
|
||||
$newAccount = $existingAccount;
|
||||
|
||||
}
|
||||
$newAccount->save();
|
||||
|
||||
return $newAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Account $opposing
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
protected function storeInitialBalance(Account $account, Account $opposing, array $data): TransactionJournal
|
||||
{
|
||||
$transactionType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'transaction_type_id' => $transactionType->id,
|
||||
'bill_id' => null,
|
||||
'transaction_currency_id' => $data['openingBalanceCurrency'],
|
||||
'description' => 'Initial balance for "' . $account->name . '"',
|
||||
'completed' => true,
|
||||
'date' => $data['openingBalanceDate'],
|
||||
'encrypted' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$firstAccount = $account;
|
||||
$secondAccount = $opposing;
|
||||
$firstAmount = $data['openingBalance'];
|
||||
$secondAmount = $data['openingBalance'] * -1;
|
||||
|
||||
if ($data['openingBalance'] < 0) {
|
||||
$firstAccount = $opposing;
|
||||
$secondAccount = $account;
|
||||
$firstAmount = $data['openingBalance'] * -1;
|
||||
$secondAmount = $data['openingBalance'];
|
||||
}
|
||||
|
||||
$one = new Transaction(['account_id' => $firstAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $firstAmount]);
|
||||
$one->save();// first transaction: from
|
||||
|
||||
$two = new Transaction(['account_id' => $secondAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $secondAmount]);
|
||||
$two->save(); // second transaction: to
|
||||
|
||||
return $journal;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
protected function storeMetadata(Account $account, array $data)
|
||||
{
|
||||
foreach ($this->validFields as $field) {
|
||||
if (isset($data[$field])) {
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => $field,
|
||||
'data' => $data[$field],
|
||||
]
|
||||
);
|
||||
$metaData->save();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
protected function updateInitialBalance(Account $account, TransactionJournal $journal, array $data): TransactionJournal
|
||||
{
|
||||
$journal->date = $data['openingBalanceDate'];
|
||||
$journal->save();
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
if ($account->id == $transaction->account_id) {
|
||||
$transaction->amount = $data['openingBalance'];
|
||||
$transaction->save();
|
||||
}
|
||||
if ($account->id != $transaction->account_id) {
|
||||
$transaction->amount = $data['openingBalance'] * -1;
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
*/
|
||||
protected function updateMetadata(Account $account, array $data)
|
||||
{
|
||||
foreach ($this->validFields as $field) {
|
||||
$entry = $account->accountMeta()->where('name', $field)->first();
|
||||
|
||||
if (isset($data[$field])) {
|
||||
// update if new data is present:
|
||||
if (!is_null($entry)) {
|
||||
$entry->data = $data[$field];
|
||||
$entry->save();
|
||||
|
||||
continue;
|
||||
}
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => $field,
|
||||
'data' => $data[$field],
|
||||
]
|
||||
);
|
||||
$metaData->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return TransactionJournal|null
|
||||
*/
|
||||
private function openingBalanceTransaction(Account $account): TransactionJournal
|
||||
{
|
||||
$journal = TransactionJournal
|
||||
::sortCorrectly()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->transactionTypes([TransactionType::OPENING_BALANCE])
|
||||
->first(['transaction_journals.*']);
|
||||
if (is_null($journal)) {
|
||||
return new TransactionJournal;
|
||||
}
|
||||
|
||||
return $journal;
|
||||
}
|
||||
}
|
78
app/Crud/Account/AccountCrudInterface.php
Normal file
78
app/Crud/Account/AccountCrudInterface.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* AccountCrudInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Crud\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface AccountCrudInterface
|
||||
*
|
||||
* @package FireflyIII\Crud\Account
|
||||
*/
|
||||
interface AccountCrudInterface
|
||||
{
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Account $moveTo
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function destroy(Account $account, Account $moveTo): bool;
|
||||
|
||||
/**
|
||||
* @param int $accountId
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function find(int $accountId): Account;
|
||||
|
||||
/**
|
||||
* @param array $accountIds
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccountsById(array $accountIds): Collection;
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccountsByType(array $types): Collection;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function store(array $data) : Account;
|
||||
|
||||
/**
|
||||
* @param $account
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return AccountMeta
|
||||
*/
|
||||
public function storeMeta(Account $account, string $name, $value): AccountMeta;
|
||||
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function update(Account $account, array $data): Account;
|
||||
}
|
218
app/Crud/Split/Journal.php
Normal file
218
app/Crud/Split/Journal.php
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* Journal.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Crud\Split;
|
||||
|
||||
use FireflyIII\Events\TransactionStored;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class Journal
|
||||
*
|
||||
* @package FireflyIII\Crud\Split
|
||||
*/
|
||||
class Journal implements JournalInterface
|
||||
{
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* AttachmentRepository constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function markAsComplete(TransactionJournal $journal)
|
||||
{
|
||||
$journal->completed = 1;
|
||||
$journal->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function storeTransaction(TransactionJournal $journal, array $transaction): Collection
|
||||
{
|
||||
// store accounts (depends on type)
|
||||
list($sourceAccount, $destinationAccount) = $this->storeAccounts($journal->transactionType->type, $transaction);
|
||||
|
||||
// store transaction one way:
|
||||
/** @var Transaction $one */
|
||||
$one = Transaction::create(
|
||||
['account_id' => $sourceAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'] * -1,
|
||||
'description' => $transaction['description']]
|
||||
);
|
||||
$two = Transaction::create(
|
||||
['account_id' => $destinationAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'],
|
||||
'description' => $transaction['description']]
|
||||
);
|
||||
|
||||
if (strlen($transaction['category']) > 0) {
|
||||
$category = Category::firstOrCreateEncrypted(['name' => $transaction['category'], 'user_id' => $journal->user_id]);
|
||||
$one->categories()->save($category);
|
||||
$two->categories()->save($category);
|
||||
}
|
||||
if (intval($transaction['budget_id']) > 0) {
|
||||
$budget = Budget::find($transaction['budget_id']);
|
||||
$one->budgets()->save($budget);
|
||||
$two->budgets()->save($budget);
|
||||
}
|
||||
|
||||
if ($transaction['piggy_bank_id'] > 0) {
|
||||
$transaction['date'] = $journal->date->format('Y-m-d');
|
||||
event(new TransactionStored($transaction));
|
||||
}
|
||||
|
||||
return new Collection([$one, $two]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function updateJournal(TransactionJournal $journal, array $data): TransactionJournal
|
||||
{
|
||||
echo '<pre>';
|
||||
print_r($data);
|
||||
|
||||
$journal->description = $data['journal_description'];
|
||||
$journal->transaction_currency_id = $data['journal_currency_id'];
|
||||
$journal->date = $data['date'];
|
||||
$journal->interest_date = $data['interest_date'];
|
||||
$journal->book_date = $data['book_date'];
|
||||
$journal->process_date = $data['process_date'];
|
||||
$journal->save();
|
||||
|
||||
// delete original transactions, and recreate them.
|
||||
$journal->transactions()->delete();
|
||||
|
||||
foreach ($data['transactions'] as $transaction) {
|
||||
$this->storeTransaction($journal, $transaction);
|
||||
}
|
||||
|
||||
$journal->completed = true;
|
||||
$journal->save();
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function storeAccounts(string $type, array $transaction): array
|
||||
{
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
switch ($type) {
|
||||
case TransactionType::WITHDRAWAL:
|
||||
list($sourceAccount, $destinationAccount) = $this->storeWithdrawalAccounts($transaction);
|
||||
break;
|
||||
case TransactionType::DEPOSIT:
|
||||
list($sourceAccount, $destinationAccount) = $this->storeDepositAccounts($transaction);
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $transaction['source_account_id'])->first();
|
||||
$destinationAccount = Account::where('user_id', $this->user->id)->where('id', $transaction['destination_account_id'])->first();
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot handle ' . e($type));
|
||||
}
|
||||
|
||||
return [$sourceAccount, $destinationAccount];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function storeDepositAccounts(array $data): array
|
||||
{
|
||||
$destinationAccount = Account::where('user_id', $this->user->id)->where('id', $data['destination_account_id'])->first(['accounts.*']);
|
||||
|
||||
if (strlen($data['source_account_name']) > 0) {
|
||||
$sourceType = AccountType::where('type', 'Revenue account')->first();
|
||||
$sourceAccount = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => $data['source_account_name'], 'active' => 1]
|
||||
);
|
||||
|
||||
return [$sourceAccount, $destinationAccount];
|
||||
}
|
||||
|
||||
$sourceType = AccountType::where('type', 'Cash account')->first();
|
||||
$sourceAccount = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
);
|
||||
|
||||
return [$sourceAccount, $destinationAccount];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function storeWithdrawalAccounts(array $data): array
|
||||
{
|
||||
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $data['source_account_id'])->first(['accounts.*']);
|
||||
|
||||
if (strlen($data['destination_account_name']) > 0) {
|
||||
$destinationType = AccountType::where('type', 'Expense account')->first();
|
||||
$destinationAccount = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'account_type_id' => $destinationType->id,
|
||||
'name' => $data['destination_account_name'],
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
return [$sourceAccount, $destinationAccount];
|
||||
}
|
||||
$destinationType = AccountType::where('type', 'Cash account')->first();
|
||||
$destinationAccount = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $this->user->id, 'account_type_id' => $destinationType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
);
|
||||
|
||||
return [$sourceAccount, $destinationAccount];
|
||||
|
||||
|
||||
}
|
||||
}
|
47
app/Crud/Split/JournalInterface.php
Normal file
47
app/Crud/Split/JournalInterface.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* JournalInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Crud\Split;
|
||||
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface JournalInterface
|
||||
*
|
||||
* @package FireflyIII\Crud\Split
|
||||
*/
|
||||
interface JournalInterface
|
||||
{
|
||||
/**
|
||||
* @param $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function markAsComplete(TransactionJournal $journal);
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function storeTransaction(TransactionJournal $journal, array $transaction): Collection;
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function updateJournal(TransactionJournal $journal, array $data): TransactionJournal;
|
||||
}
|
48
app/Events/BudgetLimitStored.php
Normal file
48
app/Events/BudgetLimitStored.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLimitStored.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class BudgetLimitStored
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class BudgetLimitStored extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
/** @var BudgetLimit */
|
||||
public $budgetLimit;
|
||||
|
||||
/** @var Carbon */
|
||||
public $end; // the only variable we can't get from the budget limit (if necessary).
|
||||
|
||||
/**
|
||||
* BudgetLimitEvents constructor.
|
||||
*
|
||||
* @param BudgetLimit $budgetLimit
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function __construct(BudgetLimit $budgetLimit, Carbon $end)
|
||||
{
|
||||
//
|
||||
$this->budgetLimit = $budgetLimit;
|
||||
$this->end = $end;
|
||||
|
||||
}
|
||||
|
||||
}
|
48
app/Events/BudgetLimitUpdated.php
Normal file
48
app/Events/BudgetLimitUpdated.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLimitUpdated.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class BudgetLimitUpdated
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class BudgetLimitUpdated extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
/** @var BudgetLimit */
|
||||
public $budgetLimit;
|
||||
|
||||
/** @var Carbon */
|
||||
public $end; // the only variable we can't get from the budget limit (if necessary).
|
||||
|
||||
/**
|
||||
* BudgetLimitEvents constructor.
|
||||
*
|
||||
* @param BudgetLimit $budgetLimit
|
||||
* @param Carbon $end
|
||||
*/
|
||||
public function __construct(BudgetLimit $budgetLimit, Carbon $end)
|
||||
{
|
||||
//
|
||||
$this->budgetLimit = $budgetLimit;
|
||||
$this->end = $end;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,14 +1,21 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
<?php
|
||||
/**
|
||||
* Event.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
/**
|
||||
* Class Event
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
abstract class Event
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
|
@@ -1,34 +0,0 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalCreated
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalCreated extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $journal;
|
||||
public $piggyBankId;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
* @param $piggyBankId
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal, $piggyBankId)
|
||||
{
|
||||
//
|
||||
$this->journal = $journal;
|
||||
$this->piggyBankId = $piggyBankId;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalDeleted
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalDeleted extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
40
app/Events/ResendConfirmation.php
Normal file
40
app/Events/ResendConfirmation.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* ResendConfirmation.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class ResendConfirmation
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class ResendConfirmation extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $ipAddress;
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
||||
*/
|
||||
public function __construct(User $user, string $ipAddress)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->ipAddress = $ipAddress;
|
||||
}
|
||||
}
|
44
app/Events/TransactionJournalStored.php
Normal file
44
app/Events/TransactionJournalStored.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionJournalStored.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class TransactionJournalStored
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class TransactionJournalStored extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $journal;
|
||||
public $piggyBankId;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
* @param int $piggyBankId
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal, int $piggyBankId)
|
||||
{
|
||||
//
|
||||
$this->journal = $journal;
|
||||
$this->piggyBankId = $piggyBankId;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,15 +1,25 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
<?php
|
||||
/**
|
||||
* TransactionJournalUpdated.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalSaved
|
||||
* Class TransactionJournalUpdated
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalSaved extends Event
|
||||
class TransactionJournalUpdated extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
39
app/Events/TransactionStored.php
Normal file
39
app/Events/TransactionStored.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionStored.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class TransactionJournalStored
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class TransactionStored extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $transaction = [];
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param array $transaction
|
||||
*/
|
||||
public function __construct(array $transaction)
|
||||
{
|
||||
//
|
||||
$this->transaction = $transaction;
|
||||
}
|
||||
|
||||
}
|
40
app/Events/UserRegistration.php
Normal file
40
app/Events/UserRegistration.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* UserRegistration.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class UserRegistration
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class UserRegistration extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $ipAddress;
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
||||
*/
|
||||
public function __construct(User $user, string $ipAddress)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->ipAddress = $ipAddress;
|
||||
}
|
||||
}
|
@@ -1,12 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* FireflyException.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
||||
/**
|
||||
* Class FireflyException
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class FireflyException extends \Exception
|
||||
|
@@ -1,18 +1,32 @@
|
||||
<?php namespace FireflyIII\Exceptions;
|
||||
<?php
|
||||
/**
|
||||
* Handler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
use Auth;
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use FireflyIII\Jobs\MailError;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Request;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of the exception types that should not be reported.
|
||||
*
|
||||
@@ -20,40 +34,68 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
protected $dontReport
|
||||
= [
|
||||
'Symfony\Component\HttpKernel\Exception\HttpException'
|
||||
AuthorizationException::class,
|
||||
HttpException::class,
|
||||
ModelNotFoundException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
* @param \Exception $exception
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
public function render($request, Exception $exception)
|
||||
{
|
||||
if ($e instanceof HttpException) {
|
||||
return $this->renderHttpException($e);
|
||||
} else {
|
||||
return parent::render($request, $e);
|
||||
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
|
||||
|
||||
$isDebug = env('APP_DEBUG', false);
|
||||
|
||||
return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500);
|
||||
}
|
||||
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param Exception $exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $e)
|
||||
public function report(Exception $exception)
|
||||
{
|
||||
parent::report($e);
|
||||
}
|
||||
|
||||
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
|
||||
$userData = [
|
||||
'id' => 0,
|
||||
'email' => 'unknown@example.com',
|
||||
];
|
||||
if (Auth::check()) {
|
||||
$userData['id'] = Auth::user()->id;
|
||||
$userData['email'] = Auth::user()->email;
|
||||
}
|
||||
$data = [
|
||||
'class' => get_class($exception),
|
||||
'errorMessage' => $exception->getMessage(),
|
||||
'time' => date('r'),
|
||||
'stackTrace' => $exception->getTraceAsString(),
|
||||
'file' => $exception->getFile(),
|
||||
'line' => $exception->getLine(),
|
||||
'code' => $exception->getCode(),
|
||||
];
|
||||
|
||||
// create job that will mail.
|
||||
$job = new MailError($userData, env('SITE_OWNER'), Request::ip(), $data);
|
||||
dispatch($job);
|
||||
}
|
||||
|
||||
parent::report($exception);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* NotImplementedException.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
||||
/**
|
||||
* Class NotImplementedException
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class NotImplementedException extends \Exception
|
||||
|
@@ -1,10 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* ValidationException.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
/**
|
||||
* Class ValidationExceptions
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exception
|
||||
*/
|
||||
class ValidationException extends \Exception
|
||||
|
147
app/Export/Collector/AttachmentCollector.php
Normal file
147
app/Export/Collector/AttachmentCollector.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentCollector.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
use Amount;
|
||||
use Crypt;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Storage;
|
||||
|
||||
/**
|
||||
* Class AttachmentCollector
|
||||
*
|
||||
* @package FireflyIII\Export\Collector
|
||||
*/
|
||||
class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $explanationString = '';
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $exportDisk;
|
||||
/** @var AttachmentRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $uploadDisk;
|
||||
|
||||
/**
|
||||
* AttachmentCollector constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
/** @var AttachmentRepositoryInterface repository */
|
||||
$this->repository = app(AttachmentRepositoryInterface::class);
|
||||
// make storage:
|
||||
$this->uploadDisk = Storage::disk('upload');
|
||||
$this->exportDisk = Storage::disk('export');
|
||||
|
||||
parent::__construct($job);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool
|
||||
{
|
||||
// grab all the users attachments:
|
||||
$attachments = $this->getAttachments();
|
||||
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($attachments as $attachment) {
|
||||
$this->exportAttachment($attachment);
|
||||
}
|
||||
|
||||
// put the explanation string in a file and attach it as well.
|
||||
$file = $this->job->key . '-Source of all your attachments explained.txt';
|
||||
$this->exportDisk->put($file, $this->explanationString);
|
||||
$this->getFiles()->push($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*/
|
||||
private function explain(Attachment $attachment)
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $attachment->attachable;
|
||||
$args = [
|
||||
'attachment_name' => $attachment->filename,
|
||||
'attachment_id' => $attachment->id,
|
||||
'type' => strtolower($journal->transactionType->type),
|
||||
'description' => $journal->description,
|
||||
'journal_id' => $journal->id,
|
||||
'date' => $journal->date->formatLocalized(strval(trans('config.month_and_day'))),
|
||||
'amount' => Amount::formatJournal($journal, false),
|
||||
];
|
||||
$string = trans('firefly.attachment_explanation', $args) . "\n";
|
||||
$this->explanationString .= $string;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function exportAttachment(Attachment $attachment): bool
|
||||
{
|
||||
$file = $attachment->fileName();
|
||||
if ($this->uploadDisk->exists($file)) {
|
||||
try {
|
||||
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
|
||||
$exportFile = $this->exportFileName($attachment);
|
||||
$this->exportDisk->put($exportFile, $decrypted);
|
||||
$this->getFiles()->push($exportFile);
|
||||
|
||||
// explain:
|
||||
$this->explain($attachment);
|
||||
} catch (DecryptException $e) {
|
||||
Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new file name for the export file.
|
||||
*
|
||||
* @param $attachment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function exportFileName($attachment): string
|
||||
{
|
||||
|
||||
return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
private function getAttachments(): Collection
|
||||
{
|
||||
$attachments = $this->repository->get();
|
||||
|
||||
return $attachments;
|
||||
}
|
||||
}
|
58
app/Export/Collector/BasicCollector.php
Normal file
58
app/Export/Collector/BasicCollector.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* BasicCollector.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BasicCollector
|
||||
*
|
||||
* @package FireflyIII\Export\Collector
|
||||
*/
|
||||
class BasicCollector
|
||||
{
|
||||
/** @var ExportJob */
|
||||
protected $job;
|
||||
/** @var Collection */
|
||||
private $files;
|
||||
|
||||
/**
|
||||
* BasicCollector constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
$this->files = new Collection;
|
||||
$this->job = $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getFiles(): Collection
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $files
|
||||
*/
|
||||
public function setFiles(Collection $files)
|
||||
{
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
|
||||
}
|
39
app/Export/Collector/CollectorInterface.php
Normal file
39
app/Export/Collector/CollectorInterface.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* CollectorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface CollectorInterface
|
||||
*
|
||||
* @package FireflyIII\Export\Collector
|
||||
*/
|
||||
interface CollectorInterface
|
||||
{
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getFiles(): Collection;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool;
|
||||
|
||||
/**
|
||||
* @param Collection $files
|
||||
*
|
||||
*/
|
||||
public function setFiles(Collection $files);
|
||||
|
||||
}
|
118
app/Export/Collector/UploadCollector.php
Normal file
118
app/Export/Collector/UploadCollector.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* UploadCollector.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
use Auth;
|
||||
use Crypt;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Log;
|
||||
use Storage;
|
||||
|
||||
/**
|
||||
* Class UploadCollector
|
||||
*
|
||||
* @package FireflyIII\Export\Collector
|
||||
*/
|
||||
class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $expected;
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $exportDisk;
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $uploadDisk;
|
||||
|
||||
/**
|
||||
* AttachmentCollector constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
parent::__construct($job);
|
||||
|
||||
// make storage:
|
||||
$this->uploadDisk = Storage::disk('upload');
|
||||
$this->exportDisk = Storage::disk('export');
|
||||
$this->expected = 'csv-upload-' . Auth::user()->id . '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool
|
||||
{
|
||||
// grab upload directory.
|
||||
$files = $this->uploadDisk->files();
|
||||
|
||||
foreach ($files as $entry) {
|
||||
$this->processOldUpload($entry);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entry
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getOriginalUploadDate(string $entry): string
|
||||
{
|
||||
// this is an original upload.
|
||||
$parts = explode('-', str_replace(['.csv.encrypted', $this->expected], '', $entry));
|
||||
$originalUpload = intval($parts[1]);
|
||||
$date = date('Y-m-d \a\t H-i-s', $originalUpload);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entry
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidFile(string $entry): bool
|
||||
{
|
||||
$len = strlen($this->expected);
|
||||
if (substr($entry, 0, $len) === $this->expected) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $entry
|
||||
*/
|
||||
private function processOldUpload(string $entry)
|
||||
{
|
||||
$content = '';
|
||||
|
||||
if ($this->isValidFile($entry)) {
|
||||
try {
|
||||
$content = Crypt::decrypt($this->uploadDisk->get($entry));
|
||||
} catch (DecryptException $e) {
|
||||
Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
if (strlen($content) > 0) {
|
||||
// continue with file:
|
||||
$date = $this->getOriginalUploadDate($entry);
|
||||
$file = $this->job->key . '-Old CSV import dated ' . $date . '.csv';
|
||||
$this->exportDisk->put($file, $content);
|
||||
$this->getFiles()->push($file);
|
||||
}
|
||||
}
|
||||
}
|
66
app/Export/ConfigurationFile.php
Normal file
66
app/Export/ConfigurationFile.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* ConfigurationFile.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Storage;
|
||||
|
||||
/**
|
||||
* Class ConfigurationFile
|
||||
*
|
||||
* @package FireflyIII\Export
|
||||
*/
|
||||
class ConfigurationFile
|
||||
{
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $exportDisk;
|
||||
/** @var ExportJob */
|
||||
private $job;
|
||||
|
||||
/**
|
||||
* ConfigurationFile constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
$this->job = $job;
|
||||
$this->exportDisk = Storage::disk('export');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function make(): string
|
||||
{
|
||||
$fields = array_keys(Entry::getFieldsAndTypes());
|
||||
$types = Entry::getFieldsAndTypes();
|
||||
|
||||
$configuration = [
|
||||
'date-format' => 'Y-m-d', // unfortunately, this is hard-coded.
|
||||
'has-headers' => true,
|
||||
'map' => [], // we could build a map if necessary for easy re-import.
|
||||
'roles' => [],
|
||||
'mapped' => [],
|
||||
'specifix' => [],
|
||||
];
|
||||
foreach ($fields as $field) {
|
||||
$configuration['roles'][] = $types[$field];
|
||||
}
|
||||
$file = $this->job->key . '-configuration.json';
|
||||
$this->exportDisk->put($file, json_encode($configuration, JSON_PRETTY_PRINT));
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
}
|
130
app/Export/Entry/Entry.php
Normal file
130
app/Export/Entry/Entry.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* Entry.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Entry;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* To extend the exported object, in case of new features in Firefly III for example,
|
||||
* do the following:
|
||||
*
|
||||
* - Add the field(s) to this class. If you add more than one related field, add a new object.
|
||||
* - Make sure the "fromJournal"-routine fills these fields.
|
||||
* - Add them to the static function that returns its type (key=value. Remember that the only
|
||||
* valid types can be found in config/csv.php (under "roles").
|
||||
*
|
||||
* These new entries should be should be strings and numbers as much as possible.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Class Entry
|
||||
*
|
||||
* @package FireflyIII\Export\Entry
|
||||
*/
|
||||
final class Entry
|
||||
{
|
||||
/** @var string */
|
||||
public $amount;
|
||||
/** @var EntryBill */
|
||||
public $bill;
|
||||
/** @var EntryBudget */
|
||||
public $budget;
|
||||
/** @var EntryCategory */
|
||||
public $category;
|
||||
/** @var string */
|
||||
public $date;
|
||||
/** @var string */
|
||||
public $description;
|
||||
/** @var EntryAccount */
|
||||
public $destinationAccount;
|
||||
/** @var Collection */
|
||||
public $destinationAccounts;
|
||||
/** @var EntryAccount */
|
||||
public $sourceAccount;
|
||||
/** @var Collection */
|
||||
public $sourceAccounts;
|
||||
|
||||
/**
|
||||
* Entry constructor.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->sourceAccounts = new Collection;
|
||||
$this->destinationAccounts = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Entry
|
||||
*/
|
||||
public static function fromJournal(TransactionJournal $journal)
|
||||
{
|
||||
|
||||
$entry = new self;
|
||||
$entry->description = $journal->description;
|
||||
$entry->date = $journal->date->format('Y-m-d');
|
||||
$entry->amount = TransactionJournal::amount($journal);
|
||||
|
||||
$entry->budget = new EntryBudget($journal->budgets->first());
|
||||
$entry->category = new EntryCategory($journal->categories->first());
|
||||
$entry->bill = new EntryBill($journal->bill);
|
||||
|
||||
$sources = TransactionJournal::sourceAccountList($journal);
|
||||
$destinations = TransactionJournal::destinationAccountList($journal);
|
||||
$entry->sourceAccount = new EntryAccount($sources->first());
|
||||
$entry->destinationAccount = new EntryAccount($destinations->first());
|
||||
|
||||
foreach ($sources as $source) {
|
||||
$entry->sourceAccounts->push(new EntryAccount($source));
|
||||
}
|
||||
|
||||
foreach ($destinations as $destination) {
|
||||
$entry->destinationAccounts->push(new EntryAccount($destination));
|
||||
}
|
||||
|
||||
return $entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getFieldsAndTypes(): array
|
||||
{
|
||||
// key = field name (see top of class)
|
||||
// value = field type (see csv.php under 'roles')
|
||||
return [
|
||||
'description' => 'description',
|
||||
'amount' => 'amount',
|
||||
'date' => 'date-transaction',
|
||||
'source_account_id' => 'account-id',
|
||||
'source_account_name' => 'account-name',
|
||||
'source_account_iban' => 'account-iban',
|
||||
'source_account_type' => '_ignore',
|
||||
'source_account_number' => 'account-number',
|
||||
'destination_account_id' => 'opposing-id',
|
||||
'destination_account_name' => 'opposing-name',
|
||||
'destination_account_iban' => 'opposing-iban',
|
||||
'destination_account_type' => '_ignore',
|
||||
'destination_account_number' => 'account-number',
|
||||
'budget_id' => 'budget-id',
|
||||
'budget_name' => 'budget-name',
|
||||
'category_id' => 'category-id',
|
||||
'category_name' => 'category-name',
|
||||
'bill_id' => 'bill-id',
|
||||
'bill_name' => 'bill-name',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
47
app/Export/Entry/EntryAccount.php
Normal file
47
app/Export/Entry/EntryAccount.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryAccount.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Entry;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class EntryAccount
|
||||
*
|
||||
* @package FireflyIII\Export\Entry
|
||||
*/
|
||||
class EntryAccount
|
||||
{
|
||||
/** @var int */
|
||||
public $accountId;
|
||||
/** @var string */
|
||||
public $iban;
|
||||
/** @var string */
|
||||
public $name;
|
||||
/** @var string */
|
||||
public $number;
|
||||
/** @var string */
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* EntryAccount constructor.
|
||||
*
|
||||
* @param Account $account
|
||||
*/
|
||||
public function __construct(Account $account)
|
||||
{
|
||||
$this->accountId = $account->id;
|
||||
$this->name = $account->name;
|
||||
$this->iban = $account->iban;
|
||||
$this->type = $account->accountType->type;
|
||||
$this->number = $account->getMeta('accountNumber');
|
||||
}
|
||||
}
|
41
app/Export/Entry/EntryBill.php
Normal file
41
app/Export/Entry/EntryBill.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryBill.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Entry;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
|
||||
/**
|
||||
* Class EntryBill
|
||||
*
|
||||
* @package FireflyIII\Export\Entry
|
||||
*/
|
||||
class EntryBill
|
||||
{
|
||||
/** @var int */
|
||||
public $billId = '';
|
||||
/** @var string */
|
||||
public $name = '';
|
||||
|
||||
/**
|
||||
* EntryBill constructor.
|
||||
*
|
||||
* @param Bill $bill
|
||||
*/
|
||||
public function __construct(Bill $bill = null)
|
||||
{
|
||||
if (!is_null($bill)) {
|
||||
$this->billId = $bill->id;
|
||||
$this->name = $bill->name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
41
app/Export/Entry/EntryBudget.php
Normal file
41
app/Export/Entry/EntryBudget.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryBudget.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Entry;
|
||||
|
||||
use FireflyIII\Models\Budget;
|
||||
|
||||
/**
|
||||
* Class EntryBudget
|
||||
*
|
||||
* @package FireflyIII\Export\Entry
|
||||
*/
|
||||
class EntryBudget
|
||||
{
|
||||
/** @var int */
|
||||
public $budgetId = '';
|
||||
/** @var string */
|
||||
public $name = '';
|
||||
|
||||
/**
|
||||
* EntryBudget constructor.
|
||||
*
|
||||
* @param Budget $budget
|
||||
*/
|
||||
public function __construct(Budget $budget = null)
|
||||
{
|
||||
if (!is_null($budget)) {
|
||||
$this->budgetId = $budget->id;
|
||||
$this->name = $budget->name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
40
app/Export/Entry/EntryCategory.php
Normal file
40
app/Export/Entry/EntryCategory.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryCategory.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Entry;
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
/**
|
||||
* Class EntryCategory
|
||||
*
|
||||
* @package FireflyIII\Export\Entry
|
||||
*/
|
||||
class EntryCategory
|
||||
{
|
||||
/** @var int */
|
||||
public $categoryId = '';
|
||||
/** @var string */
|
||||
public $name = '';
|
||||
|
||||
/**
|
||||
* EntryCategory constructor.
|
||||
*
|
||||
* @param Category $category
|
||||
*/
|
||||
public function __construct(Category $category = null)
|
||||
{
|
||||
if (!is_null($category)) {
|
||||
$this->categoryId = $category->id;
|
||||
$this->name = $category->name;
|
||||
}
|
||||
}
|
||||
}
|
57
app/Export/Exporter/BasicExporter.php
Normal file
57
app/Export/Exporter/BasicExporter.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* BasicExporter.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BasicExporter
|
||||
*
|
||||
* @package FireflyIII\Export\Exporter
|
||||
*/
|
||||
class BasicExporter
|
||||
{
|
||||
/** @var ExportJob */
|
||||
protected $job;
|
||||
private $entries;
|
||||
|
||||
/**
|
||||
* BasicExporter constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
$this->entries = new Collection;
|
||||
$this->job = $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEntries(): Collection
|
||||
{
|
||||
return $this->entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*/
|
||||
public function setEntries(Collection $entries)
|
||||
{
|
||||
$this->entries = $entries;
|
||||
}
|
||||
|
||||
|
||||
}
|
172
app/Export/Exporter/CsvExporter.php
Normal file
172
app/Export/Exporter/CsvExporter.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/**
|
||||
* CsvExporter.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Export\Entry\EntryAccount;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Csv\Writer;
|
||||
use SplFileObject;
|
||||
|
||||
/**
|
||||
* Class CsvExporter
|
||||
*
|
||||
* @package FireflyIII\Export\Exporter
|
||||
*/
|
||||
class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $fileName;
|
||||
|
||||
/**
|
||||
* CsvExporter constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
parent::__construct($job);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName(): string
|
||||
{
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool
|
||||
{
|
||||
// create temporary file:
|
||||
$this->tempFile();
|
||||
|
||||
// necessary for CSV writer:
|
||||
$fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName;
|
||||
$writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
|
||||
$rows = [];
|
||||
|
||||
// Count the maximum number of sources and destinations each entry has. May need to expand the number of export fields:
|
||||
$maxSourceAccounts = 1;
|
||||
$maxDestAccounts = 1;
|
||||
/** @var Entry $entry */
|
||||
foreach ($this->getEntries() as $entry) {
|
||||
$sources = $entry->sourceAccounts->count();
|
||||
$destinations = $entry->destinationAccounts->count();
|
||||
$maxSourceAccounts = max($maxSourceAccounts, $sources);
|
||||
$maxDestAccounts = max($maxDestAccounts, $destinations);
|
||||
}
|
||||
$rows[] = array_keys($this->getFieldsAndTypes($maxSourceAccounts, $maxDestAccounts));
|
||||
|
||||
/** @var Entry $entry */
|
||||
foreach ($this->getEntries() as $entry) {
|
||||
// order is defined in Entry::getFieldsAndTypes.
|
||||
$current = [$entry->description, $entry->amount, $entry->date];
|
||||
$sourceData = $this->getAccountData($maxSourceAccounts, $entry->sourceAccounts);
|
||||
$current = array_merge($current, $sourceData);
|
||||
$destData = $this->getAccountData($maxDestAccounts, $entry->destinationAccounts);
|
||||
$current = array_merge($current, $destData);
|
||||
$rest = [$entry->budget->budgetId, $entry->budget->name, $entry->category->categoryId, $entry->category->name, $entry->bill->billId,
|
||||
$entry->bill->name];
|
||||
$current = array_merge($current, $rest);
|
||||
$rows[] = $current;
|
||||
}
|
||||
$writer->insertAll($rows);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $max
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAccountData(int $max, Collection $accounts): array
|
||||
{
|
||||
$current = [];
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
/** @var EntryAccount $source */
|
||||
$source = $accounts->get($i);
|
||||
$currentId = '';
|
||||
$currentName = '';
|
||||
$currentIban = '';
|
||||
$currentType = '';
|
||||
$currentNumber = '';
|
||||
if ($source) {
|
||||
$currentId = $source->accountId;
|
||||
$currentName = $source->name;
|
||||
$currentIban = $source->iban;
|
||||
$currentType = $source->type;
|
||||
$currentNumber = $source->number;
|
||||
}
|
||||
$current[] = $currentId;
|
||||
$current[] = $currentName;
|
||||
$current[] = $currentIban;
|
||||
$current[] = $currentType;
|
||||
$current[] = $currentNumber;
|
||||
}
|
||||
unset($source);
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $sources
|
||||
* @param int $destinations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getFieldsAndTypes(int $sources, int $destinations): array
|
||||
{
|
||||
// key = field name (see top of class)
|
||||
// value = field type (see csv.php under 'roles')
|
||||
$array = [
|
||||
'description' => 'description',
|
||||
'amount' => 'amount',
|
||||
'date' => 'date-transaction',
|
||||
];
|
||||
for ($i = 0; $i < $sources; $i++) {
|
||||
$array['source_account_' . $i . '_id'] = 'account-id';
|
||||
$array['source_account_' . $i . '_name'] = 'account-name';
|
||||
$array['source_account_' . $i . '_iban'] = 'account-iban';
|
||||
$array['source_account_' . $i . '_type'] = '_ignore';
|
||||
$array['source_account_' . $i . '_number'] = 'account-number';
|
||||
}
|
||||
for ($i = 0; $i < $destinations; $i++) {
|
||||
$array['destination_account_' . $i . '_id'] = 'account-id';
|
||||
$array['destination_account_' . $i . '_name'] = 'account-name';
|
||||
$array['destination_account_' . $i . '_iban'] = 'account-iban';
|
||||
$array['destination_account_' . $i . '_type'] = '_ignore';
|
||||
$array['destination_account_' . $i . '_number'] = 'account-number';
|
||||
}
|
||||
|
||||
$array['budget_id'] = 'budget-id';
|
||||
$array['budget_name'] = 'budget-name';
|
||||
$array['category_id'] = 'category-id';
|
||||
$array['category_name'] = 'category-name';
|
||||
$array['bill_id'] = 'bill-id';
|
||||
$array['bill_name'] = 'bill-name';
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
private function tempFile()
|
||||
{
|
||||
$this->fileName = $this->job->key . '-records.csv';
|
||||
}
|
||||
}
|
44
app/Export/Exporter/ExporterInterface.php
Normal file
44
app/Export/Exporter/ExporterInterface.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* ExporterInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ExporterInterface
|
||||
*
|
||||
* @package FireflyIII\Export\Exporter
|
||||
*/
|
||||
interface ExporterInterface
|
||||
{
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEntries(): Collection;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName(): string;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
*/
|
||||
public function setEntries(Collection $entries);
|
||||
|
||||
}
|
203
app/Export/Processor.php
Normal file
203
app/Export/Processor.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Processor.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Export\Collector\AttachmentCollector;
|
||||
use FireflyIII\Export\Collector\UploadCollector;
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Support\Collection;
|
||||
use Storage;
|
||||
use ZipArchive;
|
||||
|
||||
/**
|
||||
* Class Processor
|
||||
*
|
||||
* @package FireflyIII\Export
|
||||
*/
|
||||
class Processor
|
||||
{
|
||||
|
||||
/** @var Collection */
|
||||
public $accounts;
|
||||
/** @var string */
|
||||
public $exportFormat;
|
||||
/** @var bool */
|
||||
public $includeAttachments;
|
||||
/** @var bool */
|
||||
public $includeConfig;
|
||||
/** @var bool */
|
||||
public $includeOldUploads;
|
||||
/** @var ExportJob */
|
||||
public $job;
|
||||
/** @var array */
|
||||
public $settings;
|
||||
/** @var \FireflyIII\Export\ConfigurationFile */
|
||||
private $configurationMaker;
|
||||
/** @var Collection */
|
||||
private $exportEntries;
|
||||
/** @var Collection */
|
||||
private $files;
|
||||
/** @var Collection */
|
||||
private $journals;
|
||||
|
||||
/**
|
||||
* Processor constructor.
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct(array $settings)
|
||||
{
|
||||
// save settings
|
||||
$this->settings = $settings;
|
||||
$this->accounts = $settings['accounts'];
|
||||
$this->exportFormat = $settings['exportFormat'];
|
||||
$this->includeAttachments = $settings['includeAttachments'];
|
||||
$this->includeConfig = $settings['includeConfig'];
|
||||
$this->includeOldUploads = $settings['includeOldUploads'];
|
||||
$this->job = $settings['job'];
|
||||
$this->journals = new Collection;
|
||||
$this->exportEntries = new Collection;
|
||||
$this->files = new Collection;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function collectAttachments(): bool
|
||||
{
|
||||
/** @var AttachmentCollector $attachmentCollector */
|
||||
$attachmentCollector = app(AttachmentCollector::class, [$this->job]);
|
||||
$attachmentCollector->run();
|
||||
$this->files = $this->files->merge($attachmentCollector->getFiles());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function collectJournals(): bool
|
||||
{
|
||||
/** @var JournalRepositoryInterface $repository */
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
$this->journals = $repository->getJournalsInRange($this->accounts, $this->settings['startDate'], $this->settings['endDate']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function collectOldUploads(): bool
|
||||
{
|
||||
/** @var UploadCollector $uploadCollector */
|
||||
$uploadCollector = app(UploadCollector::class, [$this->job]);
|
||||
$uploadCollector->run();
|
||||
|
||||
$this->files = $this->files->merge($uploadCollector->getFiles());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function convertJournals(): bool
|
||||
{
|
||||
$count = 0;
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($this->journals as $journal) {
|
||||
$this->exportEntries->push(Entry::fromJournal($journal));
|
||||
$count++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function createConfigFile(): bool
|
||||
{
|
||||
$this->configurationMaker = app(ConfigurationFile::class, [$this->job]);
|
||||
$this->files->push($this->configurationMaker->make());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function createZipFile(): bool
|
||||
{
|
||||
$zip = new ZipArchive;
|
||||
$file = $this->job->key . '.zip';
|
||||
$fullPath = storage_path('export') . '/' . $file;
|
||||
|
||||
if ($zip->open($fullPath, ZipArchive::CREATE) !== true) {
|
||||
throw new FireflyException('Cannot store zip file.');
|
||||
}
|
||||
// for each file in the collection, add it to the zip file.
|
||||
$disk = Storage::disk('export');
|
||||
foreach ($this->getFiles() as $entry) {
|
||||
// is part of this job?
|
||||
$zipFileName = str_replace($this->job->key . '-', '', $entry);
|
||||
$zip->addFromString($zipFileName, $disk->get($entry));
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
// delete the files:
|
||||
$this->deleteFiles($disk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function exportJournals(): bool
|
||||
{
|
||||
$exporterClass = config('firefly.export_formats.' . $this->exportFormat);
|
||||
$exporter = app($exporterClass, [$this->job]);
|
||||
$exporter->setEntries($this->exportEntries);
|
||||
$exporter->run();
|
||||
$this->files->push($exporter->getFileName());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getFiles(): Collection
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FilesystemAdapter $disk
|
||||
*/
|
||||
private function deleteFiles(FilesystemAdapter $disk)
|
||||
{
|
||||
foreach ($this->getFiles() as $file) {
|
||||
$disk->delete($file);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* AccountChartGeneratorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
@@ -7,11 +16,11 @@ use FireflyIII\Models\Account;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface AccountChartGenerator
|
||||
* Interface AccountChartGeneratorInterface
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Account
|
||||
*/
|
||||
interface AccountChartGenerator
|
||||
interface AccountChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -21,16 +30,7 @@ interface AccountChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end);
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
@@ -39,5 +39,14 @@ interface AccountChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $labels
|
||||
* @param array $dataSet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, array $labels, array $dataSet): array;
|
||||
}
|
@@ -1,18 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsAccountChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Support\Collection;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class ChartJsAccountChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Account
|
||||
*/
|
||||
class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -22,36 +29,13 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end)
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [], 'datasets' => [[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []]]];
|
||||
|
||||
bcscale(2);
|
||||
$start->subDay();
|
||||
$ids = $this->getIdsFromCollection($accounts);
|
||||
$startBalances = Steam::balancesById($ids, $start);
|
||||
$endBalances = Steam::balancesById($ids, $end);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($startBalances, $endBalances) {
|
||||
$id = $account->id;
|
||||
$startBalance = $this->isInArray($startBalances, $id);
|
||||
$endBalance = $this->isInArray($endBalances, $id);
|
||||
$diff = bcsub($endBalance, $startBalance);
|
||||
$account->difference = round($diff, 2);
|
||||
}
|
||||
);
|
||||
|
||||
$accounts = $accounts->sortByDesc(
|
||||
function (Account $account) {
|
||||
return $account->difference;
|
||||
}
|
||||
);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
if ($account->difference > 0) {
|
||||
$data['labels'][] = $account->name;
|
||||
@@ -62,22 +46,6 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @param $entryId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function isInArray($array, $entryId)
|
||||
{
|
||||
if (isset($array[$entryId])) {
|
||||
return $array[$entryId];
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@@ -85,24 +53,19 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// language:
|
||||
$format = trans('config.month_and_day');
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
$format = (string)trans('config.month_and_day');
|
||||
$data = ['count' => 0, 'labels' => [], 'datasets' => [],];
|
||||
$current = clone $start;
|
||||
while ($current <= $end) {
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = [
|
||||
$data['datasets'][] = [
|
||||
'label' => $account->name,
|
||||
'fillColor' => 'rgba(220,220,220,0.2)',
|
||||
'strokeColor' => 'rgba(220,220,220,1)',
|
||||
@@ -110,20 +73,8 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
'pointStrokeColor' => '#fff',
|
||||
'pointHighlightFill' => '#fff',
|
||||
'pointHighlightStroke' => 'rgba(220,220,220,1)',
|
||||
'data' => [],
|
||||
'data' => $account->balances,
|
||||
];
|
||||
$current = clone $start;
|
||||
$range = Steam::balanceInRange($account, $start, $end);
|
||||
$previous = array_values($range)[0];
|
||||
while ($current <= $end) {
|
||||
$format = $current->format('Y-m-d');
|
||||
$balance = isset($range[$format]) ? $range[$format] : $previous;
|
||||
|
||||
$set['data'][] = $balance;
|
||||
$previous = $balance;
|
||||
$current->addDay();
|
||||
}
|
||||
$data['datasets'][] = $set;
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
@@ -132,51 +83,25 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param array $labels
|
||||
* @param array $dataSet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end)
|
||||
public function single(Account $account, array $labels, array $dataSet): array
|
||||
{
|
||||
// language:
|
||||
$format = trans('config.month_and_day');
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'labels' => $labels,
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => $account->name,
|
||||
'data' => []
|
||||
]
|
||||
'data' => $dataSet,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$current = clone $start;
|
||||
|
||||
while ($end >= $current) {
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = Steam::balance($account, $current);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getIdsFromCollection(Collection $collection)
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($collection as $entry) {
|
||||
$ids[] = $entry->id;
|
||||
}
|
||||
|
||||
return array_unique($ids);
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BillChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Bill
|
||||
*/
|
||||
interface BillChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $unpaid);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries);
|
||||
|
||||
}
|
42
app/Generator/Chart/Bill/BillChartGeneratorInterface.php
Normal file
42
app/Generator/Chart/Bill/BillChartGeneratorInterface.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* BillChartGeneratorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BillChartGeneratorInterface
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Bill
|
||||
*/
|
||||
interface BillChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $paid
|
||||
* @param string $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(string $paid, string $unpaid): array;
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries): array;
|
||||
|
||||
}
|
@@ -1,62 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsBillChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
use Config;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class ChartJsBillChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Bill
|
||||
*/
|
||||
class ChartJsBillChartGenerator implements BillChartGenerator
|
||||
class ChartJsBillChartGenerator implements BillChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
* @param string $paid
|
||||
* @param string $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $unpaid)
|
||||
public function frontpage(string $paid, string $unpaid): array
|
||||
{
|
||||
$paidDescriptions = [];
|
||||
$paidAmount = 0;
|
||||
$unpaidDescriptions = [];
|
||||
$unpaidAmount = 0;
|
||||
bcscale(2);
|
||||
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($paid as $entry) { // loop paid and create single entry:
|
||||
$paidDescriptions[] = $entry->description;
|
||||
$paidAmount = bcadd($paidAmount, $entry->amount_positive);
|
||||
}
|
||||
/** @var Bill $entry */
|
||||
foreach ($unpaid as $entry) { // loop unpaid:
|
||||
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
||||
$amount = bcdiv(bcadd($entry[0]->amount_max, $entry[0]->amount_min), 2);
|
||||
$unpaidDescriptions[] = $description;
|
||||
$unpaidAmount = bcadd($unpaidAmount, $amount);
|
||||
unset($amount, $description);
|
||||
}
|
||||
|
||||
$data = [
|
||||
[
|
||||
'value' => $unpaidAmount,
|
||||
'color' => 'rgba(53, 124, 165,0.7)',
|
||||
'highlight' => 'rgba(53, 124, 165,0.9)',
|
||||
'label' => trans('firefly.unpaid'),
|
||||
'datasets' => [
|
||||
[
|
||||
'data' => [round($unpaid, 2), round(bcmul($paid, '-1'), 2)],
|
||||
'backgroundColor' => ['rgba(53, 124, 165,0.7)', 'rgba(0, 141, 76, 0.7)',],
|
||||
],
|
||||
|
||||
],
|
||||
[
|
||||
'value' => $paidAmount,
|
||||
'color' => 'rgba(0, 141, 76, 0.7)',
|
||||
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
||||
'label' => trans('firefly.paid'),
|
||||
]
|
||||
'labels' => [strval(trans('firefly.unpaid')), strval(trans('firefly.paid'))],
|
||||
|
||||
];
|
||||
|
||||
return $data;
|
||||
@@ -68,40 +52,34 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries)
|
||||
public function single(Bill $bill, Collection $entries): array
|
||||
{
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 3,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
// dataset: max amount
|
||||
// dataset: min amount
|
||||
// dataset: actual amount
|
||||
|
||||
$format = (string)trans('config.month');
|
||||
$data = ['count' => 3, 'labels' => [], 'datasets' => [],];
|
||||
$minAmount = [];
|
||||
$maxAmount = [];
|
||||
$actualAmount = [];
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry->date->formatLocalized($format);
|
||||
$minAmount[] = round($bill->amount_min, 2);
|
||||
$maxAmount[] = round($bill->amount_max, 2);
|
||||
$actualAmount[] = round(($entry->amount * -1), 2);
|
||||
// journalAmount has been collected in BillRepository::getJournals
|
||||
$actualAmount[] = round(TransactionJournal::amountPositive($entry), 2);
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
'type' => 'bar',
|
||||
'label' => trans('firefly.minAmount'),
|
||||
'data' => $minAmount,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'type' => 'line',
|
||||
'label' => trans('firefly.billEntry'),
|
||||
'data' => $actualAmount,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'type' => 'bar',
|
||||
'label' => trans('firefly.maxAmount'),
|
||||
'data' => $maxAmount,
|
||||
];
|
||||
|
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BudgetChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Budget
|
||||
*/
|
||||
interface BudgetChartGenerator
|
||||
{
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries);
|
||||
|
||||
}
|
62
app/Generator/Chart/Budget/BudgetChartGeneratorInterface.php
Normal file
62
app/Generator/Chart/Budget/BudgetChartGeneratorInterface.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetChartGeneratorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BudgetChartGeneratorInterface
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Budget
|
||||
*/
|
||||
interface BudgetChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries, string $dateFormat): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $viewRange
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function period(Collection $entries, string $viewRange) : array;
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries): array;
|
||||
|
||||
}
|
@@ -1,33 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsBudgetChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
* Class ChartJsBudgetChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Budget
|
||||
*/
|
||||
class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries, $dateFormat = 'month')
|
||||
public function budgetLimit(Collection $entries, string $dateFormat = 'month_and_day'): array
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
|
||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
||||
|
||||
$data = [
|
||||
$format = strval(trans('config.' . $dateFormat));
|
||||
$data = [
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
@@ -50,44 +54,36 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries)
|
||||
public function frontpage(Collection $entries): array
|
||||
{
|
||||
return $this->budget($entries, 'monthAndDay');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries)
|
||||
{
|
||||
$data = [
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// dataset: left
|
||||
// dataset: spent
|
||||
// dataset: overspent
|
||||
$left = [];
|
||||
$spent = [];
|
||||
$overspent = [];
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||
$data['labels'][] = $entry[0];
|
||||
$left[] = round($entry[1], 2);
|
||||
$spent[] = round($entry[2], 2);
|
||||
$overspent[] = round($entry[3], 2);
|
||||
$filtered = $entries->filter(
|
||||
function ($entry) {
|
||||
return ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0);
|
||||
}
|
||||
);
|
||||
foreach ($filtered as $entry) {
|
||||
$data['labels'][] = $entry[0];
|
||||
$left[] = round($entry[1], 2);
|
||||
$spent[] = round(bcmul($entry[2], '-1'), 2); // spent is coming in negative, must be positive
|
||||
$overspent[] = round(bcmul($entry[3], '-1'), 2); // same
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.overspent'),
|
||||
'data' => $overspent,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.left'),
|
||||
'data' => $left,
|
||||
@@ -96,47 +92,8 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => $spent,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.overspent'),
|
||||
'data' => $overspent,
|
||||
];
|
||||
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($budgets as $budget) {
|
||||
$data['labels'][] = $budget->name;
|
||||
}
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$array = [
|
||||
'label' => $entry[0]->formatLocalized($format),
|
||||
'data' => [],
|
||||
];
|
||||
array_shift($entry);
|
||||
$array['data'] = $entry;
|
||||
$data['datasets'][] = $array;
|
||||
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
$data['count'] = 3;
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -146,7 +103,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries)
|
||||
public function multiYear(Collection $entries): array
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
@@ -156,7 +113,8 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
];
|
||||
// get labels from one of the budgets (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
foreach ($first['budgeted'] as $year => $noInterest) {
|
||||
$keys = array_keys($first['budgeted']);
|
||||
foreach ($keys as $year) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
|
||||
@@ -173,4 +131,78 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $viewRange
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function period(Collection $entries, string $viewRange) : array
|
||||
{
|
||||
$data = [
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
0 => [
|
||||
'label' => trans('firefly.budgeted'),
|
||||
'data' => [],
|
||||
],
|
||||
1 => [
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
'count' => 2,
|
||||
];
|
||||
foreach ($entries as $entry) {
|
||||
$label = Navigation::periodShow($entry['date'], $viewRange);
|
||||
$data['labels'][] = $label;
|
||||
// data set 0 is budgeted
|
||||
// data set 1 is spent:
|
||||
$data['datasets'][0]['data'][] = $entry['budgeted'];
|
||||
$data['datasets'][1]['data'][] = round(($entry['spent'] * -1), 2);
|
||||
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries): array
|
||||
{
|
||||
// language:
|
||||
$format = (string)trans('config.month');
|
||||
|
||||
$data = [
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($budgets as $budget) {
|
||||
$data['labels'][] = $budget->name;
|
||||
}
|
||||
// also add "no budget"
|
||||
$data['labels'][] = strval(trans('firefly.no_budget'));
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$array = [
|
||||
'label' => $entry[0]->formatLocalized($format),
|
||||
'data' => [],
|
||||
];
|
||||
array_shift($entry);
|
||||
$array['data'] = $entry;
|
||||
$data['datasets'][] = $array;
|
||||
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* CategoryChartGeneratorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface CategoryChartGenerator
|
||||
* Interface CategoryChartGeneratorInterface
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Category
|
||||
*/
|
||||
interface CategoryChartGenerator
|
||||
interface CategoryChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -17,7 +26,7 @@ interface CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $entries);
|
||||
public function all(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
@@ -25,28 +34,28 @@ interface CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Collection $categories, Collection $entries);
|
||||
public function earnedInPeriod(Collection $categories, Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries);
|
||||
public function frontpage(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries);
|
||||
public function multiYear(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function period(Collection $entries);
|
||||
public function period(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
@@ -54,5 +63,5 @@ interface CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInYear(Collection $categories, Collection $entries);
|
||||
public function spentInPeriod(Collection $categories, Collection $entries): array;
|
||||
}
|
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsCategoryChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -10,7 +18,7 @@ use Illuminate\Support\Collection;
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Category
|
||||
*/
|
||||
class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -18,43 +26,74 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $entries)
|
||||
public function all(Collection $entries): array
|
||||
{
|
||||
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.earned'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[1];
|
||||
$spent = round($entry[2], 2);
|
||||
$earned = round($entry[3], 2);
|
||||
$spent = $entry[2];
|
||||
$earned = $entry[3];
|
||||
|
||||
$data['datasets'][0]['data'][] = $spent == 0 ? null : $spent * -1;
|
||||
$data['datasets'][1]['data'][] = $earned == 0 ? null : $earned;
|
||||
$data['datasets'][0]['data'][] = bccomp($spent, '0') === 0 ? null : round(bcmul($spent, '-1'), 4);
|
||||
$data['datasets'][1]['data'][] = bccomp($earned, '0') === 0 ? null : round($earned, 4);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Collection $categories, Collection $entries): array
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = (string)trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$data['labels'][] = $category->name;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$date = $entry[0]->formatLocalized($format);
|
||||
array_shift($entry);
|
||||
$data['count']++;
|
||||
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries)
|
||||
public function frontpage(Collection $entries): array
|
||||
{
|
||||
$data = [
|
||||
'count' => 1,
|
||||
@@ -62,14 +101,14 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry['sum'] != 0) {
|
||||
$data['labels'][] = $entry['name'];
|
||||
$data['datasets'][0]['data'][] = round(($entry['sum'] * -1), 2);
|
||||
if ($entry->spent != 0) {
|
||||
$data['labels'][] = $entry->name;
|
||||
$data['datasets'][0]['data'][] = round(bcmul($entry->spent, '-1'), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,135 +116,15 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function period(Collection $entries)
|
||||
public function multiYear(Collection $entries): array
|
||||
{
|
||||
return $this->all($entries);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInYear(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$data['labels'][] = $category->name;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$date = $entry[0]->formatLocalized($format);
|
||||
array_shift($entry);
|
||||
$data['count']++;
|
||||
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$data['labels'][] = $category->name;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$date = $entry[0]->formatLocalized($format);
|
||||
array_shift($entry);
|
||||
$data['count']++;
|
||||
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriod(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$data['labels'][] = $category->name;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$date = $entry[0]->formatLocalized($format);
|
||||
array_shift($entry);
|
||||
$data['count']++;
|
||||
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries)
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// get labels from one of the categories (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
foreach ($first['spent'] as $year => $noInterest) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
$data = ['count' => 0, 'labels' => array_keys($first['spent']), 'datasets' => [],];
|
||||
|
||||
// then, loop all entries and create datasets:
|
||||
foreach ($entries as $entry) {
|
||||
@@ -221,6 +140,50 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function period(Collection $entries): array
|
||||
{
|
||||
return $this->all($entries);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriod(Collection $categories, Collection $entries): array
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = (string)trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$data['labels'][] = $category->name;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$date = $entry[0]->formatLocalized($format);
|
||||
array_shift($entry);
|
||||
$data['count']++;
|
||||
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsPiggyBankChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
|
||||
/**
|
||||
@@ -13,7 +19,7 @@ use Preferences;
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
class ChartJsPiggyBankChartGenerator implements PiggyBankChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -21,11 +27,11 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function history(Collection $set)
|
||||
public function history(Collection $set): array
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = trans('config.month_and_day');
|
||||
$format = (string)trans('config.month_and_day');
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
@@ -33,15 +39,14 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Diff',
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$sum = '0';
|
||||
bcscale(2);
|
||||
foreach ($set as $entry) {
|
||||
$date = new Carbon($entry->date);
|
||||
$sum = bcadd($sum, $entry->sum);
|
||||
foreach ($set as $key => $value) {
|
||||
$date = new Carbon($key);
|
||||
$sum = bcadd($sum, $value);
|
||||
$data['labels'][] = $date->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($sum, 2);
|
||||
}
|
||||
|
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface PiggyBankChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
interface PiggyBankChartGenerator
|
||||
{
|
||||
/**
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function history(Collection $set);
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* PiggyBankChartGeneratorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface PiggyBankChartGeneratorInterface
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
interface PiggyBankChartGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function history(Collection $set): array;
|
||||
}
|
@@ -1,53 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsReportChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class ChartJsReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
class ChartJsReportChartGenerator implements ReportChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
$data['datasets'][1]['data'][] = round($entry[2], 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as above but other translations.
|
||||
*
|
||||
@@ -55,7 +27,7 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOut(Collection $entries)
|
||||
public function multiYearInOut(Collection $entries): array
|
||||
{
|
||||
$data = [
|
||||
'count' => 2,
|
||||
@@ -63,12 +35,12 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -88,21 +60,20 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOutSummarized($income, $expense, $count)
|
||||
public function multiYearInOutSummarized(string $income, string $expense, int $count): array
|
||||
{
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [trans('firefly.sum_of_year'), trans('firefly.average_of_year')],
|
||||
'labels' => [trans('firefly.sum_of_years'), trans('firefly.average_of_years')],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$data['datasets'][0]['data'][] = round($income, 2);
|
||||
@@ -113,6 +84,66 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function netWorth(Collection $entries) : array
|
||||
{
|
||||
$format = (string)trans('config.month_and_day');
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.net_worth'),
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = trim($entry['date']->formatLocalized($format));
|
||||
$data['datasets'][0]['data'][] = round($entry['net-worth'], 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries): array
|
||||
{
|
||||
// language:
|
||||
$format = (string)trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
$data['datasets'][1]['data'][] = round($entry[2], 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
@@ -120,20 +151,21 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOutSummarized($income, $expense, $count)
|
||||
public function yearInOutSummarized(string $income, string $expense, int $count): array
|
||||
{
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [trans('firefly.sum_of_years'), trans('firefly.average_of_years')],
|
||||
'labels' => [trans('firefly.sum_of_year'), trans('firefly.average_of_year')],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$data['datasets'][0]['data'][] = round($income, 2);
|
||||
|
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
interface ReportChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOut(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOutSummarized($income, $expense, $count);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOutSummarized($income, $expense, $count);
|
||||
|
||||
}
|
63
app/Generator/Chart/Report/ReportChartGeneratorInterface.php
Normal file
63
app/Generator/Chart/Report/ReportChartGeneratorInterface.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* ReportChartGeneratorInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ReportChartGeneratorInterface
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
interface ReportChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOut(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOutSummarized(string $income, string $expense, int $count): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function netWorth(Collection $entries) : array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOutSummarized(string $income, string $expense, int $count): array;
|
||||
|
||||
}
|
50
app/Handlers/Events/AttachUserRole.php
Normal file
50
app/Handlers/Events/AttachUserRole.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachUserRole.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\UserRegistration;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class AttachUserRole
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class AttachUserRole
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param UserRegistration $event
|
||||
*/
|
||||
public function handle(UserRegistration $event)
|
||||
{
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
|
||||
// first user ever?
|
||||
if ($repository->count() == 1) {
|
||||
$repository->attachRole($event->user, 'owner');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
107
app/Handlers/Events/BudgetLimitEventHandler.php
Normal file
107
app/Handlers/Events/BudgetLimitEventHandler.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLimitEventHandler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\BudgetLimitStored;
|
||||
use FireflyIII\Events\BudgetLimitUpdated;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class BudgetLimitEventHandler
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class BudgetLimitEventHandler
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* In a perfect world, the store() routine should be different from the update()
|
||||
* routine. It would not have to check count() == 0 because there could be NO
|
||||
* limit repetitions at this point. However, the database can be wrong so we check.
|
||||
*
|
||||
* @param BudgetLimitStored $event
|
||||
*/
|
||||
public function store(BudgetLimitStored $event)
|
||||
{
|
||||
$budgetLimit = $event->budgetLimit;
|
||||
$end = $event->end;
|
||||
$set = $budgetLimit->limitrepetitions()
|
||||
->where('startdate', $budgetLimit->startdate->format('Y-m-d 00:00:00'))
|
||||
->where('enddate', $end->format('Y-m-d 00:00:00'))
|
||||
->get();
|
||||
if ($set->count() == 0) {
|
||||
$repetition = new LimitRepetition;
|
||||
$repetition->startdate = $budgetLimit->startdate;
|
||||
$repetition->enddate = $end;
|
||||
$repetition->amount = $budgetLimit->amount;
|
||||
$repetition->budgetLimit()->associate($budgetLimit);
|
||||
|
||||
try {
|
||||
$repetition->save();
|
||||
} catch (QueryException $e) {
|
||||
Log::error('Trying to save new LimitRepetition failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ($set->count() == 1) {
|
||||
$repetition = $set->first();
|
||||
$repetition->amount = $budgetLimit->amount;
|
||||
$repetition->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetLimitUpdated $event
|
||||
*/
|
||||
public function update(BudgetLimitUpdated $event)
|
||||
{
|
||||
$budgetLimit = $event->budgetLimit;
|
||||
$end = $event->end;
|
||||
$set = $budgetLimit->limitrepetitions()
|
||||
->where('startdate', $budgetLimit->startdate->format('Y-m-d 00:00:00'))
|
||||
->where('enddate', $end->format('Y-m-d 00:00:00'))
|
||||
->get();
|
||||
if ($set->count() == 0) {
|
||||
$repetition = new LimitRepetition;
|
||||
$repetition->startdate = $budgetLimit->startdate;
|
||||
$repetition->enddate = $end;
|
||||
$repetition->amount = $budgetLimit->amount;
|
||||
$repetition->budgetLimit()->associate($budgetLimit);
|
||||
|
||||
try {
|
||||
$repetition->save();
|
||||
} catch (QueryException $e) {
|
||||
Log::error('Trying to save new LimitRepetition failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ($set->count() == 1) {
|
||||
$repetition = $set->first();
|
||||
$repetition->amount = $budgetLimit->amount;
|
||||
$repetition->save();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,7 +1,18 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
<?php
|
||||
/**
|
||||
* ConnectJournalToPiggyBank.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
@@ -15,26 +26,13 @@ class ConnectJournalToPiggyBank
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
* Connect a new transaction journal to any related piggy banks.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event when journal is saved.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @param JournalCreated $event
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function handle(JournalCreated $event)
|
||||
public function handle(TransactionJournalStored $event): bool
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
@@ -44,19 +42,19 @@ class ConnectJournalToPiggyBank
|
||||
$piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
$amount = $journal->amount_positive;
|
||||
$amount = TransactionJournal::amountPositive($journal);
|
||||
// if piggy account matches source account, the amount is positive
|
||||
if ($piggyBank->account_id == $journal->source_account->id) {
|
||||
$amount = $amount * -1;
|
||||
$sources = TransactionJournal::sourceAccountList($journal)->pluck('id')->toArray();
|
||||
if (in_array($piggyBank->account_id, $sources)) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
|
||||
|
67
app/Handlers/Events/ConnectTransactionToPiggyBank.php
Normal file
67
app/Handlers/Events/ConnectTransactionToPiggyBank.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* ConnectTransactionToPiggyBank.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\TransactionStored;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class ConnectTransactionToPiggyBank
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class ConnectTransactionToPiggyBank
|
||||
{
|
||||
|
||||
/**
|
||||
* Connect a new transaction journal to any related piggy banks.
|
||||
*
|
||||
* @param TransactionStored $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionStored $event): bool
|
||||
{
|
||||
echo '<pre>';
|
||||
/** @var PiggyBankRepositoryInterface $repository */
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$transaction = $event->transaction;
|
||||
$piggyBank = $repository->find($transaction['piggy_bank_id']);
|
||||
|
||||
// valid piggy:
|
||||
if (is_null($piggyBank->id)) {
|
||||
return true;
|
||||
}
|
||||
$amount = strval($transaction['amount']);
|
||||
// piggy bank account something with amount:
|
||||
if ($transaction['source_account_id'] == $piggyBank->account_id) {
|
||||
// if the source of this transaction is the same as the piggy bank,
|
||||
// the money is being removed from the piggy bank. So the
|
||||
// amount must be negative:
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
$repetition = $piggyBank->currentRelevantRep();
|
||||
// add or remove the money from the piggy bank:
|
||||
$newAmount = bcadd(strval($repetition->currentamount), $amount);
|
||||
$repetition->currentamount = $newAmount;
|
||||
$repetition->save();
|
||||
|
||||
// now generate a piggy bank event:
|
||||
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'date' => $transaction['date'], 'amount' => $newAmount]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
67
app/Handlers/Events/FireRulesForStore.php
Normal file
67
app/Handlers/Events/FireRulesForStore.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* FireRulesForStore.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* Class FireRulesForStore
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class FireRulesForStore
|
||||
{
|
||||
|
||||
/**
|
||||
* Connect a new transaction journal to any related piggy banks.
|
||||
*
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalStored $event): bool
|
||||
{
|
||||
// get all the user's rule groups, with the rules, order by 'order'.
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get();
|
||||
//
|
||||
/** @var RuleGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
$rules = $group->rules()
|
||||
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
|
||||
->where('rule_triggers.trigger_type', 'user_action')
|
||||
->where('rule_triggers.trigger_value', 'store-journal')
|
||||
->where('rules.active', 1)
|
||||
->get(['rules.*']);
|
||||
/** @var Rule $rule */
|
||||
foreach ($rules as $rule) {
|
||||
|
||||
$processor = Processor::make($rule);
|
||||
$processor->handleTransactionJournal($event->journal);
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
64
app/Handlers/Events/FireRulesForUpdate.php
Normal file
64
app/Handlers/Events/FireRulesForUpdate.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* FireRulesForUpdate.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\User;
|
||||
|
||||
/**
|
||||
* Class FireRulesForUpdate
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class FireRulesForUpdate
|
||||
{
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalUpdated $event): bool
|
||||
{
|
||||
// get all the user's rule groups, with the rules, order by 'order'.
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get();
|
||||
//
|
||||
/** @var RuleGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
$rules = $group->rules()
|
||||
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
|
||||
->where('rule_triggers.trigger_type', 'user_action')
|
||||
->where('rule_triggers.trigger_value', 'update-journal')
|
||||
->where('rules.active', 1)
|
||||
->get(['rules.*']);
|
||||
/** @var Rule $rule */
|
||||
foreach ($rules as $rule) {
|
||||
$processor = Processor::make($rule);
|
||||
$processor->handleTransactionJournal($event->journal);
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class RescanJournal
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param JournalSaved $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(JournalSaved $event)
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')');
|
||||
|
||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||
$list = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get();
|
||||
|
||||
Log::debug('Found ' . $list->count() . ' bills to check.');
|
||||
|
||||
/** @var \FireflyIII\Models\Bill $bill */
|
||||
foreach ($list as $bill) {
|
||||
Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')');
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
|
||||
Log::debug('Done!');
|
||||
}
|
||||
|
||||
}
|
40
app/Handlers/Events/ScanForBillsAfterStore.php
Normal file
40
app/Handlers/Events/ScanForBillsAfterStore.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* ScanForBillsAfterStore.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Support\Events\BillScanner;
|
||||
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class ScanForBillsAfterStore
|
||||
{
|
||||
|
||||
/**
|
||||
* Scan a transaction journal for possible links to bills, right after storing.
|
||||
*
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalStored $event): bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
BillScanner::scan($journal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
39
app/Handlers/Events/ScanForBillsAfterUpdate.php
Normal file
39
app/Handlers/Events/ScanForBillsAfterUpdate.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* ScanForBillsAfterUpdate.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use FireflyIII\Support\Events\BillScanner;
|
||||
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class ScanForBillsAfterUpdate
|
||||
{
|
||||
/**
|
||||
* Scan a transaction journal for possibly related bills after it has been updated.
|
||||
*
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalUpdated $event): bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
BillScanner::scan($journal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
67
app/Handlers/Events/SendRegistrationMail.php
Normal file
67
app/Handlers/Events/SendRegistrationMail.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* SendRegistrationMail.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\UserRegistration;
|
||||
use Illuminate\Mail\Message;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Swift_TransportException;
|
||||
|
||||
/**
|
||||
* Class SendRegistrationMail
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class SendRegistrationMail
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param UserRegistration $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(UserRegistration $event): bool
|
||||
{
|
||||
$sendMail = env('SEND_REGISTRATION_MAIL', true);
|
||||
if (!$sendMail) {
|
||||
return true;
|
||||
}
|
||||
// get the email address
|
||||
$email = $event->user->email;
|
||||
$address = route('index');
|
||||
$ipAddress = $event->ipAddress;
|
||||
// send email.
|
||||
try {
|
||||
Mail::send(
|
||||
['emails.registered-html', 'emails.registered'], ['address' => $address, 'ip' => $ipAddress], function (Message $message) use ($email) {
|
||||
$message->to($email, $email)->subject('Welcome to Firefly III! ');
|
||||
}
|
||||
);
|
||||
} catch (Swift_TransportException $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,35 +1,36 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
<?php
|
||||
/**
|
||||
* UpdateJournalConnection.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/**
|
||||
* Class UpdateJournalConnection
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UpdateJournalConnection
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param JournalSaved $event
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(JournalSaved $event)
|
||||
public function handle(TransactionJournalUpdated $event):bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
@@ -37,7 +38,7 @@ class UpdateJournalConnection
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
|
||||
if (is_null($event)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
$piggyBank = $event->piggyBank()->first();
|
||||
$repetition = null;
|
||||
@@ -47,11 +48,10 @@ class UpdateJournalConnection
|
||||
}
|
||||
|
||||
if (is_null($repetition)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
$amount = $journal->amount;
|
||||
$amount = TransactionJournal::amount($journal);
|
||||
$diff = bcsub($amount, $event->amount); // update current repetition
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $diff);
|
||||
@@ -60,6 +60,8 @@ class UpdateJournalConnection
|
||||
|
||||
$event->amount = $amount;
|
||||
$event->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
107
app/Handlers/Events/UserConfirmation.php
Normal file
107
app/Handlers/Events/UserConfirmation.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* UserConfirmation.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Events\ResendConfirmation;
|
||||
use FireflyIII\Events\UserRegistration;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Mail\Message;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Preferences;
|
||||
use Swift_TransportException;
|
||||
|
||||
/**
|
||||
* Class UserConfirmation
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UserConfirmation
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResendConfirmation $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function resendConfirmation(ResendConfirmation $event): bool
|
||||
{
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->ipAddress;
|
||||
$this->doConfirm($user, $ipAddress);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param UserRegistration $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sendConfirmation(UserRegistration $event): bool
|
||||
{
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->ipAddress;
|
||||
$this->doConfirm($user, $ipAddress);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
||||
*/
|
||||
private function doConfirm(User $user, string $ipAddress)
|
||||
{
|
||||
$confirmAccount = env('MUST_CONFIRM_ACCOUNT', false);
|
||||
if ($confirmAccount === false) {
|
||||
Preferences::setForUser($user, 'user_confirmed', true);
|
||||
Preferences::setForUser($user, 'user_confirmed_last_mail', 0);
|
||||
Preferences::mark();
|
||||
|
||||
return;
|
||||
}
|
||||
$email = $user->email;
|
||||
$code = str_random(16);
|
||||
$route = route('do_confirm_account', [$code]);
|
||||
Preferences::setForUser($user, 'user_confirmed', false);
|
||||
Preferences::setForUser($user, 'user_confirmed_last_mail', time());
|
||||
Preferences::setForUser($user, 'user_confirmed_code', $code);
|
||||
try {
|
||||
Mail::send(
|
||||
['emails.confirm-account-html', 'emails.confirm-account'], ['route' => $route, 'ip' => $ipAddress],
|
||||
function (Message $message) use ($email) {
|
||||
$message->to($email, $email)->subject('Please confirm your Firefly III account');
|
||||
}
|
||||
);
|
||||
} catch (Swift_TransportException $e) {
|
||||
Log::error($e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
36
app/Handlers/Events/UserEventListener.php
Normal file
36
app/Handlers/Events/UserEventListener.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* UserEventListener.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class UserEventListener
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UserEventListener
|
||||
{
|
||||
/**
|
||||
* Handle user logout events.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function onUserLogout(): bool
|
||||
{
|
||||
// dump stuff from the session:
|
||||
Session::forget('twofactor-authenticated');
|
||||
Session::forget('twofactor-authenticated-date');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,15 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentHelper.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Attachments;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use Crypt;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Input;
|
||||
use Log;
|
||||
use Storage;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Class AttachmentHelper
|
||||
@@ -19,24 +29,28 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
class AttachmentHelper implements AttachmentHelperInterface
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
protected $maxUploadSize;
|
||||
/** @var array */
|
||||
protected $allowedMimes;
|
||||
/** @var MessageBag */
|
||||
public $errors;
|
||||
/** @var MessageBag */
|
||||
public $messages;
|
||||
/** @var array */
|
||||
protected $allowedMimes;
|
||||
/** @var int */
|
||||
protected $maxUploadSize;
|
||||
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
protected $uploadDisk;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->maxUploadSize = Config::get('firefly.maxUploadSize');
|
||||
$this->allowedMimes = Config::get('firefly.allowedMimes');
|
||||
$this->maxUploadSize = config('firefly.maxUploadSize');
|
||||
$this->allowedMimes = config('firefly.allowedMimes');
|
||||
$this->errors = new MessageBag;
|
||||
$this->messages = new MessageBag;
|
||||
$this->uploadDisk = Storage::disk('upload');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,30 +58,44 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment)
|
||||
public function getAttachmentLocation(Attachment $attachment): string
|
||||
{
|
||||
$path = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data';
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors(): MessageBag
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages(): MessageBag
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model)
|
||||
public function saveAttachmentsForModel(Model $model): bool
|
||||
{
|
||||
$files = Input::file('attachments');
|
||||
$files = $this->getFiles();
|
||||
|
||||
if (!is_null($files) && !is_array($files)) {
|
||||
$this->processFile($files, $model);
|
||||
}
|
||||
|
||||
if (is_array($files)) {
|
||||
foreach ($files as $entry) {
|
||||
if (!is_null($entry)) {
|
||||
$this->processFile($entry, $model);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->processFile($files, $model);
|
||||
$this->processFiles($files, $model);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -79,7 +107,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasFile(UploadedFile $file, Model $model)
|
||||
protected function hasFile(UploadedFile $file, Model $model): bool
|
||||
{
|
||||
$md5 = md5_file($file->getRealPath());
|
||||
$name = $file->getClientOriginalName();
|
||||
@@ -87,7 +115,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
$count = Auth::user()->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
|
||||
|
||||
if ($count > 0) {
|
||||
$msg = trans('validation.file_already_attached', ['name' => $name]);
|
||||
$msg = (string)trans('validation.file_already_attached', ['name' => $name]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return true;
|
||||
@@ -96,13 +124,97 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return Attachment
|
||||
*/
|
||||
protected function processFile(UploadedFile $file, Model $model): Attachment
|
||||
{
|
||||
$validation = $this->validateUpload($file, $model);
|
||||
if ($validation === false) {
|
||||
return new Attachment;
|
||||
}
|
||||
|
||||
$attachment = new Attachment; // create Attachment object.
|
||||
$attachment->user()->associate(Auth::user());
|
||||
$attachment->attachable()->associate($model);
|
||||
$attachment->md5 = md5_file($file->getRealPath());
|
||||
$attachment->filename = $file->getClientOriginalName();
|
||||
$attachment->mime = $file->getMimeType();
|
||||
$attachment->size = $file->getSize();
|
||||
$attachment->uploaded = 0;
|
||||
$attachment->save();
|
||||
|
||||
$fileObject = $file->openFile('r');
|
||||
$fileObject->rewind();
|
||||
$content = $fileObject->fread($file->getSize());
|
||||
$encrypted = Crypt::encrypt($content);
|
||||
|
||||
// store it:
|
||||
$this->uploadDisk->put($attachment->fileName(), $encrypted);
|
||||
|
||||
$attachment->uploaded = 1; // update attachment
|
||||
$attachment->save();
|
||||
|
||||
$name = e($file->getClientOriginalName()); // add message:
|
||||
$msg = (string)trans('validation.file_attached', ['name' => $name]);
|
||||
$this->messages->add('attachments', $msg);
|
||||
|
||||
// return it.
|
||||
return $attachment;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validMime(UploadedFile $file): bool
|
||||
{
|
||||
$mime = e($file->getMimeType());
|
||||
$name = e($file->getClientOriginalName());
|
||||
|
||||
if (!in_array($mime, $this->allowedMimes)) {
|
||||
$msg = (string)trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validSize(UploadedFile $file): bool
|
||||
{
|
||||
$size = $file->getSize();
|
||||
$name = e($file->getClientOriginalName());
|
||||
if ($size > $this->maxUploadSize) {
|
||||
$msg = (string)trans('validation.file_too_large', ['name' => $name]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateUpload(UploadedFile $file, Model $model)
|
||||
protected function validateUpload(UploadedFile $file, Model $model): bool
|
||||
{
|
||||
if (!$this->validMime($file)) {
|
||||
return false;
|
||||
@@ -118,105 +230,38 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool|Attachment
|
||||
* @return array|null|UploadedFile
|
||||
*/
|
||||
protected function processFile(UploadedFile $file, Model $model)
|
||||
private function getFiles()
|
||||
{
|
||||
$validation = $this->validateUpload($file, $model);
|
||||
if ($validation === false) {
|
||||
return false;
|
||||
$files = null;
|
||||
try {
|
||||
if (Input::hasFile('attachments')) {
|
||||
$files = Input::file('attachments');
|
||||
}
|
||||
} catch (TypeError $e) {
|
||||
// Log it, do nothing else.
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
$attachment = new Attachment; // create Attachment object.
|
||||
$attachment->user()->associate(Auth::user());
|
||||
$attachment->attachable()->associate($model);
|
||||
$attachment->md5 = md5_file($file->getRealPath());
|
||||
$attachment->filename = $file->getClientOriginalName();
|
||||
$attachment->mime = $file->getMimeType();
|
||||
$attachment->size = $file->getSize();
|
||||
$attachment->uploaded = 0;
|
||||
$attachment->save();
|
||||
|
||||
$path = $file->getRealPath(); // encrypt and move file to storage.
|
||||
$content = file_get_contents($path);
|
||||
$encrypted = Crypt::encrypt($content);
|
||||
|
||||
// store it:
|
||||
$upload = $this->getAttachmentLocation($attachment);
|
||||
if (is_writable(dirname($upload))) {
|
||||
file_put_contents($upload, $encrypted);
|
||||
}
|
||||
|
||||
$attachment->uploaded = 1; // update attachment
|
||||
$attachment->save();
|
||||
|
||||
$name = e($file->getClientOriginalName()); // add message:
|
||||
$msg = trans('validation.file_attached', ['name' => $name]);
|
||||
$this->messages->add('attachments', $msg);
|
||||
|
||||
// return it.
|
||||
return $attachment;
|
||||
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param array $files
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validMime(UploadedFile $file)
|
||||
private function processFiles(array $files, Model $model): bool
|
||||
{
|
||||
$mime = e($file->getMimeType());
|
||||
$name = e($file->getClientOriginalName());
|
||||
|
||||
if (!in_array($mime, $this->allowedMimes)) {
|
||||
$msg = trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return false;
|
||||
foreach ($files as $entry) {
|
||||
if (!is_null($entry)) {
|
||||
$this->processFile($entry, $model);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validSize(UploadedFile $file)
|
||||
{
|
||||
$size = $file->getSize();
|
||||
$name = e($file->getClientOriginalName());
|
||||
if ($size > $this->maxUploadSize) {
|
||||
$msg = trans('validation.file_too_large', ['name' => $name]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentHelperInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Attachments;
|
||||
|
||||
use FireflyIII\Models\Attachment;
|
||||
@@ -14,28 +22,28 @@ use Illuminate\Support\MessageBag;
|
||||
interface AttachmentHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment): string;
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors(): MessageBag;
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages(): MessageBag;
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model);
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors();
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages();
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment);
|
||||
public function saveAttachmentsForModel(Model $model): bool;
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Account.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class Account
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
@@ -15,73 +22,81 @@ class Account
|
||||
|
||||
/** @var Collection */
|
||||
protected $accounts;
|
||||
/** @var float */
|
||||
protected $difference;
|
||||
/** @var float */
|
||||
protected $end;
|
||||
/** @var float */
|
||||
protected $start;
|
||||
/** @var string */
|
||||
protected $difference = '';
|
||||
/** @var string */
|
||||
protected $end = '';
|
||||
/** @var string */
|
||||
protected $start = '';
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
* Account constructor.
|
||||
*/
|
||||
public function getAccounts()
|
||||
public function __construct()
|
||||
{
|
||||
$this->accounts = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccounts(): Collection
|
||||
{
|
||||
return $this->accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Support\Collection $accounts
|
||||
* @param Collection $accounts
|
||||
*/
|
||||
public function setAccounts($accounts)
|
||||
public function setAccounts(Collection $accounts)
|
||||
{
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getDifference()
|
||||
public function getDifference(): string
|
||||
{
|
||||
return $this->difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $difference
|
||||
* @param string $difference
|
||||
*/
|
||||
public function setDifference($difference)
|
||||
public function setDifference(string $difference)
|
||||
{
|
||||
$this->difference = $difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getEnd()
|
||||
public function getEnd(): string
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $end
|
||||
* @param string $end
|
||||
*/
|
||||
public function setEnd($end)
|
||||
public function setEnd(string $end)
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getStart()
|
||||
public function getStart(): string
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $start
|
||||
* @param string $start
|
||||
*/
|
||||
public function setStart($start)
|
||||
public function setStart(string $start)
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
@@ -1,11 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Balance.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Balance
|
||||
*
|
||||
@@ -39,26 +46,34 @@ class Balance
|
||||
/**
|
||||
* @return BalanceHeader
|
||||
*/
|
||||
public function getBalanceHeader()
|
||||
public function getBalanceHeader(): BalanceHeader
|
||||
{
|
||||
return $this->balanceHeader;
|
||||
return $this->balanceHeader ?? new BalanceHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BalanceHeader $balanceHeader
|
||||
*/
|
||||
public function setBalanceHeader($balanceHeader)
|
||||
public function setBalanceHeader(BalanceHeader $balanceHeader)
|
||||
{
|
||||
$this->balanceHeader = $balanceHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBalanceLines()
|
||||
public function getBalanceLines(): Collection
|
||||
{
|
||||
return $this->balanceLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $balanceLines
|
||||
*/
|
||||
public function setBalanceLines(Collection $balanceLines)
|
||||
{
|
||||
$this->balanceLines = $balanceLines;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* BalanceEntry.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BalanceEntry
|
||||
*
|
||||
@@ -17,15 +24,15 @@ class BalanceEntry
|
||||
|
||||
/** @var AccountModel */
|
||||
protected $account;
|
||||
/** @var float */
|
||||
protected $left = 0.0;
|
||||
/** @var float */
|
||||
protected $spent = 0.0;
|
||||
/** @var string */
|
||||
protected $left = '0';
|
||||
/** @var string */
|
||||
protected $spent = '0';
|
||||
|
||||
/**
|
||||
* @return AccountModel
|
||||
*/
|
||||
public function getAccount()
|
||||
public function getAccount(): AccountModel
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
@@ -33,39 +40,39 @@ class BalanceEntry
|
||||
/**
|
||||
* @param AccountModel $account
|
||||
*/
|
||||
public function setAccount($account)
|
||||
public function setAccount(AccountModel $account)
|
||||
{
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getLeft()
|
||||
public function getLeft(): string
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $left
|
||||
* @param string $left
|
||||
*/
|
||||
public function setLeft($left)
|
||||
public function setLeft(string $left)
|
||||
{
|
||||
$this->left = $left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getSpent()
|
||||
public function getSpent(): string
|
||||
{
|
||||
return $this->spent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $spent
|
||||
* @param string $spent
|
||||
*/
|
||||
public function setSpent($spent)
|
||||
public function setSpent(string $spent)
|
||||
{
|
||||
$this->spent = $spent;
|
||||
}
|
||||
|
@@ -1,12 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* BalanceHeader.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BalanceHeader
|
||||
*
|
||||
@@ -37,7 +44,7 @@ class BalanceHeader
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccounts()
|
||||
public function getAccounts(): Collection
|
||||
{
|
||||
return $this->accounts;
|
||||
}
|
||||
|
@@ -1,13 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* BalanceLine.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BalanceLine
|
||||
*
|
||||
@@ -26,9 +33,12 @@ class BalanceLine
|
||||
/** @var BudgetModel */
|
||||
protected $budget;
|
||||
|
||||
/** @var LimitRepetition */
|
||||
protected $repetition;
|
||||
/** @var Carbon */
|
||||
protected $startDate;
|
||||
/** @var Carbon */
|
||||
protected $endDate;
|
||||
|
||||
/** @var int */
|
||||
protected $role = self::ROLE_DEFAULTROLE;
|
||||
|
||||
/**
|
||||
@@ -37,6 +47,7 @@ class BalanceLine
|
||||
public function __construct()
|
||||
{
|
||||
$this->balanceEntries = new Collection;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,16 +58,64 @@ class BalanceLine
|
||||
$this->balanceEntries->push($balanceEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBalanceEntries(): Collection
|
||||
{
|
||||
return $this->balanceEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $balanceEntries
|
||||
*/
|
||||
public function setBalanceEntries(Collection $balanceEntries)
|
||||
{
|
||||
$this->balanceEntries = $balanceEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BudgetModel
|
||||
*/
|
||||
public function getBudget(): BudgetModel
|
||||
{
|
||||
return $this->budget ?? new BudgetModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetModel $budget
|
||||
*/
|
||||
public function setBudget(BudgetModel $budget)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRole(): int
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $role
|
||||
*/
|
||||
public function setRole(int $role)
|
||||
{
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
public function getTitle(): string
|
||||
{
|
||||
if ($this->getBudget() instanceof BudgetModel) {
|
||||
if ($this->getBudget() instanceof BudgetModel && !is_null($this->getBudget()->id)) {
|
||||
return $this->getBudget()->name;
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_DEFAULTROLE) {
|
||||
return trans('firefly.noBudget');
|
||||
return trans('firefly.no_budget');
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_TAGROLE) {
|
||||
return trans('firefly.coveredWithTags');
|
||||
@@ -69,85 +128,54 @@ class BalanceLine
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BudgetModel
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getBudget()
|
||||
public function getStartDate()
|
||||
{
|
||||
return $this->budget;
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetModel $budget
|
||||
* @param Carbon $startDate
|
||||
*/
|
||||
public function setBudget($budget)
|
||||
public function setStartDate($startDate)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
$this->startDate = $startDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getRole()
|
||||
public function getEndDate()
|
||||
{
|
||||
return $this->role;
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $role
|
||||
* @param Carbon $endDate
|
||||
*/
|
||||
public function setRole($role)
|
||||
public function setEndDate($endDate)
|
||||
{
|
||||
$this->role = $role;
|
||||
$this->endDate = $endDate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine
|
||||
* should have a "spent" value, which is the amount of money that has been spent
|
||||
* on the given budget/repetition. If you subtract all those amounts from the budget/repetition's
|
||||
* total amount, this is returned:
|
||||
*
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function leftOfRepetition()
|
||||
public function leftOfRepetition(): string
|
||||
{
|
||||
$start = $this->getRepetition() ? $this->getRepetition()->amount : 0;
|
||||
$start = $this->budget->amount ?? '0';
|
||||
/** @var BalanceEntry $balanceEntry */
|
||||
foreach ($this->getBalanceEntries() as $balanceEntry) {
|
||||
$start += $balanceEntry->getSpent();
|
||||
$start = bcadd($balanceEntry->getSpent(), $start);
|
||||
}
|
||||
|
||||
return $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LimitRepetition
|
||||
*/
|
||||
public function getRepetition()
|
||||
{
|
||||
return $this->repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LimitRepetition $repetition
|
||||
*/
|
||||
public function setRepetition($repetition)
|
||||
{
|
||||
$this->repetition = $repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBalanceEntries()
|
||||
{
|
||||
return $this->balanceEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $balanceEntries
|
||||
*/
|
||||
public function setBalanceEntries($balanceEntries)
|
||||
{
|
||||
$this->balanceEntries = $balanceEntries;
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Bill.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class Bill
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
@@ -38,7 +45,7 @@ class Bill
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBills()
|
||||
public function getBills(): Collection
|
||||
{
|
||||
$set = $this->bills->sortBy(
|
||||
function (BillLine $bill) {
|
||||
|
@@ -1,11 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* BillLine.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Bill as BillModel;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BillLine
|
||||
*
|
||||
@@ -27,18 +34,21 @@ class BillLine
|
||||
/** @var string */
|
||||
protected $min;
|
||||
|
||||
/** @var int */
|
||||
private $transactionJournalId;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAmount()
|
||||
public function getAmount(): string
|
||||
{
|
||||
return $this->amount;
|
||||
return $this->amount ?? '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
*/
|
||||
public function setAmount($amount)
|
||||
public function setAmount(string $amount)
|
||||
{
|
||||
$this->amount = $amount;
|
||||
}
|
||||
@@ -46,7 +56,7 @@ class BillLine
|
||||
/**
|
||||
* @return BillModel
|
||||
*/
|
||||
public function getBill()
|
||||
public function getBill(): BillModel
|
||||
{
|
||||
return $this->bill;
|
||||
}
|
||||
@@ -54,7 +64,7 @@ class BillLine
|
||||
/**
|
||||
* @param BillModel $bill
|
||||
*/
|
||||
public function setBill($bill)
|
||||
public function setBill(BillModel $bill)
|
||||
{
|
||||
$this->bill = $bill;
|
||||
}
|
||||
@@ -62,7 +72,7 @@ class BillLine
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMax()
|
||||
public function getMax(): string
|
||||
{
|
||||
return $this->max;
|
||||
}
|
||||
@@ -70,7 +80,7 @@ class BillLine
|
||||
/**
|
||||
* @param string $max
|
||||
*/
|
||||
public function setMax($max)
|
||||
public function setMax(string $max)
|
||||
{
|
||||
$this->max = $max;
|
||||
}
|
||||
@@ -78,7 +88,7 @@ class BillLine
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMin()
|
||||
public function getMin(): string
|
||||
{
|
||||
return $this->min;
|
||||
}
|
||||
@@ -86,42 +96,57 @@ class BillLine
|
||||
/**
|
||||
* @param string $min
|
||||
*/
|
||||
public function setMin($min)
|
||||
public function setMin(string $min)
|
||||
{
|
||||
$this->min = $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @return int
|
||||
*/
|
||||
public function isActive()
|
||||
public function getTransactionJournalId(): int
|
||||
{
|
||||
return $this->transactionJournalId ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $transactionJournalId
|
||||
*/
|
||||
public function setTransactionJournalId(int $transactionJournalId)
|
||||
{
|
||||
$this->transactionJournalId = $transactionJournalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $active
|
||||
* @param bool $active
|
||||
*/
|
||||
public function setActive($active)
|
||||
public function setActive(bool $active)
|
||||
{
|
||||
$this->active = $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isHit()
|
||||
public function isHit(): bool
|
||||
{
|
||||
return $this->hit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $hit
|
||||
* @param bool $hit
|
||||
*/
|
||||
public function setHit($hit)
|
||||
public function setHit(bool $hit)
|
||||
{
|
||||
$this->hit = $hit;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,11 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Budget.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Budget
|
||||
*
|
||||
@@ -41,49 +48,45 @@ class Budget
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addBudgeted($add)
|
||||
public function addBudgeted(string $add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$add = strval(round($add, 2));
|
||||
$this->budgeted = bcadd($this->budgeted, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addLeft($add)
|
||||
public function addLeft(string $add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$add = strval(round($add, 2));
|
||||
$this->left = bcadd($this->left, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addOverspent($add)
|
||||
public function addOverspent(string $add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$add = strval(round($add, 2));
|
||||
$this->overspent = bcadd($this->overspent, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addSpent($add)
|
||||
public function addSpent(string $add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$add = strval(round($add, 2));
|
||||
$this->spent = bcadd($this->spent, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getBudgetLines()
|
||||
public function getBudgetLines(): Collection
|
||||
{
|
||||
return $this->budgetLines;
|
||||
}
|
||||
@@ -91,7 +94,7 @@ class Budget
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBudgeted()
|
||||
public function getBudgeted(): string
|
||||
{
|
||||
return $this->budgeted;
|
||||
}
|
||||
@@ -99,7 +102,7 @@ class Budget
|
||||
/**
|
||||
* @param string $budgeted
|
||||
*/
|
||||
public function setBudgeted($budgeted)
|
||||
public function setBudgeted(string $budgeted)
|
||||
{
|
||||
$this->budgeted = $budgeted;
|
||||
}
|
||||
@@ -107,7 +110,7 @@ class Budget
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLeft()
|
||||
public function getLeft(): string
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
@@ -115,7 +118,7 @@ class Budget
|
||||
/**
|
||||
* @param string $left
|
||||
*/
|
||||
public function setLeft($left)
|
||||
public function setLeft(string $left)
|
||||
{
|
||||
$this->left = $left;
|
||||
}
|
||||
@@ -123,7 +126,7 @@ class Budget
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOverspent()
|
||||
public function getOverspent(): string
|
||||
{
|
||||
return $this->overspent;
|
||||
}
|
||||
@@ -131,7 +134,7 @@ class Budget
|
||||
/**
|
||||
* @param string $overspent
|
||||
*/
|
||||
public function setOverspent($overspent)
|
||||
public function setOverspent(string $overspent)
|
||||
{
|
||||
$this->overspent = strval(round($overspent, 2));
|
||||
}
|
||||
@@ -139,7 +142,7 @@ class Budget
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSpent()
|
||||
public function getSpent(): string
|
||||
{
|
||||
return $this->spent;
|
||||
}
|
||||
@@ -147,7 +150,7 @@ class Budget
|
||||
/**
|
||||
* @param string $spent
|
||||
*/
|
||||
public function setSpent($spent)
|
||||
public function setSpent(string $spent)
|
||||
{
|
||||
$this->spent = strval(round($spent, 2));
|
||||
}
|
||||
|
@@ -1,12 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLine.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BudgetLine
|
||||
*
|
||||
@@ -17,77 +24,77 @@ class BudgetLine
|
||||
|
||||
/** @var BudgetModel */
|
||||
protected $budget;
|
||||
/** @var float */
|
||||
protected $budgeted = 0;
|
||||
/** @var float */
|
||||
protected $left = 0;
|
||||
/** @var float */
|
||||
protected $overspent = 0;
|
||||
/** @var string */
|
||||
protected $budgeted = '0';
|
||||
/** @var string */
|
||||
protected $left = '0';
|
||||
/** @var string */
|
||||
protected $overspent = '0';
|
||||
/** @var LimitRepetition */
|
||||
protected $repetition;
|
||||
/** @var float */
|
||||
protected $spent = 0;
|
||||
/** @var string */
|
||||
protected $spent = '0';
|
||||
|
||||
/**
|
||||
* @return BudgetModel
|
||||
*/
|
||||
public function getBudget()
|
||||
public function getBudget(): BudgetModel
|
||||
{
|
||||
return $this->budget;
|
||||
return $this->budget ?? new BudgetModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetModel $budget
|
||||
*/
|
||||
public function setBudget($budget)
|
||||
public function setBudget(BudgetModel $budget)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getBudgeted()
|
||||
public function getBudgeted(): string
|
||||
{
|
||||
return $this->budgeted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $budgeted
|
||||
* @param string $budgeted
|
||||
*/
|
||||
public function setBudgeted($budgeted)
|
||||
public function setBudgeted(string $budgeted)
|
||||
{
|
||||
$this->budgeted = $budgeted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getLeft()
|
||||
public function getLeft(): string
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $left
|
||||
* @param string $left
|
||||
*/
|
||||
public function setLeft($left)
|
||||
public function setLeft(string $left)
|
||||
{
|
||||
$this->left = $left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getOverspent()
|
||||
public function getOverspent(): string
|
||||
{
|
||||
return $this->overspent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $overspent
|
||||
* @param string $overspent
|
||||
*/
|
||||
public function setOverspent($overspent)
|
||||
public function setOverspent(string $overspent)
|
||||
{
|
||||
$this->overspent = $overspent;
|
||||
}
|
||||
@@ -95,31 +102,31 @@ class BudgetLine
|
||||
/**
|
||||
* @return LimitRepetition
|
||||
*/
|
||||
public function getRepetition()
|
||||
public function getRepetition(): LimitRepetition
|
||||
{
|
||||
return $this->repetition;
|
||||
return $this->repetition ?? new LimitRepetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LimitRepetition $repetition
|
||||
*/
|
||||
public function setRepetition($repetition)
|
||||
public function setRepetition(LimitRepetition $repetition)
|
||||
{
|
||||
$this->repetition = $repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
* @return string
|
||||
*/
|
||||
public function getSpent()
|
||||
public function getSpent(): string
|
||||
{
|
||||
return $this->spent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $spent
|
||||
* @param string $spent
|
||||
*/
|
||||
public function setSpent($spent)
|
||||
public function setSpent(string $spent)
|
||||
{
|
||||
$this->spent = $spent;
|
||||
}
|
||||
|
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Category.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Category as CategoryModel;
|
||||
@@ -7,7 +15,6 @@ use Illuminate\Support\Collection;
|
||||
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Category
|
||||
*
|
||||
@@ -42,19 +49,18 @@ class Category
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addTotal($add)
|
||||
public function addTotal(string $add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$add = strval(round($add, 2));
|
||||
$this->total = bcadd($this->total, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCategories()
|
||||
public function getCategories(): Collection
|
||||
{
|
||||
$set = $this->categories->sortBy(
|
||||
function (CategoryModel $category) {
|
||||
@@ -69,7 +75,7 @@ class Category
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotal()
|
||||
public function getTotal(): string
|
||||
{
|
||||
return strval(round($this->total, 2));
|
||||
}
|
||||
|
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Expense.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
@@ -7,7 +15,6 @@ use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Expense
|
||||
*
|
||||
@@ -33,37 +40,39 @@ class Expense
|
||||
*/
|
||||
public function addOrCreateExpense(TransactionJournal $entry)
|
||||
{
|
||||
bcscale(2);
|
||||
// add each account individually:
|
||||
$destinations = TransactionJournal::destinationTransactionList($entry);
|
||||
|
||||
$accountId = $entry->account_id;
|
||||
$amount = strval(round($entry->amount, 2));
|
||||
if (bccomp('0', $amount) === -1) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
foreach ($destinations as $transaction) {
|
||||
$amount = strval($transaction->amount);
|
||||
$account = $transaction->account;
|
||||
if (bccomp('0', $amount) === -1) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
$object = new stdClass;
|
||||
$object->amount = $amount;
|
||||
$object->name = $account->name;
|
||||
$object->count = 1;
|
||||
$object->id = $account->id;
|
||||
|
||||
// overrule some properties:
|
||||
if ($this->expenses->has($account->id)) {
|
||||
$object = $this->expenses->get($account->id);
|
||||
$object->amount = bcadd($object->amount, $amount);
|
||||
$object->count++;
|
||||
}
|
||||
$this->expenses->put($account->id, $object);
|
||||
}
|
||||
|
||||
if (!$this->expenses->has($accountId)) {
|
||||
$newObject = new stdClass;
|
||||
$newObject->amount = $amount;
|
||||
$newObject->name = $entry->name;
|
||||
$newObject->count = 1;
|
||||
$newObject->id = $accountId;
|
||||
$this->expenses->put($accountId, $newObject);
|
||||
} else {
|
||||
$existing = $this->expenses->get($accountId);
|
||||
$existing->amount = bcadd($existing->amount, $amount);
|
||||
$existing->count++;
|
||||
$this->expenses->put($accountId, $existing);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addToTotal($add)
|
||||
public function addToTotal(string $add)
|
||||
{
|
||||
bcscale(2);
|
||||
|
||||
|
||||
$add = strval(round($add, 2));
|
||||
if (bccomp('0', $add) === -1) {
|
||||
$add = bcmul($add, '-1');
|
||||
@@ -79,7 +88,7 @@ class Expense
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getExpenses()
|
||||
public function getExpenses(): Collection
|
||||
{
|
||||
$set = $this->expenses->sortBy(
|
||||
function (stdClass $object) {
|
||||
@@ -93,7 +102,7 @@ class Expense
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotal()
|
||||
public function getTotal(): string
|
||||
{
|
||||
return strval(round($this->total, 2));
|
||||
}
|
||||
|
@@ -1,5 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Income.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
@@ -7,7 +15,6 @@ use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Income
|
||||
*
|
||||
@@ -19,7 +26,7 @@ class Income
|
||||
/** @var Collection */
|
||||
protected $incomes;
|
||||
/** @var string */
|
||||
protected $total;
|
||||
protected $total = '0';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -34,38 +41,44 @@ class Income
|
||||
*/
|
||||
public function addOrCreateIncome(TransactionJournal $entry)
|
||||
{
|
||||
// add each account individually:
|
||||
$sources = TransactionJournal::sourceTransactionList($entry);
|
||||
|
||||
$accountId = $entry->account_id;
|
||||
if (!$this->incomes->has($accountId)) {
|
||||
$newObject = new stdClass;
|
||||
$newObject->amount = strval(round($entry->amount_positive, 2));
|
||||
$newObject->name = $entry->name;
|
||||
$newObject->count = 1;
|
||||
$newObject->id = $accountId;
|
||||
$this->incomes->put($accountId, $newObject);
|
||||
} else {
|
||||
bcscale(2);
|
||||
$existing = $this->incomes->get($accountId);
|
||||
$existing->amount = bcadd($existing->amount, $entry->amount_positive);
|
||||
$existing->count++;
|
||||
$this->incomes->put($accountId, $existing);
|
||||
foreach ($sources as $transaction) {
|
||||
$amount = strval($transaction->amount);
|
||||
$account = $transaction->account;
|
||||
$amount = bcmul($amount, '-1');
|
||||
|
||||
$object = new stdClass;
|
||||
$object->amount = $amount;
|
||||
$object->name = $account->name;
|
||||
$object->count = 1;
|
||||
$object->id = $account->id;
|
||||
|
||||
// overrule some properties:
|
||||
if ($this->incomes->has($account->id)) {
|
||||
$object = $this->incomes->get($account->id);
|
||||
$object->amount = bcadd($object->amount, $amount);
|
||||
$object->count++;
|
||||
}
|
||||
$this->incomes->put($account->id, $object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $add
|
||||
* @param string $add
|
||||
*/
|
||||
public function addToTotal($add)
|
||||
public function addToTotal(string $add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$add = strval(round($add, 2));
|
||||
$this->total = bcadd($this->total, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getIncomes()
|
||||
public function getIncomes(): Collection
|
||||
{
|
||||
$set = $this->incomes->sortByDesc(
|
||||
function (stdClass $object) {
|
||||
@@ -79,7 +92,7 @@ class Income
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotal()
|
||||
public function getTotal(): string
|
||||
{
|
||||
return strval(round($this->total, 2));
|
||||
}
|
||||
|
@@ -1,9 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* AccountId.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AccountId
|
||||
@@ -16,22 +23,12 @@ class AccountId extends BasicConverter implements ConverterInterface
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
public function convert()
|
||||
public function convert(): Account
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
|
||||
/** @var Account $account */
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
|
||||
/** @var Account $account */
|
||||
$account = Auth::user()->accounts()->find($this->value);
|
||||
|
||||
if (!is_null($account)) {
|
||||
Log::debug('Found ' . $account->accountType->type . ' named "******" with ID: ' . $this->value . ' (not mapped) ');
|
||||
}
|
||||
}
|
||||
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
|
||||
$var = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
|
||||
$account = $crud->find($var);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
@@ -1,9 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Amount.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
@@ -13,14 +19,14 @@ class Amount extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
* @return string
|
||||
*/
|
||||
public function convert()
|
||||
public function convert(): string
|
||||
{
|
||||
if (is_numeric($this->value)) {
|
||||
return $this->value;
|
||||
return strval($this->value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return '0';
|
||||
}
|
||||
}
|
||||
|
36
app/Helpers/Csv/Converter/AmountComma.php
Normal file
36
app/Helpers/Csv/Converter/AmountComma.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* AmountComma.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
/**
|
||||
* Class AmountComma
|
||||
*
|
||||
* Parses the input as the amount with a comma as decimal separator
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class AmountComma extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
*/
|
||||
public function convert(): string
|
||||
{
|
||||
$value = str_replace(',', '.', strval($this->value));
|
||||
|
||||
if (is_numeric($value)) {
|
||||
return strval($value);
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
}
|
@@ -1,8 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccountIban.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Crud\Account\AccountCrudInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
@@ -15,46 +25,38 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
* @return Account
|
||||
*/
|
||||
public function convert()
|
||||
public function convert(): Account
|
||||
{
|
||||
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
|
||||
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
$account = $crud->find(intval($this->mapped[$this->index][$this->value]));
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
|
||||
if (strlen($this->value) > 0) {
|
||||
// find or create new account:
|
||||
$account = $this->findAccount();
|
||||
$accountType = AccountType::where('type', 'Asset account')->first();
|
||||
|
||||
if (is_null($account)) {
|
||||
// create it if doesn't exist.
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'iban' => $this->value,
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
$account = $this->searchOrCreate($crud);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
return null;
|
||||
return new Account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
* @param AccountCrudInterface $crud
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
protected function findAccount()
|
||||
private function searchOrCreate(AccountCrudInterface $crud)
|
||||
{
|
||||
$set = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
|
||||
// find or create new account:
|
||||
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
if ($entry->iban == $this->value) {
|
||||
@@ -63,6 +65,25 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
// create it if doesn't exist.
|
||||
$accountData = [
|
||||
'name' => $this->value,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => $this->value,
|
||||
'accountNumber' => $this->value,
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
];
|
||||
|
||||
$account = $crud->store($accountData);
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccountName.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
@@ -17,34 +26,39 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
public function convert()
|
||||
public function convert(): Account
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
|
||||
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
$account = $crud->find(intval($this->mapped[$this->index][$this->value]));
|
||||
|
||||
return $account;
|
||||
}
|
||||
// find or create new account:
|
||||
$accountType = AccountType::where('type', 'Asset account')->first();
|
||||
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
|
||||
|
||||
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
if ($entry->name == $this->value) {
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
$accountData = [
|
||||
'name' => $this->value,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => null,
|
||||
'accountNumber' => $this->value,
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
];
|
||||
|
||||
// create it if doesnt exist.
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'iban' => '',
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
$account = $crud->store($accountData);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
77
app/Helpers/Csv/Converter/AssetAccountNumber.php
Normal file
77
app/Helpers/Csv/Converter/AssetAccountNumber.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccountNumber.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Class AssetAccountNumber
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class AssetAccountNumber extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
public function convert(): Account
|
||||
{
|
||||
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
|
||||
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = $crud->find(intval($this->mapped[$this->index][$this->value]));
|
||||
|
||||
return $account;
|
||||
}
|
||||
// if not, search for it (or create it):
|
||||
$value = $this->value ?? '';
|
||||
if (strlen($value) > 0) {
|
||||
// find or create new account:
|
||||
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
$accountNumber = $entry->getMeta('accountNumber');
|
||||
if ($accountNumber == $this->value) {
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
$accountData = [
|
||||
'name' => $this->value,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'virtualBalanceCurrency' => 1, // hard coded.
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => null,
|
||||
'accountNumber' => $this->value,
|
||||
'accountRole' => null,
|
||||
'openingBalance' => 0,
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => 1, // hard coded.
|
||||
|
||||
];
|
||||
|
||||
$account = $crud->store($accountData);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
return null; // is this accepted?
|
||||
}
|
||||
|
||||
}
|
@@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* BasicConverter.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
/**
|
||||
* Class BasicConverter
|
||||
*
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.NumberOfChildren)
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class BasicConverter
|
||||
@@ -18,14 +28,12 @@ class BasicConverter
|
||||
/** @var array */
|
||||
protected $mapped;
|
||||
/** @var string */
|
||||
protected $role;
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
public function getData(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
@@ -41,7 +49,7 @@ class BasicConverter
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getField()
|
||||
public function getField(): string
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
@@ -49,7 +57,7 @@ class BasicConverter
|
||||
/**
|
||||
* @param string $field
|
||||
*/
|
||||
public function setField($field)
|
||||
public function setField(string $field)
|
||||
{
|
||||
$this->field = $field;
|
||||
}
|
||||
@@ -57,7 +65,7 @@ class BasicConverter
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getIndex()
|
||||
public function getIndex(): int
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
@@ -65,7 +73,7 @@ class BasicConverter
|
||||
/**
|
||||
* @param int $index
|
||||
*/
|
||||
public function setIndex($index)
|
||||
public function setIndex(int $index)
|
||||
{
|
||||
$this->index = $index;
|
||||
}
|
||||
@@ -73,7 +81,7 @@ class BasicConverter
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMapped()
|
||||
public function getMapped(): array
|
||||
{
|
||||
return $this->mapped;
|
||||
}
|
||||
@@ -81,7 +89,7 @@ class BasicConverter
|
||||
/**
|
||||
* @param array $mapped
|
||||
*/
|
||||
public function setMapped($mapped)
|
||||
public function setMapped(array $mapped)
|
||||
{
|
||||
$this->mapped = $mapped;
|
||||
}
|
||||
@@ -89,23 +97,7 @@ class BasicConverter
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRole()
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $role
|
||||
*/
|
||||
public function setRole($role)
|
||||
{
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
@@ -113,7 +105,7 @@ class BasicConverter
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
public function setValue(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
@@ -1,9 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* BillId.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class BillId
|
||||
@@ -16,14 +24,12 @@ class BillId extends BasicConverter implements ConverterInterface
|
||||
/**
|
||||
* @return Bill
|
||||
*/
|
||||
public function convert()
|
||||
public function convert(): Bill
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$bill = Auth::user()->bills()->find($this->value);
|
||||
}
|
||||
/** @var BillRepositoryInterface $repository */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$value = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
|
||||
$bill = $repository->find($value);
|
||||
|
||||
return $bill;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user