mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-01 19:47:11 +00:00
Compare commits
532 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f299b895b | ||
|
|
4e1bb5fbac | ||
|
|
47ccc513ad | ||
|
|
cce1a01936 | ||
|
|
6f2b1a6a76 | ||
|
|
8526907f50 | ||
|
|
bc192a8e54 | ||
|
|
9ff6f8fc52 | ||
|
|
6573bd6b4b | ||
|
|
9dc3f614af | ||
|
|
3888b8cceb | ||
|
|
294df4a2b3 | ||
|
|
265dd37212 | ||
|
|
eb7c79ad27 | ||
|
|
de111c7100 | ||
|
|
e892c9a824 | ||
|
|
5eb0e18cae | ||
|
|
27cabb398e | ||
|
|
64dbb14241 | ||
|
|
bb4e2be9eb | ||
|
|
7d1de0da17 | ||
|
|
bf16c9a42b | ||
|
|
1a7b1ce499 | ||
|
|
efc9bc71a7 | ||
|
|
fc5b315af0 | ||
|
|
7a4a78628d | ||
|
|
d16fb30a62 | ||
|
|
2d177e660e | ||
|
|
2f131dc170 | ||
|
|
94810e371a | ||
|
|
59731878f6 | ||
|
|
54ede8aa18 | ||
|
|
b415b6b043 | ||
|
|
70c922cdc5 | ||
|
|
068fc32cb2 | ||
|
|
3dcdacc3b8 | ||
|
|
a6594358d8 | ||
|
|
f98921da46 | ||
|
|
25747fbcf2 | ||
|
|
aac5c2b13c | ||
|
|
cc810a5b6f | ||
|
|
1b3592d959 | ||
|
|
d75614e9a7 | ||
|
|
08703e282f | ||
|
|
2904baf44e | ||
|
|
f99e46bf75 | ||
|
|
9f87890ead | ||
|
|
638184cf66 | ||
|
|
03babfe75c | ||
|
|
238ed3c788 | ||
|
|
6a9d931ba3 | ||
|
|
a3d2a9e00b | ||
|
|
39b88e8207 | ||
|
|
449c6dfde5 | ||
|
|
7cc47ca0b1 | ||
|
|
95f4a83f41 | ||
|
|
35154dc7a3 | ||
|
|
0fd0d7d080 | ||
|
|
658265c938 | ||
|
|
38fe9e7e1c | ||
|
|
77056dcf8d | ||
|
|
026683a8e1 | ||
|
|
6ab6dd6ac3 | ||
|
|
83de3482ce | ||
|
|
919a35aed3 | ||
|
|
ad3defb071 | ||
|
|
9c929ecd1b | ||
|
|
f79c9f7cf1 | ||
|
|
8e75c345d9 | ||
|
|
44886d9aad | ||
|
|
c2d444347d | ||
|
|
5cb497596d | ||
|
|
1857469d2f | ||
|
|
ea71b4843d | ||
|
|
97727e2e3d | ||
|
|
f81e7da8bb | ||
|
|
8e827bf83b | ||
|
|
9e1fa284ca | ||
|
|
3bf800be6e | ||
|
|
635b9f9dba | ||
|
|
52a0d7cf7b | ||
|
|
a34516932b | ||
|
|
929a2a30a2 | ||
|
|
ffa88eeb08 | ||
|
|
51b45b4ed4 | ||
|
|
f263844793 | ||
|
|
18c46df9aa | ||
|
|
15846e157b | ||
|
|
bc59f2db0d | ||
|
|
cd2be8c1a4 | ||
|
|
f958115c50 | ||
|
|
e7d677bfb6 | ||
|
|
3e80ffc52b | ||
|
|
d0c7a5c076 | ||
|
|
f3f4e6b354 | ||
|
|
5a45b25614 | ||
|
|
0b5ee1edfc | ||
|
|
da3dc599f9 | ||
|
|
f013b435ab | ||
|
|
5f6975a113 | ||
|
|
c5dee29e4b | ||
|
|
633ee02f13 | ||
|
|
6b750c909a | ||
|
|
5f8b6640a9 | ||
|
|
dd42d8437c | ||
|
|
67a178591d | ||
|
|
f5e5659c1f | ||
|
|
8b0f0fb615 | ||
|
|
209116e766 | ||
|
|
79392ab656 | ||
|
|
3ca1207231 | ||
|
|
cec1b147f2 | ||
|
|
46cfcfa3e7 | ||
|
|
b833e8dfa2 | ||
|
|
77b843efd8 | ||
|
|
db72ad7c60 | ||
|
|
eadc630fcb | ||
|
|
170c1793cc | ||
|
|
9f7c6c2d0c | ||
|
|
72d054c55c | ||
|
|
524edfe7c2 | ||
|
|
c25c5623d2 | ||
|
|
4f38b77ef6 | ||
|
|
5862803434 | ||
|
|
5b3beded39 | ||
|
|
c61fb7a598 | ||
|
|
33d9148029 | ||
|
|
63969f5a33 | ||
|
|
edde18aeef | ||
|
|
657116d361 | ||
|
|
e16269daa8 | ||
|
|
c07591ff5c | ||
|
|
75a478ad54 | ||
|
|
8dae8b1a7f | ||
|
|
15fd8cf486 | ||
|
|
55333156ac | ||
|
|
8cdcba3231 | ||
|
|
8bab9e84e2 | ||
|
|
2faae83912 | ||
|
|
5a61a11a61 | ||
|
|
a6d71988f2 | ||
|
|
7069e242ae | ||
|
|
56ee830558 | ||
|
|
6dd12729e6 | ||
|
|
14a48303cb | ||
|
|
72cf6c9c0f | ||
|
|
144ee6b8ca | ||
|
|
8967d86da6 | ||
|
|
18c6edbb5d | ||
|
|
53de3c4717 | ||
|
|
ad577e4e81 | ||
|
|
44811a3e7c | ||
|
|
1ab3f05b3a | ||
|
|
5e76488ae7 | ||
|
|
32771fe7e1 | ||
|
|
9b40cc6881 | ||
|
|
2e35260bbb | ||
|
|
a067704277 | ||
|
|
de281818ac | ||
|
|
c49bfad38d | ||
|
|
c1ba591b26 | ||
|
|
719af38a61 | ||
|
|
ac61dfae6b | ||
|
|
813fb679a7 | ||
|
|
e7562781f7 | ||
|
|
56d36b7f53 | ||
|
|
53b3f7f821 | ||
|
|
08a53156bd | ||
|
|
8985cd6309 | ||
|
|
3833da7410 | ||
|
|
4210cd10db | ||
|
|
a7bd1c6892 | ||
|
|
52b0111afa | ||
|
|
7921d128e4 | ||
|
|
d7e838701a | ||
|
|
289bcb22aa | ||
|
|
3fe57b7983 | ||
|
|
32e92c2a16 | ||
|
|
1b3d208540 | ||
|
|
6a8bf0aa62 | ||
|
|
56715556ed | ||
|
|
838330b909 | ||
|
|
69553b138b | ||
|
|
36d7a02994 | ||
|
|
301528e2d2 | ||
|
|
0303b45707 | ||
|
|
ba722e8ed5 | ||
|
|
289e5a5442 | ||
|
|
fdad96e2bc | ||
|
|
af994e4dae | ||
|
|
006d68e279 | ||
|
|
29dc122ad3 | ||
|
|
cf4a8c6204 | ||
|
|
3c73fe92bf | ||
|
|
6637590797 | ||
|
|
b8bab11acd | ||
|
|
a2f600feac | ||
|
|
80dd62ef0a | ||
|
|
827b1c9cd8 | ||
|
|
2e4fcf803d | ||
|
|
d00d95fc6f | ||
|
|
3e3ab9bd25 | ||
|
|
6eecc7722d | ||
|
|
ada4aaf69a | ||
|
|
93244c1f78 | ||
|
|
be056cea6b | ||
|
|
659ca8be14 | ||
|
|
ea9af8366d | ||
|
|
80edd47d36 | ||
|
|
d7746b3649 | ||
|
|
c4c4fbc34c | ||
|
|
59f57c96e9 | ||
|
|
a2f852fecf | ||
|
|
ad114ed329 | ||
|
|
c4c3d0f07f | ||
|
|
6cf8102de5 | ||
|
|
e7e4aa2218 | ||
|
|
6d84f4b6c1 | ||
|
|
ce3e9ffd11 | ||
|
|
3ada260e0e | ||
|
|
8fdd0cb795 | ||
|
|
913e05a2e6 | ||
|
|
fa1f703ef6 | ||
|
|
4004c53e1b | ||
|
|
4838670649 | ||
|
|
a985e09282 | ||
|
|
9bd1503cb4 | ||
|
|
a2ccbf7844 | ||
|
|
61bbe8a905 | ||
|
|
59bc5d22d1 | ||
|
|
1423d5b314 | ||
|
|
152d0eb1d0 | ||
|
|
6426d1df06 | ||
|
|
9284eb3fe9 | ||
|
|
afdae8bc1e | ||
|
|
2a7085e593 | ||
|
|
2408fb3ed4 | ||
|
|
8316afb176 | ||
|
|
e59fd098a3 | ||
|
|
e044199693 | ||
|
|
8f8e29fc22 | ||
|
|
8de5384158 | ||
|
|
216c659335 | ||
|
|
041ca8a5d3 | ||
|
|
fe4f1b306d | ||
|
|
a0972d99fb | ||
|
|
e332bfef7c | ||
|
|
cba5e226d8 | ||
|
|
5aff0c4943 | ||
|
|
cb49c00f4d | ||
|
|
e26d797d57 | ||
|
|
938581527e | ||
|
|
c38ae09735 | ||
|
|
28c3cfe084 | ||
|
|
4a2823bcba | ||
|
|
18eba02026 | ||
|
|
d4690ce580 | ||
|
|
a785c450b1 | ||
|
|
7480dc4a19 | ||
|
|
ad01891a67 | ||
|
|
67fe35d564 | ||
|
|
7f19b6957a | ||
|
|
0a54caf202 | ||
|
|
4b4c1c7f8f | ||
|
|
d071f3947e | ||
|
|
b3d99cd210 | ||
|
|
90e696f82c | ||
|
|
958fcd1cfa | ||
|
|
8f57c7dcb3 | ||
|
|
77262f52a4 | ||
|
|
16bfbc8a12 | ||
|
|
1fd375b875 | ||
|
|
46131ad39d | ||
|
|
0b5c5b2ae9 | ||
|
|
55be174037 | ||
|
|
a17b7025f1 | ||
|
|
170cf7fd77 | ||
|
|
23cdb4d326 | ||
|
|
cbbe529572 | ||
|
|
0b382426e9 | ||
|
|
1cbbf9baa4 | ||
|
|
8d41ff7b79 | ||
|
|
e3b6057bf8 | ||
|
|
66a4042cad | ||
|
|
56c08d8302 | ||
|
|
d4e759754d | ||
|
|
a96e171cbf | ||
|
|
bd4a8c8397 | ||
|
|
04f71b3b43 | ||
|
|
d124de51db | ||
|
|
d87d12a0f5 | ||
|
|
f2b08346d0 | ||
|
|
d3682a6727 | ||
|
|
371bbd9508 | ||
|
|
a8a28f442f | ||
|
|
65ddd8a736 | ||
|
|
8bb27de233 | ||
|
|
37e2f097ba | ||
|
|
1966d87ce6 | ||
|
|
7b8c86e1e3 | ||
|
|
de634da513 | ||
|
|
96836e2d6c | ||
|
|
8a9d576f61 | ||
|
|
791d12fbb4 | ||
|
|
d1329be2fa | ||
|
|
3ed6561702 | ||
|
|
7a0587f433 | ||
|
|
0fe682bfe6 | ||
|
|
0f685e8789 | ||
|
|
420771c233 | ||
|
|
5e3e9271ca | ||
|
|
1e603c0833 | ||
|
|
03e1673e92 | ||
|
|
9f992f003d | ||
|
|
f50244a41f | ||
|
|
8b9607f9b5 | ||
|
|
af107ad5e8 | ||
|
|
8926d62165 | ||
|
|
45344ee347 | ||
|
|
baf9ebab15 | ||
|
|
b7dab817f2 | ||
|
|
fb2fa54480 | ||
|
|
2c966a1234 | ||
|
|
143ea69c0d | ||
|
|
8a02ead013 | ||
|
|
930d5ab941 | ||
|
|
e54a56d3a8 | ||
|
|
f5216c0d85 | ||
|
|
ebc77540b9 | ||
|
|
28d2583c10 | ||
|
|
b0988a7b00 | ||
|
|
2c4920db2d | ||
|
|
8321663815 | ||
|
|
ac0280d460 | ||
|
|
ba6f4268f0 | ||
|
|
0bd18f94ac | ||
|
|
66fb63661f | ||
|
|
d9b16beb0a | ||
|
|
6a01a9bdfd | ||
|
|
b81b34a706 | ||
|
|
3750a00b5f | ||
|
|
05ddcc169d | ||
|
|
f571a5f1bd | ||
|
|
48b786adea | ||
|
|
d691fa9b4d | ||
|
|
da50f9e419 | ||
|
|
103de5e18a | ||
|
|
dac6efd98b | ||
|
|
46aa7f81b2 | ||
|
|
0683c7cd67 | ||
|
|
50d7aa7b6a | ||
|
|
b781215d0a | ||
|
|
866bc2f3bd | ||
|
|
49d4705014 | ||
|
|
9163fcfccb | ||
|
|
7e10641461 | ||
|
|
cdc0e3cfd8 | ||
|
|
466e81d56a | ||
|
|
5953f691d1 | ||
|
|
e2790ca6c1 | ||
|
|
66dbd48b76 | ||
|
|
73cfbbd2ba | ||
|
|
38bc38bf26 | ||
|
|
e12d13c838 | ||
|
|
fcc3af6136 | ||
|
|
491298e1cb | ||
|
|
72b5895217 | ||
|
|
0a8f4017bd | ||
|
|
cb985f5897 | ||
|
|
968ec0853f | ||
|
|
0bde72d3df | ||
|
|
45293fbd42 | ||
|
|
72997065f0 | ||
|
|
a838dc163d | ||
|
|
3d15a4ca6d | ||
|
|
51c7d4fb1b | ||
|
|
fa586dba7e | ||
|
|
8ad40389f2 | ||
|
|
b3333cc2d3 | ||
|
|
3699a7ba9a | ||
|
|
204e521ba4 | ||
|
|
c9bab3e5c3 | ||
|
|
3d00e20238 | ||
|
|
c3958ed3c4 | ||
|
|
e5b88be5fa | ||
|
|
425552988a | ||
|
|
a81dd8abe5 | ||
|
|
bac8154a5b | ||
|
|
737d15fa0e | ||
|
|
5f2317af7f | ||
|
|
2bd1f783e5 | ||
|
|
d6c0c9f963 | ||
|
|
21b6ad7a41 | ||
|
|
a65d609fdc | ||
|
|
04e676b936 | ||
|
|
be8eaaffdf | ||
|
|
28c753523f | ||
|
|
7fbd0b2ffc | ||
|
|
7ffb48a87a | ||
|
|
d485270e1f | ||
|
|
5fd688b266 | ||
|
|
3716668e0c | ||
|
|
ae7fd18c34 | ||
|
|
4f59b1d32f | ||
|
|
90cb3279df | ||
|
|
cf0c7ef6b2 | ||
|
|
47c23781d9 | ||
|
|
e258c050f7 | ||
|
|
57801b2f34 | ||
|
|
710e9c9423 | ||
|
|
deefef83bd | ||
|
|
51e30aed66 | ||
|
|
8d109a3cfe | ||
|
|
3424e019b5 | ||
|
|
c6b4bceb67 | ||
|
|
afb4155015 | ||
|
|
8d99baf38a | ||
|
|
b91cb60328 | ||
|
|
c0d62237fc | ||
|
|
223ea80860 | ||
|
|
5a77bef494 | ||
|
|
80c0efe821 | ||
|
|
8044d89557 | ||
|
|
4f0ed97410 | ||
|
|
af7952f204 | ||
|
|
d8dcae856b | ||
|
|
7296796ed9 | ||
|
|
a2c2bb4948 | ||
|
|
72ebfdc20e | ||
|
|
16b95ea78a | ||
|
|
c04f08dfd8 | ||
|
|
a30793e818 | ||
|
|
e39e1eaf21 | ||
|
|
ab22d2cbaa | ||
|
|
96ddbe7227 | ||
|
|
4d09235aef | ||
|
|
136b8975e3 | ||
|
|
e21b1eca17 | ||
|
|
244b90b1d4 | ||
|
|
b318f3f940 | ||
|
|
e211c9812e | ||
|
|
eef28d96f4 | ||
|
|
c8227e09ee | ||
|
|
3e05fd91d9 | ||
|
|
450baba56a | ||
|
|
17a8c4918c | ||
|
|
0e2419d61a | ||
|
|
79b1a2ca6d | ||
|
|
2213c68155 | ||
|
|
2492b1fa96 | ||
|
|
6c6598dac5 | ||
|
|
a137112e66 | ||
|
|
8642ae8180 | ||
|
|
894c4dc5a7 | ||
|
|
d96063ea6e | ||
|
|
c3dc193f3e | ||
|
|
3c2952009e | ||
|
|
f4ade470df | ||
|
|
2e33b43389 | ||
|
|
92799699bc | ||
|
|
7ab0508167 | ||
|
|
3c65c28936 | ||
|
|
43892da07e | ||
|
|
7c436920a4 | ||
|
|
89d565e63b | ||
|
|
150b6fe5b6 | ||
|
|
0e77574c26 | ||
|
|
df23863443 | ||
|
|
581bf11b21 | ||
|
|
d602d4b429 | ||
|
|
d1d4a52934 | ||
|
|
375d113769 | ||
|
|
9b83974bff | ||
|
|
3c68c99bd5 | ||
|
|
ec4b37c596 | ||
|
|
ba9601d21c | ||
|
|
50c13fd469 | ||
|
|
7af072b8fc | ||
|
|
faa128d41e | ||
|
|
868fe46932 | ||
|
|
e9e4307ce5 | ||
|
|
774d4844a9 | ||
|
|
586c53e670 | ||
|
|
68e073fbff | ||
|
|
8101dc37b1 | ||
|
|
63f16c458d | ||
|
|
821e007e95 | ||
|
|
1656a2f11a | ||
|
|
4dbc135dce | ||
|
|
fc886f6bc1 | ||
|
|
f93e480466 | ||
|
|
fe807e23f8 | ||
|
|
ecf61c31f1 | ||
|
|
4feff18af5 | ||
|
|
a07c52e0d8 | ||
|
|
7bb07d7f55 | ||
|
|
f12dfc8a14 | ||
|
|
be030f15c4 | ||
|
|
f5fb6c063b | ||
|
|
fb722f06b9 | ||
|
|
c0ea19e15e | ||
|
|
cdeb1ad87c | ||
|
|
0dbe4e94fa | ||
|
|
b5e2e8aa1d | ||
|
|
9502010248 | ||
|
|
fea0557b47 | ||
|
|
ed4fcc9011 | ||
|
|
ed12ea7cfb | ||
|
|
73e526645e | ||
|
|
72aeafb2b5 | ||
|
|
cc1af60cb4 | ||
|
|
359fab315f | ||
|
|
6a9574bab9 | ||
|
|
83d6158483 | ||
|
|
63ef89b6cc | ||
|
|
b0beab4cd3 | ||
|
|
a34782575f | ||
|
|
142bdc9430 | ||
|
|
14b79cb0a4 | ||
|
|
ce5beeaf2c | ||
|
|
31114a2ca5 | ||
|
|
32528094ad | ||
|
|
0a2a01c44c | ||
|
|
c1888dc3ac | ||
|
|
4d76afbe01 | ||
|
|
76d7a97f93 | ||
|
|
8b1366b20a | ||
|
|
e0f9685578 | ||
|
|
5235657954 | ||
|
|
a15fbc8094 | ||
|
|
546f1d9c50 | ||
|
|
74231f552a |
13
.env.example
13
.env.example
@@ -1,6 +1,7 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY=SomeRandomString
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
@@ -11,11 +12,19 @@ DB_PASSWORD=secret
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
||||
DEFAULT_CURRENCY=EUR
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_DRIVER=smtp
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=
|
||||
EMAIL_PRETEND=false
|
||||
|
||||
SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
|
||||
ANALYTICS_ID=
|
||||
RUNCLEANUP=true
|
||||
SITE_OWNER=mail@example.com
|
||||
|
||||
BLOCKED_DOMAINS=
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,7 +5,7 @@ Thumbs.db
|
||||
.idea/
|
||||
tests/_output/*
|
||||
_ide_helper.php
|
||||
/build/logs/clover.xml
|
||||
/build/logs
|
||||
index.html*
|
||||
app/storage/firefly-export*
|
||||
.vagrant
|
||||
|
||||
@@ -10,6 +10,9 @@ install:
|
||||
- composer update
|
||||
- php artisan env
|
||||
- mv -v .env.testing .env
|
||||
- touch storage/database/testing.db
|
||||
- php artisan migrate --env=testing
|
||||
- php artisan migrate --seed --env=testing
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
|
||||
37
README.md
37
README.md
@@ -11,15 +11,12 @@
|
||||
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared
|
||||
household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
|
||||
|
||||
_Firefly is a system you'll have install yourself on webhosting of your choosing._
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people
|
||||
make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase
|
||||
their current cashflow. There are tons of ways to save and earn money.
|
||||
|
||||
Firefly works on the principle that if you know where you're money is going, you can stop it from going there.
|
||||
|
||||
|
||||
To get to know Firefly, and to see if it fits you, check out these resources:
|
||||
|
||||
- The screenshots below on this very page.
|
||||
@@ -27,6 +24,11 @@ To get to know Firefly, and to see if it fits you, check out these resources:
|
||||
- The [full description](https://github.com/JC5/firefly-iii/wiki/full-description), which will tell you how Firefly works,
|
||||
and the philosophy behind it.
|
||||
|
||||
#### A quick technical overview
|
||||
|
||||
Firefly is a system you'll have install yourself on webhosting of your choosing. It needs PHP and MySQL. The current version of Firefly III requires PHP 5.6.4 or
|
||||
higher. Soon, this will be PHP 7.0.0 or higher.
|
||||
|
||||
|
||||
#### About the name (should you care)
|
||||
|
||||
@@ -61,19 +63,19 @@ Everything is organised:
|
||||
|
||||
_Please note that everything in these screenshots is fictional and may not be realistic._
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
## Running and installing
|
||||
|
||||
@@ -82,7 +84,19 @@ If you're still interested please read [the installation guide](https://github.c
|
||||
and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**.
|
||||
|
||||
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
|
||||
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site.
|
||||
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. Accounts on the demo sites will stop working after one month. It's a trial.
|
||||
|
||||
## Security
|
||||
|
||||
You should always run Firefly III on a site with TLS enabled (https://). Please note that although some parts of the
|
||||
database are encrypted (transaction descriptions, names, etc.) some parts are _not_ (amounts, dates, etc). If you need
|
||||
more security, you must enable transparent database encryption or a comparable technology. Please remember that this
|
||||
is open source software under active development, and it is in no way guaranteed to be safe or secure.
|
||||
|
||||
## Translations
|
||||
|
||||
Firefly III is currently available in Dutch and English. Support for other languages is being worked on. I could use
|
||||
your help. Checkout [Crowdin](https://crowdin.com/project/firefly-iii) for more information.
|
||||
|
||||
## Credits
|
||||
|
||||
@@ -90,6 +104,7 @@ Firefly III uses the following libraries and tools:
|
||||
|
||||
* The AdminLTE template by [Almsaseed Studio](https://almsaeedstudio.com/)
|
||||
* The [Google charts](https://developers.google.com/chart/) library.
|
||||
* [Chart.js](http://www.chartjs.org/)
|
||||
* [Bootstrap](http://getbootstrap.com/)
|
||||
* [Laravel](http://laravel.com/)
|
||||
* [Twig](http://twig.sensiolabs.org/)
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalDeleted
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalDeleted extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,15 +14,6 @@ use Illuminate\Support\Collection;
|
||||
interface AccountChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@@ -40,4 +31,13 @@ interface AccountChartGenerator
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
@@ -17,20 +15,68 @@ use Steam;
|
||||
class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $accounts, Carbon $start, Carbon $end)
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
return $this->frontpage($accounts, $start, $end);
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [], 'datasets' => [[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []]]];
|
||||
|
||||
bcscale(2);
|
||||
$start->subDay();
|
||||
$ids = $this->getIdsFromCollection($accounts);
|
||||
$startBalances = Steam::balancesById($ids, $start);
|
||||
$endBalances = Steam::balancesById($ids, $end);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($startBalances, $endBalances) {
|
||||
$id = $account->id;
|
||||
$startBalance = $this->isInArray($startBalances, $id);
|
||||
$endBalance = $this->isInArray($endBalances, $id);
|
||||
$diff = bcsub($endBalance, $startBalance);
|
||||
$account->difference = round($diff, 2);
|
||||
}
|
||||
);
|
||||
|
||||
$accounts = $accounts->sortByDesc(
|
||||
function (Account $account) {
|
||||
return $account->difference;
|
||||
}
|
||||
);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
if ($account->difference > 0) {
|
||||
$data['labels'][] = $account->name;
|
||||
$data['datasets'][0]['data'][] = $account->difference;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @param $entryId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function isInArray($array, $entryId)
|
||||
{
|
||||
if (isset($array[$entryId])) {
|
||||
return $array[$entryId];
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
@@ -42,8 +88,7 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.monthAndDay.' . $language);
|
||||
$format = trans('config.month_and_day');
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
@@ -55,6 +100,7 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = [
|
||||
'label' => $account->name,
|
||||
@@ -67,8 +113,14 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
'data' => [],
|
||||
];
|
||||
$current = clone $start;
|
||||
$range = Steam::balanceInRange($account, $start, clone $end);
|
||||
$previous = array_values($range)[0];
|
||||
while ($current <= $end) {
|
||||
$set['data'][] = Steam::balance($account, $current);
|
||||
$format = $current->format('Y-m-d');
|
||||
$balance = isset($range[$format]) ? $range[$format] : $previous;
|
||||
|
||||
$set['data'][] = $balance;
|
||||
$previous = $balance;
|
||||
$current->addDay();
|
||||
}
|
||||
$data['datasets'][] = $set;
|
||||
@@ -88,8 +140,7 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
public function single(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.monthAndDay.' . $language);
|
||||
$format = trans('config.month_and_day');
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
@@ -101,15 +152,36 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$range = Steam::balanceInRange($account, $start, $end);
|
||||
$current = clone $start;
|
||||
$previous = array_values($range)[0];
|
||||
|
||||
while ($end >= $current) {
|
||||
$theDate = $current->format('Y-m-d');
|
||||
$balance = isset($range[$theDate]) ? $range[$theDate] : $previous;
|
||||
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = Steam::balance($account, $current);
|
||||
$data['datasets'][0]['data'][] = $balance;
|
||||
$previous = $balance;
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getIdsFromCollection(Collection $collection)
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($collection as $entry) {
|
||||
$ids[] = $entry->id;
|
||||
}
|
||||
|
||||
return array_unique($ids);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Support\Collection;
|
||||
use Steam;
|
||||
|
||||
|
||||
/**
|
||||
* Class GoogleAccountChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Account
|
||||
*/
|
||||
class GoogleAccountChartGenerator implements AccountChartGenerator
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
// make chart (original code):
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
||||
$index = 1;
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
||||
$chart->addCertainty($index);
|
||||
$index++;
|
||||
}
|
||||
$current = clone $start;
|
||||
$current->subDay();
|
||||
$today = Carbon::now();
|
||||
while ($end >= $current) {
|
||||
$row = [clone $current];
|
||||
$certain = $current < $today;
|
||||
foreach ($accounts as $account) {
|
||||
$row[] = Steam::balance($account, $current);
|
||||
$row[] = $certain;
|
||||
}
|
||||
$chart->addRowArray($row);
|
||||
$current->addDay();
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
return $this->all($accounts, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
$current = clone $start;
|
||||
$today = new Carbon;
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.dayOfMonth'), 'date');
|
||||
$chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number');
|
||||
$chart->addCertainty(1);
|
||||
|
||||
while ($end >= $current) {
|
||||
$certain = $current < $today;
|
||||
$chart->addRow(clone $current, Steam::balance($account, $current), $certain);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,12 @@ interface BillChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
* @param string $paid
|
||||
* @param string $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $unpaid);
|
||||
public function frontpage($paid, $unpaid);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
use Config;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class ChartJsBillChartGenerator
|
||||
@@ -17,42 +15,23 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
* @param string $paid
|
||||
* @param string $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $unpaid)
|
||||
public function frontpage($paid, $unpaid)
|
||||
{
|
||||
$paidDescriptions = [];
|
||||
$paidAmount = 0;
|
||||
$unpaidDescriptions = [];
|
||||
$unpaidAmount = 0;
|
||||
bcscale(2);
|
||||
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($paid as $entry) { // loop paid and create single entry:
|
||||
$paidDescriptions[] = $entry->description;
|
||||
$paidAmount = bcadd($paidAmount, $entry->amount);
|
||||
}
|
||||
/** @var Bill $entry */
|
||||
foreach ($unpaid as $entry) { // loop unpaid:
|
||||
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
||||
$amount = ($entry[0]->amount_max + $entry[0]->amount_min) / 2;
|
||||
$unpaidDescriptions[] = $description;
|
||||
$unpaidAmount = bcadd($unpaidAmount, $amount);
|
||||
unset($amount, $description);
|
||||
}
|
||||
|
||||
$data = [
|
||||
[
|
||||
'value' => $unpaidAmount,
|
||||
'value' => round($unpaid, 2),
|
||||
'color' => 'rgba(53, 124, 165,0.7)',
|
||||
'highlight' => 'rgba(53, 124, 165,0.9)',
|
||||
'label' => trans('firefly.unpaid'),
|
||||
],
|
||||
[
|
||||
'value' => $paidAmount,
|
||||
'value' => round($paid * -1, 2), // paid is negative, must be positive.
|
||||
'color' => 'rgba(0, 141, 76, 0.7)',
|
||||
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
||||
'label' => trans('firefly.paid'),
|
||||
@@ -70,28 +49,24 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
|
||||
$format = trans('config.month');
|
||||
$data = [
|
||||
'count' => 3,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
// dataset: max amount
|
||||
// dataset: min amount
|
||||
// dataset: actual amount
|
||||
|
||||
$minAmount = [];
|
||||
$maxAmount = [];
|
||||
$actualAmount = [];
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry->date->formatLocalized($format);
|
||||
$minAmount[] = round($bill->amount_min, 2);
|
||||
$maxAmount[] = round($bill->amount_max, 2);
|
||||
$actualAmount[] = round($entry->amount, 2);
|
||||
/*
|
||||
* journalAmount has been collected in BillRepository::getJournals
|
||||
*/
|
||||
$actualAmount[] = round(($entry->journalAmount * -1), 2);
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class GoogleBillChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Bill
|
||||
*/
|
||||
class GoogleBillChartGenerator implements BillChartGenerator
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $unpaid)
|
||||
{
|
||||
// loop paid and create single entry:
|
||||
$paidDescriptions = [];
|
||||
$paidAmount = 0;
|
||||
$unpaidDescriptions = [];
|
||||
$unpaidAmount = 0;
|
||||
|
||||
bcscale(2);
|
||||
|
||||
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($paid as $entry) {
|
||||
|
||||
$paidDescriptions[] = $entry->description;
|
||||
$paidAmount = bcadd($paidAmount, $entry->amount);
|
||||
}
|
||||
|
||||
// loop unpaid:
|
||||
/** @var Bill $entry */
|
||||
foreach ($unpaid as $entry) {
|
||||
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
||||
$amount = ($entry[0]->amount_max + $entry[0]->amount_min) / 2;
|
||||
$unpaidDescriptions[] = $description;
|
||||
$unpaidAmount = bcadd($unpaidAmount, $amount);
|
||||
unset($amount, $description);
|
||||
}
|
||||
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.name'), 'string');
|
||||
$chart->addColumn(trans('firefly.amount'), 'number');
|
||||
|
||||
$chart->addRow(trans('firefly.unpaid') . ': ' . join(', ', $unpaidDescriptions), $unpaidAmount);
|
||||
$chart->addRow(trans('firefly.paid') . ': ' . join(', ', $paidDescriptions), $paidAmount);
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries)
|
||||
{
|
||||
// make chart:
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.date'), 'date');
|
||||
$chart->addColumn(trans('firefly.maxAmount'), 'number');
|
||||
$chart->addColumn(trans('firefly.minAmount'), 'number');
|
||||
$chart->addColumn(trans('firefly.billEntry'), 'number');
|
||||
|
||||
/** @var TransactionJournal $result */
|
||||
foreach ($entries as $result) {
|
||||
$chart->addRow(
|
||||
clone $result->date,
|
||||
floatval($bill->amount_max),
|
||||
floatval($bill->amount_min),
|
||||
floatval($result->amount)
|
||||
);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,13 @@ interface BudgetChartGenerator
|
||||
*/
|
||||
public function frontpage(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
|
||||
@@ -24,7 +24,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
public function budget(Collection $entries, $dateFormat = 'month')
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
|
||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
||||
|
||||
$data = [
|
||||
@@ -33,7 +33,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
[
|
||||
'label' => 'Amount',
|
||||
'data' => [],
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -73,19 +73,19 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// dataset: left
|
||||
// dataset: spent
|
||||
// dataset: overspent
|
||||
$left = [];
|
||||
$spent = [];
|
||||
$overspent = [];
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||
$filtered = $entries->filter(
|
||||
function ($entry) {
|
||||
return ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0);
|
||||
}
|
||||
);
|
||||
foreach ($filtered as $entry) {
|
||||
$data['labels'][] = $entry[0];
|
||||
$left[] = round($entry[1], 2);
|
||||
$spent[] = round($entry[2], 2);
|
||||
$overspent[] = round($entry[3], 2);
|
||||
}
|
||||
$spent[] = round($entry[2] * -1, 2); // spent is coming in negative, must be positive
|
||||
$overspent[] = round($entry[3] * -1, 2); // same
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
@@ -115,8 +115,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
public function year(Collection $budgets, Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'labels' => [],
|
||||
@@ -141,4 +140,37 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries)
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// get labels from one of the budgets (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
foreach ($first['budgeted'] as $year => $noInterest) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
|
||||
// then, loop all entries and create datasets:
|
||||
foreach ($entries as $entry) {
|
||||
$name = $entry['name'];
|
||||
$spent = $entry['spent'];
|
||||
$budgeted = $entry['budgeted'];
|
||||
$data['datasets'][] = ['label' => 'Spent on ' . $name, 'data' => array_values($spent)];
|
||||
$data['datasets'][] = ['label' => 'Budgeted for ' . $name, 'data' => array_values($budgeted)];
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class GoogleBudgetChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Budget
|
||||
*/
|
||||
class GoogleBudgetChartGenerator implements BudgetChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries)
|
||||
{
|
||||
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.period'), 'date');
|
||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$chart->addRow($entry[0], $entry[1]);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries)
|
||||
{
|
||||
return $this->budget($entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.budget'), 'string');
|
||||
$chart->addColumn(trans('firefly.left'), 'number');
|
||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||
$chart->addColumn(trans('firefly.overspent'), 'number');
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||
$chart->addRow($entry[0], $entry[1], $entry[2], $entry[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
// add columns:
|
||||
$chart->addColumn(trans('firefly.month'), 'date');
|
||||
foreach ($budgets as $budget) {
|
||||
$chart->addColumn($budget->name, 'number');
|
||||
}
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
|
||||
$chart->addRowArray($entry);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,14 @@ interface CategoryChartGenerator
|
||||
*/
|
||||
public function all(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Collection $categories, Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
@@ -31,8 +39,14 @@ interface CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function month(Collection $entries);
|
||||
public function multiYear(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function period(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
@@ -40,5 +54,5 @@ interface CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries);
|
||||
public function spentInPeriod(Collection $categories, Collection $entries);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
|
||||
/**
|
||||
@@ -17,36 +15,73 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $entries, $dateFormat = 'month')
|
||||
public function all(Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.earned'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
$data['labels'][] = $entry[1];
|
||||
$spent = round($entry[2], 2);
|
||||
$earned = round($entry[3], 2);
|
||||
|
||||
$data['datasets'][0]['data'][] = $spent == 0 ? null : $spent * -1;
|
||||
$data['datasets'][1]['data'][] = $earned == 0 ? null : $earned;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$data['labels'][] = $category->name;
|
||||
}
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$date = $entry[0]->formatLocalized($format);
|
||||
array_shift($entry);
|
||||
$data['count']++;
|
||||
$data['datasets'][] = ['label' => $date, 'data' => $entry];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
@@ -65,15 +100,52 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
],
|
||||
];
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry['sum'] != 0) {
|
||||
$data['labels'][] = $entry['name'];
|
||||
$data['datasets'][0]['data'][] = round($entry['sum'], 2);
|
||||
if ($entry->spent != 0) {
|
||||
$data['labels'][] = $entry->name;
|
||||
$data['datasets'][0]['data'][] = round(($entry->spent * -1), 2);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries)
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// get labels from one of the categories (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
foreach ($first['spent'] as $year => $noInterest) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
|
||||
// then, loop all entries and create datasets:
|
||||
foreach ($entries as $entry) {
|
||||
$name = $entry['name'];
|
||||
$spent = $entry['spent'];
|
||||
$earned = $entry['earned'];
|
||||
if (array_sum(array_values($spent)) != 0) {
|
||||
$data['datasets'][] = ['label' => 'Spent in category ' . $name, 'data' => array_values($spent)];
|
||||
}
|
||||
if (array_sum(array_values($earned)) != 0) {
|
||||
$data['datasets'][] = ['label' => 'Earned in category ' . $name, 'data' => array_values($earned)];
|
||||
}
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
@@ -81,9 +153,9 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function month(Collection $entries)
|
||||
public function period(Collection $entries)
|
||||
{
|
||||
return $this->all($entries, 'monthAndDay');
|
||||
return $this->all($entries);
|
||||
|
||||
}
|
||||
|
||||
@@ -93,12 +165,11 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries)
|
||||
public function spentInPeriod(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 0,
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class GoogleCategoryChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Category
|
||||
*/
|
||||
class GoogleCategoryChartGenerator implements CategoryChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.period'), 'date');
|
||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$chart->addRow($entry[0], $entry[1]);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.category'), 'string');
|
||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$sum = $entry['sum'];
|
||||
if ($sum != 0) {
|
||||
$chart->addRow($entry['name'], $sum);
|
||||
}
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function month(Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
|
||||
$chart->addColumn(trans('firefly.period'), 'date');
|
||||
$chart->addColumn(trans('firefly.spent'), 'number');
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$chart->addRow($entry[0], $entry[1]);
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
|
||||
$chart->addColumn(trans('firefly.month'), 'date');
|
||||
foreach ($categories as $category) {
|
||||
$chart->addColumn($category->name, 'number');
|
||||
}
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$chart->addRowArray($entry);
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,11 @@
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
|
||||
/**
|
||||
* Class GooglePiggyBankChartGenerator
|
||||
* Class ChartJsPiggyBankChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
@@ -25,8 +23,7 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
{
|
||||
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
$format = trans('config.month_and_day');
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
|
||||
/**
|
||||
* Class GooglePiggyBankChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
class GooglePiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function history(Collection $set)
|
||||
{
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.date'), 'date');
|
||||
$chart->addColumn(trans('firefly.balance'), 'number');
|
||||
|
||||
$sum = '0';
|
||||
bcscale(2);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$sum = bcadd($sum, $entry->sum);
|
||||
$chart->addRow(new Carbon($entry->date), $sum);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,80 @@
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class GoogleReportChartGenerator
|
||||
* Class ChartJsReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* Same as above but other translations.
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOut(Collection $entries)
|
||||
{
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized('%Y');
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
$data['datasets'][1]['data'][] = round($entry[2], 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOutSummarized($income, $expense, $count)
|
||||
{
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [trans('firefly.sum_of_years'), trans('firefly.average_of_years')],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
$data['datasets'][0]['data'][] = round($income, 2);
|
||||
$data['datasets'][1]['data'][] = round($expense, 2);
|
||||
$data['datasets'][0]['data'][] = round(($income / $count), 2);
|
||||
$data['datasets'][1]['data'][] = round(($expense / $count), 2);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
@@ -22,8 +84,7 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
public function yearInOut(Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
$format = trans('config.month');
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class GoogleReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
class GoogleReportChartGenerator implements ReportChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries)
|
||||
{
|
||||
$chart = new GChart;
|
||||
$chart->addColumn(trans('firefly.month'), 'date');
|
||||
$chart->addColumn(trans('firefly.income'), 'number');
|
||||
$chart->addColumn(trans('firefly.expenses'), 'number');
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$chart->addRowArray($entry);
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOutSummarized($income, $expense, $count)
|
||||
{
|
||||
$chart = new GChart;
|
||||
|
||||
$chart->addColumn(trans('firefly.summary'), 'string');
|
||||
$chart->addColumn(trans('firefly.income'), 'number');
|
||||
$chart->addColumn(trans('firefly.expenses'), 'number');
|
||||
$chart->addRow(trans('firefly.sum'), $income, $expense);
|
||||
$chart->addRow(trans('firefly.average'), ($income / $count), ($expense / $count));
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return $chart->getData();
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,22 @@ use Illuminate\Support\Collection;
|
||||
interface ReportChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOut(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYearInOutSummarized($income, $expense, $count);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
|
||||
@@ -28,8 +28,6 @@ class ConnectJournalToPiggyBank
|
||||
/**
|
||||
* Handle the event when journal is saved.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @param JournalCreated $event
|
||||
*
|
||||
* @return boolean
|
||||
@@ -53,7 +51,7 @@ class ConnectJournalToPiggyBank
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
$amount = $journal->actual_amount;
|
||||
$amount = $journal->amount_positive;
|
||||
// if piggy account matches source account, the amount is positive
|
||||
if ($piggyBank->account_id == $journal->source_account->id) {
|
||||
$amount = $amount * -1;
|
||||
|
||||
@@ -49,10 +49,12 @@ class UpdateJournalConnection
|
||||
if (is_null($repetition)) {
|
||||
return;
|
||||
}
|
||||
$amount = $journal->amount;
|
||||
$diff = $amount - $event->amount; // update current repetition
|
||||
bcscale(2);
|
||||
|
||||
$repetition->currentamount += $diff;
|
||||
$amount = $journal->amount;
|
||||
$diff = bcsub($amount, $event->amount); // update current repetition
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $diff);
|
||||
$repetition->save();
|
||||
|
||||
|
||||
|
||||
224
app/Helpers/Attachments/AttachmentHelper.php
Normal file
224
app/Helpers/Attachments/AttachmentHelper.php
Normal file
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Attachments;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use Crypt;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Input;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
/**
|
||||
* Class AttachmentHelper
|
||||
*
|
||||
* @package FireflyIII\Helpers\Attachments
|
||||
*/
|
||||
class AttachmentHelper implements AttachmentHelperInterface
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
protected $maxUploadSize;
|
||||
/** @var array */
|
||||
protected $allowedMimes;
|
||||
/** @var MessageBag */
|
||||
public $errors;
|
||||
/** @var MessageBag */
|
||||
public $messages;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->maxUploadSize = Config::get('firefly.maxUploadSize');
|
||||
$this->allowedMimes = Config::get('firefly.allowedMimes');
|
||||
$this->errors = new MessageBag;
|
||||
$this->messages = new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment)
|
||||
{
|
||||
$path = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data';
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model)
|
||||
{
|
||||
$files = Input::file('attachments');
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasFile(UploadedFile $file, Model $model)
|
||||
{
|
||||
$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();
|
||||
|
||||
if ($count > 0) {
|
||||
$msg = trans('validation.file_already_attached', ['name' => $name]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateUpload(UploadedFile $file, Model $model)
|
||||
{
|
||||
if (!$this->validMime($file)) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->validSize($file)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->hasFile($file, $model)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool|Attachment
|
||||
*/
|
||||
protected function processFile(UploadedFile $file, Model $model)
|
||||
{
|
||||
$validation = $this->validateUpload($file, $model);
|
||||
if ($validation === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$attachment = new Attachment; // create Attachment object.
|
||||
$attachment->user()->associate(Auth::user());
|
||||
$attachment->attachable()->associate($model);
|
||||
$attachment->md5 = md5_file($file->getRealPath());
|
||||
$attachment->filename = $file->getClientOriginalName();
|
||||
$attachment->mime = $file->getMimeType();
|
||||
$attachment->size = $file->getSize();
|
||||
$attachment->uploaded = 0;
|
||||
$attachment->save();
|
||||
|
||||
$path = $file->getRealPath(); // encrypt and move file to storage.
|
||||
$content = file_get_contents($path);
|
||||
$encrypted = Crypt::encrypt($content);
|
||||
|
||||
// store it:
|
||||
$upload = $this->getAttachmentLocation($attachment);
|
||||
if (is_writable(dirname($upload))) {
|
||||
file_put_contents($upload, $encrypted);
|
||||
}
|
||||
|
||||
$attachment->uploaded = 1; // update attachment
|
||||
$attachment->save();
|
||||
|
||||
$name = e($file->getClientOriginalName()); // add message:
|
||||
$msg = trans('validation.file_attached', ['name' => $name]);
|
||||
$this->messages->add('attachments', $msg);
|
||||
|
||||
// return it.
|
||||
return $attachment;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validMime(UploadedFile $file)
|
||||
{
|
||||
$mime = e($file->getMimeType());
|
||||
$name = e($file->getClientOriginalName());
|
||||
|
||||
if (!in_array($mime, $this->allowedMimes)) {
|
||||
$msg = trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validSize(UploadedFile $file)
|
||||
{
|
||||
$size = $file->getSize();
|
||||
$name = e($file->getClientOriginalName());
|
||||
if ($size > $this->maxUploadSize) {
|
||||
$msg = trans('validation.file_too_large', ['name' => $name]);
|
||||
$this->errors->add('attachments', $msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
41
app/Helpers/Attachments/AttachmentHelperInterface.php
Normal file
41
app/Helpers/Attachments/AttachmentHelperInterface.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Attachments;
|
||||
|
||||
use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface AttachmentHelperInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Attachments
|
||||
*/
|
||||
interface AttachmentHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model);
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors();
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages();
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment);
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -26,9 +25,6 @@ class BalanceLine
|
||||
/** @var BudgetModel */
|
||||
protected $budget;
|
||||
|
||||
/** @var LimitRepetition */
|
||||
protected $repetition;
|
||||
|
||||
protected $role = self::ROLE_DEFAULTROLE;
|
||||
|
||||
/**
|
||||
@@ -48,24 +44,19 @@ class BalanceLine
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @return Collection
|
||||
*/
|
||||
public function getTitle()
|
||||
public function getBalanceEntries()
|
||||
{
|
||||
if ($this->getBudget() instanceof BudgetModel) {
|
||||
return $this->getBudget()->name;
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_DEFAULTROLE) {
|
||||
return trans('firefly.noBudget');
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_TAGROLE) {
|
||||
return trans('firefly.coveredWithTags');
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_DIFFROLE) {
|
||||
return trans('firefly.leftUnbalanced');
|
||||
return $this->balanceEntries;
|
||||
}
|
||||
|
||||
return '';
|
||||
/**
|
||||
* @param Collection $balanceEntries
|
||||
*/
|
||||
public function setBalanceEntries($balanceEntries)
|
||||
{
|
||||
$this->balanceEntries = $balanceEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,6 +91,27 @@ class BalanceLine
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
if ($this->getBudget() instanceof BudgetModel) {
|
||||
return $this->getBudget()->name;
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_DEFAULTROLE) {
|
||||
return trans('firefly.noBudget');
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_TAGROLE) {
|
||||
return trans('firefly.coveredWithTags');
|
||||
}
|
||||
if ($this->getRole() == self::ROLE_DIFFROLE) {
|
||||
return trans('firefly.leftUnbalanced');
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine
|
||||
* should have a "spent" value, which is the amount of money that has been spent
|
||||
@@ -110,7 +122,7 @@ class BalanceLine
|
||||
*/
|
||||
public function leftOfRepetition()
|
||||
{
|
||||
$start = $this->getRepetition() ? $this->getRepetition()->amount : 0;
|
||||
$start = isset($this->budget->amount) ? $this->budget->amount : 0;
|
||||
/** @var BalanceEntry $balanceEntry */
|
||||
foreach ($this->getBalanceEntries() as $balanceEntry) {
|
||||
$start += $balanceEntry->getSpent();
|
||||
@@ -118,56 +130,4 @@ class BalanceLine
|
||||
|
||||
return $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LimitRepetition
|
||||
*/
|
||||
public function getRepetition()
|
||||
{
|
||||
return $this->repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LimitRepetition $repetition
|
||||
*/
|
||||
public function setRepetition($repetition)
|
||||
{
|
||||
$this->repetition = $repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBalanceEntries()
|
||||
{
|
||||
return $this->balanceEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $balanceEntries
|
||||
*/
|
||||
public function setBalanceEntries($balanceEntries)
|
||||
{
|
||||
$this->balanceEntries = $balanceEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the BalanceEntries for a BalanceLine have a "left" value, the amount
|
||||
* of money left in the entire BalanceLine is returned here:
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function sumOfLeft()
|
||||
{
|
||||
$sum = '0';
|
||||
bcscale(2);
|
||||
/** @var BalanceEntry $balanceEntry */
|
||||
foreach ($this->getBalanceEntries() as $balanceEntry) {
|
||||
$sum = bcadd($sum, $balanceEntry->getLeft());
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,10 @@ class Category
|
||||
*/
|
||||
public function addCategory(CategoryModel $category)
|
||||
{
|
||||
if ($category->spent > 0) {
|
||||
// spent is minus zero for an expense report:
|
||||
if ($category->spent < 0) {
|
||||
$this->categories->push($category);
|
||||
$this->addTotal($category->spent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +56,7 @@ class Category
|
||||
*/
|
||||
public function getCategories()
|
||||
{
|
||||
$set = $this->categories->sortByDesc(
|
||||
$set = $this->categories->sortBy(
|
||||
function (CategoryModel $category) {
|
||||
return $category->spent;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Crypt;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
@@ -33,19 +34,24 @@ class Expense
|
||||
*/
|
||||
public function addOrCreateExpense(TransactionJournal $entry)
|
||||
{
|
||||
bcscale(2);
|
||||
|
||||
$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 = strval(round($entry->amount, 2));
|
||||
$newObject->name = $entry->name;
|
||||
$newObject->amount = $amount;
|
||||
$newObject->name = Crypt::decrypt($entry->account_name);
|
||||
$newObject->count = 1;
|
||||
$newObject->id = $accountId;
|
||||
$this->expenses->put($accountId, $newObject);
|
||||
} else {
|
||||
bcscale(2);
|
||||
$existing = $this->expenses->get($accountId);
|
||||
$existing->amount = bcadd($existing->amount, $entry->amount);
|
||||
$existing->amount = bcadd($existing->amount, $amount);
|
||||
$existing->count++;
|
||||
$this->expenses->put($accountId, $existing);
|
||||
}
|
||||
@@ -56,8 +62,18 @@ class Expense
|
||||
*/
|
||||
public function addToTotal($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
|
||||
|
||||
$add = strval(round($add, 2));
|
||||
if (bccomp('0', $add) === -1) {
|
||||
$add = bcmul($add, '-1');
|
||||
}
|
||||
|
||||
// if amount is positive, the original transaction
|
||||
// was a transfer. But since this is an expense report,
|
||||
// that amount must be negative.
|
||||
|
||||
$this->total = bcadd($this->total, $add);
|
||||
}
|
||||
|
||||
@@ -66,7 +82,7 @@ class Expense
|
||||
*/
|
||||
public function getExpenses()
|
||||
{
|
||||
$set = $this->expenses->sortByDesc(
|
||||
$set = $this->expenses->sortBy(
|
||||
function (stdClass $object) {
|
||||
return $object->amount;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Crypt;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
@@ -38,15 +39,15 @@ class Income
|
||||
$accountId = $entry->account_id;
|
||||
if (!$this->incomes->has($accountId)) {
|
||||
$newObject = new stdClass;
|
||||
$newObject->amount = strval(round($entry->amount, 2));
|
||||
$newObject->name = $entry->name;
|
||||
$newObject->amount = strval(round($entry->journalAmount, 2));
|
||||
$newObject->name = Crypt::decrypt($entry->account_name);
|
||||
$newObject->count = 1;
|
||||
$newObject->id = $accountId;
|
||||
$this->incomes->put($accountId, $newObject);
|
||||
} else {
|
||||
bcscale(2);
|
||||
$existing = $this->incomes->get($accountId);
|
||||
$existing->amount = bcadd($existing->amount, $entry->amount);
|
||||
$existing->amount = bcadd($existing->amount, $entry->journalAmount);
|
||||
$existing->count++;
|
||||
$this->incomes->put($accountId, $existing);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class AccountId extends BasicConverter implements ConverterInterface
|
||||
$account = Auth::user()->accounts()->find($this->value);
|
||||
|
||||
if (!is_null($account)) {
|
||||
Log::debug('Found ' . $account->accountType->type . ' named "******" with ID: ' . $this->value.' (not mapped) ');
|
||||
Log::debug('Found ' . $account->accountType->type . ' named "******" with ID: ' . $this->value . ' (not mapped) ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
@@ -14,13 +17,22 @@ class Date extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
* @return static
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
$format = Session::get('csv-date-format');
|
||||
|
||||
try {
|
||||
$date = Carbon::createFromFormat($format, $this->value);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::error('Date conversion error: ' . $e->getMessage() . '. Value was "' . $this->value . '", format was "' . $format . '".');
|
||||
|
||||
$message = trans('firefly.csv_date_parse_error', ['format' => $format, 'value' => $this->value]);
|
||||
|
||||
throw new FireflyException($message);
|
||||
}
|
||||
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ class Importer
|
||||
*/
|
||||
protected function parseRow($index)
|
||||
{
|
||||
return (($this->data->hasHeaders() && $index > 1) || !$this->data->hasHeaders());
|
||||
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,7 +296,7 @@ class Importer
|
||||
|
||||
// some debug info:
|
||||
$journalId = $journal->id;
|
||||
$type = $journal->transactionType->type;
|
||||
$type = $journal->getTransactionType();
|
||||
/** @var Account $asset */
|
||||
$asset = $this->importData['asset-account-object'];
|
||||
/** @var Account $opposing */
|
||||
@@ -314,13 +314,13 @@ class Importer
|
||||
*/
|
||||
protected function getTransactionType()
|
||||
{
|
||||
$transactionType = TransactionType::where('type', 'Deposit')->first();
|
||||
$transactionType = TransactionType::where('type', TransactionType::DEPOSIT)->first();
|
||||
if ($this->importData['amount'] < 0) {
|
||||
$transactionType = TransactionType::where('type', 'Withdrawal')->first();
|
||||
$transactionType = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
|
||||
}
|
||||
|
||||
if (in_array($this->importData['opposing-account-object']->accountType->type, ['Asset account', 'Default account'])) {
|
||||
$transactionType = TransactionType::where('type', 'Transfer')->first();
|
||||
$transactionType = TransactionType::where('type', TransactionType::TRANSFER)->first();
|
||||
}
|
||||
|
||||
return $transactionType;
|
||||
|
||||
@@ -24,7 +24,7 @@ class Currency implements PostProcessorInterface
|
||||
|
||||
// fix currency
|
||||
if (is_null($this->data['currency'])) {
|
||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||
$currencyPreference = Preferences::get('currencyPreference', env('DEFAULT_CURRENCY', 'EUR'));
|
||||
$this->data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,22 @@ class RabobankDescription
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
public function setRow($row)
|
||||
{
|
||||
$this->row = $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes Rabobank specific thing.
|
||||
*/
|
||||
@@ -46,21 +62,5 @@ class RabobankDescription
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
public function setRow($row)
|
||||
{
|
||||
$this->row = $row;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@ use Crypt;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Csv\Mapper\MapperInterface;
|
||||
use League\Csv\Reader;
|
||||
use Log;
|
||||
use ReflectionException;
|
||||
use Session;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Wizard
|
||||
*
|
||||
@@ -110,6 +111,7 @@ class Wizard implements WizardInterface
|
||||
foreach ($fields as $field) {
|
||||
if (!Session::has($field)) {
|
||||
Log::error('Session is missing field: ' . $field);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use FireflyIII\Helpers\Collection\Account as AccountCollection;
|
||||
use FireflyIII\Helpers\Collection\Balance;
|
||||
use FireflyIII\Helpers\Collection\BalanceEntry;
|
||||
@@ -19,6 +20,9 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class ReportHelper
|
||||
@@ -43,48 +47,150 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return CategoryCollection
|
||||
*/
|
||||
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$object = new CategoryCollection;
|
||||
|
||||
/**
|
||||
* GET CATEGORIES:
|
||||
*/
|
||||
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||
|
||||
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
||||
foreach ($set as $category) {
|
||||
$object->addCategory($category);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfMonths(Carbon $date)
|
||||
{
|
||||
|
||||
$start = clone $date;
|
||||
$end = Carbon::now();
|
||||
$months = [];
|
||||
while ($start <= $end) {
|
||||
$year = $start->year;
|
||||
|
||||
if (!isset($months[$year])) {
|
||||
$months[$year] = [
|
||||
'start' => Carbon::createFromDate($year, 1, 1)->format('Y-m-d'),
|
||||
'end' => Carbon::createFromDate($year, 12, 31)->format('Y-m-d'),
|
||||
'months' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$currentEnd = clone $start;
|
||||
$currentEnd->endOfMonth();
|
||||
$months[$year]['months'][] = [
|
||||
'formatted' => $start->formatLocalized('%B %Y'),
|
||||
'start' => $start->format('Y-m-d'),
|
||||
'end' => $currentEnd->format('Y-m-d'),
|
||||
'month' => $start->month,
|
||||
'year' => $year,
|
||||
];
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method generates a full report for the given period on all
|
||||
* the users asset and cash accounts.
|
||||
* given accounts
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return AccountCollection
|
||||
*/
|
||||
public function getAccountReport(Carbon $date, Carbon $end, $shared)
|
||||
public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
|
||||
|
||||
$accounts = $this->query->getAllAccounts($date, $end, $shared);
|
||||
$start = '0';
|
||||
$end = '0';
|
||||
$startAmount = '0';
|
||||
$endAmount = '0';
|
||||
$diff = '0';
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
|
||||
$yesterday = clone $start;
|
||||
$yesterday->subDay();
|
||||
|
||||
bcscale(2);
|
||||
|
||||
// remove cash account, if any:
|
||||
$accounts = $accounts->filter(
|
||||
function (Account $account) {
|
||||
if ($account->accountType->type != 'Cash account') {
|
||||
return $account;
|
||||
// get balances for start.
|
||||
$startSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->whereIn('accounts.id', $ids)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_journals.date', '<=', $yesterday->format('Y-m-d'))
|
||||
->groupBy('accounts.id')
|
||||
->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]);
|
||||
|
||||
// and for end:
|
||||
$endSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->whereIn('accounts.id', $ids)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
||||
->groupBy('accounts.id')
|
||||
->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]);
|
||||
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($startSet, $endSet) {
|
||||
/**
|
||||
* The balance for today always incorporates transactions
|
||||
* made on today. So to get todays "start" balance, we sub one
|
||||
* day.
|
||||
*/
|
||||
//
|
||||
$currentStart = $startSet->filter(
|
||||
function (Account $entry) use ($account) {
|
||||
return $account->id == $entry->id;
|
||||
}
|
||||
);
|
||||
if ($currentStart->first()) {
|
||||
$account->startBalance = $currentStart->first()->balance;
|
||||
}
|
||||
|
||||
return null;
|
||||
$currentEnd = $endSet->filter(
|
||||
function (Account $entry) use ($account) {
|
||||
return $account->id == $entry->id;
|
||||
}
|
||||
);
|
||||
if ($currentEnd->first()) {
|
||||
$account->endBalance = $currentEnd->first()->balance;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// summarize:
|
||||
foreach ($accounts as $account) {
|
||||
$start = bcadd($start, $account->startBalance);
|
||||
$end = bcadd($end, $account->endBalance);
|
||||
$diff = bcadd($diff, ($account->endBalance - $account->startBalance));
|
||||
$startAmount = bcadd($startAmount, $account->startBalance);
|
||||
$endAmount = bcadd($endAmount, $account->endBalance);
|
||||
$diff = bcadd($diff, bcsub($account->endBalance, $account->startBalance));
|
||||
}
|
||||
|
||||
$object = new AccountCollection;
|
||||
$object->setStart($start);
|
||||
$object->setEnd($end);
|
||||
$object->setStart($startAmount);
|
||||
$object->setEnd($endAmount);
|
||||
$object->setDifference($diff);
|
||||
$object->setAccounts($accounts);
|
||||
|
||||
@@ -92,37 +198,149 @@ class ReportHelper implements ReportHelperInterface
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The balance report contains a Balance object which in turn contains:
|
||||
*
|
||||
* A BalanceHeader object which contains all relevant user asset accounts for the report.
|
||||
*
|
||||
* A number of BalanceLine objects, which hold:
|
||||
* - A budget
|
||||
* - A number of BalanceEntry objects.
|
||||
*
|
||||
* The BalanceEntry object holds:
|
||||
* - The same budget (again)
|
||||
* - A user asset account as mentioned in the BalanceHeader
|
||||
* - The amount of money spent on the budget by the user asset account
|
||||
* Get a full report on the users incomes during the period for the given accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Income
|
||||
*/
|
||||
public function getIncomeReport($start, $end, Collection $accounts)
|
||||
{
|
||||
$object = new Income;
|
||||
$set = $this->query->income($accounts, $start, $end);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->journalAmount);
|
||||
$object->addOrCreateIncome($entry);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a full report on the users expenses during the period for a list of accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Expense
|
||||
*/
|
||||
public function getExpenseReport($start, $end, Collection $accounts)
|
||||
{
|
||||
$object = new Expense;
|
||||
$set = $this->query->expense($accounts, $start, $end);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer
|
||||
$object->addOrCreateExpense($entry);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return BudgetCollection
|
||||
*/
|
||||
public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$object = new BudgetCollection;
|
||||
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
||||
$set = $repository->getBudgets();
|
||||
$allRepetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
|
||||
$allTotalSpent = $repository->spentAllPerDayForAccounts($accounts, $start, $end);
|
||||
bcscale(2);
|
||||
|
||||
foreach ($set as $budget) {
|
||||
|
||||
$repetitions = $allRepetitions->filter(
|
||||
function (LimitRepetition $rep) use ($budget) {
|
||||
return $rep->budget_id == $budget->id;
|
||||
}
|
||||
);
|
||||
$totalSpent = isset($allTotalSpent[$budget->id]) ? $allTotalSpent[$budget->id] : [];
|
||||
|
||||
// no repetition(s) for this budget:
|
||||
if ($repetitions->count() == 0) {
|
||||
$spent = array_sum($totalSpent);
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setBudget($budget);
|
||||
$budgetLine->setOverspent($spent);
|
||||
$object->addOverspent($spent);
|
||||
$object->addBudgetLine($budgetLine);
|
||||
continue;
|
||||
}
|
||||
|
||||
// one or more repetitions for budget:
|
||||
/** @var LimitRepetition $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setBudget($budget);
|
||||
$budgetLine->setRepetition($repetition);
|
||||
$expenses = $this->getSumOfRange($start, $end, $totalSpent);
|
||||
|
||||
// 200 en -100 is 100, vergeleken met 0 === 1
|
||||
// 200 en -200 is 0, vergeleken met 0 === 0
|
||||
// 200 en -300 is -100, vergeleken met 0 === -1
|
||||
|
||||
$left = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : 0;
|
||||
$spent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0';
|
||||
$overspent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount);
|
||||
|
||||
$budgetLine->setLeft($left);
|
||||
$budgetLine->setSpent($spent);
|
||||
$budgetLine->setOverspent($overspent);
|
||||
$budgetLine->setBudgeted($repetition->amount);
|
||||
|
||||
$object->addBudgeted($repetition->amount);
|
||||
$object->addSpent($spent);
|
||||
$object->addLeft($left);
|
||||
$object->addOverspent($overspent);
|
||||
$object->addBudgetLine($budgetLine);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// stuff outside of budgets:
|
||||
$noBudget = $repository->getWithoutBudgetSum($start, $end);
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setOverspent($noBudget);
|
||||
$budgetLine->setSpent($noBudget);
|
||||
$object->addOverspent($noBudget);
|
||||
$object->addBudgetLine($budgetLine);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Balance
|
||||
*/
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, $shared)
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
||||
|
||||
/** @var \FireflyIII\Repositories\Tag\TagRepositoryInterface $tagRepository */
|
||||
$tagRepository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface');
|
||||
|
||||
$balance = new Balance;
|
||||
|
||||
// build a balance header:
|
||||
$header = new BalanceHeader;
|
||||
|
||||
$accounts = $this->query->getAllAccounts($start, $end, $shared);
|
||||
$budgets = $repository->getBudgets();
|
||||
$budgets = $repository->getBudgetsAndLimitsInRange($start, $end);
|
||||
$spentData = $repository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end);
|
||||
foreach ($accounts as $account) {
|
||||
$header->addAccount($account);
|
||||
}
|
||||
@@ -132,18 +350,21 @@ class ReportHelper implements ReportHelperInterface
|
||||
$line = new BalanceLine;
|
||||
$line->setBudget($budget);
|
||||
|
||||
// get budget amount for current period:
|
||||
$rep = $repository->getCurrentRepetition($budget, $start);
|
||||
$line->setRepetition($rep);
|
||||
|
||||
// loop accounts:
|
||||
foreach ($accounts as $account) {
|
||||
$balanceEntry = new BalanceEntry;
|
||||
$balanceEntry->setAccount($account);
|
||||
|
||||
// get spent:
|
||||
$spent = $this->query->spentInBudgetCorrected($account, $budget, $start, $end); // I think shared is irrelevant.
|
||||
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($budget, $account) {
|
||||
return $model->account_id == $account->id && $model->budget_id == $budget->id;
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
$balanceEntry->setSpent($spent);
|
||||
$line->addBalanceEntry($balanceEntry);
|
||||
}
|
||||
@@ -153,18 +374,36 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
// then a new line for without budget.
|
||||
// and one for the tags:
|
||||
// and one for "left unbalanced".
|
||||
$empty = new BalanceLine;
|
||||
$tags = new BalanceLine;
|
||||
$diffLine = new BalanceLine;
|
||||
$tagsLeft = $tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
|
||||
|
||||
$tags->setRole(BalanceLine::ROLE_TAGROLE);
|
||||
$diffLine->setRole(BalanceLine::ROLE_DIFFROLE);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$spent = $this->query->spentNoBudget($account, $start, $end);
|
||||
$left = $tagRepository->coveredByBalancingActs($account, $start, $end);
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($budget, $account) {
|
||||
return $model->account_id == $account->id && is_null($model->budget_id);
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
$leftEntry = $tagsLeft->filter(
|
||||
function (Tag $tag) use ($account) {
|
||||
return $tag->account_id == $account->id;
|
||||
}
|
||||
);
|
||||
$left = 0;
|
||||
if (!is_null($leftEntry->first())) {
|
||||
$left = $leftEntry->first()->sum;
|
||||
}
|
||||
bcscale(2);
|
||||
$diff = bcsub($spent, $left);
|
||||
$diff = bcadd($spent, $left);
|
||||
|
||||
// budget
|
||||
$budgetEntry = new BalanceEntry;
|
||||
@@ -199,16 +438,20 @@ class ReportHelper implements ReportHelperInterface
|
||||
* This method generates a full report for the given period on all
|
||||
* the users bills and their payments.
|
||||
*
|
||||
* Excludes bills which have not had a payment on the mentioned accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return BillCollection
|
||||
*/
|
||||
public function getBillReport(Carbon $start, Carbon $end)
|
||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||
$bills = $repository->getBills();
|
||||
$bills = $repository->getBillsForAccounts($accounts);
|
||||
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
|
||||
$collection = new BillCollection;
|
||||
|
||||
/** @var Bill $bill */
|
||||
@@ -221,16 +464,17 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
// is hit in period?
|
||||
bcscale(2);
|
||||
$set = $repository->getJournalsInRange($bill, $start, $end);
|
||||
if ($set->count() == 0) {
|
||||
$billLine->setHit(false);
|
||||
} else {
|
||||
$billLine->setHit(true);
|
||||
$amount = '0';
|
||||
foreach ($set as $entry) {
|
||||
$amount = bcadd($amount, $entry->amount);
|
||||
|
||||
$entry = $journals->filter(
|
||||
function (TransactionJournal $journal) use ($bill) {
|
||||
return $journal->bill_id == $bill->id;
|
||||
}
|
||||
$billLine->setAmount($amount);
|
||||
);
|
||||
if (!is_null($entry->first())) {
|
||||
$billLine->setAmount($entry->first()->journalAmount);
|
||||
$billLine->setHit(true);
|
||||
} else {
|
||||
$billLine->setHit(false);
|
||||
}
|
||||
|
||||
$collection->addBill($billLine);
|
||||
@@ -238,165 +482,33 @@ class ReportHelper implements ReportHelperInterface
|
||||
}
|
||||
|
||||
return $collection;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
*
|
||||
* @return BudgetCollection
|
||||
*/
|
||||
public function getBudgetReport(Carbon $start, Carbon $end, $shared)
|
||||
{
|
||||
$object = new BudgetCollection;
|
||||
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
||||
$set = $repository->getBudgets();
|
||||
|
||||
foreach ($set as $budget) {
|
||||
|
||||
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
||||
|
||||
// no repetition(s) for this budget:
|
||||
if ($repetitions->count() == 0) {
|
||||
$spent = $repository->spentInPeriodCorrected($budget, $start, $end, $shared);
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setBudget($budget);
|
||||
$budgetLine->setOverspent($spent);
|
||||
$object->addOverspent($spent);
|
||||
$object->addBudgetLine($budgetLine);
|
||||
continue;
|
||||
}
|
||||
|
||||
// one or more repetitions for budget:
|
||||
/** @var LimitRepetition $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setBudget($budget);
|
||||
$budgetLine->setRepetition($repetition);
|
||||
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, $shared);
|
||||
$left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0;
|
||||
$spent = $expenses > floatval($repetition->amount) ? 0 : $expenses;
|
||||
$overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0;
|
||||
|
||||
$budgetLine->setLeft($left);
|
||||
$budgetLine->setSpent($spent);
|
||||
$budgetLine->setOverspent($overspent);
|
||||
$budgetLine->setBudgeted($repetition->amount);
|
||||
|
||||
$object->addBudgeted($repetition->amount);
|
||||
$object->addSpent($spent);
|
||||
$object->addLeft($left);
|
||||
$object->addOverspent($overspent);
|
||||
$object->addBudgetLine($budgetLine);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// stuff outside of budgets:
|
||||
$noBudget = $repository->getWithoutBudgetSum($start, $end);
|
||||
$budgetLine = new BudgetLine;
|
||||
$budgetLine->setOverspent($noBudget);
|
||||
$object->addOverspent($noBudget);
|
||||
$object->addBudgetLine($budgetLine);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
*
|
||||
* @return CategoryCollection
|
||||
*/
|
||||
public function getCategoryReport(Carbon $start, Carbon $end, $shared)
|
||||
{
|
||||
$object = new CategoryCollection;
|
||||
|
||||
|
||||
/**
|
||||
* GET CATEGORIES:
|
||||
*/
|
||||
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||
$set = $repository->getCategories();
|
||||
foreach ($set as $category) {
|
||||
$spent = $repository->spentInPeriodCorrected($category, $start, $end, $shared);
|
||||
$category->spent = $spent;
|
||||
$object->addCategory($category);
|
||||
$object->addTotal($spent);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a full report on the users expenses during the period.
|
||||
* Take the array as returned by SingleCategoryRepositoryInterface::spentPerDay and SingleCategoryRepositoryInterface::earnedByDay
|
||||
* and sum up everything in the array in the given range.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param array $array
|
||||
*
|
||||
* @return Expense
|
||||
* @return string
|
||||
*/
|
||||
public function getExpenseReport($start, $end, $shared)
|
||||
protected function getSumOfRange(Carbon $start, Carbon $end, array $array)
|
||||
{
|
||||
$object = new Expense;
|
||||
$set = $this->query->expenseInPeriodCorrected($start, $end, $shared);
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->amount);
|
||||
$object->addOrCreateExpense($entry);
|
||||
bcscale(2);
|
||||
$sum = '0';
|
||||
$currentStart = clone $start; // to not mess with the original one
|
||||
$currentEnd = clone $end; // to not mess with the original one
|
||||
|
||||
while ($currentStart <= $currentEnd) {
|
||||
$date = $currentStart->format('Y-m-d');
|
||||
if (isset($array[$date])) {
|
||||
$sum = bcadd($sum, $array[$date]);
|
||||
}
|
||||
$currentStart->addDay();
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a full report on the users incomes during the period.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
*
|
||||
* @return Income
|
||||
*/
|
||||
public function getIncomeReport($start, $end, $shared)
|
||||
{
|
||||
$object = new Income;
|
||||
$set = $this->query->incomeInPeriodCorrected($start, $end, $shared);
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->amount);
|
||||
$object->addOrCreateIncome($entry);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfMonths(Carbon $date)
|
||||
{
|
||||
|
||||
$start = clone $date;
|
||||
$end = Carbon::now();
|
||||
$months = [];
|
||||
while ($start <= $end) {
|
||||
$year = $start->year;
|
||||
$months[$year][] = [
|
||||
'formatted' => $start->formatLocalized('%B %Y'),
|
||||
'month' => $start->month,
|
||||
'year' => $year,
|
||||
];
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
return $months;
|
||||
return $sum;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use FireflyIII\Helpers\Collection\Budget as BudgetCollection;
|
||||
use FireflyIII\Helpers\Collection\Category as CategoryCollection;
|
||||
use FireflyIII\Helpers\Collection\Expense;
|
||||
use FireflyIII\Helpers\Collection\Income;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ReportHelperInterface
|
||||
@@ -21,75 +22,78 @@ interface ReportHelperInterface
|
||||
|
||||
/**
|
||||
* This method generates a full report for the given period on all
|
||||
* the users asset and cash accounts.
|
||||
* given accounts
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return AccountCollection
|
||||
*/
|
||||
public function getAccountReport(Carbon $date, Carbon $end, $shared);
|
||||
public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* This method generates a full report for the given period on all
|
||||
* the users bills and their payments.
|
||||
*
|
||||
* Excludes bills which have not had a payment on the mentioned accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return BillCollection
|
||||
*/
|
||||
public function getBillReport(Carbon $start, Carbon $end);
|
||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Balance
|
||||
*/
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, $shared);
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return BudgetCollection
|
||||
*/
|
||||
public function getBudgetReport(Carbon $start, Carbon $end, $shared);
|
||||
public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return CategoryCollection
|
||||
*/
|
||||
public function getCategoryReport(Carbon $start, Carbon $end, $shared);
|
||||
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* Get a full report on the users expenses during the period.
|
||||
* Get a full report on the users expenses during the period for a list of accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Expense
|
||||
*/
|
||||
public function getExpenseReport($start, $end, $shared);
|
||||
public function getExpenseReport($start, $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* Get a full report on the users incomes during the period.
|
||||
* Get a full report on the users incomes during the period for the given accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param boolean $shared
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Income
|
||||
*/
|
||||
public function getIncomeReport($start, $end, $shared);
|
||||
public function getIncomeReport($start, $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
|
||||
@@ -4,14 +4,10 @@ namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use DB;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class ReportQuery
|
||||
@@ -20,265 +16,163 @@ use Steam;
|
||||
*/
|
||||
class ReportQuery implements ReportQueryInterface
|
||||
{
|
||||
/**
|
||||
* See ReportQueryInterface::incomeInPeriodCorrected.
|
||||
*
|
||||
* This method's length is caused mainly by the query build stuff. Therefor:
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param bool $includeShared
|
||||
*
|
||||
* @return Collection
|
||||
*
|
||||
*/
|
||||
public function expenseInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false)
|
||||
{
|
||||
$query = $this->queryJournalsWithTransactions($start, $end);
|
||||
if ($includeShared === false) {
|
||||
$query->where(
|
||||
function (Builder $query) {
|
||||
$query->where(
|
||||
function (Builder $q) { // only get withdrawals not from a shared account
|
||||
$q->where('transaction_types.type', 'Withdrawal');
|
||||
$q->where('acm_from.data', '!=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function (Builder $q) { // and transfers from a shared account.
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_to.data', '=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
$query->where('transaction_types.type', 'Withdrawal'); // any withdrawal is fine.
|
||||
}
|
||||
$query->orderBy('transaction_journals.date');
|
||||
$data = $query->get( // get everything
|
||||
['transaction_journals.*', 'transaction_types.type', 'ac_to.name as name', 'ac_to.id as account_id', 'ac_to.encrypted as account_encrypted']
|
||||
);
|
||||
|
||||
$data->each(
|
||||
function (TransactionJournal $journal) {
|
||||
if (intval($journal->account_encrypted) == 1) {
|
||||
$journal->name = Crypt::decrypt($journal->name);
|
||||
}
|
||||
}
|
||||
);
|
||||
$data = $data->filter(
|
||||
function (TransactionJournal $journal) {
|
||||
if ($journal->amount != 0) {
|
||||
return $journal;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a users accounts combined with various meta-data related to the start and end date.
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param bool $includeShared
|
||||
*
|
||||
* @return Collection
|
||||
* @return array
|
||||
*/
|
||||
public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false)
|
||||
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$query = Auth::user()->accounts()->orderBy('accounts.name', 'ASC')
|
||||
->accountTypeIn(['Default account', 'Asset account', 'Cash account']);
|
||||
if ($includeShared === false) {
|
||||
$query->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$query = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions AS t_from', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->where(
|
||||
function (Builder $query) {
|
||||
|
||||
$query->where('account_meta.data', '!=', '"sharedAsset"');
|
||||
$query->orWhereNull('account_meta.data');
|
||||
|
||||
->leftJoin(
|
||||
'transactions AS t_to', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->whereIn('t_from.account_id', $ids)
|
||||
->whereNotIn('t_to.account_id', $ids)
|
||||
->after($start)
|
||||
->before($end)
|
||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->groupBy('dateFormatted')
|
||||
->get(
|
||||
[
|
||||
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
||||
DB::Raw('SUM(`t_from`.`amount`) AS `sum`')
|
||||
]
|
||||
);
|
||||
}
|
||||
$set = $query->get(['accounts.*']);
|
||||
$set->each(
|
||||
function (Account $account) use ($start, $end) {
|
||||
/**
|
||||
* The balance for today always incorporates transactions
|
||||
* made on today. So to get todays "start" balance, we sub one
|
||||
* day.
|
||||
*/
|
||||
$yesterday = clone $start;
|
||||
$yesterday->subDay();
|
||||
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$account->startBalance = Steam::balance($account, $yesterday);
|
||||
$account->endBalance = Steam::balance($account, $end);
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
$array = [];
|
||||
foreach ($query as $result) {
|
||||
$array[$result->dateFormatted] = $result->sum;
|
||||
}
|
||||
|
||||
return $array;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results
|
||||
* will simply list the transaction journals only. This should allow any follow up counting to be accurate with
|
||||
* regards to tags.
|
||||
*
|
||||
* This method returns all "income" journals in a certain period, which are both transfers from a shared account
|
||||
* and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
|
||||
* not group and returns different fields.
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedPerMonth(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$query = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions AS t_from', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions AS t_to', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->whereIn('t_to.account_id', $ids)
|
||||
->whereNotIn('t_from.account_id', $ids)
|
||||
->after($start)
|
||||
->before($end)
|
||||
->transactionTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->groupBy('dateFormatted')
|
||||
->get(
|
||||
[
|
||||
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
||||
DB::Raw('SUM(`t_to`.`amount`) AS `sum`')
|
||||
]
|
||||
);
|
||||
$array = [];
|
||||
foreach ($query as $result) {
|
||||
$array[$result->dateFormatted] = $result->sum;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all the "in" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param bool $includeShared
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function incomeInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false)
|
||||
public function income(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$query = $this->queryJournalsWithTransactions($start, $end);
|
||||
if ($includeShared === false) {
|
||||
// only get deposits not to a shared account
|
||||
// and transfers to a shared account.
|
||||
$query->where(
|
||||
function (Builder $query) {
|
||||
$query->where(
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Deposit');
|
||||
$q->where('acm_to.data', '!=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_from.data', '=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// any deposit is fine.
|
||||
$query->where('transaction_types.type', 'Deposit');
|
||||
}
|
||||
$query->orderBy('transaction_journals.date');
|
||||
|
||||
// get everything
|
||||
$data = $query->get(
|
||||
['transaction_journals.*', 'transaction_types.type', 'ac_from.name as name', 'ac_from.id as account_id', 'ac_from.encrypted as account_encrypted']
|
||||
);
|
||||
|
||||
$data->each(
|
||||
function (TransactionJournal $journal) {
|
||||
if (intval($journal->account_encrypted) == 1) {
|
||||
$journal->name = Crypt::decrypt($journal->name);
|
||||
}
|
||||
}
|
||||
);
|
||||
$data = $data->filter(
|
||||
function (TransactionJournal $journal) {
|
||||
if ($journal->amount != 0) {
|
||||
return $journal;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Covers tags
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function spentInBudgetCorrected(Account $account, Budget $budget, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
||||
return floatval(
|
||||
Auth::user()->transactionjournals()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->where('transactions.account_id', $account->id)
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('budget_transaction_journal.budget_id', $budget->id)
|
||||
->get(['transaction_journals.*'])->sum('amount')
|
||||
) * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function spentNoBudget(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
return
|
||||
Auth::user()->transactionjournals()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->where('transactions.account_id', $account->id)
|
||||
->before($end)
|
||||
->after($start)
|
||||
->whereNull('budget_transaction_journal.budget_id')->get(['transaction_journals.*'])->sum('amount');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function queryJournalsWithTransactions(Carbon $start, Carbon $end)
|
||||
{
|
||||
$query = TransactionJournal::
|
||||
leftJoin(
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$set = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_from', function (JoinClause $join) {
|
||||
$join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id')
|
||||
->leftJoin('accounts', 't_from.account_id', '=', 'accounts.id')
|
||||
->transactionTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->before($end)
|
||||
->after($start)
|
||||
->whereIn('t_to.account_id', $ids)
|
||||
->whereNotIn('t_from.account_id', $ids)
|
||||
->get(['transaction_journals.*', 't_to.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all the "out" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expense(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$set = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'account_meta as acm_to', function (JoinClause $join) {
|
||||
$join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole');
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
$query->before($end)->after($start)->where('transaction_journals.user_id', Auth::user()->id);
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 't_to.account_id', '=', 'accounts.id')
|
||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->before($end)
|
||||
->after($start)
|
||||
->whereIn('t_from.account_id', $ids)
|
||||
->whereNotIn('t_to.account_id', $ids)
|
||||
->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
|
||||
|
||||
return $query;
|
||||
return $set;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -16,65 +14,52 @@ interface ReportQueryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* See ReportQueryInterface::incomeInPeriodCorrected
|
||||
*
|
||||
* This method returns all "expense" journals in a certain period, which are both transfers to a shared account
|
||||
* and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
|
||||
* not group and returns different fields.
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param bool $includeShared
|
||||
*
|
||||
* @return Collection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false);
|
||||
public function earnedPerMonth(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* Get a users accounts combined with various meta-data related to the start and end date.
|
||||
* This method returns all the "out" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param bool $includeShared
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false);
|
||||
public function expense(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results
|
||||
* will simply list the transaction journals only. This should allow any follow up counting to be accurate with
|
||||
* regards to tags.
|
||||
* This method returns all the "in" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param bool $includeShared
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function incomeInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false);
|
||||
public function income(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* Covers tags as well.
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Budget $budget
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return float
|
||||
* @return array
|
||||
*/
|
||||
public function spentInBudgetCorrected(Account $account, Budget $budget, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function spentNoBudget(Account $account, Carbon $start, Carbon $end);
|
||||
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests\AccountFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Session;
|
||||
@@ -38,6 +38,8 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function create($what = 'asset')
|
||||
{
|
||||
|
||||
|
||||
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
|
||||
$subTitle = trans('firefly.make_new_' . $what . '_account');
|
||||
|
||||
@@ -54,11 +56,12 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function delete(AccountRepositoryInterface $repository, Account $account)
|
||||
public function delete(ARI $repository, Account $account)
|
||||
{
|
||||
$typeName = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
$subTitle = trans('firefly.delete_' . $typeName . '_account', ['name' => $account->name]);
|
||||
@@ -74,12 +77,12 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(AccountRepositoryInterface $repository, Account $account)
|
||||
public function destroy(ARI $repository, Account $account)
|
||||
{
|
||||
$type = $account->accountType->type;
|
||||
$typeName = Config::get('firefly.shortNamesByFullName.' . $type);
|
||||
@@ -95,12 +98,12 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function edit(AccountRepositoryInterface $repository, Account $account)
|
||||
public function edit(ARI $repository, Account $account)
|
||||
{
|
||||
|
||||
$what = Config::get('firefly.shortNamesByFullName')[$account->accountType->type];
|
||||
@@ -130,7 +133,7 @@ class AccountController extends Controller
|
||||
'ccMonthlyPaymentDate' => $account->getMeta('ccMonthlyPaymentDate'),
|
||||
'openingBalanceDate' => $openingBalance ? $openingBalance->date->format('Y-m-d') : null,
|
||||
'openingBalance' => $openingBalanceAmount,
|
||||
'virtualBalance' => floatval($account->virtual_balance)
|
||||
'virtualBalance' => round($account->virtual_balance, 2)
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
Session::flash('gaEventCategory', 'accounts');
|
||||
@@ -140,39 +143,31 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param $what
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository, $what)
|
||||
public function index(ARI $repository, $what)
|
||||
{
|
||||
$subTitle = trans('firefly.' . $what . '_accounts');
|
||||
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
|
||||
$types = Config::get('firefly.accountTypesByIdentifier.' . $what);
|
||||
$accounts = $repository->getAccounts($types);
|
||||
// last activity:
|
||||
/**
|
||||
* HERE WE ARE
|
||||
*/
|
||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = clone Session::get('end', Carbon::now()->endOfMonth());
|
||||
$start->subDay();
|
||||
|
||||
// start balances:
|
||||
$ids = [];
|
||||
foreach ($accounts as $account) {
|
||||
$ids[] = $account->id;
|
||||
}
|
||||
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$startBalances = Steam::balancesById($ids, $start);
|
||||
$endBalances = Steam::balancesById($ids, $end);
|
||||
$activities = Steam::getLastActivities($ids);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($startBalances, $endBalances) {
|
||||
$account->lastActivityDate = null;//$repository->getLastActivity($account);
|
||||
$account->startBalance = isset($startBalances[$account->id]) ? $startBalances[$account->id] : null;
|
||||
$account->endBalance = isset($endBalances[$account->id]) ? $endBalances[$account->id] : null;
|
||||
function (Account $account) use ($activities, $startBalances, $endBalances) {
|
||||
$account->lastActivityDate = $this->isInArray($activities, $account->id);
|
||||
$account->startBalance = $this->isInArray($startBalances, $account->id);
|
||||
$account->endBalance = $this->isInArray($endBalances, $account->id);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -180,12 +175,12 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(AccountRepositoryInterface $repository, Account $account)
|
||||
public function show(ARI $repository, Account $account)
|
||||
{
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type);
|
||||
@@ -200,23 +195,24 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* @param AccountFormRequest $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(AccountFormRequest $request, AccountRepositoryInterface $repository)
|
||||
public function store(AccountFormRequest $request, ARI $repository)
|
||||
{
|
||||
$accountData = [
|
||||
'name' => $request->input('name'),
|
||||
'accountType' => $request->input('what'),
|
||||
'virtualBalance' => floatval($request->input('virtualBalance')),
|
||||
'virtualBalance' => round($request->input('virtualBalance'), 2),
|
||||
'virtualBalanceCurrency' => intval($request->input('amount_currency_id_virtualBalance')),
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => $request->input('iban'),
|
||||
'accountRole' => $request->input('accountRole'),
|
||||
'openingBalance' => floatval($request->input('openingBalance')),
|
||||
'openingBalance' => round($request->input('openingBalance'), 2),
|
||||
'openingBalanceDate' => new Carbon((string)$request->input('openingBalanceDate')),
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'openingBalanceCurrency' => intval($request->input('amount_currency_id_openingBalance')),
|
||||
|
||||
];
|
||||
|
||||
@@ -238,12 +234,12 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* @param AccountFormRequest $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(AccountFormRequest $request, AccountRepositoryInterface $repository, Account $account)
|
||||
public function update(AccountFormRequest $request, ARI $repository, Account $account)
|
||||
{
|
||||
|
||||
$accountData = [
|
||||
@@ -252,8 +248,8 @@ class AccountController extends Controller
|
||||
'user' => Auth::user()->id,
|
||||
'iban' => $request->input('iban'),
|
||||
'accountRole' => $request->input('accountRole'),
|
||||
'virtualBalance' => floatval($request->input('virtualBalance')),
|
||||
'openingBalance' => floatval($request->input('openingBalance')),
|
||||
'virtualBalance' => round($request->input('virtualBalance'), 2),
|
||||
'openingBalance' => round($request->input('openingBalance'), 2),
|
||||
'openingBalanceDate' => new Carbon((string)$request->input('openingBalanceDate')),
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'ccType' => $request->input('ccType'),
|
||||
@@ -278,4 +274,20 @@ class AccountController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param $entryId
|
||||
*
|
||||
* @return null|mixed
|
||||
*/
|
||||
protected function isInArray(array $array, $entryId)
|
||||
{
|
||||
if (isset($array[$entryId])) {
|
||||
return $array[$entryId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
174
app/Http/Controllers/AttachmentController.php
Normal file
174
app/Http/Controllers/AttachmentController.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
|
||||
use Crypt;
|
||||
use File;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Requests\AttachmentFormRequest;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class AttachmentController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class AttachmentController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
View::share('mainTitleIcon', 'fa-paperclip');
|
||||
View::share('title', trans('firefly.attachments'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function edit(Attachment $attachment)
|
||||
{
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$subTitle = trans('firefly.edit_attachment', ['name' => $attachment->filename]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('attachments.edit.fromUpdate') !== true) {
|
||||
Session::put('attachments.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('attachments.edit.fromUpdate');
|
||||
|
||||
return view('attachments.edit', compact('attachment', 'subTitleIcon', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function delete(Attachment $attachment)
|
||||
{
|
||||
$subTitle = trans('firefly.delete_attachment', ['name' => $attachment->filename]);
|
||||
|
||||
// put previous url in session
|
||||
Session::put('attachments.delete.url', URL::previous());
|
||||
Session::flash('gaEventCategory', 'attachments');
|
||||
Session::flash('gaEventAction', 'delete-attachment');
|
||||
|
||||
return view('attachments.delete', compact('attachment', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AttachmentRepositoryInterface $repository
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(AttachmentRepositoryInterface $repository, Attachment $attachment)
|
||||
{
|
||||
$name = $attachment->filename;
|
||||
|
||||
$repository->destroy($attachment);
|
||||
|
||||
Session::flash('success', trans('firefly.attachment_deleted', ['name' => $name]));
|
||||
Preferences::mark();
|
||||
|
||||
return redirect(Session::get('attachments.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
* @param AttachmentHelperInterface $helper
|
||||
*/
|
||||
public function download(Attachment $attachment, AttachmentHelperInterface $helper)
|
||||
{
|
||||
|
||||
$file = $helper->getAttachmentLocation($attachment);
|
||||
if (file_exists($file)) {
|
||||
|
||||
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
|
||||
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . $quoted);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Connection: Keep-Alive');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . $attachment->size);
|
||||
|
||||
echo Crypt::decrypt(file_get_contents($file));
|
||||
|
||||
} else {
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function preview(Attachment $attachment)
|
||||
{
|
||||
if ($attachment->mime == 'application/pdf') {
|
||||
$file = public_path('images/page_white_acrobat.png');
|
||||
} else {
|
||||
$file = public_path('images/page_green.png');
|
||||
}
|
||||
|
||||
$response = Response::make(File::get($file));
|
||||
$response->header('Content-Type', 'image/png');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param AttachmentFormRequest $request
|
||||
* @param AttachmentRepositoryInterface $repository
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(AttachmentFormRequest $request, AttachmentRepositoryInterface $repository, Attachment $attachment)
|
||||
{
|
||||
|
||||
$attachmentData = [
|
||||
'title' => $request->input('title'),
|
||||
'description' => $request->input('description'),
|
||||
'notes' => $request->input('notes'),
|
||||
];
|
||||
|
||||
$repository->update($attachment, $attachmentData);
|
||||
|
||||
Session::flash('success', 'Attachment "' . $attachment->filename . '" updated.');
|
||||
Preferences::mark();
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
// set value so edit routine will not overwrite URL:
|
||||
Session::put('attachments.edit.fromUpdate', true);
|
||||
|
||||
return redirect(route('attachments.edit', [$attachment->id]))->withInput(['return_to_edit' => 1]);
|
||||
}
|
||||
|
||||
// redirect to previous URL.
|
||||
return redirect(Session::get('attachments.edit.url'));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
<?php namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Role;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Message;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Request as Rq;
|
||||
use Session;
|
||||
use Twig;
|
||||
use Validator;
|
||||
@@ -19,19 +23,76 @@ use Validator;
|
||||
*/
|
||||
class AuthController extends Controller
|
||||
{
|
||||
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Registration & Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users, as well as the
|
||||
| authentication of existing users. By default, this controller uses
|
||||
| a simple trait to add these behaviors. Why don't you explore it?
|
||||
|
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getLogout()
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
return redirect('/auth/login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getRegister()
|
||||
{
|
||||
$host = Rq::getHttpHost();
|
||||
|
||||
return view('auth.register', compact('host'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a login request to the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function postLogin(Request $request)
|
||||
{
|
||||
$this->validate($request, [$this->loginUsername() => 'required', 'password' => 'required',]);
|
||||
$throttles = $this->isUsingThrottlesLoginsTrait();
|
||||
|
||||
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
$credentials = $this->getCredentials($request);
|
||||
$credentials['blocked'] = 0; // most not be blocked.
|
||||
|
||||
if (Auth::attempt($credentials, $request->has('remember'))) {
|
||||
return $this->handleUserWasAuthenticated($request, $throttles);
|
||||
}
|
||||
|
||||
$message = $this->getFailedLoginMessage();
|
||||
/** @var User $foundUser */
|
||||
$foundUser = User::where('email', $credentials['email'])->where('blocked', 1)->first();
|
||||
if (!is_null($foundUser)) {
|
||||
// if it exists, show message:
|
||||
$code = $foundUser->blocked_code;
|
||||
if (strlen($code) == 0) {
|
||||
$code = 'general_blocked';
|
||||
}
|
||||
$message = trans('firefly.' . $code . '_error', ['email' => $credentials['email']]);
|
||||
}
|
||||
|
||||
if ($throttles) {
|
||||
$this->incrementLoginAttempts($request);
|
||||
}
|
||||
|
||||
return redirect($this->loginPath())
|
||||
->withInput($request->only($this->loginUsername(), 'remember'))
|
||||
->withErrors([$this->loginUsername() => $message,]);
|
||||
}
|
||||
|
||||
use AuthenticatesAndRegistersUsers;
|
||||
|
||||
public $redirectTo = '/';
|
||||
|
||||
@@ -79,21 +140,35 @@ class AuthController extends Controller
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$data = $request->all();
|
||||
$data['password'] = bcrypt($data['password']);
|
||||
|
||||
// is user email domain blocked?
|
||||
if ($this->isBlockedDomain($data['email'])) {
|
||||
$validator->getMessageBag()->add('email', trans('validation.invalid_domain'));
|
||||
$this->throwValidationException(
|
||||
$request, $validator
|
||||
);
|
||||
}
|
||||
|
||||
Auth::login($this->create($data));
|
||||
|
||||
// get the email address
|
||||
if (Auth::user() instanceof User) {
|
||||
$email = Auth::user()->email;
|
||||
$address = route('index');
|
||||
$ipAddress = $request->ip();
|
||||
// send email.
|
||||
try {
|
||||
Mail::send(
|
||||
['emails.registered-html', 'emails.registered'], ['address' => $address], function (Message $message) use ($email) {
|
||||
['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());
|
||||
}
|
||||
|
||||
// set flash message
|
||||
Session::flash('success', 'You have registered successfully!');
|
||||
@@ -116,6 +191,40 @@ class AuthController extends Controller
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getBlockedDomains()
|
||||
{
|
||||
$set = Config::get('mail.blocked_domains');
|
||||
$domains = [];
|
||||
foreach ($set as $entry) {
|
||||
$domain = trim($entry);
|
||||
if (strlen($domain) > 0) {
|
||||
$domains[] = $domain;
|
||||
}
|
||||
}
|
||||
|
||||
return $domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $email
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlockedDomain($email)
|
||||
{
|
||||
$parts = explode('@', $email);
|
||||
$blocked = $this->getBlockedDomains();
|
||||
|
||||
if (isset($parts[1]) && in_array($parts[1], $blocked)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<?php namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Message;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
/**
|
||||
* Class PasswordController
|
||||
@@ -41,4 +45,41 @@ class PasswordController extends Controller
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reset link to the given user.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function postEmail(Request $request)
|
||||
{
|
||||
$this->validate($request, ['email' => 'required|email']);
|
||||
|
||||
$user = User::whereEmail($request->get('email'))->first();
|
||||
|
||||
if (!is_null($user) && intval($user->blocked) === 1) {
|
||||
$response = 'passwords.blocked';
|
||||
} else {
|
||||
$response = Password::sendResetLink(
|
||||
$request->only('email'), function (Message $message) {
|
||||
$message->subject($this->getEmailSubject());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
switch ($response) {
|
||||
case Password::RESET_LINK_SENT:
|
||||
return redirect()->back()->with('status', trans($response));
|
||||
|
||||
case Password::INVALID_USER:
|
||||
case 'passwords.blocked':
|
||||
return redirect()->back()->withErrors(['email' => trans($response)]);
|
||||
|
||||
}
|
||||
abort(404);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests\BudgetFormRequest;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
@@ -18,7 +21,6 @@ use View;
|
||||
* Class BudgetController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
*/
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
@@ -132,28 +134,35 @@ class BudgetController extends Controller
|
||||
/**
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @param ARI $accountRepository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(BudgetRepositoryInterface $repository)
|
||||
public function index(BudgetRepositoryInterface $repository, ARI $accountRepository)
|
||||
{
|
||||
$budgets = $repository->getActiveBudgets();
|
||||
$inactive = $repository->getInactiveBudgets();
|
||||
$spent = '0';
|
||||
$budgeted = '0';
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||
$end = Navigation::endOfPeriod($start, $range);
|
||||
$key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
|
||||
$budgetIncomeTotal = Preferences::get($key, 1000)->data;
|
||||
$period = Navigation::periodShow($start, $range);
|
||||
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']);
|
||||
|
||||
bcscale(2);
|
||||
/**
|
||||
* Do some cleanup:
|
||||
*/
|
||||
$repository->cleanupBudgets();
|
||||
|
||||
|
||||
// loop the budgets:
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$budget->spent = $repository->spentInPeriodCorrected($budget, $date, $end);
|
||||
$budget->currentRep = $repository->getCurrentRepetition($budget, $date);
|
||||
$budget->spent = $repository->balanceInPeriod($budget, $start, $end, $accounts);
|
||||
$budget->currentRep = $repository->getCurrentRepetition($budget, $start, $end);
|
||||
if ($budget->currentRep) {
|
||||
$budgeted = bcadd($budgeted, $budget->currentRep->amount);
|
||||
}
|
||||
@@ -161,13 +170,12 @@ class BudgetController extends Controller
|
||||
|
||||
}
|
||||
|
||||
$dateAsString = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
$budgetIncomeTotal = Preferences::get('budgetIncomeTotal' . $dateAsString, 1000)->data;
|
||||
|
||||
$budgetMaximum = Preferences::get('budgetMaximum', 1000)->data;
|
||||
$defaultCurrency = Amount::getDefaultCurrency();
|
||||
|
||||
return view(
|
||||
'budgets.index', compact('budgetMaximum', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted')
|
||||
'budgets.index', compact('budgetMaximum', 'period', 'range', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -178,8 +186,9 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function noBudget(BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||
$end = Navigation::endOfPeriod($start, $range);
|
||||
$list = $repository->getWithoutBudget($start, $end);
|
||||
$subTitle = trans(
|
||||
'firefly.without_budget_between',
|
||||
@@ -194,9 +203,12 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function postUpdateIncome()
|
||||
{
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||
$end = Navigation::endOfPeriod($start, $range);
|
||||
$key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
|
||||
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
Preferences::set('budgetIncomeTotal' . $date, intval(Input::get('amount')));
|
||||
Preferences::set($key, intval(Input::get('amount')));
|
||||
Preferences::mark();
|
||||
|
||||
return redirect(route('budgets.index'));
|
||||
@@ -220,13 +232,26 @@ class BudgetController extends Controller
|
||||
$journals = $repository->getJournals($budget, $repetition);
|
||||
|
||||
if (is_null($repetition->id)) {
|
||||
$limits = $repository->getBudgetLimits($budget);
|
||||
$start = $repository->firstActivity($budget);
|
||||
$end = new Carbon;
|
||||
$set = $budget->limitrepetitions()->orderBy('startdate', 'DESC')->get();
|
||||
$subTitle = e($budget->name);
|
||||
} else {
|
||||
$limits = [$repetition->budgetLimit];
|
||||
$start = $repetition->startdate;
|
||||
$end = $repetition->enddate;
|
||||
$set = new Collection([$repetition]);
|
||||
$subTitle = trans('firefly.budget_in_month', ['name' => $budget->name, 'month' => $repetition->startdate->formatLocalized($this->monthFormat)]);
|
||||
}
|
||||
|
||||
$spentArray = $repository->spentPerDay($budget, $start, $end);
|
||||
$limits = new Collection();
|
||||
|
||||
/** @var LimitRepetition $entry */
|
||||
foreach ($set as $entry) {
|
||||
$entry->spent = $this->getSumOfRange($entry->startdate, $entry->enddate, $spentArray);
|
||||
$limits->push($entry);
|
||||
}
|
||||
|
||||
$journals->setPath('/budgets/show/' . $budget->id);
|
||||
|
||||
return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle'));
|
||||
@@ -272,7 +297,7 @@ class BudgetController extends Controller
|
||||
{
|
||||
$budgetData = [
|
||||
'name' => $request->input('name'),
|
||||
'active' => intval($request->input('active')) == 1
|
||||
'active' => intval($request->input('active')) == 1,
|
||||
];
|
||||
|
||||
$repository->update($budget, $budgetData);
|
||||
@@ -297,8 +322,11 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function updateIncome()
|
||||
{
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
$amount = Preferences::get('budgetIncomeTotal' . $date, 1000);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||
$end = Navigation::endOfPeriod($start, $range);
|
||||
$key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
|
||||
$amount = Preferences::get($key, 1000);
|
||||
|
||||
return view('budgets.income', compact('amount'));
|
||||
}
|
||||
|
||||
@@ -4,9 +4,13 @@ use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests\CategoryFormRequest;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface as SCRI;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use URL;
|
||||
@@ -65,12 +69,12 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(CategoryRepositoryInterface $repository, Category $category)
|
||||
public function destroy(SCRI $repository, Category $category)
|
||||
{
|
||||
|
||||
$name = $category->name;
|
||||
@@ -104,17 +108,18 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param CRI $repository
|
||||
* @param SCRI $singleRepository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(CategoryRepositoryInterface $repository)
|
||||
public function index(CRI $repository, SCRI $singleRepository)
|
||||
{
|
||||
$categories = $repository->getCategories();
|
||||
$categories = $repository->listCategories();
|
||||
|
||||
$categories->each(
|
||||
function (Category $category) use ($repository) {
|
||||
$category->lastActivity = $repository->getLatestActivity($category);
|
||||
function (Category $category) use ($singleRepository) {
|
||||
$category->lastActivity = $singleRepository->getLatestActivity($category);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -122,15 +127,15 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param CRI $repository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function noCategory(CategoryRepositoryInterface $repository)
|
||||
public function noCategory(CRI $repository)
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = $repository->getWithoutCategory($start, $end);
|
||||
$list = $repository->listNoCategory($start, $end);
|
||||
$subTitle = trans(
|
||||
'firefly.without_category_between',
|
||||
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
||||
@@ -140,30 +145,100 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @param $date
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showWithDate(SCRI $repository, Category $category, $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($carbon, $range);
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $category->name;
|
||||
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
|
||||
$set = $repository->getJournalsInRange($category, $page, $start, $end);
|
||||
$count = $repository->countJournalsInRange($category, $start, $end);
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('categories/show/' . $category->id . '/' . $date);
|
||||
|
||||
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(CategoryRepositoryInterface $repository, Category $category)
|
||||
public function show(SCRI $repository, Category $category)
|
||||
{
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
$set = $repository->getJournals($category, $page);
|
||||
$count = $repository->countJournals($category);
|
||||
$subTitle = $category->name;
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('categories/show/' . $category->id);
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory'));
|
||||
// list of ranges for list of periods:
|
||||
|
||||
// oldest transaction in category:
|
||||
$start = $repository->getFirstActivityDate($category);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($start, $range);
|
||||
$end = Navigation::endOfX(new Carbon, $range);
|
||||
$entries = new Collection;
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('category-show');
|
||||
$cache->addProperty($category->id);
|
||||
|
||||
// get all spent and earned data:
|
||||
// get amount earned in period, grouped by day.
|
||||
$spentArray = $repository->spentPerDay($category, $start, $end);
|
||||
$earnedArray = $repository->earnedPerDay($category, $start, $end);
|
||||
|
||||
if ($cache->has()) {
|
||||
$entries = $cache->get();
|
||||
} else {
|
||||
|
||||
while ($end >= $start) {
|
||||
$end = Navigation::startOfPeriod($end, $range);
|
||||
$currentEnd = Navigation::endOfPeriod($end, $range);
|
||||
|
||||
// get data from spentArray:
|
||||
$spent = $this->getSumOfRange($end, $currentEnd, $spentArray);
|
||||
$earned = $this->getSumOfRange($end, $currentEnd, $earnedArray);
|
||||
$dateStr = $end->format('Y-m-d');
|
||||
$dateName = Navigation::periodShow($end, $range);
|
||||
$entries->push([$dateStr, $dateName, $spent, $earned]);
|
||||
|
||||
$end = Navigation::subtractPeriod($end, $range, 1);
|
||||
|
||||
}
|
||||
$cache->store($entries);
|
||||
}
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param SCRI $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(CategoryFormRequest $request, CategoryRepositoryInterface $repository)
|
||||
public function store(CategoryFormRequest $request, SCRI $repository)
|
||||
{
|
||||
$categoryData = [
|
||||
'name' => $request->input('name'),
|
||||
@@ -186,12 +261,12 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(CategoryFormRequest $request, CategoryRepositoryInterface $repository, Category $category)
|
||||
public function update(CategoryFormRequest $request, SCRI $repository, Category $category)
|
||||
{
|
||||
$categoryData = [
|
||||
'name' => $request->input('name'),
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace FireflyIII\Http\Controllers\Chart;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
@@ -35,58 +35,75 @@ class AccountController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Shows the balances for all the user's accounts.
|
||||
* Shows the balances for a given set of dates and accounts.
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @param $year
|
||||
* @param $month
|
||||
* @param bool $shared
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function all(AccountRepositoryInterface $repository, $year, $month, $shared = false)
|
||||
public function report($reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$start = new Carbon($year . '-' . $month . '-01');
|
||||
$end = clone $start;
|
||||
$end->endOfMonth();
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('all');
|
||||
$cache->addProperty('accounts');
|
||||
$cache->addProperty('default');
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($accounts);
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/** @var Collection $accounts */
|
||||
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
||||
if ($shared === false) {
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $index => $account) {
|
||||
if ($account->getMeta('accountRole') == 'sharedAsset') {
|
||||
$accounts->forget($index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make chart:
|
||||
$data = $this->generator->all($accounts, $start, $end);
|
||||
$data = $this->generator->frontpage($accounts, $start, $end);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the balances for all the user's frontpage accounts.
|
||||
* Shows the balances for all the user's expense accounts.
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function frontpage(AccountRepositoryInterface $repository)
|
||||
public function expenseAccounts(ARI $repository)
|
||||
{
|
||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = clone Session::get('end', Carbon::now()->endOfMonth());
|
||||
$accounts = $repository->getAccounts(['Expense account', 'Beneficiary account']);
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('expenseAccounts');
|
||||
$cache->addProperty('accounts');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$data = $this->generator->expenseAccounts($accounts, $start, $end);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the balances for all the user's frontpage accounts.
|
||||
*
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function frontpage(ARI $repository)
|
||||
{
|
||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||
|
||||
@@ -33,7 +33,7 @@ class BillController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows all bills and whether or not theyve been paid this month (pie chart).
|
||||
* Shows all bills and whether or not they've been paid this month (pie chart).
|
||||
*
|
||||
* @param BillRepositoryInterface $repository
|
||||
*
|
||||
@@ -43,26 +43,22 @@ class BillController extends Controller
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$cache = new CacheProperties(); // chart properties for cache:
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('bills');
|
||||
$cache->addProperty('frontpage');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
$paid = $repository->getBillsPaidInRange($start, $end); // will be a negative amount.
|
||||
$unpaid = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount.
|
||||
$creditCardDue = $repository->getCreditCardBill($start, $end);
|
||||
|
||||
if ($creditCardDue < 0) {
|
||||
// expenses are negative (bill not yet paid),
|
||||
$creditCardDue = bcmul($creditCardDue, '-1');
|
||||
$unpaid = bcadd($unpaid, $creditCardDue);
|
||||
} else {
|
||||
// if more than zero, the bill has been paid: (transfer = positive).
|
||||
// amount must be negative to be added to $paid:
|
||||
$paid = bcadd($paid, $creditCardDue);
|
||||
}
|
||||
|
||||
$set = $repository->getBillsForChart($start, $end);
|
||||
|
||||
// optionally expand this set with credit card data
|
||||
$set = $repository->getCreditCardInfoForChart($set, $start, $end);
|
||||
$paid = $set->get('paid');
|
||||
$unpaid = $set->get('unpaid');
|
||||
|
||||
|
||||
// build chart:
|
||||
$data = $this->generator->frontpage($paid, $unpaid);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -35,6 +36,86 @@ class BudgetController extends Controller
|
||||
$this->generator = app('FireflyIII\Generator\Chart\Budget\BudgetChartGenerator');
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO expand with no budget chart.
|
||||
*
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $budgets
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function multiYear(BudgetRepositoryInterface $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts, Collection $budgets)
|
||||
{
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty($budgets);
|
||||
$cache->addProperty('multiYearBudget');
|
||||
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the budgeted amounts for each budgets in each year.
|
||||
*/
|
||||
$budgetedSet = $repository->getBudgetedPerYear($budgets, $start, $end);
|
||||
$budgetedArray = [];
|
||||
/** @var Budget $entry */
|
||||
foreach ($budgetedSet as $entry) {
|
||||
$budgetedArray[$entry->id][$entry->dateFormatted] = $entry->budgeted;
|
||||
}
|
||||
|
||||
$set = $repository->getBudgetsAndExpensesPerYear($budgets, $accounts, $start, $end);
|
||||
$entries = new Collection;
|
||||
// go by budget, not by year.
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$entry = ['name' => '', 'spent' => [], 'budgeted' => []];
|
||||
$id = $budget->id;
|
||||
$currentStart = clone $start;
|
||||
while ($currentStart < $end) {
|
||||
// fix the date:
|
||||
$currentEnd = clone $currentStart;
|
||||
$currentEnd->endOfYear();
|
||||
|
||||
// save to array:
|
||||
$year = $currentStart->year;
|
||||
$entry['name'] = $budget->name;
|
||||
$spent = 0;
|
||||
$budgeted = 0;
|
||||
if (isset($set[$id]['entries'][$year])) {
|
||||
$spent = $set[$id]['entries'][$year] * -1;
|
||||
}
|
||||
|
||||
if (isset($budgetedArray[$id][$year])) {
|
||||
$budgeted = round($budgetedArray[$id][$year], 2);
|
||||
}
|
||||
|
||||
$entry['spent'][$year] = $spent;
|
||||
$entry['budgeted'][$year] = $budgeted;
|
||||
|
||||
// jump to next year.
|
||||
$currentStart = clone $currentEnd;
|
||||
$currentStart->addDay();
|
||||
}
|
||||
$entries->push($entry);
|
||||
}
|
||||
// generate chart with data:
|
||||
$data = $this->generator->multiYear($entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
* @param Budget $budget
|
||||
@@ -48,9 +129,6 @@ class BudgetController extends Controller
|
||||
$first = $repository->getFirstBudgetLimitDate($budget);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$last = Session::get('end', new Carbon);
|
||||
$final = clone $last;
|
||||
$final->addYears(2);
|
||||
$last = Navigation::endOfX($last, $range, $final);
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
@@ -58,18 +136,29 @@ class BudgetController extends Controller
|
||||
$cache->addProperty($last);
|
||||
$cache->addProperty('budget');
|
||||
if ($cache->has()) {
|
||||
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$final = clone $last;
|
||||
$final->addYears(2);
|
||||
$last = Navigation::endOfX($last, $range, $final);
|
||||
$entries = new Collection;
|
||||
// get all expenses:
|
||||
$set = $repository->getExpensesPerMonth($budget, $first, $last); // TODO
|
||||
|
||||
while ($first < $last) {
|
||||
$end = Navigation::addPeriod($first, $range, 0);
|
||||
$end->subDay();
|
||||
$chartDate = clone $end;
|
||||
$chartDate->startOfMonth();
|
||||
$spent = $repository->spentInPeriodCorrected($budget, $first, $end);
|
||||
$entries->push([$chartDate, $spent]);
|
||||
$monthFormatted = $first->format('Y-m');
|
||||
|
||||
$filtered = $set->filter(
|
||||
function (Budget $obj) use ($monthFormatted) {
|
||||
return $obj->dateFormatted == $monthFormatted;
|
||||
}
|
||||
);
|
||||
$spent = is_null($filtered->first()) ? '0' : $filtered->first()->monthlyAmount;
|
||||
|
||||
$entries->push([$first, round(($spent * -1), 2)]);
|
||||
|
||||
$first = Navigation::addPeriod($first, $range, 0);
|
||||
}
|
||||
|
||||
@@ -106,15 +195,24 @@ class BudgetController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$set = $repository->getExpensesPerDay($budget, $start, $end);
|
||||
$entries = new Collection;
|
||||
$amount = $repetition->amount;
|
||||
|
||||
// get sum (har har)!
|
||||
while ($start <= $end) {
|
||||
$formatted = $start->format('Y-m-d');
|
||||
$filtered = $set->filter(
|
||||
function (Budget $obj) use ($formatted) {
|
||||
return $obj->date == $formatted;
|
||||
}
|
||||
);
|
||||
$sum = is_null($filtered->first()) ? '0' : $filtered->first()->dailyAmount;
|
||||
|
||||
/*
|
||||
* Sum of expenses on this day:
|
||||
*/
|
||||
$sum = $repository->expensesOnDayCorrected($budget, $start);
|
||||
$amount = bcadd($amount, $sum);
|
||||
$amount = round(bcadd($amount, $sum), 2);
|
||||
$entries->push([clone $start, $amount]);
|
||||
$start->addDay();
|
||||
}
|
||||
@@ -131,14 +229,14 @@ class BudgetController extends Controller
|
||||
*
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @param ARI $accountRepository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function frontpage(BudgetRepositoryInterface $repository)
|
||||
public function frontpage(BudgetRepositoryInterface $repository, ARI $accountRepository)
|
||||
{
|
||||
$budgets = $repository->getBudgets();
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$allEntries = new Collection;
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
@@ -150,81 +248,97 @@ class BudgetController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$budgets = $repository->getBudgetsAndLimitsInRange($start, $end);
|
||||
$allEntries = new Collection;
|
||||
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']);
|
||||
|
||||
|
||||
bcscale(2);
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
||||
if ($repetitions->count() == 0) {
|
||||
$expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true);
|
||||
$allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]);
|
||||
continue;
|
||||
}
|
||||
/** @var LimitRepetition $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$expenses = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true);
|
||||
// $left can be less than zero.
|
||||
// $overspent can be more than zero ( = overspending)
|
||||
|
||||
$left = max(bcsub($repetition->amount, $expenses), 0); // limited at zero.
|
||||
$overspent = max(bcsub($expenses, $repetition->amount), 0); // limited at zero.
|
||||
// we already have amount, startdate and enddate.
|
||||
// if this "is" a limit repetition (as opposed to a budget without one entirely)
|
||||
// depends on whether startdate and enddate are null.
|
||||
$name = $budget->name;
|
||||
|
||||
// $spent is maxed to the repetition amount:
|
||||
$spent = $expenses > $repetition->amount ? $repetition->amount : $expenses;
|
||||
|
||||
|
||||
$allEntries->push([$name, $left, $spent, $overspent, $repetition->amount, $expenses]);
|
||||
}
|
||||
if (is_null($budget->startdate) && is_null($budget->enddate)) {
|
||||
$currentStart = clone $start;
|
||||
$currentEnd = clone $end;
|
||||
$expenses = $repository->balanceInPeriod($budget, $currentStart, $currentEnd, $accounts);
|
||||
$amount = 0;
|
||||
$left = 0;
|
||||
$spent = $expenses;
|
||||
$overspent = 0;
|
||||
} else {
|
||||
$currentStart = clone $budget->startdate;
|
||||
$currentEnd = clone $budget->enddate;
|
||||
$expenses = $repository->balanceInPeriod($budget, $currentStart, $currentEnd, $accounts);
|
||||
$amount = $budget->amount;
|
||||
// smaller than 1 means spent MORE than budget allows.
|
||||
$left = bccomp(bcadd($budget->amount, $expenses), '0') < 1 ? 0 : bcadd($budget->amount, $expenses);
|
||||
$spent = bccomp(bcadd($budget->amount, $expenses), '0') < 1 ? ($amount * -1) : $expenses;
|
||||
$overspent = bccomp(bcadd($budget->amount, $expenses), '0') < 1 ? bcadd($budget->amount, $expenses) : 0;
|
||||
}
|
||||
|
||||
$noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end) * -1;
|
||||
$allEntries->push([$name, $left, $spent, $overspent, $amount, $expenses]);
|
||||
}
|
||||
|
||||
$noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end);
|
||||
$allEntries->push([trans('firefly.noBudget'), 0, 0, $noBudgetExpenses, 0, 0]);
|
||||
|
||||
$data = $this->generator->frontpage($allEntries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a yearly overview for a budget.
|
||||
* TODO expand with no budget chart.
|
||||
*
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
* @param $year
|
||||
* @param bool $shared
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function year(BudgetRepositoryInterface $repository, $year, $shared = false)
|
||||
public function year(BudgetRepositoryInterface $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$budgets = $repository->getBudgets();
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty('budget');
|
||||
$cache->addProperty('year');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$budgetInformation = $repository->getBudgetsAndExpensesPerMonth($accounts, $start, $end);
|
||||
$budgets = new Collection;
|
||||
$entries = new Collection;
|
||||
|
||||
/** @var array $row */
|
||||
foreach ($budgetInformation as $row) {
|
||||
$budgets->push($row['budget']);
|
||||
}
|
||||
|
||||
while ($start < $end) {
|
||||
// month is the current end of the period:
|
||||
$month = clone $start;
|
||||
$month->endOfMonth();
|
||||
$row = [clone $start];
|
||||
$dateFormatted = $start->format('Y-m');
|
||||
|
||||
// each budget, fill the row:
|
||||
foreach ($budgets as $budget) {
|
||||
$spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared);
|
||||
// each budget, check if there is an entry for this month:
|
||||
/** @var array $row */
|
||||
foreach ($budgetInformation as $budgetRow) {
|
||||
$spent = 0; // nothing spent.
|
||||
if (isset($budgetRow['entries'][$dateFormatted])) {
|
||||
$spent = $budgetRow['entries'][$dateFormatted] * -1; // to fit array
|
||||
}
|
||||
$row[] = $spent;
|
||||
}
|
||||
$entries->push($row);
|
||||
|
||||
@@ -6,13 +6,15 @@ namespace FireflyIII\Http\Controllers\Chart;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface as SCRI;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class CategoryController
|
||||
@@ -38,19 +40,18 @@ class CategoryController extends Controller
|
||||
/**
|
||||
* Show an overview for a category for all time, per month/week/year.
|
||||
*
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function all(CategoryRepositoryInterface $repository, Category $category)
|
||||
public function all(SCRI $repository, Category $category)
|
||||
{
|
||||
// oldest transaction in category:
|
||||
$start = $repository->getFirstActivityDate($category);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($start, $range);
|
||||
$end = new Carbon;
|
||||
|
||||
$entries = new Collection;
|
||||
|
||||
|
||||
@@ -63,14 +64,25 @@ class CategoryController extends Controller
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$spentArray = $repository->spentPerDay($category, $start, $end);
|
||||
$earnedArray = $repository->earnedPerDay($category, $start, $end);
|
||||
|
||||
|
||||
while ($start <= $end) {
|
||||
$currentEnd = Navigation::endOfPeriod($start, $range);
|
||||
$spent = $repository->spentInPeriodCorrected($category, $start, $currentEnd);
|
||||
$entries->push([clone $start, $spent]);
|
||||
$start = Navigation::addPeriod($start, $range, 0);
|
||||
|
||||
// get the sum from $spentArray and $earnedArray:
|
||||
$spent = $this->getSumOfRange($start, $currentEnd, $spentArray);
|
||||
$earned = $this->getSumOfRange($start, $currentEnd, $earnedArray);
|
||||
|
||||
$date = Navigation::periodShow($start, $range);
|
||||
$entries->push([clone $start, $date, $spent, $earned]);
|
||||
$start = Navigation::addPeriod($start, $range, 0);
|
||||
}
|
||||
// limit the set to the last 40:
|
||||
$entries = $entries->reverse();
|
||||
$entries = $entries->slice(0, 48);
|
||||
$entries = $entries->reverse();
|
||||
|
||||
$data = $this->generator->all($entries);
|
||||
$cache->store($data);
|
||||
@@ -80,14 +92,15 @@ class CategoryController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show this month's category overview.
|
||||
*
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param CRI $repository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function frontpage(CategoryRepositoryInterface $repository)
|
||||
public function frontpage(CRI $repository)
|
||||
{
|
||||
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
@@ -103,32 +116,130 @@ class CategoryController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$array = $repository->getCategoriesAndExpensesCorrected($start, $end);
|
||||
// sort by callback:
|
||||
uasort(
|
||||
$array,
|
||||
function ($left, $right) {
|
||||
if ($left['sum'] == $right['sum']) {
|
||||
return 0;
|
||||
}
|
||||
// get data for categories (and "no category"):
|
||||
$set = $repository->spentForAccountsPerMonth(new Collection, $start, $end);
|
||||
$outside = $repository->sumSpentNoCategory(new Collection, $start, $end);
|
||||
|
||||
return ($left['sum'] < $right['sum']) ? 1 : -1;
|
||||
}
|
||||
);
|
||||
$set = new Collection($array);
|
||||
// this is a "fake" entry for the "no category" entry.
|
||||
$entry = new stdClass();
|
||||
$entry->name = trans('firefly.no_category');
|
||||
$entry->spent = $outside;
|
||||
$set->push($entry);
|
||||
|
||||
$set = $set->sortBy('spent');
|
||||
$data = $this->generator->frontpage($set);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param Collection $categories
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function multiYear($reportType, Carbon $start, Carbon $end, Collection $accounts, Collection $categories)
|
||||
{
|
||||
/** @var CRI $repository */
|
||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty($categories);
|
||||
$cache->addProperty('multiYearCategory');
|
||||
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* category
|
||||
* year:
|
||||
* spent: x
|
||||
* earned: x
|
||||
* year
|
||||
* spent: x
|
||||
* earned: x
|
||||
*/
|
||||
$entries = new Collection;
|
||||
// go by category, not by year.
|
||||
|
||||
// given a set of categories and accounts, it should not be difficult to get
|
||||
// the exact array of data we need.
|
||||
|
||||
// then get the data for "no category".
|
||||
$set = $repository->listMultiYear($categories, $accounts, $start, $end);
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$entry = ['name' => '', 'spent' => [], 'earned' => []];
|
||||
|
||||
$currentStart = clone $start;
|
||||
while ($currentStart < $end) {
|
||||
// fix the date:
|
||||
$year = $currentStart->year;
|
||||
$currentEnd = clone $currentStart;
|
||||
$currentEnd->endOfYear();
|
||||
|
||||
|
||||
// get data:
|
||||
if (is_null($category->id)) {
|
||||
$name = trans('firefly.noCategory');
|
||||
$spent = $repository->sumSpentNoCategory($accounts, $currentStart, $currentEnd);
|
||||
$earned = $repository->sumEarnedNoCategory($accounts, $currentStart, $currentEnd);
|
||||
} else {
|
||||
// get from set:
|
||||
$entrySpent = $set->filter(
|
||||
function (Category $cat) use ($year, $category) {
|
||||
return ($cat->type == 'Withdrawal' && $cat->dateFormatted == $year && $cat->id == $category->id);
|
||||
}
|
||||
)->first();
|
||||
$entryEarned = $set->filter(
|
||||
function (Category $cat) use ($year, $category) {
|
||||
return ($cat->type == 'Deposit' && $cat->dateFormatted == $year && $cat->id == $category->id);
|
||||
}
|
||||
)->first();
|
||||
|
||||
$name = $category->name;
|
||||
$spent = !is_null($entrySpent) ? $entrySpent->sum : 0;
|
||||
$earned = !is_null($entryEarned) ? $entryEarned->sum : 0;
|
||||
}
|
||||
|
||||
// save to array:
|
||||
$entry['name'] = $name;
|
||||
$entry['spent'][$year] = ($spent * -1);
|
||||
$entry['earned'][$year] = $earned;
|
||||
|
||||
// jump to next year.
|
||||
$currentStart = clone $currentEnd;
|
||||
$currentStart->addDay();
|
||||
}
|
||||
$entries->push($entry);
|
||||
}
|
||||
// generate chart with data:
|
||||
$data = $this->generator->multiYear($entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function month(CategoryRepositoryInterface $repository, Category $category)
|
||||
public function currentPeriod(SCRI $repository, Category $category)
|
||||
{
|
||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
@@ -139,21 +250,75 @@ class CategoryController extends Controller
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($category->id);
|
||||
$cache->addProperty('category');
|
||||
$cache->addProperty('month');
|
||||
$cache->addProperty('current-period');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$entries = new Collection;
|
||||
|
||||
// get amount earned in period, grouped by day.
|
||||
// get amount spent in period, grouped by day.
|
||||
$spentArray = $repository->spentPerDay($category, $start, $end);
|
||||
$earnedArray = $repository->earnedPerDay($category, $start, $end);
|
||||
|
||||
while ($start <= $end) {
|
||||
$spent = $repository->spentOnDaySumCorrected($category, $start);
|
||||
|
||||
$entries->push([clone $start, $spent]);
|
||||
$str = $start->format('Y-m-d');
|
||||
$spent = isset($spentArray[$str]) ? $spentArray[$str] : 0;
|
||||
$earned = isset($earnedArray[$str]) ? $earnedArray[$str] : 0;
|
||||
$date = Navigation::periodShow($start, '1D');
|
||||
$entries->push([clone $start, $date, $spent, $earned]);
|
||||
$start->addDay();
|
||||
}
|
||||
|
||||
$data = $this->generator->month($entries);
|
||||
$data = $this->generator->period($entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @param $date
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function specificPeriod(SCRI $repository, Category $category, $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($carbon, $range);
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($category->id);
|
||||
$cache->addProperty('category');
|
||||
$cache->addProperty('specificPeriod');
|
||||
$cache->addProperty($date);
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$entries = new Collection;
|
||||
|
||||
// get amount earned in period, grouped by day.
|
||||
$spentArray = $repository->spentPerDay($category, $start, $end);
|
||||
$earnedArray = $repository->earnedPerDay($category, $start, $end);
|
||||
// get amount spent in period, grouped by day.
|
||||
|
||||
while ($start <= $end) {
|
||||
$str = $start->format('Y-m-d');
|
||||
$spent = isset($spentArray[$str]) ? $spentArray[$str] : 0;
|
||||
$earned = isset($earnedArray[$str]) ? $earnedArray[$str] : 0;
|
||||
$date = Navigation::periodShow($start, '1D');
|
||||
$entries->push([clone $start, $date, $spent, $earned]);
|
||||
$start->addDay();
|
||||
}
|
||||
|
||||
$data = $this->generator->period($entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
@@ -162,49 +327,137 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* This chart will only show expenses.
|
||||
* Returns a chart of what has been earned in this period in each category
|
||||
* grouped by month.
|
||||
*
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param $year
|
||||
* @param bool $shared
|
||||
* @param CRI $repository
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function year(CategoryRepositoryInterface $repository, $year, $shared = false)
|
||||
public function earnedInPeriod(CRI $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
|
||||
$cache = new CacheProperties; // chart properties for cache:
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty('category');
|
||||
$cache->addProperty('year');
|
||||
$cache->addProperty('earned-in-period');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
$categories = $repository->getCategories();
|
||||
$set = $repository->earnedForAccountsPerMonth($accounts, $start, $end);
|
||||
$categories = $set->unique('id')->sortBy(
|
||||
function (Category $category) {
|
||||
return $category->name;
|
||||
}
|
||||
);
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) {
|
||||
$month = clone $start; // month is the current end of the period
|
||||
$month->endOfMonth();
|
||||
$row = [clone $start]; // make a row:
|
||||
|
||||
foreach ($categories as $category) { // each budget, fill the row
|
||||
$spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared);
|
||||
$row[] = $spent;
|
||||
while ($start < $end) { // filter the set:
|
||||
$row = [clone $start];
|
||||
// get possibly relevant entries from the big $set
|
||||
$currentSet = $set->filter(
|
||||
function (Category $category) use ($start) {
|
||||
return $category->dateFormatted == $start->format("Y-m");
|
||||
}
|
||||
);
|
||||
// check for each category if its in the current set.
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
// if its in there, use the value.
|
||||
$entry = $currentSet->filter(
|
||||
function (Category $cat) use ($category) {
|
||||
return ($cat->id == $category->id);
|
||||
}
|
||||
)->first();
|
||||
if (!is_null($entry)) {
|
||||
$row[] = round($entry->earned, 2);
|
||||
} else {
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
$entries->push($row);
|
||||
|
||||
$entries->push($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
$data = $this->generator->year($categories, $entries);
|
||||
$data = $this->generator->earnedInPeriod($categories, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a chart of what has been spent in this period in each category
|
||||
* grouped by month.
|
||||
*
|
||||
* @param CRI $repository
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function spentInPeriod(CRI $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$cache = new CacheProperties; // chart properties for cache:
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty('category');
|
||||
$cache->addProperty('spent-in-period');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
||||
$categories = $set->unique('id')->sortBy(
|
||||
function (Category $category) {
|
||||
return $category->name;
|
||||
}
|
||||
);
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) { // filter the set:
|
||||
$row = [clone $start];
|
||||
// get possibly relevant entries from the big $set
|
||||
$currentSet = $set->filter(
|
||||
function (Category $category) use ($start) {
|
||||
return $category->dateFormatted == $start->format("Y-m");
|
||||
}
|
||||
);
|
||||
// check for each category if its in the current set.
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
// if its in there, use the value.
|
||||
$entry = $currentSet->filter(
|
||||
function (Category $cat) use ($category) {
|
||||
return ($cat->id == $category->id);
|
||||
}
|
||||
)->first();
|
||||
if (!is_null($entry)) {
|
||||
$row[] = round(($entry->spent * -1), 2);
|
||||
} else {
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$entries->push($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
$data = $this->generator->spentInPeriod($categories, $entries);
|
||||
$cache->store($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -36,40 +36,39 @@ class ReportController extends Controller
|
||||
* Summarizes all income and expenses, per month, for a given year.
|
||||
*
|
||||
* @param ReportQueryInterface $query
|
||||
* @param $year
|
||||
* @param bool $shared
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function yearInOut(ReportQueryInterface $query, $year, $shared = false)
|
||||
public function yearInOut(ReportQueryInterface $query, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// get start and end of year
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('yearInOut');
|
||||
$cache->addProperty($year);
|
||||
$cache->addProperty($shared);
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty($end);
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$entries = new Collection;
|
||||
while ($start < $end) {
|
||||
$month = clone $start;
|
||||
$month->endOfMonth();
|
||||
// total income and total expenses:
|
||||
$incomeSum = $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount');
|
||||
$expenseSum = $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount');
|
||||
// spent per month, and earned per month. For a specific set of accounts
|
||||
// grouped by month
|
||||
$spentArray = $query->spentPerMonth($accounts, $start, $end);
|
||||
$earnedArray = $query->earnedPerMonth($accounts, $start, $end);
|
||||
|
||||
$entries->push([clone $start, $incomeSum, $expenseSum]);
|
||||
$start->addMonth();
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
// data = method X
|
||||
$data = $this->multiYearInOut($earnedArray, $spentArray, $start, $end);
|
||||
} else {
|
||||
// data = method Y
|
||||
$data = $this->singleYearInOut($earnedArray, $spentArray, $start, $end);
|
||||
}
|
||||
|
||||
$data = $this->generator->yearInOut($entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
@@ -80,46 +79,170 @@ class ReportController extends Controller
|
||||
* Summarizes all income and expenses for a given year. Gives a total and an average.
|
||||
*
|
||||
* @param ReportQueryInterface $query
|
||||
* @param $year
|
||||
* @param bool $shared
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function yearInOutSummarized(ReportQueryInterface $query, $year, $shared = false)
|
||||
public function yearInOutSummarized(ReportQueryInterface $query, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('yearInOutSummarized');
|
||||
$cache->addProperty($year);
|
||||
$cache->addProperty($shared);
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($reportType);
|
||||
$cache->addProperty($accounts);
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
// spent per month, and earned per month. For a specific set of accounts
|
||||
// grouped by month
|
||||
$spentArray = $query->spentPerMonth($accounts, $start, $end);
|
||||
$earnedArray = $query->earnedPerMonth($accounts, $start, $end);
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
// per year
|
||||
$data = $this->multiYearInOutSummarized($earnedArray, $spentArray, $start, $end);
|
||||
} else {
|
||||
// per month!
|
||||
$data = $this->singleYearInOutSummarized($earnedArray, $spentArray, $start, $end);
|
||||
}
|
||||
$cache->store($data);
|
||||
|
||||
$start = new Carbon($year . '-01-01');
|
||||
$end = new Carbon($year . '-12-31');
|
||||
$shared = $shared == 'shared' ? true : false;
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $earned
|
||||
* @param array $spent
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function singleYearInOutSummarized(array $earned, array $spent, Carbon $start, Carbon $end)
|
||||
{
|
||||
$income = '0';
|
||||
$expense = '0';
|
||||
$count = 0;
|
||||
|
||||
bcscale(2);
|
||||
|
||||
while ($start < $end) {
|
||||
$month = clone $start;
|
||||
$month->endOfMonth();
|
||||
// total income and total expenses:
|
||||
$income = bcadd($income, $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
||||
$expense = bcadd($expense, $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
||||
$date = $start->format('Y-m');
|
||||
$currentIncome = isset($earned[$date]) ? $earned[$date] : 0;
|
||||
$currentExpense = isset($spent[$date]) ? ($spent[$date] * -1) : 0;
|
||||
$income = bcadd($income, $currentIncome);
|
||||
$expense = bcadd($expense, $currentExpense);
|
||||
|
||||
$count++;
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
$data = $this->generator->yearInOutSummarized($income, $expense, $count);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $earned
|
||||
* @param array $spent
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function multiYearInOutSummarized(array $earned, array $spent, Carbon $start, Carbon $end)
|
||||
{
|
||||
$income = '0';
|
||||
$expense = '0';
|
||||
$count = 0;
|
||||
while ($start < $end) {
|
||||
|
||||
$currentIncome = $this->pluckFromArray($start->year, $earned);
|
||||
$currentExpense = $this->pluckFromArray($start->year, $spent) * -1;
|
||||
$income = bcadd($income, $currentIncome);
|
||||
$expense = bcadd($expense, $currentExpense);
|
||||
|
||||
$count++;
|
||||
$start->addYear();
|
||||
}
|
||||
|
||||
$data = $this->generator->multiYearInOutSummarized($income, $expense, $count);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $earned
|
||||
* @param array $spent
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function multiYearInOut(array $earned, array $spent, Carbon $start, Carbon $end)
|
||||
{
|
||||
$entries = new Collection;
|
||||
while ($start < $end) {
|
||||
|
||||
$incomeSum = $this->pluckFromArray($start->year, $earned);
|
||||
$expenseSum = $this->pluckFromArray($start->year, $spent) * -1;
|
||||
|
||||
$entries->push([clone $start, $incomeSum, $expenseSum]);
|
||||
$start->addYear();
|
||||
}
|
||||
|
||||
$data = $this->generator->multiYearInOut($entries);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $earned
|
||||
* @param array $spent
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function singleYearInOut(array $earned, array $spent, Carbon $start, Carbon $end)
|
||||
{
|
||||
// per month? simply use each month.
|
||||
|
||||
$entries = new Collection;
|
||||
while ($start < $end) {
|
||||
// total income and total expenses:
|
||||
$date = $start->format('Y-m');
|
||||
$incomeSum = isset($earned[$date]) ? $earned[$date] : 0;
|
||||
$expenseSum = isset($spent[$date]) ? ($spent[$date] * -1) : 0;
|
||||
|
||||
$entries->push([clone $start, $incomeSum, $expenseSum]);
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
$data = $this->generator->yearInOut($entries);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
* @param array $set
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pluckFromArray($year, array $set)
|
||||
{
|
||||
bcscale(2);
|
||||
$sum = '0';
|
||||
foreach ($set as $date => $amount) {
|
||||
if (substr($date, 0, 4) == $year) {
|
||||
$sum = bcadd($sum, $amount);
|
||||
}
|
||||
}
|
||||
|
||||
return $sum;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
@@ -34,14 +34,43 @@ abstract class Controller extends BaseController
|
||||
View::share('hideTags', false);
|
||||
|
||||
if (Auth::check()) {
|
||||
$pref = Preferences::get('language', 'en');
|
||||
$pref = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'));
|
||||
$lang = $pref->data;
|
||||
$this->monthFormat = Config::get('firefly.month.' . $lang);
|
||||
$this->monthAndDayFormat = Config::get('firefly.monthAndDay.' . $lang);
|
||||
$this->monthFormat = trans('config.month');
|
||||
$this->monthAndDayFormat = trans('config.month_and_day');
|
||||
|
||||
View::share('monthFormat', $this->monthFormat);
|
||||
View::share('monthAndDayFormat', $this->monthAndDayFormat);
|
||||
View::share('language', $lang);
|
||||
View::share('localeconv', localeconv());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the array as returned by SingleCategoryRepositoryInterface::spentPerDay and SingleCategoryRepositoryInterface::earnedByDay
|
||||
* and sum up everything in the array in the given range.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSumOfRange(Carbon $start, Carbon $end, array $array)
|
||||
{
|
||||
bcscale(2);
|
||||
$sum = '0';
|
||||
$currentStart = clone $start; // to not mess with the original one
|
||||
$currentEnd = clone $end; // to not mess with the original one
|
||||
|
||||
while ($currentStart <= $currentEnd) {
|
||||
$date = $currentStart->format('Y-m-d');
|
||||
if (isset($array[$date])) {
|
||||
$sum = bcadd($sum, $array[$date]);
|
||||
}
|
||||
$currentStart->addDay();
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Csv\Data;
|
||||
use FireflyIII\Helpers\Csv\Importer;
|
||||
use FireflyIII\Helpers\Csv\WizardInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Illuminate\Http\Request;
|
||||
use Input;
|
||||
use Log;
|
||||
@@ -146,9 +146,11 @@ class CsvController extends Controller
|
||||
*
|
||||
* STEP ONE
|
||||
*
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
$subTitle = trans('firefly.csv_import');
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ class CurrencyController extends Controller
|
||||
public function index(CurrencyRepositoryInterface $repository)
|
||||
{
|
||||
$currencies = $repository->get();
|
||||
$defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', 'EUR'));
|
||||
$defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', env('DEFAULT_CURRENCY', 'EUR')));
|
||||
|
||||
|
||||
if (!Auth::user()->hasRole('owner')) {
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Artisan;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Input;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Route;
|
||||
use Session;
|
||||
use Steam;
|
||||
|
||||
@@ -58,16 +56,17 @@ class HomeController extends Controller
|
||||
|
||||
|
||||
Session::clear();
|
||||
Artisan::call('cache:clear');
|
||||
|
||||
return redirect(route('index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
$types = Config::get('firefly.accountTypesByIdentifier.asset');
|
||||
$count = $repository->countAccounts($types);
|
||||
@@ -85,10 +84,8 @@ class HomeController extends Controller
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$showTour = Preferences::get('tour', true)->data;
|
||||
|
||||
$accounts = $repository->getFrontpageAccounts($frontPage);
|
||||
$savings = $repository->getSavingsAccounts();
|
||||
|
||||
$piggyBankAccounts = $repository->getPiggyBankAccounts();
|
||||
|
||||
|
||||
@@ -120,33 +117,4 @@ class HomeController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return \Illuminate\Http\RedirectResponse|string
|
||||
*/
|
||||
public function routes()
|
||||
{
|
||||
if (!Auth::user()->hasRole('owner')) {
|
||||
Session::flash('warning', 'This page is broken.');
|
||||
|
||||
return redirect(route('index'));
|
||||
}
|
||||
Log::debug('Make log.');
|
||||
|
||||
// get all routes:
|
||||
$routeCollection = Route::getRoutes();
|
||||
/** @var \Illuminate\Routing\Route $value */
|
||||
foreach ($routeCollection as $value) {
|
||||
$name = $value->getName();
|
||||
$methods = $value->getMethods();
|
||||
$isPost = in_array('POST', $methods);
|
||||
$index = str_replace('.', '-', $name);
|
||||
|
||||
if (strlen($name) > 0 && !$isPost) {
|
||||
echo "'" . $index . "' => '" . $name . "',<br />";
|
||||
}
|
||||
}
|
||||
|
||||
return ' ';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,19 +3,15 @@
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class JsonController
|
||||
@@ -66,107 +62,50 @@ class JsonController extends Controller
|
||||
/**
|
||||
* @param BillRepositoryInterface $repository
|
||||
*
|
||||
* @param AccountRepositoryInterface $accountRepository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function boxBillsPaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository)
|
||||
public function boxBillsPaid(BillRepositoryInterface $repository)
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$amount = 0;
|
||||
bcscale(2);
|
||||
|
||||
// works for json too!
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('box-bills-paid');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
/*
|
||||
* Since both this method and the chart use the exact same data, we can suffice
|
||||
* with calling the one method in the bill repository that will get this amount.
|
||||
*/
|
||||
$amount = $repository->getBillsPaidInRange($start, $end); // will be a negative amount.
|
||||
$creditCardDue = $repository->getCreditCardBill($start, $end);
|
||||
if ($creditCardDue >= 0) {
|
||||
$amount = bcadd($amount, $creditCardDue);
|
||||
}
|
||||
$bills = $repository->getActiveBills(); // these two functions are the same as the chart
|
||||
$amount = $amount * -1;
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
$amount = bcadd($amount, $repository->billPaymentsInRange($bill, $start, $end));
|
||||
}
|
||||
unset($bill, $bills);
|
||||
|
||||
$creditCards = $accountRepository->getCreditCards(); // Find credit card accounts and possibly unpaid credit card bills.
|
||||
/** @var Account $creditCard */
|
||||
foreach ($creditCards as $creditCard) {
|
||||
$balance = Steam::balance($creditCard, $end, true); // if the balance is not zero, the monthly payment is still underway.
|
||||
if ($balance == 0) {
|
||||
// find a transfer TO the credit card which should account for
|
||||
// anything paid. If not, the CC is not yet used.
|
||||
$amount = bcadd($amount, $accountRepository->getTransfersInRange($creditCard, $start, $end)->sum('amount'));
|
||||
}
|
||||
}
|
||||
$data = ['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BillRepositoryInterface $repository
|
||||
* @param AccountRepositoryInterface $accountRepository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function boxBillsUnpaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository)
|
||||
public function boxBillsUnpaid(BillRepositoryInterface $repository)
|
||||
{
|
||||
$amount = 0;
|
||||
bcscale(2);
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
bcscale(2);
|
||||
$amount = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount.
|
||||
$creditCardDue = $repository->getCreditCardBill($start, $end);
|
||||
|
||||
// works for json too!
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('box-bills-unpaid');
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$bills = $repository->getActiveBills();
|
||||
$unpaid = new Collection; // bills
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
$ranges = $repository->getRanges($bill, $start, $end);
|
||||
|
||||
foreach ($ranges as $range) {
|
||||
$journals = $repository->getJournalsInRange($bill, $range['start'], $range['end']);
|
||||
if ($journals->count() == 0) {
|
||||
$unpaid->push([$bill, $range['start']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($bill, $bills, $range, $ranges);
|
||||
|
||||
$creditCards = $accountRepository->getCreditCards();
|
||||
foreach ($creditCards as $creditCard) {
|
||||
$balance = Steam::balance($creditCard, $end, true);
|
||||
$date = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate'));
|
||||
if ($balance < 0) {
|
||||
// unpaid! create a fake bill that matches the amount.
|
||||
$description = $creditCard->name;
|
||||
$fakeAmount = $balance * -1;
|
||||
$fakeBill = $repository->createFakeBill($description, $date, $fakeAmount);
|
||||
$unpaid->push([$fakeBill, $date]);
|
||||
}
|
||||
}
|
||||
/** @var Bill $entry */
|
||||
foreach ($unpaid as $entry) {
|
||||
$current = ($entry[0]->amount_max + $entry[0]->amount_min) / 2;
|
||||
$amount = bcadd($amount, $current);
|
||||
if ($creditCardDue < 0) {
|
||||
// expenses are negative (bill not yet paid),
|
||||
$creditCardDue = bcmul($creditCardDue, '-1');
|
||||
$amount = bcadd($amount, $creditCardDue);
|
||||
}
|
||||
|
||||
$data = ['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
}
|
||||
@@ -174,9 +113,11 @@ class JsonController extends Controller
|
||||
/**
|
||||
* @param ReportQueryInterface $reportQuery
|
||||
*
|
||||
* @param ARI $accountRepository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function boxIn(ReportQueryInterface $reportQuery)
|
||||
public function boxIn(ReportQueryInterface $reportQuery, ARI $accountRepository)
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
@@ -189,8 +130,8 @@ class JsonController extends Controller
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$amount = $reportQuery->incomeInPeriodCorrected($start, $end, true)->sum('amount');
|
||||
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']);
|
||||
$amount = $reportQuery->income($accounts, $start, $end)->sum('journalAmount');
|
||||
|
||||
$data = ['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||
$cache->store($data);
|
||||
@@ -201,13 +142,16 @@ class JsonController extends Controller
|
||||
/**
|
||||
* @param ReportQueryInterface $reportQuery
|
||||
*
|
||||
* @param ARI $accountRepository
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function boxOut(ReportQueryInterface $reportQuery)
|
||||
public function boxOut(ReportQueryInterface $reportQuery, ARI $accountRepository)
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
|
||||
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']);
|
||||
|
||||
// works for json too!
|
||||
$cache = new CacheProperties;
|
||||
@@ -218,7 +162,7 @@ class JsonController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$amount = $reportQuery->expenseInPeriodCorrected($start, $end, true)->sum('amount');
|
||||
$amount = $reportQuery->expense($accounts, $start, $end)->sum('journalAmount');
|
||||
|
||||
$data = ['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||
$cache->store($data);
|
||||
@@ -229,18 +173,17 @@ class JsonController extends Controller
|
||||
/**
|
||||
* Returns a list of categories.
|
||||
*
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param CRI $repository
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function categories(CategoryRepositoryInterface $repository)
|
||||
public function categories(CRI $repository)
|
||||
{
|
||||
$list = $repository->getCategories();
|
||||
$list = $repository->listCategories();
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[] = $entry->name;
|
||||
}
|
||||
sort($return);
|
||||
|
||||
return Response::json($return);
|
||||
}
|
||||
@@ -248,11 +191,11 @@ class JsonController extends Controller
|
||||
/**
|
||||
* Returns a JSON list of all beneficiaries.
|
||||
*
|
||||
* @param AccountRepositoryInterface $accountRepository
|
||||
* @param ARI $accountRepository
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function expenseAccounts(AccountRepositoryInterface $accountRepository)
|
||||
public function expenseAccounts(ARI $accountRepository)
|
||||
{
|
||||
$list = $accountRepository->getAccounts(['Expense account', 'Beneficiary account']);
|
||||
$return = [];
|
||||
@@ -265,11 +208,11 @@ class JsonController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $accountRepository
|
||||
* @param ARI $accountRepository
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function revenueAccounts(AccountRepositoryInterface $accountRepository)
|
||||
public function revenueAccounts(ARI $accountRepository)
|
||||
{
|
||||
$list = $accountRepository->getAccounts(['Revenue account']);
|
||||
$return = [];
|
||||
|
||||
@@ -5,7 +5,7 @@ use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Http\Requests\NewUserFormRequest;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use View;
|
||||
@@ -20,11 +20,11 @@ class NewUserController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @@return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
View::share('title', 'Welcome to Firefly!');
|
||||
View::share('mainTitleIcon', 'fa-fire');
|
||||
@@ -43,24 +43,24 @@ class NewUserController extends Controller
|
||||
|
||||
/**
|
||||
* @param NewUserFormRequest $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function submit(NewUserFormRequest $request, AccountRepositoryInterface $repository)
|
||||
public function submit(NewUserFormRequest $request, ARI $repository)
|
||||
{
|
||||
|
||||
// create normal asset account:
|
||||
$assetAccount = [
|
||||
'name' => $request->get('bank_name'),
|
||||
'iban' => null,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => 'defaultAsset',
|
||||
'openingBalance' => floatval($request->input('bank_balance')),
|
||||
'openingBalance' => round($request->input('bank_balance'), 2),
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'openingBalanceCurrency' => intval($request->input('amount_currency_id_bank_balance')),
|
||||
];
|
||||
|
||||
$repository->store($assetAccount);
|
||||
@@ -69,14 +69,15 @@ class NewUserController extends Controller
|
||||
if (strlen($request->get('savings_balance') > 0)) {
|
||||
$savingsAccount = [
|
||||
'name' => $request->get('bank_name') . ' savings account',
|
||||
'iban' => null,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0,
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => 'savingAsset',
|
||||
'openingBalance' => floatval($request->input('savings_balance')),
|
||||
'openingBalance' => round($request->input('savings_balance'), 2),
|
||||
'openingBalanceDate' => new Carbon,
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'openingBalanceCurrency' => intval($request->input('amount_currency_id_savings_balance')),
|
||||
];
|
||||
$repository->store($savingsAccount);
|
||||
}
|
||||
@@ -86,14 +87,15 @@ class NewUserController extends Controller
|
||||
if (strlen($request->get('credit_card_limit') > 0)) {
|
||||
$creditAccount = [
|
||||
'name' => 'Credit card',
|
||||
'iban' => null,
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => floatval($request->get('credit_card_limit')),
|
||||
'virtualBalance' => round($request->get('credit_card_limit'), 2),
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => 'ccAsset',
|
||||
'openingBalance' => null,
|
||||
'openingBalanceDate' => null,
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'openingBalanceCurrency' => intval($request->input('amount_currency_id_credit_card_limit')),
|
||||
];
|
||||
$creditCard = $repository->store($creditAccount);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
@@ -18,7 +18,6 @@ use View;
|
||||
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
*
|
||||
* Class PiggyBankController
|
||||
*
|
||||
@@ -40,33 +39,34 @@ class PiggyBankController extends Controller
|
||||
/**
|
||||
* Add money to piggy bank
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add(AccountRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||
public function add(ARI $repository, PiggyBank $piggyBank)
|
||||
{
|
||||
bcscale(2);
|
||||
$date = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$leftOnAccount = $repository->leftOnAccount($piggyBank->account, $date);
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
|
||||
return view('piggy-banks.add', compact('piggyBank', 'maxAmount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(AccountRepositoryInterface $repository)
|
||||
public function create(ARI $repository)
|
||||
{
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$subTitle = trans('firefly.create_new_piggybank');
|
||||
$subTitle = trans('firefly.new_piggy_bank');
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
@@ -115,12 +115,12 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function edit(AccountRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||
public function edit(ARI $repository, PiggyBank $piggyBank)
|
||||
{
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
@@ -156,12 +156,12 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param PiggyBankRepositoryInterface $piggyRepository
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository, PiggyBankRepositoryInterface $piggyRepository)
|
||||
public function index(ARI $repository, PiggyBankRepositoryInterface $piggyRepository)
|
||||
{
|
||||
/** @var Collection $piggyBanks */
|
||||
$piggyBanks = $piggyRepository->getPiggyBanks();
|
||||
@@ -171,9 +171,9 @@ class PiggyBankController extends Controller
|
||||
$accounts = [];
|
||||
/** @var PiggyBank $piggyBank */
|
||||
foreach ($piggyBanks as $piggyBank) {
|
||||
$piggyBank->savedSoFar = floatval($piggyBank->currentRelevantRep()->currentamount);
|
||||
$piggyBank->savedSoFar = round($piggyBank->currentRelevantRep()->currentamount, 2);
|
||||
$piggyBank->percentage = $piggyBank->savedSoFar != 0 ? intval($piggyBank->savedSoFar / $piggyBank->targetamount * 100) : 0;
|
||||
$piggyBank->leftToSave = $piggyBank->targetamount - $piggyBank->savedSoFar;
|
||||
$piggyBank->leftToSave = bcsub($piggyBank->targetamount, $piggyBank->savedSoFar);
|
||||
|
||||
/*
|
||||
* Fill account information:
|
||||
@@ -185,7 +185,7 @@ class PiggyBankController extends Controller
|
||||
'balance' => Steam::balance($account, $end, true),
|
||||
'leftForPiggyBanks' => $repository->leftOnAccount($account, $end),
|
||||
'sumOfSaved' => $piggyBank->savedSoFar,
|
||||
'sumOfTargets' => floatval($piggyBank->targetamount),
|
||||
'sumOfTargets' => round($piggyBank->targetamount, 2),
|
||||
'leftToSave' => $piggyBank->leftToSave
|
||||
];
|
||||
} else {
|
||||
@@ -211,27 +211,27 @@ class PiggyBankController extends Controller
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $order => $id) {
|
||||
$repository->setOrder(intval($id), (intval($order) + 1));
|
||||
$repository->setOrder(intval($id), ($order + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBankRepositoryInterface $repository
|
||||
* @param AccountRepositoryInterface $accounts
|
||||
* @param ARI $accounts
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postAdd(PiggyBankRepositoryInterface $repository, AccountRepositoryInterface $accounts, PiggyBank $piggyBank)
|
||||
public function postAdd(PiggyBankRepositoryInterface $repository, ARI $accounts, PiggyBank $piggyBank)
|
||||
{
|
||||
$amount = round(floatval(Input::get('amount')), 2);
|
||||
bcscale(2);
|
||||
$amount = round(Input::get('amount'), 2);
|
||||
$date = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$leftOnAccount = $accounts->leftOnAccount($piggyBank->account, $date);
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
|
||||
$maxAmount = round(min($leftOnAccount, $leftToSave), 2);
|
||||
bcscale(2);
|
||||
|
||||
if ($amount <= $maxAmount) {
|
||||
$repetition = $piggyBank->currentRelevantRep();
|
||||
@@ -258,7 +258,7 @@ class PiggyBankController extends Controller
|
||||
*/
|
||||
public function postRemove(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
|
||||
{
|
||||
$amount = floatval(Input::get('amount'));
|
||||
$amount = round(Input::get('amount'), 2);
|
||||
bcscale(2);
|
||||
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
@@ -319,7 +319,7 @@ class PiggyBankController extends Controller
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => new Carbon,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetamount' => round($request->get('targetamount'), 2),
|
||||
'remind_me' => false,
|
||||
'reminder_skip' => 0,
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
@@ -354,7 +354,7 @@ class PiggyBankController extends Controller
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => is_null($piggyBank->startdate) ? $piggyBank->created_at : $piggyBank->startdate,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetamount' => round($request->get('targetamount'), 2),
|
||||
'remind_me' => false,
|
||||
'reminder_skip' => 0,
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Config;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Session;
|
||||
@@ -26,21 +26,23 @@ class PreferencesController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return $this|\Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
||||
$viewRangePref = Preferences::get('viewRange', '1M');
|
||||
$viewRange = $viewRangePref->data;
|
||||
$frontPageAccounts = Preferences::get('frontPageAccounts', []);
|
||||
$budgetMax = Preferences::get('budgetMaximum', 1000);
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
|
||||
$budgetMaximum = $budgetMax->data;
|
||||
|
||||
return view('preferences.index', compact('budgetMaximum', 'language', 'accounts', 'frontPageAccounts', 'viewRange'));
|
||||
$showIncomplete = env('SHOW_INCOMPLETE_TRANSLATIONS', 'false') == 'true';
|
||||
|
||||
return view('preferences.index', compact('budgetMaximum', 'language', 'accounts', 'frontPageAccounts', 'viewRange', 'showIncomplete'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +72,7 @@ class PreferencesController extends Controller
|
||||
|
||||
// language:
|
||||
$lang = Input::get('language');
|
||||
if (in_array($lang, array_keys(Config::get('firefly.lang')))) {
|
||||
if (in_array($lang, array_keys(Config::get('firefly.languages')))) {
|
||||
Preferences::set('language', $lang);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ use Auth;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\DeleteAccountFormRequest;
|
||||
use FireflyIII\Http\Requests\ProfileFormRequest;
|
||||
use FireflyIII\User;
|
||||
use Hash;
|
||||
use Session;
|
||||
|
||||
@@ -20,7 +21,7 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function changePassword()
|
||||
{
|
||||
return view('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', 'Change your password')->with(
|
||||
return view('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', trans('firefly.change_your_password'))->with(
|
||||
'mainTitleIcon', 'fa-user'
|
||||
);
|
||||
}
|
||||
@@ -30,7 +31,7 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function deleteAccount()
|
||||
{
|
||||
return view('profile.delete-account')->with('title', Auth::user()->email)->with('subTitle', 'Delete account')->with(
|
||||
return view('profile.delete-account')->with('title', Auth::user()->email)->with('subTitle', trans('firefly.delete_account'))->with(
|
||||
'mainTitleIcon', 'fa-user'
|
||||
);
|
||||
}
|
||||
@@ -41,7 +42,7 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user');
|
||||
return view('profile.index')->with('title', trans('firefly.profile'))->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,7 @@ class ProfileController extends Controller
|
||||
{
|
||||
// old, new1, new2
|
||||
if (!Hash::check($request->get('current_password'), Auth::user()->password)) {
|
||||
Session::flash('error', 'Invalid current password!');
|
||||
Session::flash('error', trans('firefly.invalid_current_password'));
|
||||
|
||||
return redirect(route('profile.change-password'));
|
||||
}
|
||||
@@ -65,10 +66,10 @@ class ProfileController extends Controller
|
||||
}
|
||||
|
||||
// update the user with the new password.
|
||||
Auth::user()->password = $request->get('new_password');
|
||||
Auth::user()->password = bcrypt($request->get('new_password'));
|
||||
Auth::user()->save();
|
||||
|
||||
Session::flash('success', 'Password changed!');
|
||||
Session::flash('success', trans('firefly.password_changed'));
|
||||
|
||||
return redirect(route('profile'));
|
||||
}
|
||||
@@ -83,7 +84,7 @@ class ProfileController extends Controller
|
||||
protected function validatePassword($old, $new1)
|
||||
{
|
||||
if ($new1 == $old) {
|
||||
return 'The idea is to change your password.';
|
||||
return trans('firefly.should_change');
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -100,17 +101,28 @@ class ProfileController extends Controller
|
||||
{
|
||||
// old, new1, new2
|
||||
if (!Hash::check($request->get('password'), Auth::user()->password)) {
|
||||
Session::flash('error', 'Invalid password!');
|
||||
Session::flash('error', trans('firefly.invalid_password'));
|
||||
|
||||
return redirect(route('profile.delete-account'));
|
||||
}
|
||||
|
||||
// DELETE!
|
||||
$email = Auth::user()->email;
|
||||
Auth::user()->delete();
|
||||
Session::flush();
|
||||
Session::flash('gaEventCategory', 'user');
|
||||
Session::flash('gaEventAction', 'delete-account');
|
||||
|
||||
// create a new user with the same email address so re-registration is blocked.
|
||||
User::create(
|
||||
[
|
||||
'email' => $email,
|
||||
'password' => 'deleted',
|
||||
'blocked' => 1,
|
||||
'blocked_code' => 'deleted'
|
||||
]
|
||||
);
|
||||
|
||||
return redirect(route('index'));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Illuminate\Support\Collection;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
@@ -34,118 +35,209 @@ class ReportController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return View
|
||||
* @internal param ReportHelperInterface $helper
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
$start = Session::get('first');
|
||||
$months = $this->helper->listOfMonths($start);
|
||||
$startOfMonth = clone Session::get('start');
|
||||
$endOfMonth = clone Session::get('start');
|
||||
$startOfYear = clone Session::get('start');
|
||||
$endOfYear = clone Session::get('start');
|
||||
$startOfMonth->startOfMonth();
|
||||
$endOfMonth->endOfMonth();
|
||||
$startOfYear->startOfYear();
|
||||
$endOfYear->endOfYear();
|
||||
|
||||
// does the user have shared accounts?
|
||||
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
||||
$hasShared = false;
|
||||
|
||||
// get id's for quick links:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
if ($account->getMeta('accountRole') == 'sharedAsset') {
|
||||
$hasShared = true;
|
||||
$accountIds [] = $account->id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return view('reports.index', compact('months', 'hasShared'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $year
|
||||
* @param string $month
|
||||
*
|
||||
* @param bool $shared
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function month($year = '2014', $month = '1', $shared = false)
|
||||
{
|
||||
$start = new Carbon($year . '-' . $month . '-01');
|
||||
$subTitle = trans('firefly.reportForMonth', ['month' => $start->formatLocalized($this->monthFormat)]);
|
||||
$subTitleIcon = 'fa-calendar';
|
||||
$end = clone $start;
|
||||
$incomeTopLength = 8;
|
||||
$expenseTopLength = 8;
|
||||
if ($shared == 'shared') {
|
||||
$shared = true;
|
||||
$subTitle = trans('firefly.reportForMonthShared', ['month' => $start->formatLocalized($this->monthFormat)]);
|
||||
}
|
||||
|
||||
$end->endOfMonth();
|
||||
|
||||
$accounts = $this->helper->getAccountReport($start, $end, $shared);
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $shared);
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $shared);
|
||||
$budgets = $this->helper->getBudgetReport($start, $end, $shared);
|
||||
$categories = $this->helper->getCategoryReport($start, $end, $shared);
|
||||
$balance = $this->helper->getBalanceReport($start, $end, $shared);
|
||||
$bills = $this->helper->getBillReport($start, $end);
|
||||
|
||||
Session::flash('gaEventCategory', 'report');
|
||||
Session::flash('gaEventAction', 'month');
|
||||
Session::flash('gaEventLabel', $start->format('F Y'));
|
||||
$accountList = join(',', $accountIds);
|
||||
|
||||
|
||||
return view(
|
||||
'reports.month',
|
||||
compact(
|
||||
'start', 'shared',
|
||||
'subTitle', 'subTitleIcon',
|
||||
'accounts',
|
||||
'incomes', 'incomeTopLength',
|
||||
'expenses', 'expenseTopLength',
|
||||
'budgets', 'balance',
|
||||
'categories',
|
||||
'bills'
|
||||
'reports.index', compact(
|
||||
'months', 'accounts', 'start', 'accountList',
|
||||
'startOfMonth', 'endOfMonth', 'startOfYear', 'endOfYear'
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $year
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @param bool $shared
|
||||
*
|
||||
* @return $this
|
||||
* @return View
|
||||
*/
|
||||
public function year($year, $shared = false)
|
||||
public function defaultYear($reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$start = new Carbon('01-01-' . $year);
|
||||
$end = clone $start;
|
||||
$subTitle = trans('firefly.reportForYear', ['year' => $year]);
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$incomeTopLength = 8;
|
||||
$expenseTopLength = 8;
|
||||
|
||||
if ($shared == 'shared') {
|
||||
$shared = true;
|
||||
$subTitle = trans('firefly.reportForYearShared', ['year' => $year]);
|
||||
}
|
||||
$end->endOfYear();
|
||||
|
||||
$accounts = $this->helper->getAccountReport($start, $end, $shared);
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $shared);
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $shared);
|
||||
$accountReport = $this->helper->getAccountReport($start, $end, $accounts);
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $accounts);
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $accounts);
|
||||
|
||||
Session::flash('gaEventCategory', 'report');
|
||||
Session::flash('gaEventAction', 'year');
|
||||
Session::flash('gaEventLabel', $start->format('Y'));
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds[] = $account->id;
|
||||
}
|
||||
$accountIds = join(',', $accountIds);
|
||||
|
||||
return view(
|
||||
'reports.year',
|
||||
compact('start', 'shared', 'accounts', 'incomes', 'expenses', 'subTitle', 'subTitleIcon', 'incomeTopLength', 'expenseTopLength')
|
||||
'reports.default.year',
|
||||
compact(
|
||||
'start', 'accountReport', 'incomes', 'reportType', 'accountIds', 'end',
|
||||
'expenses', 'incomeTopLength', 'expenseTopLength'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function defaultMonth($reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$incomeTopLength = 8;
|
||||
$expenseTopLength = 8;
|
||||
|
||||
// get report stuff!
|
||||
$accountReport = $this->helper->getAccountReport($start, $end, $accounts); // done (+2)
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $accounts); // done (+3)
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $accounts); // done (+1)
|
||||
$budgets = $this->helper->getBudgetReport($start, $end, $accounts); // done (+5)
|
||||
$categories = $this->helper->getCategoryReport($start, $end, $accounts); // done (+1) (20)
|
||||
$balance = $this->helper->getBalanceReport($start, $end, $accounts); // +566
|
||||
$bills = $this->helper->getBillReport($start, $end, $accounts);
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = join(',', $accounts->pluck('id')->toArray());
|
||||
|
||||
// continue!
|
||||
return view(
|
||||
'reports.default.month',
|
||||
compact(
|
||||
'start', 'end', 'reportType',
|
||||
'accountReport',
|
||||
'incomes', 'incomeTopLength',
|
||||
'expenses', 'expenseTopLength',
|
||||
'budgets', 'balance',
|
||||
'categories',
|
||||
'bills',
|
||||
'accountIds', 'reportType'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param $start
|
||||
* @param $end
|
||||
* @param $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function defaultMultiYear($reportType, $start, $end, $accounts)
|
||||
{
|
||||
|
||||
$incomeTopLength = 8;
|
||||
$expenseTopLength = 8;
|
||||
// list of users stuff:
|
||||
$budgets = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface')->getActiveBudgets();
|
||||
$categories = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface')->listCategories();
|
||||
$accountReport = $this->helper->getAccountReport($start, $end, $accounts); // done (+2)
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $accounts); // done (+3)
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $accounts); // done (+1)
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds[] = $account->id;
|
||||
}
|
||||
$accountIds = join(',', $accountIds);
|
||||
|
||||
return view(
|
||||
'reports.default.multi-year',
|
||||
compact(
|
||||
'budgets', 'accounts', 'categories', 'start', 'end', 'accountIds', 'reportType', 'accountReport', 'incomes', 'expenses',
|
||||
'incomeTopLength', 'expenseTopLength'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function report($reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// throw an error if necessary.
|
||||
if ($end < $start) {
|
||||
return view('error')->with('message', 'End date cannot be before start date, silly!');
|
||||
}
|
||||
|
||||
// lower threshold
|
||||
if ($start < Session::get('first')) {
|
||||
$start = Session::get('first');
|
||||
}
|
||||
|
||||
switch ($reportType) {
|
||||
default:
|
||||
case 'default':
|
||||
|
||||
View::share(
|
||||
'subTitle', trans(
|
||||
'firefly.report_default',
|
||||
[
|
||||
'start' => $start->formatLocalized($this->monthFormat),
|
||||
'end' => $end->formatLocalized($this->monthFormat),
|
||||
]
|
||||
)
|
||||
);
|
||||
View::share('subTitleIcon', 'fa-calendar');
|
||||
|
||||
// more than one year date difference means year report.
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
return $this->defaultMultiYear($reportType, $start, $end, $accounts);
|
||||
}
|
||||
// more than two months date difference means year report.
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
return $this->defaultYear($reportType, $start, $end, $accounts);
|
||||
}
|
||||
|
||||
return $this->defaultMonth($reportType, $start, $end, $accounts);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ class TagController extends Controller
|
||||
View::share('mainTitleIcon', 'fa-tags');
|
||||
View::share('hideTags', true);
|
||||
$this->tagOptions = [
|
||||
'nothing' => 'Just a regular tag.',
|
||||
'balancingAct' => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.',
|
||||
'advancePayment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.',
|
||||
'nothing' => trans('firefly.regular_tag'),
|
||||
'balancingAct' => trans('firefly.balancing_act'),
|
||||
'advancePayment' => trans('firefly.advance_payment'),
|
||||
];
|
||||
View::share('tagOptions', $this->tagOptions);
|
||||
}
|
||||
@@ -188,21 +188,24 @@ class TagController extends Controller
|
||||
|
||||
/** @var Collection $tags */
|
||||
$tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get();
|
||||
|
||||
$tags = $tags->sortBy(
|
||||
function (Tag $tag) {
|
||||
return strtolower($tag->tag);
|
||||
$date = !is_null($tag->date) ? $tag->date->format('Ymd') : '000000';
|
||||
|
||||
|
||||
return strtolower($date . $tag->tag);
|
||||
}
|
||||
);
|
||||
|
||||
/** @var Tag $tag */
|
||||
foreach ($tags as $tag) {
|
||||
$year = is_null($tag->date) ? trans('firefly.no_year') : $tag->date->year;
|
||||
$month = is_null($tag->date) ? trans('firefly.no_month') : $tag->date->formatLocalized($this->monthFormat);
|
||||
$collection[$type][$year][$month][] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
$year = is_null($tag->date) ? trans('firefly.no_year') : $tag->date->year;
|
||||
$monthFormatted = is_null($tag->date) ? trans('firefly.no_month') : $tag->date->formatLocalized($this->monthFormat);
|
||||
|
||||
$collection[$type][$year][$monthFormatted][] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
return view('tags.index', compact('title', 'mainTitleIcon', 'types', 'helpHidden', 'collection'));
|
||||
}
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Requests\JournalFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use Steam;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
@@ -36,17 +43,29 @@ class TransactionController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param string $what
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(AccountRepositoryInterface $repository, $what = 'deposit')
|
||||
public function create(ARI $repository, $what = TransactionType::DEPOSIT)
|
||||
{
|
||||
$what = strtolower($what);
|
||||
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
|
||||
$uploadSize = min($maxFileSize, $maxPostSize);
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = trans('form.noBudget');
|
||||
$piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get());
|
||||
|
||||
// piggy bank list:
|
||||
$piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggyBanks as $piggy) {
|
||||
$piggy->name = $piggy->name . ' (' . Amount::format($piggy->currentRelevantRep()->currentamount, false) . ')';
|
||||
}
|
||||
|
||||
$piggies = ExpandedForm::makeSelectList($piggyBanks);
|
||||
$piggies[0] = trans('form.noPiggybank');
|
||||
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : [];
|
||||
$respondTo = ['account_id', 'account_from_id'];
|
||||
@@ -68,7 +87,7 @@ class TransactionController extends Controller
|
||||
asort($piggies);
|
||||
|
||||
|
||||
return view('transactions.create', compact('accounts', 'budgets', 'what', 'piggies', 'subTitle'));
|
||||
return view('transactions.create', compact('accounts', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +99,7 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function delete(TransactionJournal $journal)
|
||||
{
|
||||
$what = strtolower($journal->transactionType->type);
|
||||
$what = strtolower($journal->getTransactionType());
|
||||
$subTitle = trans('firefly.delete_' . $what, ['description' => $journal->description]);
|
||||
|
||||
// put previous url in session
|
||||
@@ -114,14 +133,23 @@ class TransactionController extends Controller
|
||||
/**
|
||||
* Shows the view to edit a transaction.
|
||||
*
|
||||
* @param AccountRepositoryInterface $repository
|
||||
* @param ARI $repository
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(AccountRepositoryInterface $repository, TransactionJournal $journal)
|
||||
public function edit(ARI $repository, TransactionJournal $journal)
|
||||
{
|
||||
$what = strtolower($journal->transactionType->type);
|
||||
// cannot edit opening balance
|
||||
if ($journal->isOpeningBalance()) {
|
||||
return view('error')->with('message', 'Cannot edit this transaction. Edit the account instead!');
|
||||
}
|
||||
|
||||
|
||||
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
|
||||
$uploadSize = min($maxFileSize, $maxPostSize);
|
||||
$what = strtolower($journal->getTransactionType());
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = trans('form.noBudget');
|
||||
@@ -135,11 +163,7 @@ class TransactionController extends Controller
|
||||
'piggy_bank_id' => 0
|
||||
];
|
||||
// get tags:
|
||||
$tags = [];
|
||||
foreach ($journal->tags as $tag) {
|
||||
$tags[] = $tag->tag;
|
||||
}
|
||||
$preFilled['tags'] = join(',', $tags);
|
||||
$preFilled['tags'] = join(',', $journal->tags->pluck('tag')->toArray());
|
||||
|
||||
$category = $journal->categories()->first();
|
||||
if (!is_null($category)) {
|
||||
@@ -155,9 +179,9 @@ class TransactionController extends Controller
|
||||
$preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id;
|
||||
}
|
||||
|
||||
$preFilled['amount'] = $journal->actual_amount;
|
||||
$preFilled['amount'] = $journal->amount_positive;
|
||||
|
||||
if ($journal->transactionType->type == 'Withdrawal') {
|
||||
if ($journal->isWithdrawal()) {
|
||||
$preFilled['account_id'] = $journal->source_account->id;
|
||||
$preFilled['expense_account'] = $journal->destination_account->name_for_editform;
|
||||
} else {
|
||||
@@ -179,7 +203,7 @@ class TransactionController extends Controller
|
||||
Session::forget('transactions.edit.fromUpdate');
|
||||
|
||||
|
||||
return view('transactions.edit', compact('journal', 'accounts', 'what', 'budgets', 'piggies', 'subTitle'))->with('data', $preFilled);
|
||||
return view('transactions.edit', compact('journal', 'uploadSize', 'accounts', 'what', 'budgets', 'piggies', 'subTitle'))->with('data', $preFilled);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,34 +262,64 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function show(JournalRepositoryInterface $repository, TransactionJournal $journal)
|
||||
{
|
||||
|
||||
/** @var Collection $set */
|
||||
$events = $journal->piggyBankEvents()->get();
|
||||
$events->each(
|
||||
function (PiggyBankEvent $event) {
|
||||
$event->piggyBank = $event->piggyBank()->withTrashed()->first();
|
||||
}
|
||||
);
|
||||
|
||||
bcscale(2);
|
||||
$journal->transactions->each(
|
||||
function (Transaction $t) use ($journal, $repository) {
|
||||
$t->before = $repository->getAmountBefore($journal, $t);
|
||||
$t->after = $t->before + $t->amount;
|
||||
$t->after = bcadd($t->before, $t->amount);
|
||||
}
|
||||
);
|
||||
$what = strtolower($journal->transactionType->type);
|
||||
$subTitle = trans('firefly.' . $journal->transactionType->type) . ' "' . e($journal->description) . '"';
|
||||
$what = strtolower($journal->getTransactionType());
|
||||
$subTitle = trans('firefly.' . $journal->getTransactionType()) . ' "' . e($journal->description) . '"';
|
||||
|
||||
return view('transactions.show', compact('journal', 'subTitle', 'what'));
|
||||
return view('transactions.show', compact('journal', 'events', 'subTitle', 'what'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JournalFormRequest $request
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @param AttachmentHelperInterface $att
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att)
|
||||
{
|
||||
|
||||
$journalData = $request->getJournalData();
|
||||
|
||||
// if not withdrawal, unset budgetid.
|
||||
if ($journalData['what'] != strtolower(TransactionType::WITHDRAWAL)) {
|
||||
$journalData['budget_id'] = 0;
|
||||
}
|
||||
|
||||
$journal = $repository->store($journalData);
|
||||
|
||||
// save attachments:
|
||||
$att->saveAttachmentsForModel($journal);
|
||||
|
||||
// flash errors
|
||||
if (count($att->getErrors()->get('attachments')) > 0) {
|
||||
Session::flash('error', $att->getErrors()->get('attachments'));
|
||||
}
|
||||
// flash messages
|
||||
if (count($att->getMessages()->get('attachments')) > 0) {
|
||||
Session::flash('info', $att->getMessages()->get('attachments'));
|
||||
}
|
||||
|
||||
// rescan journal, UpdateJournalConnection
|
||||
event(new JournalSaved($journal));
|
||||
// ConnectJournalToPiggyBank
|
||||
if ($journal->transactionType->type == 'Transfer' && intval($request->get('piggy_bank_id')) > 0) {
|
||||
|
||||
if ($journal->isTransfer() && intval($request->get('piggy_bank_id')) > 0) {
|
||||
event(new JournalCreated($journal, intval($request->get('piggy_bank_id'))));
|
||||
}
|
||||
|
||||
@@ -288,16 +342,33 @@ class TransactionController extends Controller
|
||||
/**
|
||||
* @param JournalFormRequest $request
|
||||
* @param JournalRepositoryInterface $repository
|
||||
* @param AttachmentHelperInterface $att
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, TransactionJournal $journal)
|
||||
public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att, TransactionJournal $journal)
|
||||
{
|
||||
|
||||
if ($journal->isOpeningBalance()) {
|
||||
return view('error')->with('message', 'Cannot edit this transaction. Edit the account instead!');
|
||||
}
|
||||
|
||||
$journalData = $request->getJournalData();
|
||||
$repository->update($journal, $journalData);
|
||||
|
||||
// save attachments:
|
||||
$att->saveAttachmentsForModel($journal);
|
||||
|
||||
// flash errors
|
||||
if (count($att->getErrors()->get('attachments')) > 0) {
|
||||
Session::flash('error', $att->getErrors()->get('attachments'));
|
||||
}
|
||||
// flash messages
|
||||
if (count($att->getMessages()->get('attachments')) > 0) {
|
||||
Session::flash('info', $att->getMessages()->get('attachments'));
|
||||
}
|
||||
|
||||
event(new JournalSaved($journal));
|
||||
// update, get events by date and sort DESC
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Config;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
use Preferences;
|
||||
@@ -45,6 +46,7 @@ class Authenticate
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
|
||||
if ($this->auth->guest()) {
|
||||
if ($request->ajax()) {
|
||||
return response('Unauthorized.', 401);
|
||||
@@ -52,12 +54,23 @@ class Authenticate
|
||||
return redirect()->guest('auth/login');
|
||||
}
|
||||
}
|
||||
// if logged in, set user language:
|
||||
$pref = Preferences::get('language', 'en');
|
||||
App::setLocale($pref->data);
|
||||
Carbon::setLocale($pref->data);
|
||||
/** @var User $user */
|
||||
$user = $this->auth->user();
|
||||
if ($user instanceof User && intval($user->blocked) == 1) {
|
||||
Auth::logout();
|
||||
|
||||
setlocale(LC_TIME, Config::get('firefly.locales.' . $pref->data));
|
||||
return redirect()->route('index');
|
||||
}
|
||||
|
||||
// if logged in, set user language:
|
||||
$pref = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'));
|
||||
App::setLocale($pref->data);
|
||||
Carbon::setLocale(substr($pref->data, 0, 2));
|
||||
$locale = explode(',', trans('config.locale'));
|
||||
$locale = array_map('trim', $locale);
|
||||
|
||||
setlocale(LC_TIME, $locale);
|
||||
setlocale(LC_MONETARY, $locale);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ class Range
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $theNext
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
@@ -24,5 +24,4 @@ class VerifyCsrfToken extends BaseVerifier
|
||||
{
|
||||
return parent::handle($request, $next);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ class AccountFormRequest extends Request
|
||||
'active' => 'boolean',
|
||||
'ccType' => 'in:' . $ccPaymentTypes,
|
||||
'ccMonthlyPaymentDate' => 'date',
|
||||
'balance_currency_id' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_openingBalance' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_virtualBalance' => 'exists:transaction_currencies,id',
|
||||
'what' => 'in:' . $types
|
||||
];
|
||||
}
|
||||
|
||||
36
app/Http/Requests/AttachmentFormRequest.php
Normal file
36
app/Http/Requests/AttachmentFormRequest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
|
||||
/**
|
||||
* Class AttachmentFormRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class AttachmentFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
return [
|
||||
'title' => 'between:1,255',
|
||||
'description' => 'between:1,65536',
|
||||
'notes' => 'between:1,65536',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -31,9 +31,10 @@ class BillFormRequest extends Request
|
||||
return [
|
||||
'name' => $this->get('name'),
|
||||
'match' => $this->get('match'),
|
||||
'amount_min' => floatval($this->get('amount_min')),
|
||||
'amount_currency_id' => floatval($this->get('amount_currency_id')),
|
||||
'amount_max' => floatval($this->get('amount_max')),
|
||||
'amount_min' => round($this->get('amount_min'), 2),
|
||||
'amount_currency_id_amount_min' => intval($this->get('amount_currency_id_amount_min')),
|
||||
'amount_currency_id_amount_max' => intval($this->get('amount_currency_id_amount_max')),
|
||||
'amount_max' => round($this->get('amount_max'), 2),
|
||||
'date' => new Carbon($this->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $this->get('repeat_freq'),
|
||||
@@ -60,7 +61,8 @@ class BillFormRequest extends Request
|
||||
'match' => $matchRule,
|
||||
'amount_min' => 'required|numeric|min:0.01',
|
||||
'amount_max' => 'required|numeric|min:0.01',
|
||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'amount_currency_id_amount_min' => 'required|exists:transaction_currencies,id',
|
||||
'amount_currency_id_amount_max' => 'required|exists:transaction_currencies,id',
|
||||
'date' => 'required|date',
|
||||
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'required|between:0,31',
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FireflyIII\Http\Requests;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
@@ -37,9 +38,9 @@ class JournalFormRequest extends Request
|
||||
'account_to_id' => intval($this->get('account_to_id')),
|
||||
'expense_account' => $this->get('expense_account'),
|
||||
'revenue_account' => $this->get('revenue_account'),
|
||||
'amount' => floatval($this->get('amount')),
|
||||
'amount' => round($this->get('amount'), 2),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id' => intval($this->get('amount_currency_id')),
|
||||
'amount_currency_id_amount' => intval($this->get('amount_currency_id_amount')),
|
||||
'date' => new Carbon($this->get('date')),
|
||||
'budget_id' => intval($this->get('budget_id')),
|
||||
'category' => $this->get('category'),
|
||||
@@ -50,7 +51,6 @@ class JournalFormRequest extends Request
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
@@ -60,12 +60,12 @@ class JournalFormRequest extends Request
|
||||
'what' => 'required|in:withdrawal,deposit,transfer',
|
||||
'amount' => 'numeric|required|min:0.01',
|
||||
'date' => 'required|date',
|
||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'amount_currency_id_amount' => 'required|exists:transaction_currencies,id',
|
||||
|
||||
];
|
||||
|
||||
switch ($what) {
|
||||
case 'withdrawal':
|
||||
case strtolower(TransactionType::WITHDRAWAL):
|
||||
$rules['account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['expense_account'] = 'between:1,255';
|
||||
$rules['category'] = 'between:1,255';
|
||||
@@ -73,12 +73,12 @@ class JournalFormRequest extends Request
|
||||
$rules['budget_id'] = 'exists:budgets,id|belongsToUser:budgets';
|
||||
}
|
||||
break;
|
||||
case 'deposit':
|
||||
case strtolower(TransactionType::DEPOSIT):
|
||||
$rules['category'] = 'between:1,255';
|
||||
$rules['account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['revenue_account'] = 'between:1,255';
|
||||
break;
|
||||
case 'transfer':
|
||||
case strtolower(TransactionType::TRANSFER):
|
||||
$rules['account_from_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_to_id';
|
||||
$rules['account_to_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_from_id';
|
||||
$rules['category'] = 'between:1,255';
|
||||
|
||||
@@ -31,7 +31,9 @@ class NewUserFormRequest extends Request
|
||||
'bank_balance' => 'required|numeric',
|
||||
'savings_balance' => 'numeric',
|
||||
'credit_card_limit' => 'numeric',
|
||||
'balance_currency_id' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_bank_balance' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_savings_balance' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_credit_card_limit' => 'exists:transaction_currencies,id',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class PiggyBankFormRequest extends Request
|
||||
'name' => $nameRule,
|
||||
'account_id' => 'required|belongsToUser:accounts',
|
||||
'targetamount' => 'required|min:0.01',
|
||||
'amount_currency_id' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_targetamount' => 'exists:transaction_currencies,id',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => $targetDateRule,
|
||||
'order' => 'integer|min:1',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use DaveJamesMiller\Breadcrumbs\Generator;
|
||||
use DaveJamesMiller\Breadcrumbs\Generator as BreadCrumbGenerator;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
@@ -16,7 +16,7 @@ use FireflyIII\Models\TransactionJournal;
|
||||
*/
|
||||
Breadcrumbs::register(
|
||||
'home',
|
||||
function (Generator $breadcrumbs) {
|
||||
function (BreadCrumbGenerator $breadcrumbs) {
|
||||
|
||||
$breadcrumbs->push(trans('breadcrumbs.home'), route('index'));
|
||||
}
|
||||
@@ -24,7 +24,7 @@ Breadcrumbs::register(
|
||||
|
||||
Breadcrumbs::register(
|
||||
'index',
|
||||
function (Generator $breadcrumbs) {
|
||||
function (BreadCrumbGenerator $breadcrumbs) {
|
||||
|
||||
$breadcrumbs->push(trans('breadcrumbs.home'), route('index'));
|
||||
}
|
||||
@@ -33,21 +33,21 @@ Breadcrumbs::register(
|
||||
|
||||
// accounts
|
||||
Breadcrumbs::register(
|
||||
'accounts.index', function (Generator $breadcrumbs, $what) {
|
||||
'accounts.index', function (BreadCrumbGenerator $breadcrumbs, $what) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('firefly.' . strtolower(e($what)) . '_accounts'), route('accounts.index', [$what]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'accounts.create', function (Generator $breadcrumbs, $what) {
|
||||
'accounts.create', function (BreadCrumbGenerator $breadcrumbs, $what) {
|
||||
$breadcrumbs->parent('accounts.index', $what);
|
||||
$breadcrumbs->push(trans('breadcrumbs.new_' . strtolower(e($what)) . '_account'), route('accounts.create', [$what]));
|
||||
$breadcrumbs->push(trans('firefly.new_' . strtolower(e($what)) . '_account'), route('accounts.create', [$what]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'accounts.show', function (Generator $breadcrumbs, Account $account) {
|
||||
'accounts.show', function (BreadCrumbGenerator $breadcrumbs, Account $account) {
|
||||
|
||||
$what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
|
||||
@@ -57,7 +57,7 @@ Breadcrumbs::register(
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'accounts.delete', function (Generator $breadcrumbs, Account $account) {
|
||||
'accounts.delete', function (BreadCrumbGenerator $breadcrumbs, Account $account) {
|
||||
$breadcrumbs->parent('accounts.show', $account);
|
||||
$breadcrumbs->push(trans('firefly.delete_account', ['name' => e($account->name)]), route('accounts.delete', [$account->id]));
|
||||
}
|
||||
@@ -65,7 +65,7 @@ Breadcrumbs::register(
|
||||
|
||||
|
||||
Breadcrumbs::register(
|
||||
'accounts.edit', function (Generator $breadcrumbs, Account $account) {
|
||||
'accounts.edit', function (BreadCrumbGenerator $breadcrumbs, Account $account) {
|
||||
$breadcrumbs->parent('accounts.show', $account);
|
||||
$what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
|
||||
@@ -75,40 +75,40 @@ Breadcrumbs::register(
|
||||
|
||||
// budgets.
|
||||
Breadcrumbs::register(
|
||||
'budgets.index', function (Generator $breadcrumbs) {
|
||||
'budgets.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('firefly.budgets'), route('budgets.index'));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'budgets.create', function (Generator $breadcrumbs) {
|
||||
'budgets.create', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('budgets.index');
|
||||
$breadcrumbs->push(trans('firefly.create_new_budget'), route('budgets.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'budgets.edit', function (Generator $breadcrumbs, Budget $budget) {
|
||||
'budgets.edit', function (BreadCrumbGenerator $breadcrumbs, Budget $budget) {
|
||||
$breadcrumbs->parent('budgets.show', $budget);
|
||||
$breadcrumbs->push(trans('firefly.edit_budget', ['name' => e($budget->name)]), route('budgets.edit', [$budget->id]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'budgets.delete', function (Generator $breadcrumbs, Budget $budget) {
|
||||
'budgets.delete', function (BreadCrumbGenerator $breadcrumbs, Budget $budget) {
|
||||
$breadcrumbs->parent('budgets.show', $budget);
|
||||
$breadcrumbs->push(trans('firefly.delete_budget', ['name' => e($budget->name)]), route('budgets.delete', [$budget->id]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'budgets.noBudget', function (Generator $breadcrumbs, $subTitle) {
|
||||
'budgets.noBudget', function (BreadCrumbGenerator $breadcrumbs, $subTitle) {
|
||||
$breadcrumbs->parent('budgets.index');
|
||||
$breadcrumbs->push($subTitle, route('budgets.noBudget'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'budgets.show', function (Generator $breadcrumbs, Budget $budget, LimitRepetition $repetition = null) {
|
||||
'budgets.show', function (BreadCrumbGenerator $breadcrumbs, Budget $budget, LimitRepetition $repetition = null) {
|
||||
$breadcrumbs->parent('budgets.index');
|
||||
$breadcrumbs->push(e($budget->name), route('budgets.show', [$budget->id]));
|
||||
if (!is_null($repetition) && !is_null($repetition->id)) {
|
||||
@@ -121,33 +121,33 @@ Breadcrumbs::register(
|
||||
|
||||
// categories
|
||||
Breadcrumbs::register(
|
||||
'categories.index', function (Generator $breadcrumbs) {
|
||||
'categories.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('firefly.categories'), route('categories.index'));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'categories.create', function (Generator $breadcrumbs) {
|
||||
'categories.create', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('categories.index');
|
||||
$breadcrumbs->push(trans('breadcrumbs.newCategory'), route('categories.create'));
|
||||
$breadcrumbs->push(trans('firefly.new_category'), route('categories.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'categories.edit', function (Generator $breadcrumbs, Category $category) {
|
||||
'categories.edit', function (BreadCrumbGenerator $breadcrumbs, Category $category) {
|
||||
$breadcrumbs->parent('categories.show', $category);
|
||||
$breadcrumbs->push(trans('firefly.edit_category', ['name' => e($category->name)]), route('categories.edit', [$category->id]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'categories.delete', function (Generator $breadcrumbs, Category $category) {
|
||||
'categories.delete', function (BreadCrumbGenerator $breadcrumbs, Category $category) {
|
||||
$breadcrumbs->parent('categories.show', $category);
|
||||
$breadcrumbs->push(trans('firefly.delete_category', ['name' => e($category->name)]), route('categories.delete', [$category->id]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'categories.show', function (Generator $breadcrumbs, Category $category) {
|
||||
'categories.show', function (BreadCrumbGenerator $breadcrumbs, Category $category) {
|
||||
$breadcrumbs->parent('categories.index');
|
||||
$breadcrumbs->push(e($category->name), route('categories.show', [$category->id]));
|
||||
|
||||
@@ -155,7 +155,20 @@ Breadcrumbs::register(
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'categories.noCategory', function (Generator $breadcrumbs, $subTitle) {
|
||||
'categories.show.date', function (BreadCrumbGenerator $breadcrumbs, Category $category, Carbon $date) {
|
||||
|
||||
// get current period preference.
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
|
||||
$breadcrumbs->parent('categories.index');
|
||||
$breadcrumbs->push(e($category->name), route('categories.show', [$category->id]));
|
||||
$breadcrumbs->push(Navigation::periodShow($date, $range), route('categories.show.date', [$category->id, $date->format('Y-m-d')]));
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'categories.noCategory', function (BreadCrumbGenerator $breadcrumbs, $subTitle) {
|
||||
$breadcrumbs->parent('categories.index');
|
||||
$breadcrumbs->push($subTitle, route('categories.noCategory'));
|
||||
}
|
||||
@@ -163,35 +176,35 @@ Breadcrumbs::register(
|
||||
|
||||
// CSV:
|
||||
Breadcrumbs::register(
|
||||
'csv.index', function (Generator $breadcrumbs) {
|
||||
'csv.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('firefly.csv_index_title'), route('csv.index'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'csv.column-roles', function (Generator $breadcrumbs) {
|
||||
'csv.column-roles', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('csv.index');
|
||||
$breadcrumbs->push(trans('firefly.csv_define_column_roles'), route('csv.column-roles'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'csv.map', function (Generator $breadcrumbs) {
|
||||
'csv.map', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('csv.index');
|
||||
$breadcrumbs->push(trans('firefly.csv_map_values'), route('csv.map'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'csv.download-config-page', function (Generator $breadcrumbs) {
|
||||
'csv.download-config-page', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('csv.index');
|
||||
$breadcrumbs->push(trans('firefly.csv_download_config'), route('csv.download-config-page'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'csv.process', function (Generator $breadcrumbs) {
|
||||
'csv.process', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('csv.index');
|
||||
$breadcrumbs->push(trans('firefly.csv_process_title'), route('csv.process'));
|
||||
}
|
||||
@@ -200,27 +213,27 @@ Breadcrumbs::register(
|
||||
|
||||
// currencies.
|
||||
Breadcrumbs::register(
|
||||
'currency.index', function (Generator $breadcrumbs) {
|
||||
'currency.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('firefly.currencies'), route('currency.index'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'currency.create', function (Generator $breadcrumbs) {
|
||||
'currency.create', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('currency.index');
|
||||
$breadcrumbs->push(trans('firefly.create_currency'), route('currency.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'currency.edit', function (Generator $breadcrumbs, TransactionCurrency $currency) {
|
||||
'currency.edit', function (BreadCrumbGenerator $breadcrumbs, TransactionCurrency $currency) {
|
||||
$breadcrumbs->parent('currency.index');
|
||||
$breadcrumbs->push(trans('breadcrumbs.edit_currency', ['name' => e($currency->name)]), route('currency.edit', [$currency->id]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'currency.delete', function (Generator $breadcrumbs, TransactionCurrency $currency) {
|
||||
'currency.delete', function (BreadCrumbGenerator $breadcrumbs, TransactionCurrency $currency) {
|
||||
$breadcrumbs->parent('currency.index');
|
||||
$breadcrumbs->push(trans('breadcrumbs.delete_currency', ['name' => e($currency->name)]), route('currency.delete', [$currency->id]));
|
||||
}
|
||||
@@ -229,33 +242,33 @@ Breadcrumbs::register(
|
||||
|
||||
// piggy banks
|
||||
Breadcrumbs::register(
|
||||
'piggy-banks.index', function (Generator $breadcrumbs) {
|
||||
'piggy-banks.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.piggyBanks'), route('piggy-banks.index'));
|
||||
$breadcrumbs->push(trans('firefly.piggyBanks'), route('piggy-banks.index'));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'piggy-banks.create', function (Generator $breadcrumbs) {
|
||||
'piggy-banks.create', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('piggy-banks.index');
|
||||
$breadcrumbs->push(trans('breadcrumbs.newPiggyBank'), route('piggy-banks.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'piggy-banks.edit', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
'piggy-banks.edit', function (BreadCrumbGenerator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggy-banks.show', $piggyBank);
|
||||
$breadcrumbs->push(trans('breadcrumbs.edit_piggyBank', ['name' => e($piggyBank->name)]), route('piggy-banks.edit', [$piggyBank->id]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'piggy-banks.delete', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
'piggy-banks.delete', function (BreadCrumbGenerator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggy-banks.show', $piggyBank);
|
||||
$breadcrumbs->push(trans('breadcrumbs.delete_piggyBank', ['name' => e($piggyBank->name)]), route('piggy-banks.delete', [$piggyBank->id]));
|
||||
$breadcrumbs->push(trans('firefly.delete_piggy_bank', ['name' => e($piggyBank->name)]), route('piggy-banks.delete', [$piggyBank->id]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'piggy-banks.show', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
'piggy-banks.show', function (BreadCrumbGenerator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggy-banks.index');
|
||||
$breadcrumbs->push(e($piggyBank->name), route('piggy-banks.show', [$piggyBank->id]));
|
||||
|
||||
@@ -264,7 +277,7 @@ Breadcrumbs::register(
|
||||
|
||||
// preferences
|
||||
Breadcrumbs::register(
|
||||
'preferences', function (Generator $breadcrumbs) {
|
||||
'preferences', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.preferences'), route('preferences'));
|
||||
|
||||
@@ -273,49 +286,56 @@ Breadcrumbs::register(
|
||||
|
||||
// profile
|
||||
Breadcrumbs::register(
|
||||
'profile', function (Generator $breadcrumbs) {
|
||||
'profile', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.profile'), route('profile'));
|
||||
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'change-password', function (Generator $breadcrumbs) {
|
||||
'profile.change-password', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('profile');
|
||||
$breadcrumbs->push(trans('breadcrumbs.changePassword'), route('change-password'));
|
||||
$breadcrumbs->push(trans('breadcrumbs.changePassword'), route('profile.change-password'));
|
||||
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'profile.delete-account', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('profile');
|
||||
$breadcrumbs->push(trans('firefly.delete_account'), route('profile.delete-account'));
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
// bills
|
||||
Breadcrumbs::register(
|
||||
'bills.index', function (Generator $breadcrumbs) {
|
||||
'bills.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.bills'), route('bills.index'));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'bills.create', function (Generator $breadcrumbs) {
|
||||
'bills.create', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('bills.index');
|
||||
$breadcrumbs->push(trans('breadcrumbs.newBill'), route('bills.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'bills.edit', function (Generator $breadcrumbs, Bill $bill) {
|
||||
'bills.edit', function (BreadCrumbGenerator $breadcrumbs, Bill $bill) {
|
||||
$breadcrumbs->parent('bills.show', $bill);
|
||||
$breadcrumbs->push(trans('breadcrumbs.edit_bill', ['name' => e($bill->name)]), route('bills.edit', [$bill->id]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'bills.delete', function (Generator $breadcrumbs, Bill $bill) {
|
||||
'bills.delete', function (BreadCrumbGenerator $breadcrumbs, Bill $bill) {
|
||||
$breadcrumbs->parent('bills.show', $bill);
|
||||
$breadcrumbs->push(trans('breadcrumbs.delete_bill', ['name' => e($bill->name)]), route('bills.delete', [$bill->id]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'bills.show', function (Generator $breadcrumbs, Bill $bill) {
|
||||
'bills.show', function (BreadCrumbGenerator $breadcrumbs, Bill $bill) {
|
||||
$breadcrumbs->parent('bills.index');
|
||||
$breadcrumbs->push(e($bill->name), route('bills.show', [$bill->id]));
|
||||
|
||||
@@ -324,43 +344,26 @@ Breadcrumbs::register(
|
||||
|
||||
// reports
|
||||
Breadcrumbs::register(
|
||||
'reports.index', function (Generator $breadcrumbs) {
|
||||
'reports.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.reports'), route('reports.index'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'reports.year', function (Generator $breadcrumbs, Carbon $date, $shared) {
|
||||
'reports.report', function (BreadCrumbGenerator $breadcrumbs, Carbon $start, Carbon $end, $reportType, $accountIds) {
|
||||
$breadcrumbs->parent('reports.index');
|
||||
if ($shared) {
|
||||
$title = trans('breadcrumbs.yearly_report_shared', ['date' => $date->year]);
|
||||
} else {
|
||||
$title = trans('breadcrumbs.yearly_report', ['date' => $date->year]);
|
||||
}
|
||||
$breadcrumbs->push($title, route('reports.year', [$date->year]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'reports.month', function (Generator $breadcrumbs, Carbon $date, $shared) {
|
||||
$breadcrumbs->parent('reports.year', $date, $shared);
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
$monthFormat = trans('config.month_and_day');
|
||||
$title = trans('firefly.report_' . $reportType, ['start' => $start->formatLocalized($monthFormat), 'end' => $end->formatLocalized($monthFormat)]);
|
||||
|
||||
if ($shared) {
|
||||
$title = trans('breadcrumbs.monthly_report_shared', ['date' => $date->formatLocalized($format)]);
|
||||
} else {
|
||||
$title = trans('breadcrumbs.monthly_report', ['date' => $date->formatLocalized($format)]);
|
||||
}
|
||||
|
||||
$breadcrumbs->push($title, route('reports.month', [$date->year, $date->month]));
|
||||
$breadcrumbs->push($title, route('reports.report', [$reportType, $start->format('Ymd'), $end->format('Ymd'), $accountIds]));
|
||||
}
|
||||
);
|
||||
|
||||
// search
|
||||
Breadcrumbs::register(
|
||||
'search', function (Generator $breadcrumbs, $query) {
|
||||
'search', function (BreadCrumbGenerator $breadcrumbs, $query) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.searchResult', ['query' => e($query)]), route('search'));
|
||||
}
|
||||
@@ -368,35 +371,35 @@ Breadcrumbs::register(
|
||||
|
||||
// transactions
|
||||
Breadcrumbs::register(
|
||||
'transactions.index', function (Generator $breadcrumbs, $what) {
|
||||
'transactions.index', function (BreadCrumbGenerator $breadcrumbs, $what) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.' . $what . '_list'), route('transactions.index', [$what]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'transactions.create', function (Generator $breadcrumbs, $what) {
|
||||
'transactions.create', function (BreadCrumbGenerator $breadcrumbs, $what) {
|
||||
$breadcrumbs->parent('transactions.index', $what);
|
||||
$breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('transactions.create', [$what]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'transactions.edit', function (Generator $breadcrumbs, TransactionJournal $journal) {
|
||||
'transactions.edit', function (BreadCrumbGenerator $breadcrumbs, TransactionJournal $journal) {
|
||||
$breadcrumbs->parent('transactions.show', $journal);
|
||||
$breadcrumbs->push(trans('breadcrumbs.edit_journal', ['description' => $journal->description]), route('transactions.edit', [$journal->id]));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'transactions.delete', function (Generator $breadcrumbs, TransactionJournal $journal) {
|
||||
'transactions.delete', function (BreadCrumbGenerator $breadcrumbs, TransactionJournal $journal) {
|
||||
$breadcrumbs->parent('transactions.show', $journal);
|
||||
$breadcrumbs->push(trans('breadcrumbs.delete_journal', ['description' => e($journal->description)]), route('transactions.delete', [$journal->id]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'transactions.show', function (Generator $breadcrumbs, TransactionJournal $journal) {
|
||||
'transactions.show', function (BreadCrumbGenerator $breadcrumbs, TransactionJournal $journal) {
|
||||
|
||||
$breadcrumbs->parent('transactions.index', strtolower($journal->transactionType->type));
|
||||
$breadcrumbs->parent('transactions.index', strtolower($journal->getTransactionType()));
|
||||
$breadcrumbs->push($journal->description, route('transactions.show', [$journal->id]));
|
||||
|
||||
}
|
||||
@@ -404,28 +407,28 @@ Breadcrumbs::register(
|
||||
|
||||
// tags
|
||||
Breadcrumbs::register(
|
||||
'tags.index', function (Generator $breadcrumbs) {
|
||||
'tags.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('breadcrumbs.tags'), route('tags.index'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'tags.create', function (Generator $breadcrumbs) {
|
||||
'tags.create', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('tags.index');
|
||||
$breadcrumbs->push(trans('breadcrumbs.createTag'), route('tags.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'tags.edit', function (Generator $breadcrumbs, Tag $tag) {
|
||||
'tags.edit', function (BreadCrumbGenerator $breadcrumbs, Tag $tag) {
|
||||
$breadcrumbs->parent('tags.show', $tag);
|
||||
$breadcrumbs->push(trans('breadcrumbs.edit_tag', ['tag' => e($tag->tag)]), route('tags.edit', [$tag->id]));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'tags.delete', function (Generator $breadcrumbs, Tag $tag) {
|
||||
'tags.delete', function (BreadCrumbGenerator $breadcrumbs, Tag $tag) {
|
||||
$breadcrumbs->parent('tags.show', $tag);
|
||||
$breadcrumbs->push(trans('breadcrumbs.delete_tag', ['tag' => e($tag->tag)]), route('tags.delete', [$tag->id]));
|
||||
}
|
||||
@@ -433,7 +436,7 @@ Breadcrumbs::register(
|
||||
|
||||
|
||||
Breadcrumbs::register(
|
||||
'tags.show', function (Generator $breadcrumbs, Tag $tag) {
|
||||
'tags.show', function (BreadCrumbGenerator $breadcrumbs, Tag $tag) {
|
||||
$breadcrumbs->parent('tags.index');
|
||||
$breadcrumbs->push(e($tag->tag), route('tags.show', [$tag->id]));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
@@ -28,6 +30,111 @@ Route::bind(
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
// accounts
|
||||
Route::bind(
|
||||
'accountList',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.editable', 1)
|
||||
->whereIn('accounts.id', $ids)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->get(['accounts.*']);
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
// budget list
|
||||
Route::bind(
|
||||
'budgetList',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = Budget::where('active', 1)
|
||||
->whereIn('id', $ids)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->get();
|
||||
|
||||
// add empty budget if applicable.
|
||||
if (in_array('0', $ids)) {
|
||||
$object->push(new Budget);
|
||||
}
|
||||
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
// category list
|
||||
Route::bind(
|
||||
'categoryList',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = Category::whereIn('id', $ids)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->get();
|
||||
|
||||
// add empty budget if applicable.
|
||||
if (in_array('0', $ids)) {
|
||||
$object->push(new Category);
|
||||
}
|
||||
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
// Date
|
||||
Route::bind(
|
||||
'start_date',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
|
||||
try {
|
||||
$date = new Carbon($value);
|
||||
} catch (Exception $e) {
|
||||
Log::error('Could not parse date "' . $value . '" for user #' . Auth::user()->id);
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
// Date
|
||||
Route::bind(
|
||||
'end_date',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
|
||||
try {
|
||||
$date = new Carbon($value);
|
||||
} catch (Exception $e) {
|
||||
Log::error('Could not parse date "' . $value . '" for user #' . Auth::user()->id);
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'tj', function ($value) {
|
||||
@@ -42,6 +149,19 @@ Route::bind(
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'attachment', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Attachment::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'currency', function ($value) {
|
||||
if (Auth::check()) {
|
||||
@@ -163,7 +283,6 @@ Route::group(
|
||||
Route::get('/home', ['uses' => 'HomeController@index', 'as' => 'home']);
|
||||
Route::post('/daterange', ['uses' => 'HomeController@dateRange', 'as' => 'daterange']);
|
||||
Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']);
|
||||
Route::get('/routes', ['uses' => 'HomeController@routes']);
|
||||
/**
|
||||
* Account Controller
|
||||
*/
|
||||
@@ -177,6 +296,21 @@ Route::group(
|
||||
Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']);
|
||||
Route::post('/accounts/destroy/{account}', ['uses' => 'AccountController@destroy', 'as' => 'accounts.destroy']);
|
||||
|
||||
|
||||
/**
|
||||
* Attachment Controller
|
||||
*/
|
||||
|
||||
Route::post('/attachment/update/{attachment}', ['uses' => 'AttachmentController@update', 'as' => 'attachments.update']);
|
||||
Route::post('/attachment/destroy/{attachment}', ['uses' => 'AttachmentController@destroy', 'as' => 'attachments.destroy']);
|
||||
|
||||
Route::get('/attachment/edit/{attachment}', ['uses' => 'AttachmentController@edit', 'as' => 'attachments.edit']);
|
||||
Route::get('/attachment/delete/{attachment}', ['uses' => 'AttachmentController@delete', 'as' => 'attachments.delete']);
|
||||
Route::get('/attachment/show/{attachment}', ['uses' => 'AttachmentController@show', 'as' => 'attachments.show']);
|
||||
Route::get('/attachment/preview/{attachment}', ['uses' => 'AttachmentController@preview', 'as' => 'attachments.preview']);
|
||||
Route::get('/attachment/download/{attachment}', ['uses' => 'AttachmentController@download', 'as' => 'attachments.download']);
|
||||
|
||||
|
||||
/**
|
||||
* Bills Controller
|
||||
*/
|
||||
@@ -214,6 +348,7 @@ Route::group(
|
||||
Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']);
|
||||
Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']);
|
||||
Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']);
|
||||
Route::get('/categories/show/{category}/{date}', ['uses' => 'CategoryController@showWithDate', 'as' => 'categories.show.date']);
|
||||
Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noCategory']);
|
||||
Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']);
|
||||
Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
|
||||
@@ -252,9 +387,8 @@ Route::group(
|
||||
*/
|
||||
// accounts:
|
||||
Route::get('/chart/account/frontpage', ['uses' => 'Chart\AccountController@frontpage']);
|
||||
Route::get('/chart/account/month/{year}/{month}/{shared?}', ['uses' => 'Chart\AccountController@all'])->where(
|
||||
['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']
|
||||
);
|
||||
Route::get('/chart/account/expense', ['uses' => 'Chart\AccountController@expenseAccounts']);
|
||||
Route::get('/chart/account/report/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\AccountController@report']);
|
||||
Route::get('/chart/account/{account}', ['uses' => 'Chart\AccountController@single']);
|
||||
|
||||
|
||||
@@ -264,24 +398,34 @@ Route::group(
|
||||
|
||||
// budgets:
|
||||
Route::get('/chart/budget/frontpage', ['uses' => 'Chart\BudgetController@frontpage']);
|
||||
Route::get('/chart/budget/year/{year}/{shared?}', ['uses' => 'Chart\BudgetController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
|
||||
|
||||
// this chart is used in reports:
|
||||
Route::get('/chart/budget/year/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\BudgetController@year']);
|
||||
Route::get('/chart/budget/multi-year/{reportType}/{start_date}/{end_date}/{accountList}/{budgetList}', ['uses' => 'Chart\BudgetController@multiYear']);
|
||||
|
||||
Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'Chart\BudgetController@budgetLimit']);
|
||||
Route::get('/chart/budget/{budget}', ['uses' => 'Chart\BudgetController@budget']);
|
||||
|
||||
// categories:
|
||||
Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']);
|
||||
Route::get('/chart/category/year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
|
||||
Route::get('/chart/category/{category}/month', ['uses' => 'Chart\CategoryController@month']); // should be period.
|
||||
|
||||
// these three charts are for reports:
|
||||
Route::get('/chart/category/earned-in-period/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\CategoryController@earnedInPeriod']);
|
||||
Route::get('/chart/category/spent-in-period/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\CategoryController@spentInPeriod']);
|
||||
Route::get(
|
||||
'/chart/category/multi-year/{reportType}/{start_date}/{end_date}/{accountList}/{categoryList}', ['uses' => 'Chart\CategoryController@multiYear']
|
||||
);
|
||||
|
||||
Route::get('/chart/category/{category}/period', ['uses' => 'Chart\CategoryController@currentPeriod']);
|
||||
Route::get('/chart/category/{category}/period/{date}', ['uses' => 'Chart\CategoryController@specificPeriod']);
|
||||
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);
|
||||
|
||||
// piggy banks:
|
||||
Route::get('/chart/piggyBank/{piggyBank}', ['uses' => 'Chart\PiggyBankController@history']);
|
||||
Route::get('/chart/piggy-bank/{piggyBank}', ['uses' => 'Chart\PiggyBankController@history']);
|
||||
|
||||
// reports:
|
||||
Route::get('/chart/report/in-out/{year}/{shared?}', ['uses' => 'Chart\ReportController@yearInOut'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
|
||||
Route::get('/chart/report/in-out-sum/{year}/{shared?}', ['uses' => 'Chart\ReportController@yearInOutSummarized'])->where(
|
||||
['year' => '[0-9]{4}', 'shared' => 'shared']
|
||||
);
|
||||
Route::get('/chart/report/in-out/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\ReportController@yearInOut']);
|
||||
Route::get('/chart/report/in-out-sum/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\ReportController@yearInOutSummarized']);
|
||||
|
||||
|
||||
/**
|
||||
@@ -347,12 +491,7 @@ Route::group(
|
||||
* Report Controller
|
||||
*/
|
||||
Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']);
|
||||
Route::get('/reports/{year}/{shared?}', ['uses' => 'ReportController@year', 'as' => 'reports.year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
|
||||
Route::get('/reports/{year}/{month}/{shared?}', ['uses' => 'ReportController@month', 'as' => 'reports.month'])->where(
|
||||
['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']
|
||||
);
|
||||
|
||||
// pop ups for budget report:
|
||||
Route::get('/reports/report/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'ReportController@report', 'as' => 'reports.report']);
|
||||
|
||||
/**
|
||||
* Search Controller
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
* FireflyIII\Models\Account
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property integer $user_id
|
||||
* @property integer $account_type_id
|
||||
* @property string $name
|
||||
@@ -22,32 +25,14 @@ use Watson\Validating\ValidatingTrait;
|
||||
* @property boolean $encrypted
|
||||
* @property float $virtual_balance
|
||||
* @property string $iban
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\AccountMeta[] $accountMeta
|
||||
* @property-read \FireflyIII\Models\AccountType $accountType
|
||||
* @property-read Collection|AccountMeta[] $accountMeta
|
||||
* @property-read AccountType $accountType
|
||||
* @property-read mixed $name_for_editform
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Transaction[] $transactions
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereAccountTypeId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereActive($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereEncrypted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereVirtualBalance($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereIban($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account accountTypeIn($types)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account hasMetaValue($name, $value)
|
||||
* @property-read bool $joinedAccountTypes
|
||||
* @property float $startBalance
|
||||
* @property float $endBalance
|
||||
* @property float $piggyBalance
|
||||
* @property float $percentage
|
||||
* @property float $difference
|
||||
* @property \Carbon\Carbon $lastActivityDate
|
||||
* @property-read Collection|PiggyBank[] $piggyBanks
|
||||
* @property-read Collection|Transaction[] $transactions
|
||||
* @property-read User $user
|
||||
* @method static Builder|Account accountTypeIn($types)
|
||||
* @method static Builder|Account hasMetaValue($name, $value)
|
||||
*/
|
||||
class Account extends Model
|
||||
{
|
||||
@@ -65,7 +50,6 @@ class Account extends Model
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @return Account|null
|
||||
*/
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class AccountMeta
|
||||
* FireflyIII\Models\AccountMeta
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $account_id
|
||||
* @property string $name
|
||||
* @property string $data
|
||||
* @property-read \FireflyIII\Models\Account $account
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereAccountId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereData($value)
|
||||
* @property-read Account $account
|
||||
*/
|
||||
class AccountMeta extends Model
|
||||
{
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class AccountType
|
||||
* FireflyIII\Models\AccountType
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property string $type
|
||||
* @property boolean $editable
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Account[] $accounts
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereType($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereEditable($value)
|
||||
* @property-read Collection|Account[] $accounts
|
||||
*/
|
||||
class AccountType extends Model
|
||||
{
|
||||
@@ -33,6 +29,7 @@ class AccountType extends Model
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
/** @noinspection PhpMissingParentCallCommonInspection */
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at'];
|
||||
|
||||
176
app/Models/Attachment.php
Normal file
176
app/Models/Attachment.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Attachment
|
||||
*
|
||||
* @property integer $id
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property string $deleted_at
|
||||
* @property integer $attachable_id
|
||||
* @property string $attachable_type
|
||||
* @property integer $user_id
|
||||
* @property string $md5
|
||||
* @property string $filename
|
||||
* @property string $title
|
||||
* @property string $description
|
||||
* @property string $notes
|
||||
* @property string $mime
|
||||
* @property integer $size
|
||||
* @property boolean $uploaded
|
||||
* @property-read Attachment $attachable
|
||||
* @property-read User $user
|
||||
*/
|
||||
class Attachment extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'notes', 'description', 'size', 'uploaded'];
|
||||
|
||||
/**
|
||||
* Get all of the owning imageable models.
|
||||
*/
|
||||
public function attachable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('FireflyIII\User');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getFilenameAttribute($value)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setFilenameAttribute($value)
|
||||
{
|
||||
$this->attributes['filename'] = Crypt::encrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getMimeAttribute($value)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setMimeAttribute($value)
|
||||
{
|
||||
$this->attributes['mime'] = Crypt::encrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitleAttribute($value)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setTitleAttribute($value)
|
||||
{
|
||||
$this->attributes['title'] = Crypt::encrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getDescriptionAttribute($value)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setDescriptionAttribute($value)
|
||||
{
|
||||
$this->attributes['description'] = Crypt::encrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getNotesAttribute($value)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setNotesAttribute($value)
|
||||
{
|
||||
$this->attributes['notes'] = Crypt::encrypt($value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +1,31 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class Bill
|
||||
* FireflyIII\Models\Bill
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $user_id
|
||||
* @property string $name
|
||||
* @property string $match
|
||||
* @property float $amount_min
|
||||
* @property float $amount_max
|
||||
* @property \Carbon\Carbon $date
|
||||
* @property Carbon $date
|
||||
* @property boolean $active
|
||||
* @property boolean $automatch
|
||||
* @property string $repeat_freq
|
||||
* @property integer $skip
|
||||
* @property boolean $name_encrypted
|
||||
* @property boolean $match_encrypted
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatch($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAmountMin($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAmountMax($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereDate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereActive($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAutomatch($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereRepeatFreq($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereSkip($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereNameEncrypted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
|
||||
* @property-read \Carbon\Carbon $nextExpectedMatch
|
||||
* @property-read \Carbon\Carbon $lastFoundMatch
|
||||
* @property-read Collection|TransactionJournal[] $transactionjournals
|
||||
* @property-read User $user
|
||||
*/
|
||||
class Bill extends Model
|
||||
{
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class Budget
|
||||
* FireflyIII\Models\Budget
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property string $name
|
||||
* @property integer $user_id
|
||||
* @property boolean $active
|
||||
* @property boolean $encrypted
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\BudgetLimit[] $budgetlimits
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereActive($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereEncrypted($value)
|
||||
* @property-read Collection|BudgetLimit[] $budgetlimits
|
||||
* @property-read Collection|TransactionJournal[] $transactionjournals
|
||||
* @property-read User $user
|
||||
*/
|
||||
class Budget extends Model
|
||||
{
|
||||
@@ -78,7 +72,7 @@ class Budget extends Model
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'deleted_at'];
|
||||
return ['created_at', 'updated_at', 'deleted_at', 'startdate', 'enddate'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class BudgetLimit
|
||||
* FireflyIII\Models\BudgetLimit
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $budget_id
|
||||
* @property \Carbon\Carbon $startdate
|
||||
* @property Carbon $startdate
|
||||
* @property float $amount
|
||||
* @property boolean $repeats
|
||||
* @property string $repeat_freq
|
||||
* @property-read \FireflyIII\Models\Budget $budget
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\LimitRepetition[] $limitrepetitions
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereBudgetId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereStartdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereAmount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereRepeats($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereRepeatFreq($value)
|
||||
* @property-read Budget $budget
|
||||
* @property-read Collection|LimitRepetition[] $limitrepetitions
|
||||
*/
|
||||
class BudgetLimit extends Model
|
||||
{
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class Category
|
||||
* FireflyIII\Models\Category
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property string $name
|
||||
* @property integer $user_id
|
||||
* @property boolean $encrypted
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereEncrypted($value)
|
||||
* @property-read float $spent
|
||||
* @property-read \Carbon\Carbon $lastActivity
|
||||
* @property-read Collection|TransactionJournal[] $transactionjournals
|
||||
* @property-read User $user
|
||||
*/
|
||||
class Category extends Model
|
||||
{
|
||||
@@ -36,7 +29,6 @@ class Category extends Model
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class Component
|
||||
* FireflyIII\Models\Component
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property string $name
|
||||
* @property integer $user_id
|
||||
* @property string $class
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereClass($value)
|
||||
*/
|
||||
class Component extends Model
|
||||
{
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class LimitRepetition
|
||||
* FireflyIII\Models\LimitRepetition
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $budget_limit_id
|
||||
* @property \Carbon\Carbon $startdate
|
||||
* @property \Carbon\Carbon $enddate
|
||||
* @property Carbon $startdate
|
||||
* @property Carbon $enddate
|
||||
* @property float $amount
|
||||
* @property-read \FireflyIII\Models\BudgetLimit $budgetLimit
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereBudgetLimitId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereStartdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereEnddate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereAmount($value)
|
||||
* @property-read BudgetLimit $budgetLimit
|
||||
*/
|
||||
class LimitRepetition extends Model
|
||||
{
|
||||
|
||||
@@ -2,25 +2,20 @@
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Zizaco\Entrust\EntrustPermission;
|
||||
|
||||
/**
|
||||
* Class Permission
|
||||
* FireflyIII\Models\Permission
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property string $name
|
||||
* @property string $display_name
|
||||
* @property string $description
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\Config::get('entrust.role[] $roles
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Permission whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Permission whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Permission whereDisplayName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Permission whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Permission whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Permission whereUpdatedAt($value)
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property-read Collection|Role[] $roles
|
||||
*/
|
||||
class Permission extends EntrustPermission
|
||||
{
|
||||
|
||||
@@ -1,43 +1,30 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class PiggyBank
|
||||
* FireflyIII\Models\PiggyBank
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property integer $account_id
|
||||
* @property string $name
|
||||
* @property float $targetamount
|
||||
* @property \Carbon\Carbon $startdate
|
||||
* @property \Carbon\Carbon $targetdate
|
||||
* @property Carbon $startdate
|
||||
* @property Carbon $targetdate
|
||||
* @property integer $order
|
||||
* @property boolean $encrypted
|
||||
* @property boolean $remind_me
|
||||
* @property integer $reminder_skip
|
||||
* @property-read \FireflyIII\Models\Account $account
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankRepetition[] $piggyBankRepetitions
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankEvent[] $piggyBankEvents
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereAccountId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereTargetamount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereStartdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereTargetdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereOrder($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereEncrypted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereRemindMe($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereReminderSkip($value)
|
||||
* @property-read \FireflyIII\Models\PiggyBankRepetition $currentRep
|
||||
* @property-read Account $account
|
||||
* @property-read Collection|PiggyBankRepetition[] $piggyBankRepetitions
|
||||
* @property-read Collection|PiggyBankEvent[] $piggyBankEvents
|
||||
*/
|
||||
class PiggyBank extends Model
|
||||
{
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class PiggyBankEvent
|
||||
* FireflyIII\Models\PiggyBankEvent
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $piggy_bank_id
|
||||
* @property integer $transaction_journal_id
|
||||
* @property \Carbon\Carbon $date
|
||||
* @property Carbon $date
|
||||
* @property float $amount
|
||||
* @property-read \FireflyIII\Models\PiggyBank $piggyBank
|
||||
* @property-read \FireflyIII\Models\TransactionJournal $transactionJournal
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent wherePiggyBankId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent whereTransactionJournalId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent whereDate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankEvent whereAmount($value)
|
||||
* @property PiggyBank $piggyBank
|
||||
* @property-read TransactionJournal $transactionJournal
|
||||
*/
|
||||
class PiggyBankEvent extends Model
|
||||
{
|
||||
@@ -32,6 +25,7 @@ class PiggyBankEvent extends Model
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
/** @noinspection PhpMissingParentCallCommonInspection */
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'date'];
|
||||
|
||||
@@ -3,28 +3,21 @@
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
/**
|
||||
* Class PiggyBankRepetition
|
||||
* FireflyIII\Models\PiggyBankRepetition
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $piggy_bank_id
|
||||
* @property \Carbon\Carbon $startdate
|
||||
* @property \Carbon\Carbon $targetdate
|
||||
* @property Carbon $startdate
|
||||
* @property Carbon $targetdate
|
||||
* @property float $currentamount
|
||||
* @property-read \FireflyIII\Models\PiggyBank $piggyBank
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition wherePiggyBankId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition whereStartdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition whereTargetdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition whereCurrentamount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition onDates($start, $target)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBankRepetition relevantOnDate($date)
|
||||
* @property-read PiggyBank $piggyBank
|
||||
* @method static Builder|PiggyBankRepetition onDates($start, $target)
|
||||
* @method static Builder|PiggyBankRepetition relevantOnDate($date)
|
||||
*/
|
||||
class PiggyBankRepetition extends Model
|
||||
{
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class Preference
|
||||
* FireflyIII\Models\Preference
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property integer $user_id
|
||||
* @property string $name
|
||||
* @property string $name_encrypted
|
||||
* @property string $data
|
||||
* @property string $data_encrypted
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereNameEncrypted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereData($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereDataEncrypted($value)
|
||||
* @property-read User $user
|
||||
*/
|
||||
class Preference extends Model
|
||||
{
|
||||
|
||||
@@ -2,26 +2,21 @@
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Zizaco\Entrust\EntrustRole;
|
||||
|
||||
/**
|
||||
* Class Role
|
||||
* FireflyIII\Models\Role
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property string $name
|
||||
* @property string $display_name
|
||||
* @property string $description
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\Config::get('auth.model[] $users
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\Config::get('entrust.permission[] $perms
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Role whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Role whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Role whereDisplayName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Role whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Role whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Role whereUpdatedAt($value)
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property-read Collection|\FireflyIII\User[] $users
|
||||
* @property-read Collection|Permission[] $perms
|
||||
*/
|
||||
class Role extends EntrustRole
|
||||
{
|
||||
|
||||
@@ -2,40 +2,30 @@
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class Tag
|
||||
* FireflyIII\Models\Tag
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property string $deleted_at
|
||||
* @property integer $user_id
|
||||
* @property string $tag
|
||||
* @property string $tagMode
|
||||
* @property \Carbon\Carbon $date
|
||||
* @property Carbon $date
|
||||
* @property string $description
|
||||
* @property float $latitude
|
||||
* @property float $longitude
|
||||
* @property integer $zoomLevel
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereTag($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereTagMode($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereDate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereLatitude($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereLongitude($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Tag whereZoomLevel($value)
|
||||
* @property-read Collection|TransactionJournal[] $transactionjournals
|
||||
* @property-read User $user
|
||||
*/
|
||||
class Tag extends Model
|
||||
{
|
||||
@@ -54,8 +44,6 @@ class Tag extends Model
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
*
|
||||
* @return Tag|null
|
||||
*/
|
||||
@@ -64,7 +52,7 @@ class Tag extends Model
|
||||
// everything but the tag:
|
||||
unset($fields['tagMode']);
|
||||
$search = $fields;
|
||||
unset($search['name']);
|
||||
unset($search['tag']);
|
||||
|
||||
$query = Tag::orderBy('id');
|
||||
foreach ($search as $name => $value) {
|
||||
|
||||
@@ -4,34 +4,24 @@ use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class Transaction
|
||||
* FireflyIII\Models\Transaction
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property integer $account_id
|
||||
* @property integer $transaction_journal_id
|
||||
* @property string $description
|
||||
* @property float $amount
|
||||
* @property-read \FireflyIII\Models\Account $account
|
||||
* @property-read \FireflyIII\Models\TransactionJournal $transactionJournal
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereAccountId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereTransactionJournalId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction whereAmount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction after($date)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Transaction before($date)
|
||||
* @property float $before
|
||||
* @property float $after
|
||||
* @property-read Account $account
|
||||
* @property-read TransactionJournal $transactionJournal
|
||||
* @method static Builder|Transaction after($date)
|
||||
* @method static Builder|Transaction before($date)
|
||||
*/
|
||||
class Transaction extends Model
|
||||
{
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class TransactionCurrency
|
||||
* FireflyIII\Models\TransactionCurrency
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property string $code
|
||||
* @property string $name
|
||||
* @property string $symbol
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionJournals
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereCode($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionCurrency whereSymbol($value)
|
||||
* @property-read Collection|TransactionJournal[] $transactionJournals
|
||||
*/
|
||||
class TransactionCurrency extends Model
|
||||
{
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class TransactionGroup
|
||||
* FireflyIII\Models\TransactionGroup
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property integer $user_id
|
||||
* @property string $relation
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionGroup whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionGroup whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionGroup whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionGroup whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionGroup whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionGroup whereRelation($value)
|
||||
* @property-read Collection|TransactionJournal[] $transactionjournals
|
||||
* @property-read User $user
|
||||
*/
|
||||
class TransactionGroup extends Model
|
||||
{
|
||||
|
||||
@@ -3,71 +3,53 @@
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class TransactionJournal
|
||||
* FireflyIII\Models\TransactionJournal
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property integer $user_id
|
||||
* @property integer $transaction_type_id
|
||||
* @property integer $bill_id
|
||||
* @property integer $transaction_currency_id
|
||||
* @property string $description
|
||||
* @property boolean $completed
|
||||
* @property \Carbon\Carbon $date
|
||||
* @property Carbon $date
|
||||
* @property boolean $encrypted
|
||||
* @property integer $order
|
||||
* @property integer $tag_count
|
||||
* @property-read \FireflyIII\Models\Bill $bill
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Category[] $categories
|
||||
* @property-read mixed $actual_amount
|
||||
* @property-read Bill $bill
|
||||
* @property-read Collection|Budget[] $budgets
|
||||
* @property-read Collection|Category[] $categories
|
||||
* @property-read mixed $amount_positive
|
||||
* @property-read mixed $amount
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Tag[] $tags
|
||||
* @property-read mixed $correct_amount
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Transaction[] $transactions
|
||||
* @property-read Collection|Tag[] $tags
|
||||
* @property-read Collection|Transaction[] $transactions
|
||||
* @property-read mixed $destination_account
|
||||
* @property-read mixed $source_account
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBankEvent[] $piggyBankEvents
|
||||
* @property-read \FireflyIII\Models\TransactionCurrency $transactionCurrency
|
||||
* @property-read \FireflyIII\Models\TransactionType $transactionType
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionGroup[] $transactiongroups
|
||||
* @property-read \FireflyIII\User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereTransactionTypeId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereBillId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereTransactionCurrencyId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereCompleted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereDate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereEncrypted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereOrder($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal whereTagCount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal accountIs($account)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal after($date)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal before($date)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal onDate($date)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal transactionTypes($types)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionJournal withRelevantData()
|
||||
* @property-read bool $account_encrypted
|
||||
* @property-read bool $joinedTransactions
|
||||
* @property-read bool $joinedTransactionTypes
|
||||
* @property-read int $account_id
|
||||
* @property-read string $name
|
||||
* @property-read string $symbol
|
||||
* @property-read Collection|PiggyBankEvent[] $piggyBankEvents
|
||||
* @property-read Collection|Attachment[] $attachments
|
||||
* @property-read TransactionCurrency $transactionCurrency
|
||||
* @property-read TransactionType $transactionType
|
||||
* @property-read Collection|TransactionGroup[] $transactiongroups
|
||||
* @property-read User $user
|
||||
* @method static Builder|TransactionJournal accountIs($account)
|
||||
* @method static Builder|TransactionJournal after($date)
|
||||
* @method static Builder|TransactionJournal before($date)
|
||||
* @method static Builder|TransactionJournal onDate($date)
|
||||
* @method static Builder|TransactionJournal transactionTypes($types)
|
||||
* @method static Builder|TransactionJournal withRelevantData()
|
||||
*/
|
||||
class TransactionJournal extends Model
|
||||
{
|
||||
@@ -119,7 +101,7 @@ class TransactionJournal extends Model
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getActualAmountAttribute()
|
||||
public function getAmountPositiveAttribute()
|
||||
{
|
||||
$amount = '0';
|
||||
/** @var Transaction $t */
|
||||
@@ -145,18 +127,10 @@ class TransactionJournal extends Model
|
||||
}
|
||||
|
||||
bcscale(2);
|
||||
$set = $this->transactions->sortByDesc('amount');
|
||||
$amount = $set->first()->amount;
|
||||
|
||||
if (intval($this->tag_count) === 1) {
|
||||
// get amount for single tag:
|
||||
$amount = $this->amountByTag($this->tags()->first(), $amount);
|
||||
}
|
||||
|
||||
if (intval($this->tag_count) > 1) {
|
||||
// get amount for either tag.
|
||||
$amount = $this->amountByTags($amount);
|
||||
|
||||
$transaction = $this->transactions->sortByDesc('amount')->first();
|
||||
$amount = $transaction->amount;
|
||||
if ($this->isWithdrawal()) {
|
||||
$amount = $amount * -1;
|
||||
}
|
||||
$cache->store($amount);
|
||||
|
||||
@@ -172,15 +146,15 @@ class TransactionJournal extends Model
|
||||
*/
|
||||
protected function amountByTagAdvancePayment(Tag $tag, $amount)
|
||||
{
|
||||
if ($this->transactionType->type == 'Withdrawal') {
|
||||
$others = $tag->transactionJournals()->transactionTypes(['Deposit'])->get();
|
||||
if ($this->isWithdrawal()) {
|
||||
$others = $tag->transactionJournals()->transactionTypes([TransactionType::DEPOSIT])->get();
|
||||
foreach ($others as $other) {
|
||||
$amount = bcsub($amount, $other->actual_amount);
|
||||
$amount = bcsub($amount, $other->amount_positive);
|
||||
}
|
||||
|
||||
return $amount;
|
||||
}
|
||||
if ($this->transactionType->type == 'Deposit') {
|
||||
if ($this->isDeposit()) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
@@ -195,10 +169,10 @@ class TransactionJournal extends Model
|
||||
*/
|
||||
protected function amountByTagBalancingAct($tag, $amount)
|
||||
{
|
||||
if ($this->transactionType->type == 'Withdrawal') {
|
||||
$transfer = $tag->transactionJournals()->transactionTypes(['Transfer'])->first();
|
||||
if ($this->isWithdrawal()) {
|
||||
$transfer = $tag->transactionJournals()->transactionTypes([TransactionType::TRANSFER])->first();
|
||||
if ($transfer) {
|
||||
$amount = bcsub($amount, $transfer->actual_amount);
|
||||
$amount = bcsub($amount, $transfer->amount_positive);
|
||||
|
||||
return $amount;
|
||||
}
|
||||
@@ -259,21 +233,6 @@ class TransactionJournal extends Model
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCorrectAmountAttribute()
|
||||
{
|
||||
|
||||
switch ($this->transactionType->type) {
|
||||
case 'Deposit':
|
||||
return $this->transactions()->where('amount', '>', 0)->first()->amount;
|
||||
case 'Withdrawal':
|
||||
return $this->transactions()->where('amount', '<', 0)->first()->amount;
|
||||
}
|
||||
|
||||
return $this->transactions()->where('amount', '>', 0)->first()->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
@@ -467,6 +426,14 @@ class TransactionJournal extends Model
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
*/
|
||||
public function attachments()
|
||||
{
|
||||
return $this->morphMany('FireflyIII\Models\Attachment', 'attachable');
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
@@ -503,4 +470,59 @@ class TransactionJournal extends Model
|
||||
return $this->belongsTo('FireflyIII\User');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTransactionType()
|
||||
{
|
||||
return $this->transactionType->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWithdrawal()
|
||||
{
|
||||
if (!is_null($this->type)) {
|
||||
return $this->type == TransactionType::WITHDRAWAL;
|
||||
}
|
||||
|
||||
return $this->transactionType->isWithdrawal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeposit()
|
||||
{
|
||||
if (!is_null($this->type)) {
|
||||
return $this->type == TransactionType::DEPOSIT;
|
||||
}
|
||||
|
||||
return $this->transactionType->isDeposit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTransfer()
|
||||
{
|
||||
if (!is_null($this->type)) {
|
||||
return $this->type == TransactionType::TRANSFER;
|
||||
}
|
||||
|
||||
return $this->transactionType->isTransfer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOpeningBalance()
|
||||
{
|
||||
if (!is_null($this->type)) {
|
||||
return $this->type == TransactionType::OPENING_BALANCE;
|
||||
}
|
||||
|
||||
return $this->transactionType->isOpeningBalance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class TransactionRelation
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
*/
|
||||
class TransactionRelation extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +1,29 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class TransactionType
|
||||
* FireflyIII\Models\TransactionType
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Carbon $deleted_at
|
||||
* @property string $type
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionJournals
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionType whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionType whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionType whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionType whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\TransactionType whereType($value)
|
||||
* @property-read Collection|TransactionJournal[] $transactionJournals
|
||||
*/
|
||||
class TransactionType extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
const WITHDRAWAL = 'Withdrawal';
|
||||
const DEPOSIT = 'Deposit';
|
||||
const TRANSFER = 'Transfer';
|
||||
const OPENING_BALANCE = 'Opening balance';
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -31,6 +32,38 @@ class TransactionType extends Model
|
||||
return ['created_at', 'updated_at', 'deleted_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeposit()
|
||||
{
|
||||
return $this->type === TransactionType::DEPOSIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOpeningBalance()
|
||||
{
|
||||
return $this->type === TransactionType::OPENING_BALANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTransfer()
|
||||
{
|
||||
return $this->type === TransactionType::TRANSFER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWithdrawal()
|
||||
{
|
||||
return $this->type === TransactionType::WITHDRAWAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,6 @@ class ConfigServiceProvider extends ServiceProvider
|
||||
* to overwrite any "vendor" or package configuration that you may want to
|
||||
* modify before the application handles the incoming request / command.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
@@ -83,18 +83,22 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind('FireflyIII\Repositories\Account\AccountRepositoryInterface', 'FireflyIII\Repositories\Account\AccountRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Budget\BudgetRepositoryInterface', 'FireflyIII\Repositories\Budget\BudgetRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Category\CategoryRepositoryInterface', 'FireflyIII\Repositories\Category\CategoryRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface', 'FireflyIII\Repositories\Category\SingleCategoryRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Journal\JournalRepositoryInterface', 'FireflyIII\Repositories\Journal\JournalRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Bill\BillRepositoryInterface', 'FireflyIII\Repositories\Bill\BillRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Tag\TagRepositoryInterface', 'FireflyIII\Repositories\Tag\TagRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface', 'FireflyIII\Repositories\Attachment\AttachmentRepository');
|
||||
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
|
||||
|
||||
// CSV import
|
||||
$this->app->bind('FireflyIII\Helpers\Csv\WizardInterface', 'FireflyIII\Helpers\Csv\Wizard');
|
||||
|
||||
// attachments
|
||||
$this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper');
|
||||
|
||||
// make charts:
|
||||
// alternative is Google instead of ChartJs
|
||||
$this->app->bind('FireflyIII\Generator\Chart\Account\AccountChartGenerator', 'FireflyIII\Generator\Chart\Account\ChartJsAccountChartGenerator');
|
||||
$this->app->bind('FireflyIII\Generator\Chart\Bill\BillChartGenerator', 'FireflyIII\Generator\Chart\Bill\ChartJsBillChartGenerator');
|
||||
$this->app->bind('FireflyIII\Generator\Chart\Budget\BudgetChartGenerator', 'FireflyIII\Generator\Chart\Budget\ChartJsBudgetChartGenerator');
|
||||
|
||||
@@ -39,6 +39,8 @@ class RouteServiceProvider extends ServiceProvider
|
||||
*
|
||||
* @param \Illuminate\Routing\Router $router
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function map(Router $router)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user