mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-17 11:16:39 +00:00
Compare commits
643 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
cefb7d12bc | ||
|
3c0c15103e | ||
|
a8a8afc2be | ||
|
49e32abd3f | ||
|
7977eefaca | ||
|
f1fa6c3108 | ||
|
2fa0d55f39 | ||
|
5bff509346 | ||
|
a147e9b74a | ||
|
0d87f7c4ca | ||
|
8c675615df | ||
|
7edd1bff40 | ||
|
3bfcb1f3ab | ||
|
7b6c63e6a8 | ||
|
5500e5b0aa | ||
|
e4d249e73c | ||
|
091f6e918b | ||
|
5d9b68c3e7 | ||
|
12a6a61100 | ||
|
7ce3b8d4ef | ||
|
3d9b855849 | ||
|
2346d2ec05 | ||
|
a4c081c8a5 | ||
|
316980efbd | ||
|
a05bc0eed0 | ||
|
4d1c271da6 | ||
|
0dd7ecbfbe | ||
|
0dc188b083 | ||
|
6a553f77f3 | ||
|
a74cef439b | ||
|
9a3cd27700 | ||
|
801c7c0ab6 | ||
|
a95a4e783a | ||
|
af1ee9db93 | ||
|
fcdb6fd2a7 | ||
|
97c0fb389d | ||
|
a9c3992331 | ||
|
a38e057fa7 | ||
|
f83aaf77f1 | ||
|
d92768ecbf | ||
|
b9308cd74a | ||
|
78b577bc9d | ||
|
7d247897ed | ||
|
5dcbdec491 | ||
|
9bf980431e | ||
|
da60bfbcff | ||
|
92553cbc7e | ||
|
8e48e53f17 | ||
|
2f9a4bb79a | ||
|
ac968dd6cd | ||
|
6e4f2c0c8a | ||
|
d662c18ed7 | ||
|
e4ea234707 | ||
|
0b526c0168 | ||
|
2acde5c72a | ||
|
ec8cf2c459 | ||
|
3598780d54 | ||
|
35dd8ac6e6 | ||
|
5ff7c7ffab | ||
|
399db47826 | ||
|
148956a60d | ||
|
3670053a58 | ||
|
e8e2b9704f | ||
|
fcdeebcc06 | ||
|
586ed82e88 | ||
|
cc400d1e2e | ||
|
6edbfb27aa | ||
|
8fc9251b93 | ||
|
10af888a97 | ||
|
89f2328846 | ||
|
48e8cd20b4 | ||
|
394ef23eda | ||
|
62aa1eb487 | ||
|
1500018ccc | ||
|
23fad62d46 | ||
|
3cbf00734f | ||
|
1dc17dd59d | ||
|
f8935c92ea | ||
|
de6f838413 | ||
|
e8a095e543 | ||
|
717c1d080e | ||
|
0ae9afd325 | ||
|
d1b56c2afa | ||
|
8ef7c5ac33 | ||
|
7180a40cd8 | ||
|
71804af624 | ||
|
85dc7f3643 | ||
|
a866d13b75 | ||
|
fcb5e4eabc | ||
|
ade1cf9c19 | ||
|
0f1ec7d003 | ||
|
7e038afece | ||
|
9bb8e182fa | ||
|
e94ae126fd | ||
|
5bb8c6a366 | ||
|
30844df5d4 | ||
|
63e4a410a7 | ||
|
ee9a5d91e2 | ||
|
171ab8a4c3 | ||
|
96740aaac4 | ||
|
2017720096 | ||
|
b77ea6d316 | ||
|
f5adb4047f | ||
|
b082858866 | ||
|
a8a014189d | ||
|
39ea9e85a7 | ||
|
a4d2ed74fc | ||
|
90f2e27f1f | ||
|
a3359ba47a | ||
|
1d2d3523d6 | ||
|
3f40751a1a | ||
|
b5b55e862c | ||
|
c64771b76b | ||
|
ea7ee7ee9a | ||
|
a1f797c4d1 | ||
|
d0c92a2244 | ||
|
6e90c033b1 | ||
|
24f62b8fce | ||
|
d43936155c | ||
|
39dab4fdd9 | ||
|
c0fdf44ad2 | ||
|
4d91f7d23a | ||
|
49af6522a8 | ||
|
3c5f9487a8 | ||
|
f5cb87f5c3 | ||
|
cf543613c9 | ||
|
5c239c91db | ||
|
9920504232 | ||
|
5540697dbd | ||
|
b355c18e0c | ||
|
1e90485c5f | ||
|
dc784c53b5 | ||
|
5a47391a64 | ||
|
8a106bd16a | ||
|
a31ac79173 | ||
|
0d0a604254 | ||
|
724d25f2c2 | ||
|
8ed22d452d | ||
|
d7fef45a56 | ||
|
dc22802dec | ||
|
ce5af7b1d9 | ||
|
0a147e5c9c | ||
|
7d21255f7f | ||
|
13f952f182 | ||
|
b494be228b | ||
|
0fdaac53d0 | ||
|
e1b3a08878 | ||
|
dc893588b0 | ||
|
b9fcc443ec | ||
|
d8586c8043 | ||
|
4252a3e53b | ||
|
dbb5cdb9cf | ||
|
9bdfecbfdc | ||
|
3ec8a8c375 | ||
|
f85e4a24e5 | ||
|
0dda87c78e | ||
|
2fc09ff9d7 | ||
|
e4e0e21293 | ||
|
15089f0d7e | ||
|
7232c1d7bb | ||
|
9a53d8c21c | ||
|
0d198193db | ||
|
45bc23b8af | ||
|
3323c31765 | ||
|
bb7c26b77c | ||
|
9101d6a2c0 | ||
|
ad2b254be0 | ||
|
abc4f856ce | ||
|
b3b66a8f92 | ||
|
2f7cf9b916 | ||
|
b822e0c6e7 | ||
|
6fef9ee72b | ||
|
ab6dd0a1ec | ||
|
9deef5ac92 | ||
|
577187babe | ||
|
577290e813 | ||
|
f3b9798216 | ||
|
4dcaa96d16 | ||
|
0dcbf451d6 | ||
|
e87f6ca40e | ||
|
1f34e33d8c | ||
|
258e87e127 | ||
|
3ec8efcfc1 | ||
|
70ea227bd0 | ||
|
27c832ed58 | ||
|
a31b4ccf01 | ||
|
d221ea68d0 | ||
|
dc9fe58536 | ||
|
f871e29bdb | ||
|
1357352276 | ||
|
e169754693 | ||
|
1cfe4f40ba | ||
|
5545d1c1ba | ||
|
e5f7228fa9 | ||
|
11385494eb | ||
|
ae328de469 | ||
|
0574a706c8 | ||
|
70bb85a75b | ||
|
8cd901b57b | ||
|
8b9818c48e | ||
|
a95099fa46 | ||
|
221e4b7fc0 | ||
|
6cff3eb61e | ||
|
e4fd97ae77 | ||
|
5ca9099654 | ||
|
6e33e26ddf | ||
|
04461a4ab8 | ||
|
a4b9bbff54 | ||
|
4ad4252a77 | ||
|
aac0c9ab98 | ||
|
c123e1044a | ||
|
d25d0454fc | ||
|
f38984398d | ||
|
a07799cfa4 | ||
|
7c52f297ee | ||
|
50a3279b30 | ||
|
0ea14eb987 | ||
|
cf1b98e569 | ||
|
63fb435002 | ||
|
2f8263f53a | ||
|
fb649779d6 | ||
|
bb58f605f7 | ||
|
fccdf56c5d | ||
|
bd53410c71 | ||
|
7d63f124c4 | ||
|
9ffc5d857c | ||
|
2f93784acd | ||
|
d00fbe4eb3 | ||
|
51d9f041ae | ||
|
b872ab8b86 | ||
|
3d25fd79ca | ||
|
3aad78e6ef | ||
|
7d5bb72b0c | ||
|
46e5aae8bb | ||
|
b9e2ee7af3 | ||
|
c1a2892788 | ||
|
2078183e0d | ||
|
fab1d53714 | ||
|
3fe831c7d8 | ||
|
6958f71cfd | ||
|
a7351f348d | ||
|
5379e03447 | ||
|
539058e32d | ||
|
11b6b5a63c | ||
|
1155096226 | ||
|
2920dd356e | ||
|
9c3dac8170 | ||
|
49f9909b15 | ||
|
e4fef6dfc3 | ||
|
2da087401e | ||
|
629baf9de5 | ||
|
29a930dae5 | ||
|
d920537dd2 | ||
|
106b04a5da | ||
|
176752e219 | ||
|
8d19f60091 | ||
|
e937aa2f74 | ||
|
c3ccc4ccdf | ||
|
6c5cd705c0 | ||
|
ce003f217b | ||
|
8c7ef49eb6 | ||
|
29af4bd1b9 | ||
|
2ce5142b06 | ||
|
f3a8a25872 | ||
|
598e97d028 | ||
|
fa110279de | ||
|
8fdeaf73cc | ||
|
a7ffdf062a | ||
|
3bad92dd6d | ||
|
2e88024bca | ||
|
ca2301959c | ||
|
3285fae7f0 | ||
|
312079657b | ||
|
18c183afd6 | ||
|
f424d9cf20 | ||
|
5c3da9fd9e | ||
|
1f321fadd4 | ||
|
65f5d27b12 | ||
|
cdb591de7f | ||
|
a0ea3882e1 | ||
|
a9444ac702 | ||
|
d0c6afc3a9 | ||
|
e7a0a5937c | ||
|
08992b5298 | ||
|
6490a4240d | ||
|
43a7544dd7 | ||
|
0fe70dae17 | ||
|
7079e76886 | ||
|
0ec021c375 | ||
|
ff3396e286 | ||
|
78912903ce | ||
|
4c015e2d12 | ||
|
172634a55a | ||
|
58ca7d551a | ||
|
fd8ed4c9aa | ||
|
c03f5f5ff0 | ||
|
6775fc58c8 | ||
|
9f250fc61b | ||
|
94609f1419 | ||
|
53402aa5e2 | ||
|
5aadb29905 | ||
|
d4f8c41d80 | ||
|
a2e14f8b8d | ||
|
98c4ac955a | ||
|
70b63e1736 | ||
|
106665a468 | ||
|
da5e48d769 | ||
|
85f484e73c | ||
|
d287ae97f8 | ||
|
117bb602dc | ||
|
e440d55034 | ||
|
7f5b94fe43 | ||
|
c58eea6654 | ||
|
bbed5d0701 | ||
|
2775690fc8 | ||
|
1fd9f6e724 | ||
|
3d63903128 | ||
|
ef876a165a | ||
|
c4d6aaeef3 | ||
|
37b735c2e3 | ||
|
62d30c7b0e | ||
|
9cac7d46c0 | ||
|
99b3e24836 | ||
|
ffb699cb06 | ||
|
2947ec0002 | ||
|
5c4d010bde | ||
|
955306d877 | ||
|
015935ed55 | ||
|
48f4cceb19 | ||
|
9850220aac | ||
|
c4ac1460f0 | ||
|
b9e1e01337 | ||
|
76649cb7de | ||
|
5e310776b4 | ||
|
4d7fa11172 | ||
|
28962007c1 | ||
|
2111873bcf | ||
|
0aaf9a6fda | ||
|
186b704509 | ||
|
efe9933721 | ||
|
200366f5be | ||
|
c9bd72337d | ||
|
d4510440b8 | ||
|
5a9cf698f7 | ||
|
5826fec519 | ||
|
7035600984 | ||
|
b1dfb5811f | ||
|
51570a5d08 | ||
|
f065f3a0b8 | ||
|
47376f1f35 | ||
|
bcfe2c6410 | ||
|
09d63b584d | ||
|
5f5469a7d4 | ||
|
38800d61b0 | ||
|
1186e95c51 | ||
|
d870e0f42e | ||
|
0db9852769 | ||
|
7e3f9048fe | ||
|
1ba88f182b | ||
|
c8f5a6b7ad | ||
|
d26bbf3cdc | ||
|
0de72b6914 | ||
|
e41c89bd59 | ||
|
541d9ebdd9 | ||
|
1e724712e0 | ||
|
3682467ae3 | ||
|
7707c81b2d | ||
|
e434de72a3 | ||
|
ce191fa6d3 | ||
|
90865a5284 | ||
|
684f6e0b5c | ||
|
c287bc139c | ||
|
1392275b81 | ||
|
87c0f1d86e | ||
|
a4a723cfc6 | ||
|
921e2c06f4 | ||
|
cb9433f4b9 | ||
|
1be6af820e | ||
|
3b686b6d1c | ||
|
697566fe42 | ||
|
5130ba7ea4 | ||
|
c9e46a4dd1 | ||
|
f5b3dc36e3 | ||
|
f1e8d1cf1e | ||
|
e8e7ab01d2 | ||
|
9244994233 | ||
|
ae768a8525 | ||
|
162c762973 | ||
|
57b5981904 | ||
|
275d19e71d | ||
|
189b11befa | ||
|
a56a5fc228 | ||
|
cbe3fb73a8 | ||
|
3d58fbebec | ||
|
b947ff50ed | ||
|
18d2741814 | ||
|
93a54780ab | ||
|
3d201db6fc | ||
|
9ffc0936ee | ||
|
fbf9e00208 | ||
|
2c826451d1 | ||
|
617a5c0606 | ||
|
8331a7e34a | ||
|
8ee1676f0a | ||
|
5dc8620c43 | ||
|
d2733a4df0 | ||
|
ae649223d8 | ||
|
6267930938 | ||
|
bdee8cde77 | ||
|
e63f216905 | ||
|
ec18165698 | ||
|
307e6a2337 | ||
|
b80d8cf774 | ||
|
7a5ef6013a | ||
|
13b92c47d9 | ||
|
5a79bc0a99 | ||
|
beda6ec3a9 | ||
|
c619b8730b | ||
|
c14ec8b006 | ||
|
10c7786248 | ||
|
08ff08685c | ||
|
8091dbfdfa | ||
|
8dc106b79a | ||
|
7527433738 | ||
|
1502e08a7a | ||
|
c9679f1d4f | ||
|
6b976dd6b9 | ||
|
8da4abf655 | ||
|
2e26193333 | ||
|
ada43bc0dd | ||
|
a447c886c4 | ||
|
288e713f94 | ||
|
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 |
@@ -1,50 +0,0 @@
|
||||
---
|
||||
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:
|
||||
- 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/*
|
21
.env.example
21
.env.example
@@ -1,14 +1,19 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_FORCE_SSL=false
|
||||
APP_FORCE_ROOT=
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
LOG_LEVEL=warning
|
||||
APP_LOG_LEVEL=warning
|
||||
APP_URL=http://localhost
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
@@ -17,17 +22,14 @@ COOKIE_PATH="/"
|
||||
COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
DEFAULT_CURRENCY=EUR
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=enter_your_email_here
|
||||
MAIL_FROM=changeme@example.com
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
@@ -38,7 +40,8 @@ MUST_CONFIRM_ACCOUNT=false
|
||||
SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
|
||||
ANALYTICS_ID=
|
||||
RUNCLEANUP=true
|
||||
SITE_OWNER=mail@example.com
|
||||
|
||||
BLOCKED_DOMAINS=
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_APP_ID=
|
||||
|
37
.env.testing
37
.env.testing
@@ -1,37 +0,0 @@
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=array
|
||||
SESSION_DRIVER=array
|
||||
QUEUE_DRIVER=array
|
||||
|
||||
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
2
.gitattributes
vendored
@@ -1,3 +1,3 @@
|
||||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.less linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
|
13
.gitignore
vendored
Normal file → Executable file
13
.gitignore
vendored
Normal file → Executable file
@@ -1,6 +1,13 @@
|
||||
/vendor
|
||||
/node_modules
|
||||
/public/storage
|
||||
/vendor
|
||||
/.idea
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
.env
|
||||
|
||||
storage/
|
||||
_development
|
||||
.env.local
|
||||
result.html
|
||||
test-import.sh
|
||||
test-import-report.txt
|
||||
public/google*.html
|
||||
|
@@ -4,3 +4,5 @@ tools:
|
||||
filter:
|
||||
excluded_paths:
|
||||
- app/Support/Migration/*
|
||||
- app/database/migrations/*
|
||||
- database/migrations/*
|
||||
|
23
.travis.yml
23
.travis.yml
@@ -1,23 +0,0 @@
|
||||
language: php
|
||||
sudo: false
|
||||
php:
|
||||
- 7
|
||||
|
||||
install:
|
||||
- cp _development/phpunit.xml ./phpunit.xml
|
||||
- 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 --seed
|
||||
|
||||
script:
|
||||
- phpunit
|
198
CHANGELOG.md
198
CHANGELOG.md
@@ -2,10 +2,204 @@
|
||||
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.
|
||||
## [4.1.1] - 2016-10-22
|
||||
### Added
|
||||
- Option to show deposit accounts on the front page.
|
||||
- Script to upgrade split transactions
|
||||
- Can now save notes on piggy banks.
|
||||
- Extend user admin options.
|
||||
- Run import jobs from the command line
|
||||
|
||||
|
||||
### Changed
|
||||
- New preferences screen layout.
|
||||
|
||||
### Deprecated
|
||||
- ``firefly:import`` is now ``firefly:start-import``
|
||||
|
||||
### Removed
|
||||
- Lots of old code
|
||||
|
||||
### Fixed
|
||||
- #357, where non utf-8 files would break Firefly.
|
||||
- Tab delimiter is not properly loaded from import configuration (@roberthorlings)
|
||||
- System response to yearly bills
|
||||
|
||||
## [4.0.2] - 2016-10-14
|
||||
### Added
|
||||
- Added ``intl`` dependency to composer file to ease installation (thanks @telyn)
|
||||
- Added support for Croatian.
|
||||
|
||||
### Changed
|
||||
- Updated all copyright notices to refer to the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
- Fixed #344
|
||||
- Fixed #346, thanks to @SanderKleykens
|
||||
- #351
|
||||
- Did some internal remodelling.
|
||||
|
||||
### Fixed
|
||||
- PostgreSQL compatibility thanks to @SanderKleykens
|
||||
- @RobertHorlings fixed a bug in the ABN Amro import specific.
|
||||
|
||||
|
||||
## [4.0.1] - 2016-10-04
|
||||
### Added
|
||||
- New ING import specific by @tomwerf
|
||||
- New Presidents Choice specific to fix #307
|
||||
- Added some trimming (#335)
|
||||
|
||||
### Changed
|
||||
- Initial release.
|
||||
|
||||
### Deprecated
|
||||
- Initial release.
|
||||
|
||||
### Removed
|
||||
- Initial release.
|
||||
|
||||
### Fixed
|
||||
- Fixed a bug where incoming transactions would not be properly filtered in several reports.
|
||||
- #334 by @cyberkov
|
||||
- #337
|
||||
- #336
|
||||
- #338 found by @roberthorlings
|
||||
|
||||
### Security
|
||||
- Initial release.
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.0.0] - 2015-09-26
|
||||
### Added
|
||||
- Upgraded to Laravel 5.3, most other libraries upgraded as well.
|
||||
- Added GBP as currency, thanks to @Mortalife
|
||||
|
||||
### Changed
|
||||
- Jump to version 4.0.0.
|
||||
- Firefly III is now subject to a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/) license. Previous versions of this software are still MIT licensed.
|
||||
|
||||
### Fixed
|
||||
- Support for specific decimal places, thanks to @Mortalife
|
||||
- Various CSS fixes
|
||||
- Various bugs, thanks to @fuf, @sandermulders and @vissert
|
||||
- Various queries optimized for MySQL 5.7
|
||||
|
||||
## [3.10.4] - 2015-09-14
|
||||
### Fixed
|
||||
- Migration fix by @sandermulders
|
||||
- Tricky import bug fix thanks to @vissert
|
||||
- Currency preference will be correctly pulled from user settings, thanks to @fuf
|
||||
- Simplified code for upgrade instructions.
|
||||
|
||||
|
||||
## [3.10.3] - 2016-08-29
|
||||
### Added
|
||||
- More fields for mass-edit, thanks to @Vissert (#282)
|
||||
- First start of German translation
|
||||
|
||||
### Changed
|
||||
- More optional fields for transactions and the ability to filter them.
|
||||
|
||||
### Removed
|
||||
- Preference for budget maximum.
|
||||
|
||||
### Fixed
|
||||
- A bug in the translation routine broke the import.
|
||||
- It was possible to destroy your Firefly installation by removing all currencies. Thanks @mondjef
|
||||
- Translation bugs.
|
||||
- Import bug.
|
||||
|
||||
### Security
|
||||
- Firefly will not accept registrations beyond the first one, by default.
|
||||
|
||||
|
||||
## [3.10.2] - 2016-08-29
|
||||
### Added
|
||||
- New Chinese translations. Set Firefly III to show incomplete translations to follow the progress. Want to translate Firefly III in Chinese, or in any other language? Then check out [the Crowdin project](https://crowdin.com/project/firefly-iii).
|
||||
- Added more admin pages. They do nothing yet.
|
||||
|
||||
### Changed
|
||||
- Import routine will now also apply user rules.
|
||||
- Various code cleanup.
|
||||
- Some small HTML changes.
|
||||
|
||||
### Fixed
|
||||
- Bug in the mass edit routines.
|
||||
- Firefly III over a proxy will now work (see [issue #290](https://github.com/JC5/firefly-iii/issues/290)), thanks @dfiel for reporting.
|
||||
- Sneaky bug in the import routine, fixed by @Bonno
|
||||
|
||||
## [3.10.1] - 2016-08-25
|
||||
### Added
|
||||
- More feedback in the import procedure.
|
||||
- Extended model for import job.
|
||||
- Web bases import procedure.
|
||||
|
||||
|
||||
### Changed
|
||||
- Scrutinizer configuration
|
||||
- Various code clean up.
|
||||
|
||||
### Removed
|
||||
- Code climate YAML file.
|
||||
|
||||
### Fixed
|
||||
- Fixed a bug where a migration would check an empty table name.
|
||||
- Fixed various bugs in the import routine.
|
||||
- Fixed various bugs in the piggy banks pages.
|
||||
- Fixed a bug in the ``firefly:verify`` routine
|
||||
|
||||
## [3.10] - 2015-05-25
|
||||
### Added
|
||||
- New charts in year report
|
||||
- Can add / remove money from piggy bank on mobile device.
|
||||
- Bill overview shows some useful things.
|
||||
- Firefly will track registration / activation IP addresses.
|
||||
|
||||
|
||||
### Changed
|
||||
- Rewrote the import routine.
|
||||
- The date picker now supports more ranges and periods.
|
||||
- Rewrote all migrations. #272
|
||||
|
||||
### Fixed
|
||||
- Issue #264
|
||||
- Issue #265
|
||||
- Fixed amount calculation problems, #266, thanks @xzaz
|
||||
- Issue #271
|
||||
- Issue #278, #273, thanks @StevenReitsma and @rubella
|
||||
- Bug in attachment download routine would report the wrong size to the user's browser.
|
||||
- Various NULL errors fixed.
|
||||
- Various strict typing errors fixed.
|
||||
- Fixed pagination problems, #276, thanks @xzaz
|
||||
- Fixed a bug where an expense would be assigned to a piggy bank if you created a transfer first.
|
||||
- Bulk update problems, #280, thanks @stickgrinder
|
||||
- Fixed various problems with amount reporting of split transactions.
|
||||
|
||||
[3.9.1]
|
||||
### Fixed
|
||||
- Fixed a bug where removing money from a piggy bank would not work. See issue #265 and #269
|
||||
|
||||
[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.
|
||||
|
4
LICENSE
4
LICENSE
@@ -1,7 +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:
|
||||
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
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.
|
||||
|
24
README.md
24
README.md
@@ -1,16 +1,18 @@
|
||||
# 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://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://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
## A personal finances manager
|
||||
|
||||
## About
|
||||
[](https://i.nder.be/hhfv03hp) [](https://i.nder.be/hhmwmqw9)
|
||||
|
||||
"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.
|
||||
[](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.
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -24,3 +26,5 @@ Firefly works on the principle that if you know where you're money is going, you
|
||||
- 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/).
|
||||
|
||||
If you want to contact me, please open an issue or [email me](mailto:thegrumpydictator@gmail.com).
|
@@ -1 +0,0 @@
|
||||
src_dir: .
|
@@ -1,2 +0,0 @@
|
||||
--exclude-exts=.min.css
|
||||
--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes
|
@@ -1 +0,0 @@
|
||||
**/*{.,-}min.js
|
@@ -1,213 +0,0 @@
|
||||
ecmaFeatures:
|
||||
modules: true
|
||||
jsx: true
|
||||
|
||||
env:
|
||||
amd: true
|
||||
browser: true
|
||||
es6: true
|
||||
jquery: true
|
||||
node: true
|
||||
|
||||
# http://eslint.org/docs/rules/
|
||||
rules:
|
||||
# Possible Errors
|
||||
comma-dangle: [2, never]
|
||||
no-cond-assign: 2
|
||||
no-console: 0
|
||||
no-constant-condition: 2
|
||||
no-control-regex: 2
|
||||
no-debugger: 2
|
||||
no-dupe-args: 2
|
||||
no-dupe-keys: 2
|
||||
no-duplicate-case: 2
|
||||
no-empty: 2
|
||||
no-empty-character-class: 2
|
||||
no-ex-assign: 2
|
||||
no-extra-boolean-cast: 2
|
||||
no-extra-parens: 0
|
||||
no-extra-semi: 2
|
||||
no-func-assign: 2
|
||||
no-inner-declarations: [2, functions]
|
||||
no-invalid-regexp: 2
|
||||
no-irregular-whitespace: 2
|
||||
no-negated-in-lhs: 2
|
||||
no-obj-calls: 2
|
||||
no-regex-spaces: 2
|
||||
no-sparse-arrays: 2
|
||||
no-unexpected-multiline: 2
|
||||
no-unreachable: 2
|
||||
use-isnan: 2
|
||||
valid-jsdoc: 0
|
||||
valid-typeof: 2
|
||||
|
||||
# Best Practices
|
||||
accessor-pairs: 2
|
||||
block-scoped-var: 0
|
||||
complexity: [2, 6]
|
||||
consistent-return: 0
|
||||
curly: 0
|
||||
default-case: 0
|
||||
dot-location: 0
|
||||
dot-notation: 0
|
||||
eqeqeq: 2
|
||||
guard-for-in: 2
|
||||
no-alert: 2
|
||||
no-caller: 2
|
||||
no-case-declarations: 2
|
||||
no-div-regex: 2
|
||||
no-else-return: 0
|
||||
no-empty-label: 2
|
||||
no-empty-pattern: 2
|
||||
no-eq-null: 2
|
||||
no-eval: 2
|
||||
no-extend-native: 2
|
||||
no-extra-bind: 2
|
||||
no-fallthrough: 2
|
||||
no-floating-decimal: 0
|
||||
no-implicit-coercion: 0
|
||||
no-implied-eval: 2
|
||||
no-invalid-this: 0
|
||||
no-iterator: 2
|
||||
no-labels: 0
|
||||
no-lone-blocks: 2
|
||||
no-loop-func: 2
|
||||
no-magic-number: 0
|
||||
no-multi-spaces: 0
|
||||
no-multi-str: 0
|
||||
no-native-reassign: 2
|
||||
no-new-func: 2
|
||||
no-new-wrappers: 2
|
||||
no-new: 2
|
||||
no-octal-escape: 2
|
||||
no-octal: 2
|
||||
no-proto: 2
|
||||
no-redeclare: 2
|
||||
no-return-assign: 2
|
||||
no-script-url: 2
|
||||
no-self-compare: 2
|
||||
no-sequences: 0
|
||||
no-throw-literal: 0
|
||||
no-unused-expressions: 2
|
||||
no-useless-call: 2
|
||||
no-useless-concat: 2
|
||||
no-void: 2
|
||||
no-warning-comments: 0
|
||||
no-with: 2
|
||||
radix: 2
|
||||
vars-on-top: 0
|
||||
wrap-iife: 2
|
||||
yoda: 0
|
||||
|
||||
# Strict
|
||||
strict: 0
|
||||
|
||||
# Variables
|
||||
init-declarations: 0
|
||||
no-catch-shadow: 2
|
||||
no-delete-var: 2
|
||||
no-label-var: 2
|
||||
no-shadow-restricted-names: 2
|
||||
no-shadow: 0
|
||||
no-undef-init: 2
|
||||
no-undef: 0
|
||||
no-undefined: 0
|
||||
no-unused-vars: 0
|
||||
no-use-before-define: 0
|
||||
|
||||
# Node.js and CommonJS
|
||||
callback-return: 2
|
||||
global-require: 2
|
||||
handle-callback-err: 2
|
||||
no-mixed-requires: 0
|
||||
no-new-require: 0
|
||||
no-path-concat: 2
|
||||
no-process-exit: 2
|
||||
no-restricted-modules: 0
|
||||
no-sync: 0
|
||||
|
||||
# Stylistic Issues
|
||||
array-bracket-spacing: 0
|
||||
block-spacing: 0
|
||||
brace-style: 0
|
||||
camelcase: 0
|
||||
comma-spacing: 0
|
||||
comma-style: 0
|
||||
computed-property-spacing: 0
|
||||
consistent-this: 0
|
||||
eol-last: 0
|
||||
func-names: 0
|
||||
func-style: 0
|
||||
id-length: 0
|
||||
id-match: 0
|
||||
indent: 0
|
||||
jsx-quotes: 0
|
||||
key-spacing: 0
|
||||
linebreak-style: 0
|
||||
lines-around-comment: 0
|
||||
max-depth: 0
|
||||
max-len: 0
|
||||
max-nested-callbacks: 0
|
||||
max-params: 0
|
||||
max-statements: [2, 30]
|
||||
new-cap: 0
|
||||
new-parens: 0
|
||||
newline-after-var: 0
|
||||
no-array-constructor: 0
|
||||
no-bitwise: 0
|
||||
no-continue: 0
|
||||
no-inline-comments: 0
|
||||
no-lonely-if: 0
|
||||
no-mixed-spaces-and-tabs: 0
|
||||
no-multiple-empty-lines: 0
|
||||
no-negated-condition: 0
|
||||
no-nested-ternary: 0
|
||||
no-new-object: 0
|
||||
no-plusplus: 0
|
||||
no-restricted-syntax: 0
|
||||
no-spaced-func: 0
|
||||
no-ternary: 0
|
||||
no-trailing-spaces: 0
|
||||
no-underscore-dangle: 0
|
||||
no-unneeded-ternary: 0
|
||||
object-curly-spacing: 0
|
||||
one-var: 0
|
||||
operator-assignment: 0
|
||||
operator-linebreak: 0
|
||||
padded-blocks: 0
|
||||
quote-props: 0
|
||||
quotes: 0
|
||||
require-jsdoc: 0
|
||||
semi-spacing: 0
|
||||
semi: 0
|
||||
sort-vars: 0
|
||||
space-after-keywords: 0
|
||||
space-before-blocks: 0
|
||||
space-before-function-paren: 0
|
||||
space-before-keywords: 0
|
||||
space-in-parens: 0
|
||||
space-infix-ops: 0
|
||||
space-return-throw-case: 0
|
||||
space-unary-ops: 0
|
||||
spaced-comment: 0
|
||||
wrap-regex: 0
|
||||
|
||||
# ECMAScript 6
|
||||
arrow-body-style: 0
|
||||
arrow-parens: 0
|
||||
arrow-spacing: 0
|
||||
constructor-super: 0
|
||||
generator-star-spacing: 0
|
||||
no-arrow-condition: 0
|
||||
no-class-assign: 0
|
||||
no-const-assign: 0
|
||||
no-dupe-class-members: 0
|
||||
no-this-before-super: 0
|
||||
no-var: 0
|
||||
object-shorthand: 0
|
||||
prefer-arrow-callback: 0
|
||||
prefer-const: 0
|
||||
prefer-reflect: 0
|
||||
prefer-spread: 0
|
||||
prefer-template: 0
|
||||
require-yield: 0
|
@@ -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,27 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="JamesStandard">
|
||||
<rule ref="Zend">
|
||||
<exclude name="Zend.NamingConventions.ValidVariableName" />
|
||||
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace" />
|
||||
<!--<exclude name="PEAR.Whitespace.ScopeIndent"/>-->
|
||||
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace"/>
|
||||
<exclude name="Generic.Formatting.MultipleStatementAlignment.Incorrect" />
|
||||
<exclude name="PEAR.Functions.FunctionCallSignature" />
|
||||
|
||||
</rule>
|
||||
<!--
|
||||
Here we change two messages from the same sniff. Note how the
|
||||
codes are slightly different because the sniff developer has
|
||||
defined both a MaxExceeded message and a TooLong message. In the
|
||||
case of this sniff, one is used for warnings and one is used
|
||||
for errors.
|
||||
-->
|
||||
<rule ref="Generic.Files.LineLength">
|
||||
<properties>
|
||||
<property name="lineLimit" value="160"/>
|
||||
<property name="absoluteLineLimit" value="160"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
|
||||
</ruleset>
|
@@ -1,322 +0,0 @@
|
||||
<code_scheme name="Use This One">
|
||||
<option name="RIGHT_MARGIN" value="160" />
|
||||
<CoffeeScriptCodeStyleSettings>
|
||||
<option name="SPACE_BEFORE_PROPERTY_COLON" value="true" />
|
||||
</CoffeeScriptCodeStyleSettings>
|
||||
<JSCodeStyleSettings>
|
||||
<option name="ALIGN_MULTILINE_VAR_DECLARATION" value="true" />
|
||||
</JSCodeStyleSettings>
|
||||
<PHPCodeStyleSettings>
|
||||
<option name="ALIGN_KEY_VALUE_PAIRS" value="true" />
|
||||
<option name="ALIGN_PHPDOC_PARAM_NAMES" value="true" />
|
||||
<option name="ALIGN_PHPDOC_COMMENTS" value="true" />
|
||||
<option name="ALIGN_ASSIGNMENTS" value="true" />
|
||||
<option name="COMMA_AFTER_LAST_ARRAY_ELEMENT" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
|
||||
<option name="PHPDOC_WRAP_LONG_LINES" value="true" />
|
||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
||||
<option name="BLANK_LINE_BEFORE_RETURN_STATEMENT" value="true" />
|
||||
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
|
||||
<option name="ALIGN_CLASS_CONSTANTS" value="true" />
|
||||
<option name="FORCE_SHORT_DECLARATION_ARRAY_STYLE" value="true" />
|
||||
</PHPCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="CoffeeScript">
|
||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="PHP">
|
||||
<option name="RIGHT_MARGIN" value="160" />
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
|
||||
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
|
||||
<option name="ALIGN_GROUP_FIELD_DECLARATIONS" value="true" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="FOR_STATEMENT_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||
<option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<arrangement>
|
||||
<tokens>
|
||||
<token id="modifiers" name="modifiers">
|
||||
<rules>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</rules>
|
||||
</token>
|
||||
<token id="visibility" name="visibility">
|
||||
<rules>
|
||||
<rule>
|
||||
<match>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
</match>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
</match>
|
||||
</rule>
|
||||
<rule>
|
||||
<match>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
</match>
|
||||
</rule>
|
||||
</rules>
|
||||
</token>
|
||||
</tokens>
|
||||
<groups>
|
||||
<group>
|
||||
<type>GETTERS_AND_SETTERS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
</groups>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<CONST />
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD />
|
||||
<PUBLIC />
|
||||
<STATIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD />
|
||||
<PROTECTED />
|
||||
<STATIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD />
|
||||
<PRIVATE />
|
||||
<STATIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD />
|
||||
<PUBLIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD />
|
||||
<PROTECTED />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD />
|
||||
<PRIVATE />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<CONSTRUCTOR />
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD />
|
||||
<PUBLIC />
|
||||
<STATIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD />
|
||||
<PROTECTED />
|
||||
<STATIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD />
|
||||
<PRIVATE />
|
||||
<STATIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD />
|
||||
<PUBLIC />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD />
|
||||
<PROTECTED />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD />
|
||||
<PRIVATE />
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<TRAIT />
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<INTERFACE />
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<CLASS />
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
@@ -1,63 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set testing environment
|
||||
cp .env.testing .env
|
||||
|
||||
# set cover:
|
||||
cp phpunit.cover.xml phpunit.xml
|
||||
|
||||
# delete test databases:
|
||||
if [ -f storage/database/testing.db ]
|
||||
then
|
||||
echo "Will not remove test db"
|
||||
# rm storage/database/testing.db
|
||||
fi
|
||||
|
||||
if [ -f storage/database/testing-copy.db ]
|
||||
then
|
||||
echo "Will not remove test db"
|
||||
# rm storage/database/testing-copy.db
|
||||
fi
|
||||
|
||||
# test!
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Running all tests..."
|
||||
phpunit
|
||||
fi
|
||||
|
||||
# test selective..
|
||||
dirs=("acceptance/Controllers" "acceptance/Controllers/Auth" "acceptance/Controllers/Chart" "unit")
|
||||
#
|
||||
if [ ! -z "$1" ]
|
||||
then
|
||||
for i in "${dirs[@]}"
|
||||
do
|
||||
firstFile="./tests/$i/$1.php"
|
||||
secondFile="./tests/$i/$1Test.php"
|
||||
if [ -f "$firstFile" ]
|
||||
then
|
||||
# run it!
|
||||
echo "Now running $firstFile"
|
||||
phpunit $firstFile
|
||||
result=$?
|
||||
fi
|
||||
if [ -f "$secondFile" ]
|
||||
then
|
||||
# run it!
|
||||
echo "Now running $secondFile"
|
||||
phpunit $secondFile
|
||||
result=$?
|
||||
fi
|
||||
|
||||
|
||||
done
|
||||
fi
|
||||
|
||||
# restore .env file
|
||||
cp .env.local .env
|
||||
|
||||
# restore cover
|
||||
cp phpunit.default.xml phpunit.xml
|
||||
|
||||
exit ${result}
|
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="pcsg-generated-ruleset"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>Created with the PHP Coding Standard Generator. http://edorian.github.com/php-coding-standard-generator/
|
||||
</description>
|
||||
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
|
||||
<properties>
|
||||
<property name="reportLevel" value="5"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml/NPathComplexity">
|
||||
<properties>
|
||||
<property name="minimum" value="128"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength">
|
||||
<properties>
|
||||
<property name="minimum" value="40"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml/ExcessiveParameterList">
|
||||
<properties>
|
||||
<property name="minimum" value="5"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<!-- Import rule set and exclude rules -->
|
||||
<rule ref="rulesets/controversial.xml">
|
||||
<exclude name="CamelCasePropertyName" />
|
||||
</rule>
|
||||
|
||||
|
||||
</ruleset>
|
@@ -1,5 +0,0 @@
|
||||
suites:
|
||||
main:
|
||||
namespace: FireflyIII
|
||||
psr4_prefix: FireflyIII
|
||||
src_path: app
|
@@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ phpunit.cover.xml
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="bootstrap/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="Application Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">app/Http</directory>
|
||||
</whitelist>
|
||||
<blacklist>
|
||||
<directory>vendor/</directory>
|
||||
<directory>app/Console</directory>
|
||||
<directory>app/Events</directory>
|
||||
<directory>app/Exceptions</directory>
|
||||
<directory>app/Generator</directory>
|
||||
<directory>app/Handlers</directory>
|
||||
<directory>app/Helpers</directory>
|
||||
|
||||
<directory>app/Jobs</directory>
|
||||
<directory>app/Listeners</directory>
|
||||
<directory>app/Models</directory>
|
||||
<directory>app/Policies</directory>
|
||||
<directory>app/Providers</directory>
|
||||
<directory>app/Repositories</directory>
|
||||
<directory>app/Rules</directory>
|
||||
<directory>app/Sql</directory>
|
||||
<directory>app/Support</directory>
|
||||
<directory>app/Validation</directory>
|
||||
|
||||
<!-- and other directories, -->
|
||||
</blacklist>
|
||||
</filter>
|
||||
<!--
|
||||
Code coverage has never been slower.
|
||||
-->
|
||||
<logging>
|
||||
<log type="coverage-clover" target="./storage/build/clover.xml" charset="UTF-8" />
|
||||
</logging>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
</php>
|
||||
</phpunit>
|
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="bootstrap/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="true">
|
||||
<testsuites>
|
||||
<testsuite name="Application Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">app/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
</php>
|
||||
|
||||
<listeners>
|
||||
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
|
||||
</listeners>
|
||||
</phpunit>
|
@@ -1,103 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
searchFile=""
|
||||
deleteDatabases=false
|
||||
|
||||
while getopts ":nhf:" opt; do
|
||||
case $opt in
|
||||
n)
|
||||
# echo "-n was triggered: new database!" >&2
|
||||
deleteDatabases=true
|
||||
;;
|
||||
f)
|
||||
#echo "-f was triggered: file! $OPTARG" >&2
|
||||
searchFile=$OPTARG
|
||||
;;
|
||||
h)
|
||||
echo "n: new database" >&2
|
||||
echo "f: which file to run" >&2
|
||||
;;
|
||||
:)
|
||||
echo "Option -$OPTARG requires an argument." >&2
|
||||
exit 1
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# set testing environment
|
||||
cp .env.testing .env
|
||||
|
||||
# set default phpunit.
|
||||
cp phpunit.default.xml phpunit.xml
|
||||
|
||||
# "create" default attachment:
|
||||
touch storage/upload/at-1.data
|
||||
touch storage/upload/at-2.data
|
||||
|
||||
# delete databses:
|
||||
if [ "$deleteDatabases" = true ] ; then
|
||||
echo "Will delete and recreate the databases."
|
||||
|
||||
# delete test database:
|
||||
if [ -f storage/database/testing.db ]
|
||||
then
|
||||
echo "Deleted testing.db"
|
||||
rm storage/database/testing.db
|
||||
fi
|
||||
|
||||
# delete test database copy:
|
||||
if [ -f storage/database/testing-copy.db ]
|
||||
then
|
||||
echo "Delete testing-copy.db"
|
||||
rm storage/database/testing-copy.db
|
||||
fi
|
||||
fi
|
||||
|
||||
# do not delete database:
|
||||
if [ "$deleteDatabases" = false ] ; then
|
||||
echo "Will not delete databases."
|
||||
fi
|
||||
|
||||
# test!
|
||||
if [ "$searchFile" == "" ]
|
||||
then
|
||||
echo "Running all tests..."
|
||||
phpunit
|
||||
result=$?
|
||||
fi
|
||||
|
||||
# test selective..
|
||||
dirs=("acceptance/Controllers" "acceptance/Controllers/Auth" "acceptance/Controllers/Chart" "unit")
|
||||
#
|
||||
if [ "$searchFile" != "" ]
|
||||
then
|
||||
echo "Will run test for '$searchFile'"
|
||||
for i in "${dirs[@]}"
|
||||
do
|
||||
firstFile="./tests/$i/$searchFile.php"
|
||||
secondFile="./tests/$i/"$searchFile"Test.php"
|
||||
if [ -f "$firstFile" ]
|
||||
then
|
||||
# run it!
|
||||
echo "Found file '$firstFile'"
|
||||
phpunit --verbose $firstFile
|
||||
result=$?
|
||||
fi
|
||||
if [ -f "$secondFile" ]
|
||||
then
|
||||
# run it!
|
||||
echo "Found file '$secondFile'"
|
||||
phpunit --verbose $secondFile
|
||||
result=$?
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# restore .env file
|
||||
cp .env.local .env
|
||||
|
||||
exit ${result}
|
@@ -1 +0,0 @@
|
||||
These are some of the files I use for code formatting, PHPMD and PHPCS.
|
@@ -3,15 +3,19 @@
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Bootstrap;
|
||||
|
||||
use Illuminate\Log\Writer;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Foundation\Bootstrap\ConfigureLogging as IlluminateConfigureLogging;
|
||||
use Illuminate\Log\Writer;
|
||||
|
||||
/**
|
||||
* Class ConfigureLogging
|
||||
@@ -20,24 +24,40 @@ use Illuminate\Foundation\Bootstrap\ConfigureLogging as IlluminateConfigureLoggi
|
||||
*/
|
||||
class ConfigureLogging extends IlluminateConfigureLogging
|
||||
{
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param Writer $log
|
||||
*/
|
||||
protected function configureSingleHandler(Application $app, Writer $log)
|
||||
{
|
||||
$log->useFiles($app->storagePath().'/logs/firefly-iii.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param Writer $log
|
||||
* Configure the Monolog handlers for the application.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @param \Illuminate\Log\Writer $log
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureDailyHandler(Application $app, Writer $log)
|
||||
{
|
||||
$config = $app->make('config');
|
||||
|
||||
$maxFiles = $config->get('app.log_max_files');
|
||||
|
||||
$log->useDailyFiles(
|
||||
$app->storagePath().'/logs/firefly-iii.log',
|
||||
$app->make('config')->get('app.log_max_files', 5)
|
||||
$app->storagePath() . '/logs/firefly-iii.log', is_null($maxFiles) ? 5 : $maxFiles,
|
||||
$config->get('app.log_level', 'debug')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the Monolog handlers for the application.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @param \Illuminate\Log\Writer $log
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureSingleHandler(Application $app, Writer $log)
|
||||
{
|
||||
$log->useFiles(
|
||||
$app->storagePath() . '/logs/firefly-iii.log',
|
||||
$app->make('config')->get('app.log_level', 'debug')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
152
app/Console/Commands/CreateImport.php
Normal file
152
app/Console/Commands/CreateImport.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* CreateImport.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Artisan;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class CreateImport
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class CreateImport extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Use this command to create a new import. Your user ID can be found on the /profile page.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:create-import {file} {configuration} {--user=1} {--type=csv} {--start}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// find the file
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
$file = $this->argument('file');
|
||||
$configuration = $this->argument('configuration');
|
||||
$user = $userRepository->find(intval($this->option('user')));
|
||||
$cwd = getcwd();
|
||||
$type = strtolower($this->option('type'));
|
||||
|
||||
if (!$this->validArguments()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// try to parse configuration data:
|
||||
$configurationData = json_decode(file_get_contents($configuration));
|
||||
if (is_null($configurationData)) {
|
||||
$this->error(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->info(sprintf('Going to create a job to import file: %s', $file));
|
||||
$this->info(sprintf('Using configuration file: %s', $configuration));
|
||||
$this->info(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
|
||||
$this->info(sprintf('Type of import: %s', $type));
|
||||
|
||||
/** @var ImportJobRepositoryInterface $jobRepository */
|
||||
$jobRepository = app(ImportJobRepositoryInterface::class, [$user]);
|
||||
|
||||
$job = $jobRepository->create($type);
|
||||
$this->line(sprintf('Created job "%s"...', $job->key));
|
||||
|
||||
// put the file in the proper place:
|
||||
Artisan::call('firefly:encrypt', ['file' => $file, 'key' => $job->key]);
|
||||
$this->line('Stored import data...');
|
||||
|
||||
// store the configuration in the job:
|
||||
$job->configuration = $configurationData;
|
||||
$job->status = 'settings_complete';
|
||||
$job->save();
|
||||
$this->line('Stored configuration...');
|
||||
|
||||
// if user wants to run it, do!
|
||||
if ($this->option('start') === true) {
|
||||
$this->line('The import will start in a moment. This process is not visible...');
|
||||
Log::debug('Go for import!');
|
||||
Artisan::call('firefly:start-import', ['key' => $job->key]);
|
||||
$this->line('Done!');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function validArguments(): bool
|
||||
{
|
||||
// find the file
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
$file = $this->argument('file');
|
||||
$configuration = $this->argument('configuration');
|
||||
$user = $userRepository->find(intval($this->option('user')));
|
||||
$cwd = getcwd();
|
||||
$validTypes = array_keys(config('firefly.import_formats'));
|
||||
$type = strtolower($this->option('type'));
|
||||
|
||||
if (is_null($user->id)) {
|
||||
$this->error(sprintf('There is no user with ID %d.', $this->option('user')));
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!in_array($type, $validTypes)) {
|
||||
$this->error(sprintf('Cannot import file of type "%s"', $type));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($file)) {
|
||||
$this->error(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($configuration)) {
|
||||
$this->error(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
68
app/Console/Commands/EncryptFile.php
Normal file
68
app/Console/Commands/EncryptFile.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* EncryptFile.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Crypt;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class EncryptFile
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class EncryptFile extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Encrypts a file and places it in the storage/upload directory.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:encrypt {file} {key}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$file = e(strval($this->argument('file')));
|
||||
if (!file_exists($file)) {
|
||||
$this->error(sprintf('File "%s" does not seem to exist.', $file));
|
||||
|
||||
return;
|
||||
}
|
||||
$content = file_get_contents($file);
|
||||
$content = Crypt::encrypt($content);
|
||||
$newName = e(strval($this->argument('key'))) . '.upload';
|
||||
|
||||
$path = storage_path('upload') . '/' . $newName;
|
||||
file_put_contents($path, $content);
|
||||
$this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path));
|
||||
}
|
||||
}
|
125
app/Console/Commands/Import.php
Normal file
125
app/Console/Commands/Import.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* Import.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use FireflyIII\Import\ImportProcedure;
|
||||
use FireflyIII\Import\Logging\CommandHandler;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Import
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class Import extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This will start a new import.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:start-import {key}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Log::debug('Start start-import command');
|
||||
$jobKey = $this->argument('key');
|
||||
$job = ImportJob::whereKey($jobKey)->first();
|
||||
if (!$this->isValid($job)) {
|
||||
Log::error('Job is not valid for some reason. Exit.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->line('Going to import job with key "' . $job->key . '" of type ' . $job->file_type);
|
||||
|
||||
$monolog = Log::getMonolog();
|
||||
$handler = new CommandHandler($this);
|
||||
$monolog->pushHandler($handler);
|
||||
|
||||
$result = ImportProcedure::runImport($job);
|
||||
|
||||
|
||||
/**
|
||||
* @var int $index
|
||||
* @var TransactionJournal $journal
|
||||
*/
|
||||
foreach ($result as $index => $journal) {
|
||||
if (!is_null($journal->id)) {
|
||||
$this->line(sprintf('Line #%d has been imported as transaction #%d.', $index, $journal->id));
|
||||
continue;
|
||||
}
|
||||
$this->error(sprintf('Could not store line #%d', $index));
|
||||
}
|
||||
|
||||
$this->line('The import has completed.');
|
||||
|
||||
// get any errors from the importer:
|
||||
$extendedStatus = $job->extended_status;
|
||||
if (isset($extendedStatus['errors']) && count($extendedStatus['errors']) > 0) {
|
||||
$this->line(sprintf('The following %d error(s) occured during the import:', count($extendedStatus['errors'])));
|
||||
foreach ($extendedStatus['errors'] as $error) {
|
||||
$this->error($error);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValid(ImportJob $job): bool
|
||||
{
|
||||
if (is_null($job)) {
|
||||
$this->error('This job does not seem to exist.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($job->status != 'settings_complete') {
|
||||
$this->error('This job is not ready to be imported.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
101
app/Console/Commands/ScanAttachments.php
Normal file
101
app/Console/Commands/ScanAttachments.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* ScanAttachments.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Crypt;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||
use Storage;
|
||||
|
||||
/**
|
||||
* Class ScanAttachments
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class ScanAttachments extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Rescan all attachments and re-set the MD5 hash and mime.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:scan-attachments';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$attachments = Attachment::get();
|
||||
$disk = Storage::disk('upload');
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($attachments as $attachment) {
|
||||
$fileName = $attachment->fileName();
|
||||
|
||||
// try to grab file content:
|
||||
try {
|
||||
$content = $disk->get($fileName);
|
||||
} catch (FileNotFoundException $e) {
|
||||
$this->error(sprintf('Could not find data for attachment #%d', $attachment->id));
|
||||
continue;
|
||||
}
|
||||
// try to decrypt content.
|
||||
try {
|
||||
$decrypted = Crypt::decrypt($content);
|
||||
} catch (DecryptException $e) {
|
||||
$this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id));
|
||||
continue;
|
||||
}
|
||||
|
||||
// make temp file:
|
||||
$tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII');
|
||||
|
||||
// store content in temp file:
|
||||
file_put_contents($tmpfname, $decrypted);
|
||||
|
||||
// get md5 and mime
|
||||
$md5 = md5_file($tmpfname);
|
||||
$mime = mime_content_type($tmpfname);
|
||||
|
||||
// update attachment:
|
||||
$attachment->md5 = $md5;
|
||||
$attachment->mime = $mime;
|
||||
$attachment->save();
|
||||
|
||||
|
||||
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
||||
|
||||
// find file:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
121
app/Console/Commands/UpgradeDatabase.php
Normal file
121
app/Console/Commands/UpgradeDatabase.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* UpgradeDatabase.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class UpgradeDatabase
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class UpgradeDatabase extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Will run various commands to update database records.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:upgrade-database';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->setTransactionIdentifier();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is strangely complex, because the HAVING modifier is a no-no. And subqueries in Laravel are weird.
|
||||
*/
|
||||
private function setTransactionIdentifier()
|
||||
{
|
||||
$subQuery = TransactionJournal
|
||||
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->groupBy(['transaction_journals.id'])
|
||||
->select(['transaction_journals.id', DB::raw('COUNT(transactions.id) AS t_count')]);
|
||||
|
||||
$result = DB::table(DB::raw('(' . $subQuery->toSql() . ') AS derived'))
|
||||
->mergeBindings($subQuery->getQuery())
|
||||
->where('t_count', '>', 2)
|
||||
->select(['id', 't_count']);
|
||||
$journalIds = array_unique($result->pluck('id')->toArray());
|
||||
|
||||
foreach ($journalIds as $journalId) {
|
||||
// grab all positive transactiosn from this journal that are not deleted.
|
||||
// for each one, grab the negative opposing one which has 0 as an identifier and give it the same identifier.
|
||||
$identifier = 0;
|
||||
$processed = [];
|
||||
$transactions = Transaction::where('transaction_journal_id', $journalId)->where('amount', '>', 0)->get();
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
// find opposing:
|
||||
$amount = bcmul(strval($transaction->amount), '-1');
|
||||
|
||||
try {
|
||||
/** @var Transaction $opposing */
|
||||
$opposing = Transaction
|
||||
::where('transaction_journal_id', $journalId)
|
||||
->where('amount', $amount)->where('identifier', '=', 0)
|
||||
->whereNotIn('id', $processed)
|
||||
->first();
|
||||
} catch (QueryException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$this->error('Firefly III could not find the "identifier" field in the "transactions" table.');
|
||||
$this->error('This field is required for Firefly III version ' . config('firefly.version') . ' to run.');
|
||||
$this->error('Please run "php artisan migrate" to add this field to the table.');
|
||||
$this->info('Then, run "php artisan firefly:upgrade-database" to try again.');
|
||||
break 2;
|
||||
}
|
||||
if (!is_null($opposing)) {
|
||||
// give both a new identifier:
|
||||
$transaction->identifier = $identifier;
|
||||
$transaction->save();
|
||||
$opposing->identifier = $identifier;
|
||||
$opposing->save();
|
||||
$processed[] = $transaction->id;
|
||||
$processed[] = $opposing->id;
|
||||
$this->line(sprintf('Database upgrade for journal #%d, transactions #%d and #%d', $journalId, $transaction->id, $opposing->id));
|
||||
}
|
||||
$identifier++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* UpgradeFireflyInstructions.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
@@ -18,7 +27,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
protected $description = 'Instructions in case of upgrade trouble.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
@@ -37,23 +46,29 @@ class UpgradeFireflyInstructions extends Command
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//
|
||||
$version = Config::get('firefly.version');
|
||||
$config = Config::get('upgrade.text');
|
||||
$text = $config[$version] ?? null;
|
||||
/** @var string $version */
|
||||
$version = config('firefly.version');
|
||||
$config = config('upgrade.text');
|
||||
$text = null;
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
$len = strlen($compare);
|
||||
if (substr($version, 0, $len) === $compare) {
|
||||
$text = $config[$compare];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$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->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);
|
||||
|
@@ -1,16 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* VerifyDatabase.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -39,8 +49,6 @@ class VerifyDatabase extends Command
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -49,8 +57,6 @@ class VerifyDatabase extends Command
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
@@ -72,6 +78,12 @@ class VerifyDatabase extends Command
|
||||
$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();
|
||||
|
||||
// transfers with budgets.
|
||||
$this->reportTransfersBudgets();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,14 +94,17 @@ class VerifyDatabase extends Command
|
||||
$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`')]);
|
||||
->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'])
|
||||
->whereNull('transactions.account_id')
|
||||
->get(
|
||||
['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']
|
||||
);
|
||||
|
||||
/** @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.';
|
||||
$name = $entry->name;
|
||||
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
|
||||
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $name);
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
@@ -102,9 +117,9 @@ class VerifyDatabase extends Command
|
||||
$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`')]);
|
||||
->groupBy(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email'])
|
||||
->whereNull('budget_limits.id')
|
||||
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
@@ -123,7 +138,9 @@ class VerifyDatabase extends Command
|
||||
::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->get(['budgets.id', 'budgets.name', 'budget_transaction_journal.budget_id', 'budgets.user_id', 'users.email']);
|
||||
->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) {
|
||||
@@ -142,7 +159,9 @@ class VerifyDatabase extends Command
|
||||
::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')
|
||||
->leftJoin('users', 'categories.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->get(['categories.id', 'categories.name', 'category_transaction_journal.category_id', 'categories.user_id', 'users.email']);
|
||||
->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) {
|
||||
@@ -178,7 +197,7 @@ class VerifyDatabase extends Command
|
||||
$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 . '"'
|
||||
' Find it in the table called "accounts" and change the "deleted_at" field to: "' . $date . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -205,24 +224,41 @@ class VerifyDatabase extends Command
|
||||
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 . '"'
|
||||
' Find it in the table called "transactions" and change the "deleted_at" field to: "' . $entry->journal_deleted . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function reportNoTransactions()
|
||||
{
|
||||
$set = TransactionJournal
|
||||
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->groupBy('transaction_journals.id')
|
||||
->whereNull('transactions.transaction_journal_id')
|
||||
->get(['transaction_journals.id']);
|
||||
|
||||
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('FireflyIII\Repositories\User\UserRepositoryInterface');
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($userRepository->all() as $user) {
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface', [$user]);
|
||||
$sum = $repository->sumOfEverything();
|
||||
$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 . '!');
|
||||
}
|
||||
@@ -238,7 +274,9 @@ class VerifyDatabase extends Command
|
||||
::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
|
||||
->leftJoin('users', 'tags.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->get(['tags.id', 'tags.tag', 'tag_transaction_journal.tag_id', 'tags.user_id', 'users.email']);
|
||||
->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) {
|
||||
@@ -265,8 +303,33 @@ class VerifyDatabase extends Command
|
||||
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 . '"'
|
||||
' Find it in the table called "transaction_journals" and change the "deleted_at" field to: "' . $entry->transaction_deleted . '"'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function reportTransfersBudgets()
|
||||
{
|
||||
$set = TransactionJournal
|
||||
::distinct()
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('budget_transaction_journal', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
|
||||
->where('transaction_types.type', TransactionType::TRANSFER)
|
||||
->whereNotNull('budget_transaction_journal.budget_id')->get(['transaction_journals.id']);
|
||||
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($set as $entry) {
|
||||
$this->error(
|
||||
sprintf(
|
||||
'Error: Transaction journal #%d is a transfer, but has a budget. Edit it without changing anything, so the budget will be removed.',
|
||||
$entry->id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
36
app/Console/Kernel.php
Normal file → Executable file
36
app/Console/Kernel.php
Normal file → Executable file
@@ -1,16 +1,23 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Console;
|
||||
|
||||
use FireflyIII\Console\Commands\CreateImport;
|
||||
use FireflyIII\Console\Commands\EncryptFile;
|
||||
use FireflyIII\Console\Commands\Import;
|
||||
use FireflyIII\Console\Commands\ScanAttachments;
|
||||
use FireflyIII\Console\Commands\UpgradeDatabase;
|
||||
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
|
||||
use FireflyIII\Console\Commands\VerifyDatabase;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
@@ -23,11 +30,10 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The bootstrap classes for the application.
|
||||
*
|
||||
* This needs to be for with the next upgrade.
|
||||
* Next upgrade verify these are the same.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -52,16 +58,30 @@ class Kernel extends ConsoleKernel
|
||||
= [
|
||||
UpgradeFireflyInstructions::class,
|
||||
VerifyDatabase::class,
|
||||
Import::class,
|
||||
CreateImport::class,
|
||||
EncryptFile::class,
|
||||
ScanAttachments::class,
|
||||
UpgradeDatabase::class,
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the Closure based commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameters)
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
|
@@ -1,24 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* UserRegistration.php
|
||||
* ConfirmedUser.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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class UserRegistration
|
||||
* Class ConfirmedUser
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class UserRegistration extends Event
|
||||
class ConfirmedUser extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
@@ -26,7 +29,7 @@ class UserRegistration extends Event
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* Create a new event instance. This event is triggered when a user confirms their new account.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Event.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
|
@@ -1,24 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* ResendConfirmation.php
|
||||
* RegisteredUser.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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class ResendConfirmation
|
||||
* Class RegisteredUser
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class ResendConfirmation extends Event
|
||||
class RegisteredUser extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
@@ -26,7 +29,7 @@ class ResendConfirmation extends Event
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* Create a new event instance. This event is triggered when a new user registers.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
42
app/Events/ResentConfirmation.php
Normal file
42
app/Events/ResentConfirmation.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* ResentConfirmation.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class ResentConfirmation
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class ResentConfirmation extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $ipAddress;
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance. This event is triggered when a users wants a new confirmation.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
||||
*/
|
||||
public function __construct(User $user, string $ipAddress)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->ipAddress = $ipAddress;
|
||||
}
|
||||
}
|
50
app/Events/StoredBudgetLimit.php
Normal file
50
app/Events/StoredBudgetLimit.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* StoredBudgetLimit.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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 StoredBudgetLimit
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class StoredBudgetLimit 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,25 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* TransactionJournalStored.php
|
||||
* StoredTransactionJournal.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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class TransactionJournalStored
|
||||
* Class StoredTransactionJournal
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class TransactionJournalStored extends Event
|
||||
class StoredTransactionJournal extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
@@ -35,7 +37,6 @@ class TransactionJournalStored extends Event
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal, int $piggyBankId)
|
||||
{
|
||||
Log::debug('Created new TransactionJournalStored.');
|
||||
//
|
||||
$this->journal = $journal;
|
||||
$this->piggyBankId = $piggyBankId;
|
50
app/Events/UpdatedBudgetLimit.php
Normal file
50
app/Events/UpdatedBudgetLimit.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* UpdatedBudgetLimit.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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 UpdatedBudgetLimit
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class UpdatedBudgetLimit 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,18 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* UpdatedTransactionJournal.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class TransactionJournalUpdated
|
||||
* Class UpdatedTransactionJournal
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class TransactionJournalUpdated extends Event
|
||||
class UpdatedTransactionJournal extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
@@ -26,7 +35,6 @@ class TransactionJournalUpdated extends Event
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal)
|
||||
{
|
||||
Log::debug('Created new TransactionJournalUpdated');
|
||||
//
|
||||
$this->journal = $journal;
|
||||
}
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* FireflyException.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
50
app/Exceptions/Handler.php
Normal file → Executable file
50
app/Exceptions/Handler.php
Normal file → Executable file
@@ -1,16 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* Handler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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 FireflyIII\User;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Request;
|
||||
use Illuminate\Session\TokenMismatchException;
|
||||
use Illuminate\Validation\ValidationException as ValException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
/**
|
||||
@@ -27,9 +37,12 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
protected $dontReport
|
||||
= [
|
||||
AuthenticationException::class,
|
||||
AuthorizationException::class,
|
||||
HttpException::class,
|
||||
ModelNotFoundException::class,
|
||||
TokenMismatchException::class,
|
||||
ValException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -64,11 +77,15 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
{
|
||||
|
||||
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
|
||||
|
||||
$user = Auth::check() ? Auth::user() : new User;
|
||||
|
||||
$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(),
|
||||
@@ -80,10 +97,27 @@ class Handler extends ExceptionHandler
|
||||
];
|
||||
|
||||
// create job that will mail.
|
||||
$job = new MailError($user, env('SITE_OWNER'), Request::ip(), $data);
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
|
||||
$job = new MailError($userData, env('SITE_OWNER', ''), $ip, $data);
|
||||
dispatch($job);
|
||||
}
|
||||
|
||||
parent::report($exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an authentication exception into an unauthenticated response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function unauthenticated($request)
|
||||
{
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['error' => 'Unauthenticated.'], 401);
|
||||
}
|
||||
|
||||
return redirect()->guest('login');
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* NotImplementedException.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* ValidationException.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
use Amount;
|
||||
@@ -44,7 +47,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
*/
|
||||
public function __construct(ExportJob $job)
|
||||
{
|
||||
$this->repository = app('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface');
|
||||
/** @var AttachmentRepositoryInterface repository */
|
||||
$this->repository = app(AttachmentRepositoryInterface::class);
|
||||
// make storage:
|
||||
$this->uploadDisk = Storage::disk('upload');
|
||||
$this->exportDisk = Storage::disk('export');
|
||||
@@ -68,8 +72,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
// 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);
|
||||
Log::debug('Also put explanation file "' . $file . '" in the zip.');
|
||||
$this->getFiles()->push($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,15 +85,16 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $attachment->attachable;
|
||||
$args = [
|
||||
'attachment_name' => $attachment->filename,
|
||||
'attachment_name' => e($attachment->filename),
|
||||
'attachment_id' => $attachment->id,
|
||||
'type' => strtolower($journal->transactionType->type),
|
||||
'description' => $journal->description,
|
||||
'description' => e($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";
|
||||
Log::debug('Appended explanation string', ['string' => $string]);
|
||||
$this->explanationString .= $string;
|
||||
|
||||
}
|
||||
@@ -102,14 +107,12 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
private function exportAttachment(Attachment $attachment): bool
|
||||
{
|
||||
$file = $attachment->fileName();
|
||||
Log::debug('Original file is at "' . $file . '".');
|
||||
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);
|
||||
Log::debug('Stored file content in new file "' . $exportFile . '", which will be in the final zip file.');
|
||||
|
||||
// explain:
|
||||
$this->explain($attachment);
|
||||
@@ -142,8 +145,6 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
$attachments = $this->repository->get();
|
||||
|
||||
Log::debug('Found ' . $attachments->count() . ' attachments.');
|
||||
|
||||
return $attachments;
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -1,16 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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;
|
||||
@@ -28,10 +30,12 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
private $expected;
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $exportDisk;
|
||||
private $importKeys = [];
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
private $uploadDisk;
|
||||
|
||||
/**
|
||||
*
|
||||
* AttachmentCollector constructor.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
@@ -40,10 +44,17 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
parent::__construct($job);
|
||||
|
||||
Log::debug('Going to collect attachments', ['key' => $job->key]);
|
||||
|
||||
// make storage:
|
||||
$this->uploadDisk = Storage::disk('upload');
|
||||
$this->exportDisk = Storage::disk('export');
|
||||
$this->expected = 'csv-upload-' . Auth::user()->id . '-';
|
||||
|
||||
// file names associated with the old import routine.
|
||||
$this->expected = 'csv-upload-' . auth()->user()->id . '-';
|
||||
|
||||
// for the new import routine:
|
||||
$this->getImportKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,14 +64,28 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
// grab upload directory.
|
||||
$files = $this->uploadDisk->files();
|
||||
Log::debug('Found ' . count($files) . ' files in the upload directory.');
|
||||
|
||||
foreach ($files as $entry) {
|
||||
$this->processOldUpload($entry);
|
||||
$this->processUpload($entry);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function getImportKeys()
|
||||
{
|
||||
$set = auth()->user()->importJobs()->where('status', 'import_complete')->get(['import_jobs.*']);
|
||||
if ($set->count() > 0) {
|
||||
$keys = $set->pluck('key')->toArray();
|
||||
$this->importKeys = $keys;
|
||||
|
||||
}
|
||||
Log::debug('Valid import keys are ', $this->importKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entry
|
||||
*
|
||||
@@ -81,15 +106,32 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidFile(string $entry): bool
|
||||
private function isImportFile(string $entry): bool
|
||||
{
|
||||
$len = strlen($this->expected);
|
||||
if (substr($entry, 0, $len) === $this->expected) {
|
||||
Log::debug($entry . ' is part of this users original uploads.');
|
||||
$name = str_replace('.upload', '', $entry);
|
||||
if (in_array($name, $this->importKeys)) {
|
||||
Log::debug(sprintf('Import file "%s" is in array', $name), $this->importKeys);
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('Import file "%s" is NOT in array', $name), $this->importKeys);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entry
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isOldImport(string $entry): bool
|
||||
{
|
||||
$len = strlen($this->expected);
|
||||
// file is part of the old import routine:
|
||||
if (substr($entry, 0, $len) === $this->expected) {
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug($entry . ' is not part of this users original uploads.');
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -97,24 +139,63 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
/**
|
||||
* @param $entry
|
||||
*/
|
||||
private function processOldUpload(string $entry)
|
||||
private function processUpload(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());
|
||||
}
|
||||
// file is old import:
|
||||
if ($this->isOldImport($entry)) {
|
||||
$this->saveOldImportFile($entry);
|
||||
}
|
||||
if (strlen($content) > 0) {
|
||||
// continue with file:
|
||||
$date = $this->getOriginalUploadDate($entry);
|
||||
$file = $this->job->key . '-Old CSV import dated ' . $date . '.csv';
|
||||
Log::debug('Will put "' . $file . '" in the zip file.');
|
||||
|
||||
// file is current import.
|
||||
if ($this->isImportFile($entry)) {
|
||||
$this->saveImportFile($entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entry
|
||||
*/
|
||||
private function saveImportFile(string $entry)
|
||||
{
|
||||
// find job associated with import file:
|
||||
$name = str_replace('.upload', '', $entry);
|
||||
$job = auth()->user()->importJobs()->where('key', $name)->first();
|
||||
$content = '';
|
||||
try {
|
||||
$content = Crypt::decrypt($this->uploadDisk->get($entry));
|
||||
} catch (DecryptException $e) {
|
||||
Log::error('Could not decrypt old import file ' . $entry . '. Skipped because ' . $e->getMessage());
|
||||
}
|
||||
|
||||
if (!is_null($job) && strlen($content) > 0) {
|
||||
// add to export disk.
|
||||
$date = $job->created_at->format('Y-m-d');
|
||||
$file = sprintf('%s-Old %s import dated %s.%s', $this->job->key, strtoupper($job->file_type), $date, $job->file_type);
|
||||
$this->exportDisk->put($file, $content);
|
||||
$this->getFiles()->push($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entry
|
||||
*/
|
||||
private function saveOldImportFile(string $entry)
|
||||
{
|
||||
$content = '';
|
||||
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) {
|
||||
// add to export disk.
|
||||
$date = $this->getOriginalUploadDate($entry);
|
||||
$file = $this->job->key . '-Old import dated ' . $date . '.csv';
|
||||
$this->exportDisk->put($file, $content);
|
||||
$this->getFiles()->push($file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,17 +1,20 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Log;
|
||||
use Storage;
|
||||
|
||||
/**
|
||||
@@ -42,8 +45,8 @@ class ConfigurationFile
|
||||
*/
|
||||
public function make(): string
|
||||
{
|
||||
$fields = array_keys(get_class_vars(Entry::class));
|
||||
$types = Entry::getTypes();
|
||||
$fields = array_keys(Entry::getFieldsAndTypes());
|
||||
$types = Entry::getFieldsAndTypes();
|
||||
|
||||
$configuration = [
|
||||
'date-format' => 'Y-m-d', // unfortunately, this is hard-coded.
|
||||
@@ -57,8 +60,6 @@ class ConfigurationFile
|
||||
$configuration['roles'][] = $types[$field];
|
||||
}
|
||||
$file = $this->job->key . '-configuration.json';
|
||||
Log::debug('Created JSON config file.');
|
||||
Log::debug('Will put "' . $file . '" in the ZIP file.');
|
||||
$this->exportDisk->put($file, json_encode($configuration, JSON_PRETTY_PRINT));
|
||||
|
||||
return $file;
|
||||
|
@@ -1,463 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* - 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
|
||||
*/
|
||||
class Entry
|
||||
{
|
||||
/** @var string */
|
||||
public $amount;
|
||||
/** @var int */
|
||||
public $billId;
|
||||
/** @var string */
|
||||
public $billName;
|
||||
/** @var int */
|
||||
public $budgetId;
|
||||
/** @var string */
|
||||
public $budgetName;
|
||||
/** @var int */
|
||||
public $categoryId;
|
||||
/** @var string */
|
||||
public $categoryName;
|
||||
/** @var string */
|
||||
public $date;
|
||||
/** @var string */
|
||||
public $description;
|
||||
/** @var string */
|
||||
public $fromAccountIban;
|
||||
/** @var int */
|
||||
public $fromAccountId;
|
||||
/** @var string */
|
||||
public $fromAccountName;
|
||||
/** @var int */
|
||||
public $fromAccountNumber;
|
||||
/** @var string */
|
||||
public $fromAccountType;
|
||||
/** @var string */
|
||||
public $toAccountIban;
|
||||
/** @var int */
|
||||
public $toAccountId;
|
||||
/** @var string */
|
||||
public $toAccountName;
|
||||
public $toAccountNumber;
|
||||
/** @var string */
|
||||
public $toAccountType;
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Entry
|
||||
*/
|
||||
public static function fromJournal(TransactionJournal $journal)
|
||||
{
|
||||
|
||||
$entry = new self;
|
||||
$entry->setDescription($journal->description);
|
||||
$entry->setDate($journal->date->format('Y-m-d'));
|
||||
$entry->setAmount(TransactionJournal::amount($journal));
|
||||
|
||||
/** @var Budget $budget */
|
||||
$budget = $journal->budgets->first();
|
||||
if (!is_null($budget)) {
|
||||
$entry->setBudgetId($budget->id);
|
||||
$entry->setBudgetName($budget->name);
|
||||
}
|
||||
|
||||
/** @var Category $category */
|
||||
$category = $journal->categories->first();
|
||||
if (!is_null($category)) {
|
||||
$entry->setCategoryId($category->id);
|
||||
$entry->setCategoryName($category->name);
|
||||
}
|
||||
|
||||
if (!is_null($journal->bill_id)) {
|
||||
$entry->setBillId($journal->bill_id);
|
||||
$entry->setBillName($journal->bill->name);
|
||||
}
|
||||
|
||||
/** @var Account $sourceAccount */
|
||||
$sourceAccount = TransactionJournal::sourceAccount($journal);
|
||||
$entry->setFromAccountId($sourceAccount->id);
|
||||
$entry->setFromAccountName($sourceAccount->name);
|
||||
$entry->setFromAccountIban($sourceAccount->iban);
|
||||
$entry->setFromAccountType($sourceAccount->accountType->type);
|
||||
$entry->setFromAccountNumber($sourceAccount->getMeta('accountNumber'));
|
||||
|
||||
|
||||
/** @var Account $destination */
|
||||
$destination = TransactionJournal::destinationAccount($journal);
|
||||
$entry->setToAccountId($destination->id);
|
||||
$entry->setToAccountName($destination->name);
|
||||
$entry->setToAccountIban($destination->iban);
|
||||
$entry->setToAccountType($destination->accountType->type);
|
||||
$entry->setToAccountNumber($destination->getMeta('accountNumber'));
|
||||
|
||||
return $entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getTypes(): array
|
||||
{
|
||||
// key = field name (see top of class)
|
||||
// value = field type (see csv.php under 'roles')
|
||||
return [
|
||||
'amount' => 'amount',
|
||||
'date' => 'date-transaction',
|
||||
'description' => 'description',
|
||||
'billId' => 'bill-id',
|
||||
'billName' => 'bill-name',
|
||||
'budgetId' => 'budget-id',
|
||||
'budgetName' => 'budget-name',
|
||||
'categoryId' => 'category-id',
|
||||
'categoryName' => 'category-name',
|
||||
'fromAccountId' => 'account-id',
|
||||
'fromAccountNumber' => 'account-number',
|
||||
'fromAccountName' => 'account-name',
|
||||
'fromAccountIban' => 'account-iban',
|
||||
'fromAccountType' => '_ignore', // no, Firefly cannot import what it exports. I know :D
|
||||
'toAccountId' => 'opposing-id',
|
||||
'toAccountNumber' => 'account-number',
|
||||
'toAccountName' => 'opposing-name',
|
||||
'toAccountIban' => 'opposing-iban',
|
||||
'toAccountType' => '_ignore',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAmount(): string
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
*/
|
||||
public function setAmount(string $amount)
|
||||
{
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getBillId(): int
|
||||
{
|
||||
return $this->billId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $billId
|
||||
*/
|
||||
public function setBillId(int $billId)
|
||||
{
|
||||
$this->billId = $billId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBillName(): string
|
||||
{
|
||||
return $this->billName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $billName
|
||||
*/
|
||||
public function setBillName(string $billName)
|
||||
{
|
||||
$this->billName = $billName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getBudgetId(): int
|
||||
{
|
||||
return $this->budgetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $budgetId
|
||||
*/
|
||||
public function setBudgetId(int $budgetId)
|
||||
{
|
||||
$this->budgetId = $budgetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBudgetName(): string
|
||||
{
|
||||
return $this->budgetName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $budgetName
|
||||
*/
|
||||
public function setBudgetName(string $budgetName)
|
||||
{
|
||||
$this->budgetName = $budgetName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCategoryId(): int
|
||||
{
|
||||
return $this->categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $categoryId
|
||||
*/
|
||||
public function setCategoryId(int $categoryId)
|
||||
{
|
||||
$this->categoryId = $categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCategoryName(): string
|
||||
{
|
||||
return $this->categoryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $categoryName
|
||||
*/
|
||||
public function setCategoryName(string $categoryName)
|
||||
{
|
||||
$this->categoryName = $categoryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDate(): string
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*/
|
||||
public function setDate(string $date)
|
||||
{
|
||||
$this->date = $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription(string $description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFromAccountIban(): string
|
||||
{
|
||||
return $this->fromAccountIban;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fromAccountIban
|
||||
*/
|
||||
public function setFromAccountIban(string $fromAccountIban)
|
||||
{
|
||||
$this->fromAccountIban = $fromAccountIban;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFromAccountId():int
|
||||
{
|
||||
return $this->fromAccountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fromAccountId
|
||||
*/
|
||||
public function setFromAccountId(int $fromAccountId)
|
||||
{
|
||||
$this->fromAccountId = $fromAccountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFromAccountName(): string
|
||||
{
|
||||
return $this->fromAccountName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fromAccountName
|
||||
*/
|
||||
public function setFromAccountName(string $fromAccountName)
|
||||
{
|
||||
$this->fromAccountName = $fromAccountName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFromAccountNumber(): string
|
||||
{
|
||||
return $this->fromAccountNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fromAccountNumber
|
||||
*/
|
||||
public function setFromAccountNumber(string $fromAccountNumber)
|
||||
{
|
||||
$this->fromAccountNumber = $fromAccountNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFromAccountType(): string
|
||||
{
|
||||
return $this->fromAccountType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fromAccountType
|
||||
*/
|
||||
public function setFromAccountType(string $fromAccountType)
|
||||
{
|
||||
$this->fromAccountType = $fromAccountType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getToAccountIban(): string
|
||||
{
|
||||
return $this->toAccountIban;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toAccountIban
|
||||
*/
|
||||
public function setToAccountIban(string $toAccountIban)
|
||||
{
|
||||
$this->toAccountIban = $toAccountIban;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getToAccountId(): int
|
||||
{
|
||||
return $this->toAccountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $toAccountId
|
||||
*/
|
||||
public function setToAccountId(int $toAccountId)
|
||||
{
|
||||
$this->toAccountId = $toAccountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getToAccountName(): string
|
||||
{
|
||||
return $this->toAccountName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toAccountName
|
||||
*/
|
||||
public function setToAccountName(string $toAccountName)
|
||||
{
|
||||
$this->toAccountName = $toAccountName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getToAccountNumber(): string
|
||||
{
|
||||
return $this->toAccountNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toAccountNumber
|
||||
*/
|
||||
public function setToAccountNumber(string $toAccountNumber)
|
||||
{
|
||||
$this->toAccountNumber = $toAccountNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getToAccountType(): string
|
||||
{
|
||||
return $this->toAccountType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toAccountType
|
||||
*/
|
||||
public function setToAccountType(string $toAccountType)
|
||||
{
|
||||
$this->toAccountType = $toAccountType;
|
||||
}
|
||||
|
||||
|
||||
}
|
132
app/Export/Entry/Entry.php
Normal file
132
app/Export/Entry/Entry.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Entry.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
49
app/Export/Entry/EntryAccount.php
Normal file
49
app/Export/Entry/EntryAccount.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryAccount.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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');
|
||||
}
|
||||
}
|
43
app/Export/Entry/EntryBill.php
Normal file
43
app/Export/Entry/EntryBill.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryBill.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
43
app/Export/Entry/EntryBudget.php
Normal file
43
app/Export/Entry/EntryBudget.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryBudget.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
42
app/Export/Entry/EntryCategory.php
Normal file
42
app/Export/Entry/EntryCategory.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* EntryCategory.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
|
||||
|
@@ -1,17 +1,22 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
use FireflyIII\Export\Entry;
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Export\Entry\EntryAccount;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Csv\Writer;
|
||||
use SplFileObject;
|
||||
|
||||
@@ -54,27 +59,114 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
|
||||
// necessary for CSV writer:
|
||||
$fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName;
|
||||
$writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
|
||||
$rows = [];
|
||||
|
||||
// create CSV writer:
|
||||
$writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
|
||||
|
||||
// all rows:
|
||||
$rows = [];
|
||||
|
||||
// add header:
|
||||
$first = $this->getEntries()->first();
|
||||
$rows[] = array_keys(get_object_vars($first));
|
||||
|
||||
// then the rest:
|
||||
// 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) {
|
||||
$rows[] = array_values(get_object_vars($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';
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -1,23 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
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\JournalCollector;
|
||||
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Storage;
|
||||
use ZipArchive;
|
||||
|
||||
@@ -78,9 +82,11 @@ class Processor
|
||||
*/
|
||||
public function collectAttachments(): bool
|
||||
{
|
||||
$attachmentCollector = app('FireflyIII\Export\Collector\AttachmentCollector', [$this->job]);
|
||||
/** @var AttachmentCollector $attachmentCollector */
|
||||
$attachmentCollector = app(AttachmentCollector::class, [$this->job]);
|
||||
$attachmentCollector->run();
|
||||
$this->files = $this->files->merge($attachmentCollector->getFiles());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -89,17 +95,10 @@ class Processor
|
||||
*/
|
||||
public function collectJournals(): bool
|
||||
{
|
||||
$args = [$this->accounts, Auth::user(), $this->settings['startDate'], $this->settings['endDate']];
|
||||
/** @var JournalCollector $journalCollector */
|
||||
$journalCollector = app('FireflyIII\Repositories\Journal\JournalCollector', $args);
|
||||
$this->journals = $journalCollector->collect();
|
||||
Log::debug(
|
||||
'Collected ' .
|
||||
$this->journals->count() . ' journals (between ' .
|
||||
$this->settings['startDate']->format('Y-m-d') . ' and ' .
|
||||
$this->settings['endDate']->format('Y-m-d')
|
||||
. ').'
|
||||
);
|
||||
/** @var JournalTaskerInterface $tasker */
|
||||
$tasker = app(JournalTaskerInterface::class);
|
||||
$this->journals = $tasker->getJournalsInRange($this->accounts, $this->settings['startDate'], $this->settings['endDate']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -108,10 +107,12 @@ class Processor
|
||||
*/
|
||||
public function collectOldUploads(): bool
|
||||
{
|
||||
$uploadCollector = app('FireflyIII\Export\Collector\UploadCollector', [$this->job]);
|
||||
/** @var UploadCollector $uploadCollector */
|
||||
$uploadCollector = app(UploadCollector::class, [$this->job]);
|
||||
$uploadCollector->run();
|
||||
|
||||
$this->files = $this->files->merge($uploadCollector->getFiles());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,7 +127,7 @@ class Processor
|
||||
$this->exportEntries->push(Entry::fromJournal($journal));
|
||||
$count++;
|
||||
}
|
||||
Log::debug('Converted ' . $count . ' journals to "Entry" objects.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,8 +136,9 @@ class Processor
|
||||
*/
|
||||
public function createConfigFile(): bool
|
||||
{
|
||||
$this->configurationMaker = app('FireflyIII\Export\ConfigurationFile', [$this->job]);
|
||||
$this->configurationMaker = app(ConfigurationFile::class, [$this->job]);
|
||||
$this->files->push($this->configurationMaker->make());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -149,7 +151,6 @@ class Processor
|
||||
$zip = new ZipArchive;
|
||||
$file = $this->job->key . '.zip';
|
||||
$fullPath = storage_path('export') . '/' . $file;
|
||||
Log::debug('Will create zip file at ' . $fullPath);
|
||||
|
||||
if ($zip->open($fullPath, ZipArchive::CREATE) !== true) {
|
||||
throw new FireflyException('Cannot store zip file.');
|
||||
@@ -159,20 +160,14 @@ class Processor
|
||||
foreach ($this->getFiles() as $entry) {
|
||||
// is part of this job?
|
||||
$zipFileName = str_replace($this->job->key . '-', '', $entry);
|
||||
$result = $zip->addFromString($zipFileName, $disk->get($entry));
|
||||
if (!$result) {
|
||||
Log::error('Could not add "' . $entry . '" into zip file as "' . $zipFileName . '".');
|
||||
}
|
||||
$zip->addFromString($zipFileName, $disk->get($entry));
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
// delete the files:
|
||||
foreach ($this->getFiles() as $file) {
|
||||
Log::debug('Will now delete file "' . $file . '".');
|
||||
$disk->delete($file);
|
||||
}
|
||||
Log::debug('Done!');
|
||||
$this->deleteFiles($disk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -181,13 +176,12 @@ class Processor
|
||||
*/
|
||||
public function exportJournals(): bool
|
||||
{
|
||||
$exporterClass = Config::get('firefly.export_formats.' . $this->exportFormat);
|
||||
$exporterClass = config('firefly.export_formats.' . $this->exportFormat);
|
||||
$exporter = app($exporterClass, [$this->job]);
|
||||
Log::debug('Going to export ' . $this->exportEntries->count() . ' export entries into ' . $this->exportFormat . ' format.');
|
||||
$exporter->setEntries($this->exportEntries);
|
||||
$exporter->run();
|
||||
$this->files->push($exporter->getFileName());
|
||||
Log::debug('Added "' . $exporter->getFileName() . '" to the list of files to include in the zip.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -198,4 +192,14 @@ class Processor
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FilesystemAdapter $disk
|
||||
*/
|
||||
private function deleteFiles(FilesystemAdapter $disk)
|
||||
{
|
||||
foreach ($this->getFiles() as $file) {
|
||||
$disk->delete($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
@@ -21,7 +24,6 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
interface AccountChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@@ -41,11 +43,20 @@ interface AccountChartGeneratorInterface
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end): array;
|
||||
public function revenueAccounts(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,11 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsAccountChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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
|
||||
@@ -29,28 +38,6 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
|
||||
'labels' => [], 'datasets' => [[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []]]];
|
||||
|
||||
$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;
|
||||
@@ -80,7 +67,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
|
||||
}
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = [
|
||||
$data['datasets'][] = [
|
||||
'label' => $account->name,
|
||||
'fillColor' => 'rgba(220,220,220,0.2)',
|
||||
'strokeColor' => 'rgba(220,220,220,1)',
|
||||
@@ -88,20 +75,8 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
|
||||
'pointStrokeColor' => '#fff',
|
||||
'pointHighlightFill' => '#fff',
|
||||
'pointHighlightStroke' => 'rgba(220,220,220,1)',
|
||||
'data' => [],
|
||||
'data' => $account->balances,
|
||||
];
|
||||
$current = clone $start;
|
||||
$range = Steam::balanceInRange($account, $start, clone $end);
|
||||
$previous = round(array_values($range)[0], 2);
|
||||
while ($current <= $end) {
|
||||
$format = $current->format('Y-m-d');
|
||||
$balance = isset($range[$format]) ? round($range[$format], 2) : $previous;
|
||||
|
||||
$set['data'][] = $balance;
|
||||
$previous = $balance;
|
||||
$current->addDay();
|
||||
}
|
||||
$data['datasets'][] = $set;
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
@@ -109,72 +84,49 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end): array
|
||||
public function revenueAccounts(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// language:
|
||||
$format = (string)trans('config.month_and_day');
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => $account->name,
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$range = Steam::balanceInRange($account, $start, $end);
|
||||
$current = clone $start;
|
||||
$previous = array_values($range)[0];
|
||||
|
||||
while ($end >= $current) {
|
||||
$theDate = $current->format('Y-m-d');
|
||||
$balance = $range[$theDate] ?? $previous;
|
||||
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = $balance;
|
||||
$previous = $balance;
|
||||
$current->addDay();
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [], 'datasets' => [[
|
||||
'label' => trans('firefly.earned'),
|
||||
'data' => []]]];
|
||||
foreach ($accounts as $account) {
|
||||
if ($account->difference > 0) {
|
||||
$data['labels'][] = $account->name;
|
||||
$data['datasets'][0]['data'][] = $account->difference;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @param Account $account
|
||||
* @param array $labels
|
||||
* @param array $dataSet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getIdsFromCollection(Collection $collection): array
|
||||
public function single(Account $account, array $labels, array $dataSet): array
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($collection as $entry) {
|
||||
$ids[] = $entry->id;
|
||||
}
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => $labels,
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => $account->name,
|
||||
'data' => $dataSet,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return array_unique($ids);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @param $entryId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function isInArray($array, $entryId): string
|
||||
{
|
||||
if (isset($array[$entryId])) {
|
||||
return $array[$entryId];
|
||||
}
|
||||
|
||||
return '0';
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
@@ -54,11 +57,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
|
||||
public function single(Bill $bill, Collection $entries): array
|
||||
{
|
||||
$format = (string)trans('config.month');
|
||||
$data = [
|
||||
'count' => 3,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
$data = ['count' => 3, 'labels' => [], 'datasets' => [],];
|
||||
$minAmount = [];
|
||||
$maxAmount = [];
|
||||
$actualAmount = [];
|
||||
@@ -67,9 +66,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
|
||||
$data['labels'][] = $entry->date->formatLocalized($format);
|
||||
$minAmount[] = round($bill->amount_min, 2);
|
||||
$maxAmount[] = round($bill->amount_max, 2);
|
||||
/*
|
||||
* journalAmount has been collected in BillRepository::getJournals
|
||||
*/
|
||||
// journalAmount has been collected in BillRepository::getJournals
|
||||
$actualAmount[] = round(TransactionJournal::amountPositive($entry), 2);
|
||||
}
|
||||
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -19,19 +22,14 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
interface BudgetChartGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries): array;
|
||||
public function budgetLimit(Collection $entries, string $dateFormat): array;
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
@@ -47,6 +45,14 @@ interface BudgetChartGeneratorInterface
|
||||
*/
|
||||
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
|
||||
|
@@ -1,11 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsBudgetChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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
|
||||
@@ -14,20 +23,17 @@ use Preferences;
|
||||
*/
|
||||
class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries, $dateFormat = 'month'): array
|
||||
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' => [
|
||||
[
|
||||
@@ -49,17 +55,6 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries): array
|
||||
{
|
||||
return $this->budget($entries, 'monthAndDay');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
@@ -139,6 +134,42 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsCategoryChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
@@ -20,8 +30,6 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
|
||||
*/
|
||||
public function all(Collection $entries): array
|
||||
{
|
||||
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
@@ -42,8 +50,8 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
|
||||
$spent = $entry[2];
|
||||
$earned = $entry[3];
|
||||
|
||||
$data['datasets'][0]['data'][] = bccomp($spent, '0') === 0 ? null : bcmul($spent, '-1');
|
||||
$data['datasets'][1]['data'][] = bccomp($earned, '0') === 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;
|
||||
@@ -116,18 +124,9 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
|
||||
*/
|
||||
public function multiYear(Collection $entries): array
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// get labels from one of the categories (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
$keys = array_keys($first['spent']);
|
||||
foreach ($keys as $year) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
$data = ['count' => 0, 'labels' => array_keys($first['spent']), 'datasets' => [],];
|
||||
|
||||
// then, loop all entries and create datasets:
|
||||
foreach ($entries as $entry) {
|
||||
@@ -144,7 +143,6 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsPiggyBankChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
@@ -36,9 +46,9 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGeneratorInterface
|
||||
],
|
||||
];
|
||||
$sum = '0';
|
||||
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,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* PiggyBankChartGenerator.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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* ChartJsReportChartGenerator.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* ReportChartGenerator.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.
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\UserRegistration;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
Log::debug('Trigger attachuserrole');
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\User\UserRepositoryInterface');
|
||||
|
||||
// first user ever?
|
||||
if ($repository->count() == 1) {
|
||||
Log::debug('Will attach role.');
|
||||
$repository->attachRole($event->user, 'owner');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
110
app/Handlers/Events/BudgetEventHandler.php
Normal file
110
app/Handlers/Events/BudgetEventHandler.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetEventHandler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\StoredBudgetLimit;
|
||||
use FireflyIII\Events\UpdatedBudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Handles budget related events.
|
||||
*
|
||||
* Class BudgetEventHandler
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class BudgetEventHandler
|
||||
{
|
||||
/**
|
||||
* This method creates a new budget limit repetition when a new budget limit has been created.
|
||||
*
|
||||
* @param StoredBudgetLimit $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function storeRepetition(StoredBudgetLimit $event):bool
|
||||
{
|
||||
$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();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates, if present the budget limit repetition part of a budget limit.
|
||||
*
|
||||
* @param UpdatedBudgetLimit $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function updateRepetition(UpdatedBudgetLimit $event): bool
|
||||
{
|
||||
$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();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/**
|
||||
* Class ConnectJournalToPiggyBank
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class ConnectJournalToPiggyBank
|
||||
{
|
||||
|
||||
/**
|
||||
* Connect a new transaction journal to any related piggy banks.
|
||||
*
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalStored $event): bool
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank)) {
|
||||
return true;
|
||||
}
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$amount = TransactionJournal::amountPositive($journal);
|
||||
// if piggy account matches source account, the amount is positive
|
||||
if ($piggyBank->account_id == TransactionJournal::sourceAccount($journal)->id) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $amount);
|
||||
$repetition->save();
|
||||
|
||||
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
Log::debug('Now running FireRulesForStore because TransactionJournalStored fired.');
|
||||
// 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) {
|
||||
Log::debug('Now processing group "' . $group->title . '".');
|
||||
$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) {
|
||||
|
||||
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
|
||||
$processor = Processor::make($rule);
|
||||
$processor->handleTransactionJournal($event->journal);
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class FireRulesForUpdate
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class FireRulesForUpdate
|
||||
{
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalUpdated $event): bool
|
||||
{
|
||||
Log::debug('Now running FireRulesForUpdate because TransactionJournalUpdated fired.');
|
||||
// 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) {
|
||||
Log::debug('Now processing group "' . $group->title . '".');
|
||||
$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) {
|
||||
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
|
||||
|
||||
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
|
||||
$processor = Processor::make($rule);
|
||||
$processor->handleTransactionJournal($event->journal);
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* RescanJournalAfterStore.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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
124
app/Handlers/Events/StoredJournalEventHandler.php
Normal file
124
app/Handlers/Events/StoredJournalEventHandler.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* StoredJournalEventHandler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\StoredTransactionJournal;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\Support\Events\BillScanner;
|
||||
|
||||
/**
|
||||
* Class StoredJournalEventHandler
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class StoredJournalEventHandler
|
||||
{
|
||||
/**
|
||||
* This method connects a new transfer to a piggy bank.
|
||||
*
|
||||
* @param StoredTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connectToPiggyBank(StoredTransactionJournal $event): bool
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = $journal->user->piggyBanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank)) {
|
||||
return true;
|
||||
}
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$amount = TransactionJournal::amountPositive($journal);
|
||||
// if piggy account matches source account, the amount is positive
|
||||
$sources = TransactionJournal::sourceAccountList($journal)->pluck('id')->toArray();
|
||||
if (in_array($piggyBank->account_id, $sources)) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $amount);
|
||||
$repetition->save();
|
||||
|
||||
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method grabs all the users rules and processes them.
|
||||
*
|
||||
* @param StoredTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function processRules(StoredTransactionJournal $event): bool
|
||||
{
|
||||
// get all the user's rule groups, with the rules, order by 'order'.
|
||||
$journal = $event->journal;
|
||||
$groups = $journal->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($journal);
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calls a special bill scanner that will check if the stored journal is part of a bill.
|
||||
*
|
||||
* @param StoredTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function scanBills(StoredTransactionJournal $event): bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
BillScanner::scan($journal);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
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
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UpdateJournalConnection
|
||||
{
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(TransactionJournalUpdated $event):bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
// get the event connected to this journal:
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
|
||||
if (is_null($event)) {
|
||||
return false;
|
||||
}
|
||||
$piggyBank = $event->piggyBank()->first();
|
||||
$repetition = null;
|
||||
if ($piggyBank) {
|
||||
/** @var PiggyBankRepetition $repetition */
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
}
|
||||
|
||||
if (is_null($repetition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$amount = TransactionJournal::amount($journal);
|
||||
$diff = bcsub($amount, $event->amount); // update current repetition
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $diff);
|
||||
$repetition->save();
|
||||
|
||||
|
||||
$event->amount = $amount;
|
||||
$event->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
128
app/Handlers/Events/UpdatedJournalEventHandler.php
Normal file
128
app/Handlers/Events/UpdatedJournalEventHandler.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* UpdatedJournalEventHandler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\UpdatedTransactionJournal;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\Support\Events\BillScanner;
|
||||
|
||||
/**
|
||||
* Class UpdatedJournalEventHandler
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UpdatedJournalEventHandler
|
||||
{
|
||||
/**
|
||||
* This method will try to reconnect a journal to a piggy bank, updating the piggy bank repetition.
|
||||
*
|
||||
* @param UpdatedTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connectToPiggyBank(UpdatedTransactionJournal $event): bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
if (!$journal->isTransfer()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// get the event connected to this journal:
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
|
||||
if (is_null($event)) {
|
||||
return false;
|
||||
}
|
||||
$piggyBank = $event->piggyBank()->first();
|
||||
$repetition = null;
|
||||
if (!is_null($piggyBank)) {
|
||||
/** @var PiggyBankRepetition $repetition */
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
}
|
||||
|
||||
if (is_null($repetition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$amount = TransactionJournal::amount($journal);
|
||||
$diff = bcsub($amount, $event->amount); // update current repetition
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $diff);
|
||||
$repetition->save();
|
||||
|
||||
|
||||
$event->amount = $amount;
|
||||
$event->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will check all the rules when a journal is updated.
|
||||
*
|
||||
* @param UpdatedTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function processRules(UpdatedTransactionJournal $event):bool
|
||||
{
|
||||
// get all the user's rule groups, with the rules, order by 'order'.
|
||||
$journal = $event->journal;
|
||||
$groups = $journal->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($journal);
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calls a special bill scanner that will check if the updated journal is part of a bill.
|
||||
*
|
||||
* @param UpdatedTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function scanBills(UpdatedTransactionJournal $event): bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
BillScanner::scan($journal);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
Log::debug('Trigger UserConfirmation::doConfirm');
|
||||
|
||||
// if user must confirm account, send email
|
||||
$confirmAccount = env('MUST_CONFIRM_ACCOUNT', false);
|
||||
|
||||
// otherwise, auto-confirm:
|
||||
if ($confirmAccount === false) {
|
||||
Log::debug('Confirm account is false, so user will be auto-confirmed.');
|
||||
Preferences::setForUser($user, 'user_confirmed', true);
|
||||
Preferences::setForUser($user, 'user_confirmed_last_mail', 0);
|
||||
Preferences::mark();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// send email message:
|
||||
$email = $user->email;
|
||||
$code = str_random(16);
|
||||
$route = route('do_confirm_account', [$code]);
|
||||
|
||||
// set preferences:
|
||||
Preferences::setForUser($user, 'user_confirmed', false);
|
||||
Preferences::setForUser($user, 'user_confirmed_last_mail', time());
|
||||
Preferences::setForUser($user, 'user_confirmed_code', $code);
|
||||
Log::debug('Set preferences for user.');
|
||||
|
||||
// send email.
|
||||
try {
|
||||
Log::debug('Now in try block for user email message thing to ' . $email . '.');
|
||||
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::debug('Caught general exception.');
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
Log::debug('Finished mail handling for activation.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
225
app/Handlers/Events/UserEventHandler.php
Normal file
225
app/Handlers/Events/UserEventHandler.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* UserEventHandler.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Events\ConfirmedUser;
|
||||
use FireflyIII\Events\RegisteredUser;
|
||||
use FireflyIII\Events\ResentConfirmation;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Mail\Message;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use Swift_TransportException;
|
||||
|
||||
/**
|
||||
* Class UserEventHandler
|
||||
*
|
||||
* This class responds to any events that have anything to do with the User object.
|
||||
*
|
||||
* The method name reflects what is being done. This is in the present tense.
|
||||
*
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UserEventHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* This method will bestow upon a user the "owner" role if he is the first user in the system.
|
||||
*
|
||||
* @param RegisteredUser $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function attachUserRole(RegisteredUser $event): bool
|
||||
{
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
|
||||
// first user ever?
|
||||
if ($repository->count() === 1) {
|
||||
$repository->attachRole($event->user, 'owner');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user logout events.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function logoutUser(): bool
|
||||
{
|
||||
// dump stuff from the session:
|
||||
Session::forget('twofactor-authenticated');
|
||||
Session::forget('twofactor-authenticated-date');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will send a newly registered user a confirmation message, urging him or her to activate their account.
|
||||
*
|
||||
* @param RegisteredUser $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sendConfirmationMessage(RegisteredUser $event): bool
|
||||
{
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->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 true;
|
||||
}
|
||||
$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 true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has somehow lost his or her confirmation message, this event will send it to the user again.
|
||||
*
|
||||
* At the moment, this method is exactly the same as the ::sendConfirmationMessage method, but that will change.
|
||||
*
|
||||
* @param ResentConfirmation $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function sendConfirmationMessageAgain(ResentConfirmation $event): bool
|
||||
{
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->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 true;
|
||||
}
|
||||
$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 true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will send the user a registration mail, welcoming him or her to Firefly III.
|
||||
* This message is only sent when the configuration of Firefly III says so.
|
||||
*
|
||||
* @param RegisteredUser $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sendRegistrationMail(RegisteredUser $event)
|
||||
{
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the user is confirmed, this method stores the IP address of the user
|
||||
* as a preference. Since this preference cannot be edited, it is effectively hidden
|
||||
* from the user yet stored conveniently.
|
||||
*
|
||||
* @param ConfirmedUser $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function storeConfirmationIpAddress(ConfirmedUser $event): bool
|
||||
{
|
||||
Preferences::setForUser($event->user, 'confirmation_ip_address', $event->ipAddress);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This message stores the users IP address on registration, in much the same
|
||||
* fashion as the previous method.
|
||||
*
|
||||
* @param RegisteredUser $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function storeRegistrationIpAddress(RegisteredUser $event): bool
|
||||
{
|
||||
Preferences::setForUser($event->user, 'registration_ip_address', $event->ipAddress);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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,9 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentHelper.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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;
|
||||
@@ -39,8 +47,8 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
*/
|
||||
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');
|
||||
@@ -53,7 +61,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment): string
|
||||
{
|
||||
$path = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data';
|
||||
$path = sprintf('%s%sat-%d.data', storage_path('upload'), DIRECTORY_SEPARATOR, intval($attachment->id));
|
||||
|
||||
return $path;
|
||||
}
|
||||
@@ -81,26 +89,14 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model): bool
|
||||
{
|
||||
$files = null;
|
||||
try {
|
||||
if (Input::hasFile('attachments')) {
|
||||
$files = Input::file('attachments');
|
||||
}
|
||||
} catch (TypeError $e) {
|
||||
// Log it, do nothing else.
|
||||
Log::error($e->getMessage());
|
||||
$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 {
|
||||
if (!is_null($files)) {
|
||||
$this->processFile($files, $model);
|
||||
}
|
||||
$this->processFiles($files, $model);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -117,7 +113,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
$md5 = md5_file($file->getRealPath());
|
||||
$name = $file->getClientOriginalName();
|
||||
$class = get_class($model);
|
||||
$count = Auth::user()->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
|
||||
$count = auth()->user()->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
|
||||
|
||||
if ($count > 0) {
|
||||
$msg = (string)trans('validation.file_already_attached', ['name' => $name]);
|
||||
@@ -144,7 +140,7 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
}
|
||||
|
||||
$attachment = new Attachment; // create Attachment object.
|
||||
$attachment->user()->associate(Auth::user());
|
||||
$attachment->user()->associate(auth()->user());
|
||||
$attachment->attachable()->associate($model);
|
||||
$attachment->md5 = md5_file($file->getRealPath());
|
||||
$attachment->filename = $file->getClientOriginalName();
|
||||
@@ -234,5 +230,41 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null|UploadedFile
|
||||
*/
|
||||
private function getFiles()
|
||||
{
|
||||
$files = null;
|
||||
try {
|
||||
if (Input::hasFile('attachments')) {
|
||||
$files = Input::file('attachments');
|
||||
}
|
||||
} catch (TypeError $e) {
|
||||
// Log it, do nothing else.
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $files
|
||||
*
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function processFiles(array $files, Model $model): bool
|
||||
{
|
||||
foreach ($files as $entry) {
|
||||
if (!is_null($entry)) {
|
||||
$this->processFile($entry, $model);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentHelperInterface.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Attachments;
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Account.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Balance.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
@@ -59,5 +69,13 @@ class Balance
|
||||
return $this->balanceLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $balanceLines
|
||||
*/
|
||||
public function setBalanceLines(Collection $balanceLines)
|
||||
{
|
||||
$this->balanceLines = $balanceLines;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* BalanceEntry.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* BalanceHeader.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
@@ -1,7 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* BalanceLine.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International 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 Illuminate\Support\Collection;
|
||||
|
||||
@@ -23,9 +34,12 @@ class BalanceLine
|
||||
|
||||
/** @var BudgetModel */
|
||||
protected $budget;
|
||||
|
||||
/** @var Carbon */
|
||||
protected $endDate;
|
||||
/** @var int */
|
||||
protected $role = self::ROLE_DEFAULTROLE;
|
||||
/** @var Carbon */
|
||||
protected $startDate;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -76,6 +90,22 @@ class BalanceLine
|
||||
$this->budget = $budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getEndDate()
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $endDate
|
||||
*/
|
||||
public function setEndDate($endDate)
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
@@ -92,6 +122,22 @@ class BalanceLine
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getStartDate()
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $startDate
|
||||
*/
|
||||
public function setStartDate($startDate)
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Bill.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* BillLine.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
@@ -141,5 +151,4 @@ class BillLine
|
||||
$this->hit = $hit;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Budget.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
@@ -33,46 +43,66 @@ class Budget
|
||||
|
||||
/**
|
||||
* @param BudgetLine $budgetLine
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function addBudgetLine(BudgetLine $budgetLine)
|
||||
public function addBudgetLine(BudgetLine $budgetLine): Budget
|
||||
{
|
||||
$this->budgetLines->push($budgetLine);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $add
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function addBudgeted(string $add)
|
||||
public function addBudgeted(string $add): Budget
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
$this->budgeted = bcadd($this->budgeted, $add);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $add
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function addLeft(string $add)
|
||||
public function addLeft(string $add): Budget
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
$this->left = bcadd($this->left, $add);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $add
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function addOverspent(string $add)
|
||||
public function addOverspent(string $add): Budget
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
$this->overspent = bcadd($this->overspent, $add);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $add
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function addSpent(string $add)
|
||||
public function addSpent(string $add): Budget
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
$this->spent = bcadd($this->spent, $add);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,10 +123,14 @@ class Budget
|
||||
|
||||
/**
|
||||
* @param string $budgeted
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function setBudgeted(string $budgeted)
|
||||
public function setBudgeted(string $budgeted): Budget
|
||||
{
|
||||
$this->budgeted = $budgeted;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,10 +143,14 @@ class Budget
|
||||
|
||||
/**
|
||||
* @param string $left
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function setLeft(string $left)
|
||||
public function setLeft(string $left): Budget
|
||||
{
|
||||
$this->left = $left;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,10 +163,14 @@ class Budget
|
||||
|
||||
/**
|
||||
* @param string $overspent
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function setOverspent(string $overspent)
|
||||
public function setOverspent(string $overspent): Budget
|
||||
{
|
||||
$this->overspent = strval(round($overspent, 2));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,10 +183,14 @@ class Budget
|
||||
|
||||
/**
|
||||
* @param string $spent
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function setSpent(string $spent)
|
||||
public function setSpent(string $spent): Budget
|
||||
{
|
||||
$this->spent = strval(round($spent, 2));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLine.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
@@ -37,10 +47,14 @@ class BudgetLine
|
||||
|
||||
/**
|
||||
* @param BudgetModel $budget
|
||||
*
|
||||
* @return BudgetLine
|
||||
*/
|
||||
public function setBudget(BudgetModel $budget)
|
||||
public function setBudget(BudgetModel $budget): BudgetLine
|
||||
{
|
||||
$this->budget = $budget;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,10 +67,14 @@ class BudgetLine
|
||||
|
||||
/**
|
||||
* @param string $budgeted
|
||||
*
|
||||
* @return BudgetLine
|
||||
*/
|
||||
public function setBudgeted(string $budgeted)
|
||||
public function setBudgeted(string $budgeted): BudgetLine
|
||||
{
|
||||
$this->budgeted = $budgeted;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,10 +87,14 @@ class BudgetLine
|
||||
|
||||
/**
|
||||
* @param string $left
|
||||
*
|
||||
* @return BudgetLine
|
||||
*/
|
||||
public function setLeft(string $left)
|
||||
public function setLeft(string $left): BudgetLine
|
||||
{
|
||||
$this->left = $left;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,10 +107,14 @@ class BudgetLine
|
||||
|
||||
/**
|
||||
* @param string $overspent
|
||||
*
|
||||
* @return BudgetLine
|
||||
*/
|
||||
public function setOverspent(string $overspent)
|
||||
public function setOverspent(string $overspent): BudgetLine
|
||||
{
|
||||
$this->overspent = $overspent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,10 +127,14 @@ class BudgetLine
|
||||
|
||||
/**
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
* @return BudgetLine
|
||||
*/
|
||||
public function setRepetition(LimitRepetition $repetition)
|
||||
public function setRepetition(LimitRepetition $repetition): BudgetLine
|
||||
{
|
||||
$this->repetition = $repetition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,10 +147,14 @@ class BudgetLine
|
||||
|
||||
/**
|
||||
* @param string $spent
|
||||
*
|
||||
* @return BudgetLine
|
||||
*/
|
||||
public function setSpent(string $spent)
|
||||
public function setSpent(string $spent): BudgetLine
|
||||
{
|
||||
$this->spent = $spent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Category.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
@@ -1,9 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Expense.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Crypt;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
|
||||
@@ -29,30 +37,11 @@ class Expense
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $entry
|
||||
* @param stdClass $entry
|
||||
*/
|
||||
public function addOrCreateExpense(TransactionJournal $entry)
|
||||
public function addOrCreateExpense(stdClass $entry)
|
||||
{
|
||||
|
||||
$accountId = $entry->account_id;
|
||||
$amount = strval(round($entry->journalAmount, 2));
|
||||
if (bccomp('0', $amount) === -1) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
if (!$this->expenses->has($accountId)) {
|
||||
$newObject = new stdClass;
|
||||
$newObject->amount = $amount;
|
||||
$newObject->name = Crypt::decrypt($entry->account_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);
|
||||
}
|
||||
$this->expenses->put($entry->id, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,8 +49,6 @@ class Expense
|
||||
*/
|
||||
public function addToTotal(string $add)
|
||||
{
|
||||
|
||||
|
||||
$add = strval(round($add, 2));
|
||||
if (bccomp('0', $add) === -1) {
|
||||
$add = bcmul($add, '-1');
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user