mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-16 10:54:39 +00:00
Compare commits
588 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b2b82124e6 | ||
|
43669648ce | ||
|
3b73b416d5 | ||
|
5153591c8f | ||
|
3172bc90da | ||
|
76a1b2cd51 | ||
|
bdf7eee72f | ||
|
2d4b148b2c | ||
|
d67db74ca2 | ||
|
516725456f | ||
|
001d72a484 | ||
|
c555e28988 | ||
|
af13d1943f | ||
|
52df2edc8f | ||
|
cd08484a13 | ||
|
f38d38f139 | ||
|
93b6c68938 | ||
|
a4cc25175a | ||
|
3fb14b4708 | ||
|
6bdb6db330 | ||
|
d05c165ace | ||
|
ab53cdb896 | ||
|
c1f142af78 | ||
|
6e261abb73 | ||
|
39af9e4414 | ||
|
5b50abb2c7 | ||
|
13bda0a264 | ||
|
1658c666ab | ||
|
170aebfe54 | ||
|
c4ef379d0e | ||
|
18b038d8ff | ||
|
12ee5da872 | ||
|
601f9f86bb | ||
|
d7329a5915 | ||
|
9e7b730002 | ||
|
2d59d845bc | ||
|
c2645894e0 | ||
|
3751106317 | ||
|
60bb639351 | ||
|
74c50930bd | ||
|
9105104303 | ||
|
540dde135e | ||
|
f8936210cf | ||
|
1dc6d8de40 | ||
|
1069db3c13 | ||
|
65122f0144 | ||
|
d2c018f7da | ||
|
46493c2af6 | ||
|
c303e03f76 | ||
|
d8b65f62e7 | ||
|
854368a8f3 | ||
|
7653a34aea | ||
|
ee50b58e00 | ||
|
1eb60ab100 | ||
|
4a20eef351 | ||
|
26c9b2c353 | ||
|
16374bce9b | ||
|
86011d4ea2 | ||
|
fcb8b02da9 | ||
|
571165c2bb | ||
|
c842113610 | ||
|
974a8b3b70 | ||
|
2e20c99ada | ||
|
aa88ff6f2c | ||
|
5e6aa63d03 | ||
|
ad6700c114 | ||
|
f08c6efb00 | ||
|
cc807ec132 | ||
|
24e7c68243 | ||
|
ab25edd37a | ||
|
be47fde6c2 | ||
|
1ffa8c5e72 | ||
|
d855ccb8a7 | ||
|
d88919474b | ||
|
e139664301 | ||
|
5adf5f6e3f | ||
|
aef2075c8e | ||
|
922b2962a3 | ||
|
b4a401700e | ||
|
e9601bb9c1 | ||
|
58af3dc6ea | ||
|
074295df61 | ||
|
ec349b31c7 | ||
|
5ae236e016 | ||
|
d7c5897aba | ||
|
5252e7efe7 | ||
|
fc7d65629a | ||
|
f28fdf8252 | ||
|
5d07c4a949 | ||
|
fdd9eaab4b | ||
|
e0d863a46f | ||
|
3aacb6f5f3 | ||
|
428e331b3e | ||
|
847e05e9a7 | ||
|
087eb5dbe6 | ||
|
f15932b2ac | ||
|
d3a4c3795d | ||
|
b15d55e1d9 | ||
|
4f5889cc5b | ||
|
bf2a104a4e | ||
|
0c6dd5cd16 | ||
|
5efb06a7aa | ||
|
b13acef272 | ||
|
cfa67d6c0f | ||
|
e70444f19a | ||
|
0258982e60 | ||
|
70eed5cb5e | ||
|
a650fa51f7 | ||
|
cb205580d8 | ||
|
f9329aac00 | ||
|
745f4a7523 | ||
|
60254dafd7 | ||
|
a8d60388ba | ||
|
83ec60254c | ||
|
c15c45f765 | ||
|
cbe52b5089 | ||
|
e4e2921f3e | ||
|
4673170531 | ||
|
2c2ed26c38 | ||
|
94be5244fe | ||
|
f137a08493 | ||
|
48624d0a34 | ||
|
4cceb3ddaa | ||
|
f728395603 | ||
|
3e82d43807 | ||
|
2194c4e0a9 | ||
|
c581080f3f | ||
|
f6b1ec27e5 | ||
|
368b183230 | ||
|
9028ad36ad | ||
|
6cc041cd39 | ||
|
63ff01e78d | ||
|
9e5484937e | ||
|
b8ed489b14 | ||
|
765152d04b | ||
|
14934367d8 | ||
|
04164500c8 | ||
|
5160f2c298 | ||
|
124c9303b9 | ||
|
cd27f0ad69 | ||
|
a7555bcce3 | ||
|
6b5c4fd3f4 | ||
|
cc55e2acee | ||
|
1511f75a80 | ||
|
f01bbefc1f | ||
|
1d1eb5ffa8 | ||
|
a465cb2191 | ||
|
42d13e02ef | ||
|
d00786c43f | ||
|
4b47f99829 | ||
|
35aaf40003 | ||
|
cc5b4a1e02 | ||
|
7079521e8c | ||
|
b5025560a5 | ||
|
3f4bdd7f0e | ||
|
e94bb9b549 | ||
|
1ddaacbef5 | ||
|
e8b40518e0 | ||
|
0f88cbb41b | ||
|
780d137b76 | ||
|
ad8a9717d1 | ||
|
9d6ea6b2f6 | ||
|
7559383089 | ||
|
f84381c927 | ||
|
cb0122a43f | ||
|
6776b20989 | ||
|
e98d556022 | ||
|
5bf18b69d7 | ||
|
ea17f045a7 | ||
|
526f565ea7 | ||
|
4aff9d6e73 | ||
|
bf516d4d21 | ||
|
ae92e409d9 | ||
|
4d017dc8a9 | ||
|
707f4e2965 | ||
|
1c3bffdc50 | ||
|
e54ddcb8b0 | ||
|
ddefb0debc | ||
|
92d8dde90d | ||
|
1bb0508ddf | ||
|
a280a326b9 | ||
|
683e9b7c2c | ||
|
a44e5da421 | ||
|
8cd2c90ad7 | ||
|
5e57a390a2 | ||
|
620848272e | ||
|
1e86794416 | ||
|
e36717259b | ||
|
75b9238b90 | ||
|
ce5b20027e | ||
|
0de1242c83 | ||
|
8bd445ab19 | ||
|
fdef0de163 | ||
|
b1b03a4325 | ||
|
0587d96474 | ||
|
c2241567e4 | ||
|
7ac24ba418 | ||
|
c933ffec66 | ||
|
e587d934b1 | ||
|
f354e90656 | ||
|
1b0bc7ec6e | ||
|
ee1acb9c00 | ||
|
06862a2812 | ||
|
5fa87e18db | ||
|
77989e2720 | ||
|
3a1102fa4e | ||
|
8a9974ce53 | ||
|
4be8f1ca03 | ||
|
1ec2970ee3 | ||
|
81b3a22606 | ||
|
f81a475cc9 | ||
|
d7ee03d4f9 | ||
|
c1c06410c2 | ||
|
657d16bb60 | ||
|
e65a4c1010 | ||
|
e23d3f5661 | ||
|
e13611f7af | ||
|
596cd09489 | ||
|
0be5b27d34 | ||
|
a27471ae55 | ||
|
e27e3622a8 | ||
|
e95273b72b | ||
|
583d4f3249 | ||
|
d6967c4516 | ||
|
40b3097374 | ||
|
1a1f127993 | ||
|
a0f34a7ce1 | ||
|
db020db34b | ||
|
681167bc1b | ||
|
40e49ffc37 | ||
|
834b1afb38 | ||
|
62d5a1da87 | ||
|
8d8308e557 | ||
|
e1aa63487a | ||
|
b7fbe110d4 | ||
|
58859eb35a | ||
|
4b7e1ae1c6 | ||
|
3a06a6ac07 | ||
|
db0f269dc8 | ||
|
3cabe6ca5a | ||
|
d483005219 | ||
|
fea9bc4e7e | ||
|
d579992c98 | ||
|
ad1c61d959 | ||
|
bb1da31830 | ||
|
a50949e554 | ||
|
14dce8a10b | ||
|
1240c8f685 | ||
|
cc7c2e952c | ||
|
409ec2e086 | ||
|
a7f6848e53 | ||
|
4b0b79199d | ||
|
d1d6c48d9b | ||
|
21631780bb | ||
|
b935e32340 | ||
|
72dd064932 | ||
|
2e75446665 | ||
|
be17e4481e | ||
|
616c849b1f | ||
|
71947c097f | ||
|
546787802d | ||
|
294d0e388a | ||
|
193a1b0325 | ||
|
12743217a2 | ||
|
b252b9da66 | ||
|
cdef9c3c7e | ||
|
71dcebb744 | ||
|
25f248c60a | ||
|
d5cbc17831 | ||
|
7a10217511 | ||
|
7559efab77 | ||
|
8254efbd03 | ||
|
4ae24225a5 | ||
|
67d9154563 | ||
|
ad0319c188 | ||
|
eb650ea3ec | ||
|
7eba33e805 | ||
|
e1cb9d387e | ||
|
2ace7c3ca0 | ||
|
58014f0592 | ||
|
1d4938bb09 | ||
|
bbf4007c3e | ||
|
4d5124fb4c | ||
|
14a7cd05b1 | ||
|
946be80eef | ||
|
9ad8b1a980 | ||
|
f733216fcb | ||
|
ffc6139e21 | ||
|
571cac6644 | ||
|
2738ac5a5c | ||
|
7dfde51b84 | ||
|
2d2f18e538 | ||
|
3af0dd2e3b | ||
|
349e077802 | ||
|
812aae358f | ||
|
c3c59d0627 | ||
|
89518b412d | ||
|
f43b026162 | ||
|
b806c70f52 | ||
|
10bff3c0b8 | ||
|
65c12fd0b2 | ||
|
50f71c4130 | ||
|
8e401a53dc | ||
|
64a289a47c | ||
|
8f2c37061b | ||
|
39f2de6b90 | ||
|
855ba8d4f3 | ||
|
74f098e718 | ||
|
56c8a84691 | ||
|
8bbf319032 | ||
|
afbca4ae65 | ||
|
0ef6d2f91a | ||
|
fbe4435599 | ||
|
34be565dd1 | ||
|
af838e4ed1 | ||
|
60fe8ce011 | ||
|
8ece341467 | ||
|
dfa6bdbcb8 | ||
|
fb2481ebaa | ||
|
4874c116cf | ||
|
e19c44efbd | ||
|
4b687b9bdc | ||
|
6af79ef601 | ||
|
352b996ad2 | ||
|
4a93bb35f8 | ||
|
8e1f493daf | ||
|
59ee153375 | ||
|
60f7f1fc16 | ||
|
b7433683d8 | ||
|
42799b9273 | ||
|
860a0f790e | ||
|
8daccbfbb4 | ||
|
285b77dcb7 | ||
|
6e48827d3f | ||
|
f0c20cc706 | ||
|
8916c0a3de | ||
|
7193a77840 | ||
|
61930b5b51 | ||
|
11a494cacf | ||
|
17f9bf0339 | ||
|
3d9755ca8c | ||
|
b5cf2d03e6 | ||
|
e3b35b8f35 | ||
|
1c1fe672bd | ||
|
6c71f68ed8 | ||
|
8f2f912cdf | ||
|
bf6ea16acb | ||
|
288546c2b9 | ||
|
724db6c34c | ||
|
067c451c1d | ||
|
11e3696191 | ||
|
41e20664de | ||
|
d8de90d6f3 | ||
|
b01e8299d3 | ||
|
1ec11e3e2e | ||
|
422f429725 | ||
|
5c55fa5fbb | ||
|
80d845fdf2 | ||
|
601fe68346 | ||
|
9e050fb059 | ||
|
99d4adf5e6 | ||
|
85f8d1e8e9 | ||
|
8334d3d99f | ||
|
cff08d19eb | ||
|
2d86390bc1 | ||
|
7a20835571 | ||
|
ff3c9676b5 | ||
|
055f97dab1 | ||
|
8a867e71a1 | ||
|
b8275b4734 | ||
|
36b951b146 | ||
|
c5a5f17643 | ||
|
16b909c4df | ||
|
92b7648e03 | ||
|
ca46ebe3b2 | ||
|
676e48254a | ||
|
b15b55227d | ||
|
3c3b723913 | ||
|
f05002c729 | ||
|
1c2cbd5b40 | ||
|
54c6ca9f45 | ||
|
c10efbb170 | ||
|
a496ad5814 | ||
|
50cf7f6a3b | ||
|
f946f10afd | ||
|
eecb4db34c | ||
|
1f865d3ea4 | ||
|
623bb4b350 | ||
|
dc8ad673a6 | ||
|
4914ad821e | ||
|
f099cbadc3 | ||
|
42cda384c8 | ||
|
23c91b9990 | ||
|
ff0379182e | ||
|
e08a23948f | ||
|
bd56de6d36 | ||
|
42970aea80 | ||
|
003a05ee8d | ||
|
ffb11b01a6 | ||
|
e426f5d5da | ||
|
6989f61e1b | ||
|
0e6677ccb3 | ||
|
8f104d555a | ||
|
b1d3158db1 | ||
|
7645005d5a | ||
|
411f77fd29 | ||
|
568ab26db1 | ||
|
29652108f0 | ||
|
f07e4dc711 | ||
|
8a2ac457c2 | ||
|
9e54eecfaa | ||
|
95ef691077 | ||
|
7a0ad5a587 | ||
|
42b49d0e4b | ||
|
9217c2f003 | ||
|
fbdf66998d | ||
|
deda9d3c54 | ||
|
a5d78f20ae | ||
|
5ed09e3f38 | ||
|
3e9774cd66 | ||
|
54387c8fdf | ||
|
7eec949a13 | ||
|
4113c4ff40 | ||
|
1bf0968bfe | ||
|
374b90fb00 | ||
|
064e60e9d5 | ||
|
b637455970 | ||
|
68158937d1 | ||
|
adb1356b7a | ||
|
d880ccb8e0 | ||
|
050fb1d1ef | ||
|
6580752bde | ||
|
c9df265c9b | ||
|
098e5bc162 | ||
|
4b2dcc74d4 | ||
|
a9254c5c9a | ||
|
7ce57e6ccb | ||
|
0fcb32a66f | ||
|
9946535f01 | ||
|
2b17396d6b | ||
|
b01d5bc237 | ||
|
b123860304 | ||
|
033f5b67db | ||
|
6280448dfb | ||
|
01cd3333e4 | ||
|
63050907b9 | ||
|
beedf7d780 | ||
|
6b8194261f | ||
|
dbb1c4d534 | ||
|
e6263f9ff5 | ||
|
6ca119c4db | ||
|
c483a1ab3a | ||
|
2e7edd033c | ||
|
c576902501 | ||
|
66c2951594 | ||
|
b812881cdb | ||
|
cdeac2c6db | ||
|
bca2ddd529 | ||
|
e7285c6499 | ||
|
bdff275672 | ||
|
bec58a1ee6 | ||
|
f64616748c | ||
|
512ce15973 | ||
|
ed8b301574 | ||
|
d22a6c019c | ||
|
a0cb1b9d9e | ||
|
a5294c62ea | ||
|
e155d3311c | ||
|
0a372b0daf | ||
|
69143399d1 | ||
|
3270d3bf96 | ||
|
3896a66122 | ||
|
b94781aef1 | ||
|
bed1adc367 | ||
|
ae54497efa | ||
|
06b747c221 | ||
|
f159beee0d | ||
|
49d7dea086 | ||
|
3e65733dc5 | ||
|
cc375d58bb | ||
|
911c7c662a | ||
|
aae003be33 | ||
|
aede03d8b2 | ||
|
f0f5ada7de | ||
|
58365121a3 | ||
|
d5a154d2e6 | ||
|
b20f369aef | ||
|
abb8aa0b29 | ||
|
5368a0f1d7 | ||
|
d3897eece7 | ||
|
a82b829da9 | ||
|
9f5058e81a | ||
|
5b19263720 | ||
|
9d5a0db0d9 | ||
|
4bd8a7014f | ||
|
353e96d951 | ||
|
149a6f92b0 | ||
|
d66426c137 | ||
|
4fc9966392 | ||
|
417766f0db | ||
|
de9ac97887 | ||
|
6be42f112a | ||
|
3895ae63c7 | ||
|
607d416d54 | ||
|
038693dc86 | ||
|
cc9be13544 | ||
|
9c1474087f | ||
|
831de2bcf4 | ||
|
eb687333bb | ||
|
5cc7966d54 | ||
|
d1a34e7a6f | ||
|
d63d791717 | ||
|
015570c741 | ||
|
8400ebc9c6 | ||
|
9f99e7c0af | ||
|
392c1fc399 | ||
|
d3cea7a89c | ||
|
1dcf7407e6 | ||
|
d543c033a3 | ||
|
aaa186be5e | ||
|
2054b5b3dd | ||
|
98ae5b0ca0 | ||
|
36c8171d0f | ||
|
3603eb94cc | ||
|
0e068d4ccf | ||
|
199f348ff4 | ||
|
b22655fb7c | ||
|
06cc9618ba | ||
|
b9019c8c7f | ||
|
77e133e67c | ||
|
571e7df807 | ||
|
22f4d2979a | ||
|
e46e366694 | ||
|
7b4bc23815 | ||
|
9ca79f767c | ||
|
274dba7408 | ||
|
31708ca29e | ||
|
671b025588 | ||
|
a7956e4856 | ||
|
355862025a | ||
|
a2a39ee0f8 | ||
|
ec8e39c16f | ||
|
88f714999e | ||
|
c0c2aa3be0 | ||
|
822044820e | ||
|
6ffc182142 | ||
|
3d54a78573 | ||
|
8ddf7d953a | ||
|
8b9e9ad103 | ||
|
5737224c40 | ||
|
ec9aacbcae | ||
|
9395454997 | ||
|
66198a8d98 | ||
|
96ed9a4256 | ||
|
10e54b2263 | ||
|
cf00922ad2 | ||
|
84e8e007a5 | ||
|
d07b2e773b | ||
|
506ef7b0b9 | ||
|
2cd5dae8e2 | ||
|
a1cd49c111 | ||
|
aca2973aef | ||
|
0a7a691c95 | ||
|
72906a7afd | ||
|
d1a4a83570 | ||
|
e0396b29e8 | ||
|
536833cfe0 | ||
|
317b02d1b9 | ||
|
75e279ea0d | ||
|
dc2ad21f4c | ||
|
484d49aae1 | ||
|
ca39438ad4 | ||
|
49a65ebff4 | ||
|
befdc05084 | ||
|
1fbffe761b | ||
|
36aad379ff | ||
|
540cfa072e | ||
|
3b049c15cc | ||
|
3e93ed0a17 | ||
|
d7d9358136 | ||
|
5cf0939ff9 | ||
|
8dc6f91d3c | ||
|
a3a25db230 | ||
|
c06f18c815 | ||
|
6802f04036 | ||
|
beeccdf345 | ||
|
58241ed39d | ||
|
6c48afc37b |
25
.codeclimate.yml
Normal file
25
.codeclimate.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
# Save as .codeclimate.yml (note leading .) in project root directory
|
||||
languages:
|
||||
JavaScript: true
|
||||
PHP: true
|
||||
exclude_paths:
|
||||
- "public/packages/maximebf/php-debugbar/debugbar.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets.js"
|
||||
- "public/packages/maximebf/php-debugbar/openhandler.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js"
|
||||
- "public/js/bootstrap3-typeahead.min.js"
|
||||
- "public/js/bootstrap-sortable.js"
|
||||
- "public/js/bootstrap-tagsinput.min.js"
|
||||
- "public/js/bootstrap-tagsinput.min.js.map"
|
||||
- "public/js/daterangepicker.js"
|
||||
- "public/js/jquery-2.1.3.min.js"
|
||||
- "public/js/jquery-2.1.3.min.js.map"
|
||||
- "public/js/jquery-ui.min.js"
|
||||
- "public/js/metisMenu.js"
|
||||
- "public/js/moment.min.js"
|
||||
- "public/js/sb-admin-2.js"
|
||||
- "public/bootstrap/*"
|
||||
- "resources/lang/*"
|
||||
- "tests/*"
|
||||
- "database/*"
|
||||
- "storage/*"
|
@@ -1,3 +1 @@
|
||||
src_dir: .
|
||||
coverage_clover: storage/coverage/clover.xml
|
||||
json_path: storage/coverage/coveralls-upload.json
|
||||
src_dir: .
|
@@ -15,4 +15,7 @@ EMAIL_SMTP=
|
||||
EMAIL_DRIVER=smtp
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=
|
||||
ANALYTICS_ID=
|
||||
EMAIL_PRETEND=false
|
||||
RUNCLEANUP=true
|
||||
SITE_OWNER=mail@example.com
|
@@ -14,4 +14,5 @@ SESSION_DRIVER=array
|
||||
EMAIL_SMTP=
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=ABC
|
||||
ANALYTICS_ID=ABC
|
||||
EMAIL_PRETEND=true
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -31,3 +31,6 @@ addNewLines.php
|
||||
.phpstorm.meta.php
|
||||
.env.backup
|
||||
.env.local
|
||||
|
||||
tests/_output/*
|
||||
tests/_output/*
|
22
.jshintrc
Normal file
22
.jshintrc
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"undef": true,
|
||||
"unused": false,
|
||||
"strict": true,
|
||||
"browser": true,
|
||||
"jquery": true,
|
||||
"devel": true,
|
||||
"globals": [
|
||||
"language",
|
||||
"token",
|
||||
"currencyCode",
|
||||
"$",
|
||||
"token",
|
||||
"accountID",
|
||||
"billID",
|
||||
"currentMonthName",
|
||||
"previousMonthName",
|
||||
"nextMonthName",
|
||||
"everything",
|
||||
"moment"
|
||||
]
|
||||
}
|
3
.scrutinizer.yml
Normal file
3
.scrutinizer.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
# .scrutinizer.yml
|
||||
tools:
|
||||
external_code_coverage: false
|
@@ -6,10 +6,6 @@ php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
|
||||
addons:
|
||||
code_climate:
|
||||
repo_token: 26489f9e854fcdf7e7660ba29c1455694685465b1f90329a79f7d2bf448acb61
|
||||
|
||||
install:
|
||||
- composer update
|
||||
- php artisan env
|
||||
@@ -17,6 +13,3 @@ install:
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
|
||||
after_script:
|
||||
- php vendor/bin/coveralls
|
||||
|
141
README.md
141
README.md
@@ -1,82 +1,115 @@
|
||||
Firefly III (v3.4.0.2)
|
||||
===========
|
||||
# Firefly III
|
||||
|
||||
[](https://travis-ci.org/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](https://coveralls.io/r/JC5/firefly-iii?branch=master)
|
||||
[](https://coveralls.io/r/JC5/firefly-iii?branch=develop)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
|
||||
|
||||
Firefly III is a tool to help you manage your finances. Please read the full description [in the wiki](https://github.com/JC5/firefly-iii/wiki/full-description).
|
||||
## About
|
||||
|
||||
Firefly Mark III is a new version of Firefly built upon best practices and lessons learned
|
||||
from building [Firefly](https://github.com/JC5/Firefly). It's Mark III since the original Firefly never made it outside of my
|
||||
laptop and [Firefly II](https://github.com/JC5/Firefly) is live.
|
||||
|
||||
If you're not sure if this tool is for you, please read the [full description](https://github.com/JC5/firefly-iii/wiki/full-description).
|
||||
|
||||
To install and use Firefly III, please read [the installation guide](https://github.com/JC5/firefly-iii/wiki/Installation),
|
||||
[the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable) and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**.
|
||||
"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.
|
||||
|
||||
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.
|
||||
_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.
|
||||
- The featurelist below, also on this very page.
|
||||
- The [full description](https://github.com/JC5/firefly-iii/wiki/full-description), which will tell you how Firefly works,
|
||||
and the philosophy behind it.
|
||||
|
||||
|
||||
#### About the name (should you care)
|
||||
|
||||
It's III, or 3, because [version 2](https://github.com/JC5/Firefly) and version 1 (not online) preceded it. It has been growing steadily ever since.
|
||||
|
||||
## Current features
|
||||
|
||||
- [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system);
|
||||
- You can store, edit and remove withdrawals, deposits and transfers. This allows you full financial management;
|
||||
- You can manage different types of accounts
|
||||
- Asset accounts
|
||||
- Shared asset accounts (household accounts)
|
||||
- You can store, edit and remove [withdrawals, deposits and transfers](https://en.wikipedia.org/wiki/Financial_transaction). This allows you full financial management;
|
||||
- You can manage different types of accounts;
|
||||
- [Asset](https://en.wikipedia.org/wiki/Asset) accounts
|
||||
- Shared [asset accounts](https://en.wikipedia.org/wiki/Asset) ([household accounts](https://en.wikipedia.org/wiki/Household))
|
||||
- Saving accounts
|
||||
- Credit cards
|
||||
- It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_;
|
||||
- Organize transactions using categories;
|
||||
- Save towards a goal using piggy banks;
|
||||
- Predict and anticipate bills;
|
||||
- View income / expense reports;
|
||||
- Lots of help text in case you don't get it;
|
||||
- Save towards a goal using [piggy banks](https://en.wikipedia.org/wiki/Piggy_bank);
|
||||
- Predict and anticipate [bills](https://en.wikipedia.org/wiki/Invoice);
|
||||
- View income / expense [reports](https://en.wikipedia.org/wiki/Financial_statement);
|
||||
- Organize expenses using tags;
|
||||
- Lots of help text in case you don't get it.
|
||||
|
||||
Everything is organised:
|
||||
|
||||
- Clear views that should show you how you're doing;
|
||||
- Easy navigation through your records;
|
||||
- Browse back and forth to see previous months or even years;
|
||||
- Lots of charts because we all love them.
|
||||
- Financial reporting showing you how well you are doing;
|
||||
|
||||
## Changes
|
||||
|
||||
Firefly III will feature, but does not feature yet:
|
||||
|
||||
|
||||
- More control over other resources outside of personal finance
|
||||
- Debts
|
||||
- More test-coverage;
|
||||
- Firefly will be able to split transactions; a single purchase can be split in multiple entries, for more fine-grained control.
|
||||
- Firefly will be able to join transactions.
|
||||
- Any other features I might not have thought of.
|
||||
|
||||
Some stuff has been removed:
|
||||
|
||||
- The nesting of budgets, categories and beneficiaries is removed because it was pretty pointless.
|
||||
- Lots of charts because we all love them;
|
||||
- Financial reporting showing you how well you are doing.
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
_Please note that everything in these screenshots is fictional and may not be realistic._
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Running and installing
|
||||
|
||||
If you're still interested please read [the installation guide](https://github.com/JC5/firefly-iii/wiki/Installation),
|
||||
[the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable)
|
||||
and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**.
|
||||
|
||||
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
|
||||
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site.
|
||||
|
||||
## Credits
|
||||
|
||||
Firefly III uses the following libraries and tools:
|
||||
|
||||
* The AdminLTE template by [Almsaseed Studio](https://almsaeedstudio.com/)
|
||||
* The [Google charts](https://developers.google.com/chart/) library.
|
||||
* [Bootstrap](http://getbootstrap.com/)
|
||||
* [Laravel](http://laravel.com/)
|
||||
* [Twig](http://twig.sensiolabs.org/)
|
||||
* For development, some of the excellent tools made by [Barry van den Heuvel](https://github.com/barryvdh)
|
||||
* [Bootstrap sortable](https://github.com/drvic10k/bootstrap-sortable) by [Matúš Brliť](https://github.com/drvic10k).
|
||||
* [Date range picker](https://github.com/dangrossman/bootstrap-daterangepicker/) by [Dan Grossman](https://github.com/dangrossman)
|
||||
* The [real favicon generator](http://realfavicongenerator.net/)
|
||||
* Various other open source components (see [composer.json](https://github.com/JC5/firefly-iii/blob/master/composer.json))
|
||||
|
||||

|
||||
|
||||
## Current state
|
||||
I have the basics up and running. Test coverage is currently coming, slowly.
|
||||
|
||||
Questions, ideas or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. Translations are a work in progress.
|
||||
|
||||
Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
|
||||
If you like this tool, feel free to [donate me some beer money](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2ZMV952UUSCLU&lc=NL&item_name=Development%20of%20Firefly¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted).
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||

|
||||
|
@@ -2,6 +2,7 @@
|
||||
/**
|
||||
* Class Command
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Commands
|
||||
*/
|
||||
abstract class Command
|
||||
|
@@ -6,6 +6,7 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
/**
|
||||
* Class Kernel
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Console
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
@@ -25,6 +26,8 @@ class Kernel extends ConsoleKernel
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
/**
|
||||
* Class Event
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
abstract class Event
|
||||
|
@@ -6,6 +6,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
/**
|
||||
* Class JournalCreated
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalCreated extends Event
|
||||
|
@@ -5,6 +5,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
/**
|
||||
* Class JournalDeleted
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalDeleted extends Event
|
||||
|
@@ -6,6 +6,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
/**
|
||||
* Class JournalSaved
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalSaved extends Event
|
||||
|
@@ -6,6 +6,7 @@ namespace FireflyIII\Exceptions;
|
||||
/**
|
||||
* Class FireflyException
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class FireflyException extends \Exception
|
||||
|
@@ -2,10 +2,12 @@
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
@@ -26,12 +28,13 @@ class Handler extends ExceptionHandler
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
{
|
||||
if ($this->isHttpException($e)) {
|
||||
if ($e instanceof HttpException) {
|
||||
return $this->renderHttpException($e);
|
||||
} else {
|
||||
return parent::render($request, $e);
|
||||
@@ -42,6 +45,7 @@ class Handler extends ExceptionHandler
|
||||
* Report or log an exception.
|
||||
*
|
||||
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*
|
||||
* @param \Exception $e
|
||||
*
|
||||
|
@@ -5,6 +5,7 @@ namespace FireflyIII\Exceptions;
|
||||
/**
|
||||
* Class NotImplementedException
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class NotImplementedException extends \Exception
|
||||
|
@@ -4,6 +4,7 @@ namespace FireflyIII\Exceptions;
|
||||
/**
|
||||
* Class ValidationExceptions
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exception
|
||||
*/
|
||||
class ValidationException extends \Exception
|
||||
|
43
app/Generator/Chart/Account/AccountChartGenerator.php
Normal file
43
app/Generator/Chart/Account/AccountChartGenerator.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface AccountChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Account
|
||||
*/
|
||||
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
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end);
|
||||
}
|
115
app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
Normal file
115
app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class ChartJsAccountChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Account
|
||||
*/
|
||||
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)
|
||||
{
|
||||
return $this->frontpage($accounts, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.monthAndDay.' . $language);
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
$current = clone $start;
|
||||
while ($current <= $end) {
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = [
|
||||
'label' => $account->name,
|
||||
'fillColor' => 'rgba(220,220,220,0.2)',
|
||||
'strokeColor' => 'rgba(220,220,220,1)',
|
||||
'pointColor' => 'rgba(220,220,220,1)',
|
||||
'pointStrokeColor' => '#fff',
|
||||
'pointHighlightFill' => '#fff',
|
||||
'pointHighlightStroke' => 'rgba(220,220,220,1)',
|
||||
'data' => [],
|
||||
];
|
||||
$current = clone $start;
|
||||
while ($current <= $end) {
|
||||
$set['data'][] = Steam::balance($account, $current);
|
||||
$current->addDay();
|
||||
}
|
||||
$data['datasets'][] = $set;
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.monthAndDay.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => $account->name,
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$current = clone $start;
|
||||
|
||||
while ($end >= $current) {
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = Steam::balance($account, $current);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
97
app/Generator/Chart/Account/GoogleAccountChartGenerator.php
Normal file
97
app/Generator/Chart/Account/GoogleAccountChartGenerator.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
32
app/Generator/Chart/Bill/BillChartGenerator.php
Normal file
32
app/Generator/Chart/Bill/BillChartGenerator.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BillChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Bill
|
||||
*/
|
||||
interface BillChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $unpaid);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries);
|
||||
|
||||
}
|
114
app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
Normal file
114
app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
use Config;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class ChartJsBillChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Bill
|
||||
*/
|
||||
class ChartJsBillChartGenerator implements BillChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $paid
|
||||
* @param Collection $unpaid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $paid, Collection $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,
|
||||
'color' => 'rgba(53, 124, 165,0.7)',
|
||||
'highlight' => 'rgba(53, 124, 165,0.9)',
|
||||
'label' => trans('firefly.unpaid'),
|
||||
],
|
||||
[
|
||||
'value' => $paidAmount,
|
||||
'color' => 'rgba(0, 141, 76, 0.7)',
|
||||
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
||||
'label' => trans('firefly.paid'),
|
||||
]
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function single(Bill $bill, Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 3,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
// dataset: max amount
|
||||
// dataset: min amount
|
||||
// dataset: actual amount
|
||||
|
||||
$minAmount = [];
|
||||
$maxAmount = [];
|
||||
$actualAmount = [];
|
||||
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);
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.minAmount'),
|
||||
'data' => $minAmount,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.billEntry'),
|
||||
'data' => $actualAmount,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.maxAmount'),
|
||||
'data' => $maxAmount,
|
||||
];
|
||||
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
93
app/Generator/Chart/Bill/GoogleBillChartGenerator.php
Normal file
93
app/Generator/Chart/Bill/GoogleBillChartGenerator.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
43
app/Generator/Chart/Budget/BudgetChartGenerator.php
Normal file
43
app/Generator/Chart/Budget/BudgetChartGenerator.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BudgetChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Budget
|
||||
*/
|
||||
interface BudgetChartGenerator
|
||||
{
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries);
|
||||
|
||||
}
|
144
app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
Normal file
144
app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Budget;
|
||||
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class ChartJsBudgetChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Budget
|
||||
*/
|
||||
class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budget(Collection $entries, $dateFormat = 'month')
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
||||
|
||||
$data = [
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Amount',
|
||||
'data' => [],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = $entry[1];
|
||||
|
||||
}
|
||||
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function budgetLimit(Collection $entries)
|
||||
{
|
||||
return $this->budget($entries, 'monthAndDay');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries)
|
||||
{
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// dataset: left
|
||||
// dataset: spent
|
||||
// dataset: overspent
|
||||
$left = [];
|
||||
$spent = [];
|
||||
$overspent = [];
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) {
|
||||
$data['labels'][] = $entry[0];
|
||||
$left[] = round($entry[1], 2);
|
||||
$spent[] = round($entry[2], 2);
|
||||
$overspent[] = round($entry[3], 2);
|
||||
}
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.left'),
|
||||
'data' => $left,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => $spent,
|
||||
];
|
||||
$data['datasets'][] = [
|
||||
'label' => trans('firefly.overspent'),
|
||||
'data' => $overspent,
|
||||
];
|
||||
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $budgets, Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
|
||||
$data = [
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
|
||||
foreach ($budgets as $budget) {
|
||||
$data['labels'][] = $budget->name;
|
||||
}
|
||||
/** @var array $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$array = [
|
||||
'label' => $entry[0]->formatLocalized($format),
|
||||
'data' => [],
|
||||
];
|
||||
array_shift($entry);
|
||||
$array['data'] = $entry;
|
||||
$data['datasets'][] = $array;
|
||||
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
102
app/Generator/Chart/Budget/GoogleBudgetChartGenerator.php
Normal file
102
app/Generator/Chart/Budget/GoogleBudgetChartGenerator.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
44
app/Generator/Chart/Category/CategoryChartGenerator.php
Normal file
44
app/Generator/Chart/Category/CategoryChartGenerator.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface CategoryChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Category
|
||||
*/
|
||||
interface CategoryChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function month(Collection $entries);
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries);
|
||||
}
|
123
app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
Normal file
123
app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Category;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
|
||||
/**
|
||||
* Class ChartJsCategoryChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Category
|
||||
*/
|
||||
class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
* @param string $dateFormat
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(Collection $entries, $dateFormat = 'month')
|
||||
{
|
||||
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frontpage(Collection $entries)
|
||||
{
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry['sum'] != 0) {
|
||||
$data['labels'][] = $entry['name'];
|
||||
$data['datasets'][0]['data'][] = round($entry['sum'], 2);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function month(Collection $entries)
|
||||
{
|
||||
return $this->all($entries, 'monthAndDay');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function year(Collection $categories, Collection $entries)
|
||||
{
|
||||
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
|
||||
$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;
|
||||
|
||||
}
|
||||
}
|
106
app/Generator/Chart/Category/GoogleCategoryChartGenerator.php
Normal file
106
app/Generator/Chart/Category/GoogleCategoryChartGenerator.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?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();
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
|
||||
/**
|
||||
* Class GooglePiggyBankChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function history(Collection $set)
|
||||
{
|
||||
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 1,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Diff',
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
$sum = '0';
|
||||
bcscale(2);
|
||||
foreach ($set as $entry) {
|
||||
$date = new Carbon($entry->date);
|
||||
$sum = bcadd($sum, $entry->sum);
|
||||
$data['labels'][] = $date->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($sum, 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
20
app/Generator/Chart/PiggyBank/PiggyBankChartGenerator.php
Normal file
20
app/Generator/Chart/PiggyBank/PiggyBankChartGenerator.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\PiggyBank;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface PiggyBankChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\PiggyBank
|
||||
*/
|
||||
interface PiggyBankChartGenerator
|
||||
{
|
||||
/**
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function history(Collection $set);
|
||||
}
|
83
app/Generator/Chart/Report/ChartJsReportChartGenerator.php
Normal file
83
app/Generator/Chart/Report/ChartJsReportChartGenerator.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class GoogleReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries)
|
||||
{
|
||||
// language:
|
||||
$language = Preferences::get('language', 'en')->data;
|
||||
$format = Config::get('firefly.month.' . $language);
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
||||
$data['datasets'][0]['data'][] = round($entry[1], 2);
|
||||
$data['datasets'][1]['data'][] = round($entry[2], 2);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOutSummarized($income, $expense, $count)
|
||||
{
|
||||
|
||||
$data = [
|
||||
'count' => 2,
|
||||
'labels' => [],
|
||||
'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;
|
||||
}
|
||||
}
|
58
app/Generator/Chart/Report/GoogleReportChartGenerator.php
Normal file
58
app/Generator/Chart/Report/GoogleReportChartGenerator.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
31
app/Generator/Chart/Report/ReportChartGenerator.php
Normal file
31
app/Generator/Chart/Report/ReportChartGenerator.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Generator\Chart\Report;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ReportChartGenerator
|
||||
*
|
||||
* @package FireflyIII\Generator\Chart\Report
|
||||
*/
|
||||
interface ReportChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOut(Collection $entries);
|
||||
|
||||
/**
|
||||
* @param string $income
|
||||
* @param string $expense
|
||||
* @param int $count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearInOutSummarized($income, $expense, $count);
|
||||
|
||||
}
|
@@ -4,9 +4,7 @@ use Auth;
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ConnectJournalToPiggyBank
|
||||
@@ -19,6 +17,8 @@ class ConnectJournalToPiggyBank
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -28,69 +28,44 @@ class ConnectJournalToPiggyBank
|
||||
/**
|
||||
* Handle the event when journal is saved.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @param JournalCreated $event
|
||||
*
|
||||
* @return void
|
||||
* @return boolean
|
||||
*/
|
||||
public function handle(JournalCreated $event)
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
if (intval($piggyBankId) < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('JournalCreated event: ' . $journal->id . ', ' . $piggyBankId);
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank) || $journal->transactionType->type != 'Transfer') {
|
||||
return;
|
||||
}
|
||||
Log::debug('Found a piggy bank');
|
||||
$amount = $journal->amount;
|
||||
Log::debug('Amount: ' . $amount);
|
||||
if ($amount == 0) {
|
||||
return;
|
||||
if (is_null($piggyBank)) {
|
||||
return false;
|
||||
}
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
Log::debug('Found no repetition for piggy bank for date ' . $journal->date->format('Y M d'));
|
||||
return false;
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
return;
|
||||
$amount = $journal->actual_amount;
|
||||
// if piggy account matches source account, the amount is positive
|
||||
if ($piggyBank->account_id == $journal->source_account->id) {
|
||||
$amount = $amount * -1;
|
||||
}
|
||||
|
||||
Log::debug('Found rep! ' . $repetition->id);
|
||||
|
||||
/*
|
||||
* Add amount when
|
||||
*/
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
if ($transaction->account_id == $piggyBank->account_id) {
|
||||
if ($transaction->amount < 0) {
|
||||
$amount = $amount * -1;
|
||||
Log::debug('Transaction is away from piggy, so amount becomes ' . $amount);
|
||||
} else {
|
||||
Log::debug('Transaction is to from piggy, so amount stays ' . $amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$repetition->currentamount += $amount;
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $amount);
|
||||
$repetition->save();
|
||||
|
||||
PiggyBankEvent::create(
|
||||
[
|
||||
'piggy_bank_id' => $piggyBank->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'date' => $journal->date,
|
||||
'amount' => $amount
|
||||
]
|
||||
);
|
||||
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
@@ -1,35 +0,0 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\JournalDeleted;
|
||||
|
||||
/**
|
||||
* Class JournalDeletedHandler
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class JournalDeletedHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param JournalDeleted $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(JournalDeleted $event)
|
||||
{
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -7,6 +7,7 @@ use Log;
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class RescanJournal
|
||||
|
@@ -2,10 +2,12 @@
|
||||
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
|
||||
/**
|
||||
* Class UpdateJournalConnection
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UpdateJournalConnection
|
||||
@@ -38,13 +40,17 @@ class UpdateJournalConnection
|
||||
return;
|
||||
}
|
||||
$piggyBank = $event->piggyBank()->first();
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
$repetition = null;
|
||||
if ($piggyBank) {
|
||||
/** @var PiggyBankRepetition $repetition */
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
}
|
||||
|
||||
if (is_null($repetition)) {
|
||||
return;
|
||||
}
|
||||
$amount = $journal->amount;
|
||||
$diff = $amount - $event->amount;// update current repetition
|
||||
$diff = $amount - $event->amount; // update current repetition
|
||||
|
||||
$repetition->currentamount += $diff;
|
||||
$repetition->save();
|
||||
|
90
app/Helpers/Collection/Account.php
Normal file
90
app/Helpers/Collection/Account.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class Account
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Account
|
||||
{
|
||||
|
||||
/** @var Collection */
|
||||
protected $accounts;
|
||||
/** @var float */
|
||||
protected $difference;
|
||||
/** @var float */
|
||||
protected $end;
|
||||
/** @var float */
|
||||
protected $start;
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getAccounts()
|
||||
{
|
||||
return $this->accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Support\Collection $accounts
|
||||
*/
|
||||
public function setAccounts($accounts)
|
||||
{
|
||||
$this->accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getDifference()
|
||||
{
|
||||
return $this->difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $difference
|
||||
*/
|
||||
public function setDifference($difference)
|
||||
{
|
||||
$this->difference = $difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getEnd()
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $end
|
||||
*/
|
||||
public function setEnd($end)
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $start
|
||||
*/
|
||||
public function setStart($start)
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
|
||||
}
|
64
app/Helpers/Collection/Balance.php
Normal file
64
app/Helpers/Collection/Balance.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Balance
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Balance
|
||||
{
|
||||
|
||||
/** @var BalanceHeader */
|
||||
protected $balanceHeader;
|
||||
|
||||
/** @var Collection */
|
||||
protected $balanceLines;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->balanceLines = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BalanceLine $line
|
||||
*/
|
||||
public function addBalanceLine(BalanceLine $line)
|
||||
{
|
||||
$this->balanceLines->push($line);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BalanceHeader
|
||||
*/
|
||||
public function getBalanceHeader()
|
||||
{
|
||||
return $this->balanceHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BalanceHeader $balanceHeader
|
||||
*/
|
||||
public function setBalanceHeader($balanceHeader)
|
||||
{
|
||||
$this->balanceHeader = $balanceHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getBalanceLines()
|
||||
{
|
||||
return $this->balanceLines;
|
||||
}
|
||||
|
||||
|
||||
}
|
74
app/Helpers/Collection/BalanceEntry.php
Normal file
74
app/Helpers/Collection/BalanceEntry.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BalanceEntry
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class BalanceEntry
|
||||
{
|
||||
|
||||
|
||||
/** @var AccountModel */
|
||||
protected $account;
|
||||
/** @var float */
|
||||
protected $left = 0.0;
|
||||
/** @var float */
|
||||
protected $spent = 0.0;
|
||||
|
||||
/**
|
||||
* @return AccountModel
|
||||
*/
|
||||
public function getAccount()
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountModel $account
|
||||
*/
|
||||
public function setAccount($account)
|
||||
{
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getLeft()
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $left
|
||||
*/
|
||||
public function setLeft($left)
|
||||
{
|
||||
$this->left = $left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getSpent()
|
||||
{
|
||||
return $this->spent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $spent
|
||||
*/
|
||||
public function setSpent($spent)
|
||||
{
|
||||
$this->spent = $spent;
|
||||
}
|
||||
|
||||
|
||||
}
|
46
app/Helpers/Collection/BalanceHeader.php
Normal file
46
app/Helpers/Collection/BalanceHeader.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BalanceHeader
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class BalanceHeader
|
||||
{
|
||||
|
||||
/** @var Collection */
|
||||
protected $accounts;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->accounts = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountModel $account
|
||||
*/
|
||||
public function addAccount(AccountModel $account)
|
||||
{
|
||||
$this->accounts->push($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccounts()
|
||||
{
|
||||
return $this->accounts;
|
||||
}
|
||||
|
||||
|
||||
}
|
173
app/Helpers/Collection/BalanceLine.php
Normal file
173
app/Helpers/Collection/BalanceLine.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BalanceLine
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class BalanceLine
|
||||
{
|
||||
|
||||
const ROLE_DEFAULTROLE = 1;
|
||||
const ROLE_TAGROLE = 2;
|
||||
const ROLE_DIFFROLE = 3;
|
||||
|
||||
/** @var Collection */
|
||||
protected $balanceEntries;
|
||||
|
||||
/** @var BudgetModel */
|
||||
protected $budget;
|
||||
|
||||
/** @var LimitRepetition */
|
||||
protected $repetition;
|
||||
|
||||
protected $role = self::ROLE_DEFAULTROLE;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->balanceEntries = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BalanceEntry $balanceEntry
|
||||
*/
|
||||
public function addBalanceEntry(BalanceEntry $balanceEntry)
|
||||
{
|
||||
$this->balanceEntries->push($balanceEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BudgetModel
|
||||
*/
|
||||
public function getBudget()
|
||||
{
|
||||
return $this->budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetModel $budget
|
||||
*/
|
||||
public function setBudget($budget)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRole()
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $role
|
||||
*/
|
||||
public function setRole($role)
|
||||
{
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine
|
||||
* should have a "spent" value, which is the amount of money that has been spent
|
||||
* on the given budget/repetition. If you subtract all those amounts from the budget/repetition's
|
||||
* total amount, this is returned:
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function leftOfRepetition()
|
||||
{
|
||||
$start = $this->getRepetition() ? $this->getRepetition()->amount : 0;
|
||||
/** @var BalanceEntry $balanceEntry */
|
||||
foreach ($this->getBalanceEntries() as $balanceEntry) {
|
||||
$start += $balanceEntry->getSpent();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
56
app/Helpers/Collection/Bill.php
Normal file
56
app/Helpers/Collection/Bill.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class Bill
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Bill
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Collection
|
||||
*/
|
||||
protected $bills;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->bills = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BillLine $bill
|
||||
*/
|
||||
public function addBill(BillLine $bill)
|
||||
{
|
||||
$this->bills->push($bill);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBills()
|
||||
{
|
||||
$set = $this->bills->sortBy(
|
||||
function (BillLine $bill) {
|
||||
$active = intval($bill->getBill()->active) == 0 ? 1 : 0;
|
||||
$name = $bill->getBill()->name;
|
||||
|
||||
return $active . $name;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
}
|
127
app/Helpers/Collection/BillLine.php
Normal file
127
app/Helpers/Collection/BillLine.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Bill as BillModel;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BillLine
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class BillLine
|
||||
{
|
||||
|
||||
/** @var bool */
|
||||
protected $active;
|
||||
/** @var string */
|
||||
protected $amount;
|
||||
/** @var BillModel */
|
||||
protected $bill;
|
||||
/** @var bool */
|
||||
protected $hit;
|
||||
/** @var string */
|
||||
protected $max;
|
||||
/** @var string */
|
||||
protected $min;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAmount()
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
*/
|
||||
public function setAmount($amount)
|
||||
{
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BillModel
|
||||
*/
|
||||
public function getBill()
|
||||
{
|
||||
return $this->bill;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BillModel $bill
|
||||
*/
|
||||
public function setBill($bill)
|
||||
{
|
||||
$this->bill = $bill;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMax()
|
||||
{
|
||||
return $this->max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $max
|
||||
*/
|
||||
public function setMax($max)
|
||||
{
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMin()
|
||||
{
|
||||
return $this->min;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $min
|
||||
*/
|
||||
public function setMin($min)
|
||||
{
|
||||
$this->min = $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isActive()
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $active
|
||||
*/
|
||||
public function setActive($active)
|
||||
{
|
||||
$this->active = $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isHit()
|
||||
{
|
||||
return $this->hit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $hit
|
||||
*/
|
||||
public function setHit($hit)
|
||||
{
|
||||
$this->hit = $hit;
|
||||
}
|
||||
|
||||
|
||||
}
|
156
app/Helpers/Collection/Budget.php
Normal file
156
app/Helpers/Collection/Budget.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Budget
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Budget
|
||||
{
|
||||
/** @var Collection */
|
||||
protected $budgetLines;
|
||||
/** @var string */
|
||||
protected $budgeted = '0';
|
||||
/** @var string */
|
||||
protected $left = '0';
|
||||
/** @var string */
|
||||
protected $overspent = '0';
|
||||
/** @var string */
|
||||
protected $spent = '0';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->budgetLines = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetLine $budgetLine
|
||||
*/
|
||||
public function addBudgetLine(BudgetLine $budgetLine)
|
||||
{
|
||||
$this->budgetLines->push($budgetLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
*/
|
||||
public function addBudgeted($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->budgeted = bcadd($this->budgeted, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
*/
|
||||
public function addLeft($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->left = bcadd($this->left, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
*/
|
||||
public function addOverspent($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->overspent = bcadd($this->overspent, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
*/
|
||||
public function addSpent($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->spent = bcadd($this->spent, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getBudgetLines()
|
||||
{
|
||||
return $this->budgetLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBudgeted()
|
||||
{
|
||||
return $this->budgeted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $budgeted
|
||||
*/
|
||||
public function setBudgeted($budgeted)
|
||||
{
|
||||
$this->budgeted = $budgeted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLeft()
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $left
|
||||
*/
|
||||
public function setLeft($left)
|
||||
{
|
||||
$this->left = $left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOverspent()
|
||||
{
|
||||
return $this->overspent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $overspent
|
||||
*/
|
||||
public function setOverspent($overspent)
|
||||
{
|
||||
$this->overspent = strval(round($overspent, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSpent()
|
||||
{
|
||||
return $this->spent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $spent
|
||||
*/
|
||||
public function setSpent($spent)
|
||||
{
|
||||
$this->spent = strval(round($spent, 2));
|
||||
}
|
||||
|
||||
|
||||
}
|
128
app/Helpers/Collection/BudgetLine.php
Normal file
128
app/Helpers/Collection/BudgetLine.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class BudgetLine
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class BudgetLine
|
||||
{
|
||||
|
||||
/** @var BudgetModel */
|
||||
protected $budget;
|
||||
/** @var float */
|
||||
protected $budgeted = 0;
|
||||
/** @var float */
|
||||
protected $left = 0;
|
||||
/** @var float */
|
||||
protected $overspent = 0;
|
||||
/** @var LimitRepetition */
|
||||
protected $repetition;
|
||||
/** @var float */
|
||||
protected $spent = 0;
|
||||
|
||||
/**
|
||||
* @return BudgetModel
|
||||
*/
|
||||
public function getBudget()
|
||||
{
|
||||
return $this->budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetModel $budget
|
||||
*/
|
||||
public function setBudget($budget)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getBudgeted()
|
||||
{
|
||||
return $this->budgeted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $budgeted
|
||||
*/
|
||||
public function setBudgeted($budgeted)
|
||||
{
|
||||
$this->budgeted = $budgeted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getLeft()
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $left
|
||||
*/
|
||||
public function setLeft($left)
|
||||
{
|
||||
$this->left = $left;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getOverspent()
|
||||
{
|
||||
return $this->overspent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $overspent
|
||||
*/
|
||||
public function setOverspent($overspent)
|
||||
{
|
||||
$this->overspent = $overspent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LimitRepetition
|
||||
*/
|
||||
public function getRepetition()
|
||||
{
|
||||
return $this->repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LimitRepetition $repetition
|
||||
*/
|
||||
public function setRepetition($repetition)
|
||||
{
|
||||
$this->repetition = $repetition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getSpent()
|
||||
{
|
||||
return $this->spent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $spent
|
||||
*/
|
||||
public function setSpent($spent)
|
||||
{
|
||||
$this->spent = $spent;
|
||||
}
|
||||
|
||||
|
||||
}
|
76
app/Helpers/Collection/Category.php
Normal file
76
app/Helpers/Collection/Category.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\Category as CategoryModel;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Category
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Category
|
||||
{
|
||||
|
||||
/** @var Collection */
|
||||
protected $categories;
|
||||
/** @var string */
|
||||
protected $total = '0';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->categories = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryModel $category
|
||||
*/
|
||||
public function addCategory(CategoryModel $category)
|
||||
{
|
||||
if ($category->spent > 0) {
|
||||
$this->categories->push($category);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $add
|
||||
*/
|
||||
public function addTotal($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->total = bcadd($this->total, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCategories()
|
||||
{
|
||||
$set = $this->categories->sortByDesc(
|
||||
function (CategoryModel $category) {
|
||||
return $category->spent;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotal()
|
||||
{
|
||||
return strval(round($this->total, 2));
|
||||
}
|
||||
|
||||
|
||||
}
|
85
app/Helpers/Collection/Expense.php
Normal file
85
app/Helpers/Collection/Expense.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Expense
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Expense
|
||||
{
|
||||
/** @var Collection */
|
||||
protected $expenses;
|
||||
/** @var string */
|
||||
protected $total = '0';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->expenses = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $entry
|
||||
*/
|
||||
public function addOrCreateExpense(TransactionJournal $entry)
|
||||
{
|
||||
|
||||
$accountId = $entry->account_id;
|
||||
if (!$this->expenses->has($accountId)) {
|
||||
$newObject = new stdClass;
|
||||
$newObject->amount = strval(round($entry->amount, 2));
|
||||
$newObject->name = $entry->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->count++;
|
||||
$this->expenses->put($accountId, $existing);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $add
|
||||
*/
|
||||
public function addToTotal($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->total = bcadd($this->total, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getExpenses()
|
||||
{
|
||||
$set = $this->expenses->sortByDesc(
|
||||
function (stdClass $object) {
|
||||
return $object->amount;
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotal()
|
||||
{
|
||||
return strval(round($this->total, 2));
|
||||
}
|
||||
}
|
88
app/Helpers/Collection/Income.php
Normal file
88
app/Helpers/Collection/Income.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Collection;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Class Income
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collection
|
||||
*/
|
||||
class Income
|
||||
{
|
||||
|
||||
/** @var Collection */
|
||||
protected $incomes;
|
||||
/** @var string */
|
||||
protected $total;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->incomes = new Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $entry
|
||||
*/
|
||||
public function addOrCreateIncome(TransactionJournal $entry)
|
||||
{
|
||||
|
||||
$accountId = $entry->account_id;
|
||||
if (!$this->incomes->has($accountId)) {
|
||||
$newObject = new stdClass;
|
||||
$newObject->amount = strval(round($entry->amount, 2));
|
||||
$newObject->name = $entry->name;
|
||||
$newObject->count = 1;
|
||||
$newObject->id = $accountId;
|
||||
$this->incomes->put($accountId, $newObject);
|
||||
} else {
|
||||
bcscale(2);
|
||||
$existing = $this->incomes->get($accountId);
|
||||
$existing->amount = bcadd($existing->amount, $entry->amount);
|
||||
$existing->count++;
|
||||
$this->incomes->put($accountId, $existing);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $add
|
||||
*/
|
||||
public function addToTotal($add)
|
||||
{
|
||||
$add = strval(round($add, 2));
|
||||
bcscale(2);
|
||||
$this->total = bcadd($this->total, $add);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getIncomes()
|
||||
{
|
||||
$set = $this->incomes->sortByDesc(
|
||||
function (stdClass $object) {
|
||||
return $object->amount;
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotal()
|
||||
{
|
||||
return strval(round($this->total, 2));
|
||||
}
|
||||
|
||||
|
||||
}
|
29
app/Helpers/Csv/Converter/AccountId.php
Normal file
29
app/Helpers/Csv/Converter/AccountId.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class AccountId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class AccountId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$account = Auth::user()->accounts()->find($this->value);
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
26
app/Helpers/Csv/Converter/Amount.php
Normal file
26
app/Helpers/Csv/Converter/Amount.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class Amount extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (is_numeric($this->value)) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
68
app/Helpers/Csv/Converter/AssetAccountIban.php
Normal file
68
app/Helpers/Csv/Converter/AssetAccountIban.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Class AssetAccountIban
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class AssetAccountIban extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
|
||||
return $account;
|
||||
}
|
||||
if (strlen($this->value) > 0) {
|
||||
// find or create new account:
|
||||
$account = $this->findAccount();
|
||||
$accountType = AccountType::where('type', 'Asset account')->first();
|
||||
|
||||
if (is_null($account)) {
|
||||
// create it if doesn't exist.
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'iban' => $this->value,
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
protected function findAccount()
|
||||
{
|
||||
$set = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
if ($entry->iban == $this->value) {
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
51
app/Helpers/Csv/Converter/AssetAccountName.php
Normal file
51
app/Helpers/Csv/Converter/AssetAccountName.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Class AssetAccountName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class AssetAccountName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
|
||||
return $account;
|
||||
}
|
||||
// find or create new account:
|
||||
$accountType = AccountType::where('type', 'Asset account')->first();
|
||||
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
if ($entry->name == $this->value) {
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
// create it if doesnt exist.
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'iban' => '',
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
122
app/Helpers/Csv/Converter/BasicConverter.php
Normal file
122
app/Helpers/Csv/Converter/BasicConverter.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
/**
|
||||
* Class BasicConverter
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class BasicConverter
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
/** @var string */
|
||||
protected $field;
|
||||
/** @var int */
|
||||
protected $index;
|
||||
/** @var array */
|
||||
protected $mapped;
|
||||
/** @var string */
|
||||
protected $role;
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getField()
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*/
|
||||
public function setField($field)
|
||||
{
|
||||
$this->field = $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*/
|
||||
public function setIndex($index)
|
||||
{
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMapped()
|
||||
{
|
||||
return $this->mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mapped
|
||||
*/
|
||||
public function setMapped($mapped)
|
||||
{
|
||||
$this->mapped = $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRole()
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $role
|
||||
*/
|
||||
public function setRole($role)
|
||||
{
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
}
|
30
app/Helpers/Csv/Converter/BillId.php
Normal file
30
app/Helpers/Csv/Converter/BillId.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
|
||||
/**
|
||||
* Class BillId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class BillId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$bill = Auth::user()->bills()->find($this->value);
|
||||
}
|
||||
|
||||
return $bill;
|
||||
}
|
||||
}
|
38
app/Helpers/Csv/Converter/BillName.php
Normal file
38
app/Helpers/Csv/Converter/BillName.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
|
||||
/**
|
||||
* Class BillName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class BillName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
$bill = null;
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
|
||||
$bills = Auth::user()->bills()->get();
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
if ($bill->name == $this->value) {
|
||||
return $bill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bill;
|
||||
}
|
||||
}
|
29
app/Helpers/Csv/Converter/BudgetId.php
Normal file
29
app/Helpers/Csv/Converter/BudgetId.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Budget;
|
||||
|
||||
/**
|
||||
* Class AccountId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class BudgetId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Budget
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$budget = Auth::user()->budgets()->find($this->value);
|
||||
}
|
||||
|
||||
return $budget;
|
||||
}
|
||||
}
|
35
app/Helpers/Csv/Converter/BudgetName.php
Normal file
35
app/Helpers/Csv/Converter/BudgetName.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Budget;
|
||||
|
||||
/**
|
||||
* Class BudgetName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class BudgetName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Budget
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$budget = Budget::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'user_id' => Auth::user()->id,
|
||||
'active' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $budget;
|
||||
}
|
||||
}
|
29
app/Helpers/Csv/Converter/CategoryId.php
Normal file
29
app/Helpers/Csv/Converter/CategoryId.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
/**
|
||||
* Class CategoryId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class CategoryId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Category
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$category = Auth::user()->categories()->find($this->value);
|
||||
}
|
||||
|
||||
return $category;
|
||||
}
|
||||
}
|
34
app/Helpers/Csv/Converter/CategoryName.php
Normal file
34
app/Helpers/Csv/Converter/CategoryName.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
/**
|
||||
* Class CategoryName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class CategoryName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Category
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
// is mapped? Then it's easy!
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$category = Category::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'user_id' => Auth::user()->id
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $category;
|
||||
}
|
||||
}
|
49
app/Helpers/Csv/Converter/ConverterInterface.php
Normal file
49
app/Helpers/Csv/Converter/ConverterInterface.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
/**
|
||||
* Interface ConverterInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
interface ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function convert();
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data);
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
*
|
||||
*/
|
||||
public function setField($field);
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*/
|
||||
public function setIndex($index);
|
||||
|
||||
/**
|
||||
* @param array $mapped
|
||||
*/
|
||||
public function setMapped($mapped);
|
||||
|
||||
/**
|
||||
* @param string $role
|
||||
*/
|
||||
public function setRole($role);
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setValue($value);
|
||||
|
||||
}
|
28
app/Helpers/Csv/Converter/CurrencyCode.php
Normal file
28
app/Helpers/Csv/Converter/CurrencyCode.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
|
||||
/**
|
||||
* Class CurrencyCode
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class CurrencyCode extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$currency = TransactionCurrency::whereCode($this->value)->first();
|
||||
}
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
28
app/Helpers/Csv/Converter/CurrencyId.php
Normal file
28
app/Helpers/Csv/Converter/CurrencyId.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
|
||||
/**
|
||||
* Class CurrencyId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class CurrencyId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$currency = TransactionCurrency::find($this->value);
|
||||
}
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
28
app/Helpers/Csv/Converter/CurrencyName.php
Normal file
28
app/Helpers/Csv/Converter/CurrencyName.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
|
||||
/**
|
||||
* Class CurrencyName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class CurrencyName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$currency = TransactionCurrency::whereName($this->value)->first();
|
||||
}
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
28
app/Helpers/Csv/Converter/CurrencySymbol.php
Normal file
28
app/Helpers/Csv/Converter/CurrencySymbol.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
|
||||
/**
|
||||
* Class CurrencySymbol
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class CurrencySymbol extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
|
||||
} else {
|
||||
$currency = TransactionCurrency::whereSymbol($this->value)->first();
|
||||
}
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
27
app/Helpers/Csv/Converter/Date.php
Normal file
27
app/Helpers/Csv/Converter/Date.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class Date
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class Date extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
$format = Session::get('csv-date-format');
|
||||
|
||||
$date = Carbon::createFromFormat($format, $this->value);
|
||||
|
||||
return $date;
|
||||
}
|
||||
}
|
21
app/Helpers/Csv/Converter/Description.php
Normal file
21
app/Helpers/Csv/Converter/Description.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
/**
|
||||
* Class Description
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class Description extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
return trim($this->data['description'] . ' ' . $this->value);
|
||||
}
|
||||
}
|
22
app/Helpers/Csv/Converter/Ignore.php
Normal file
22
app/Helpers/Csv/Converter/Ignore.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class Ignore extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
57
app/Helpers/Csv/Converter/OpposingAccountIban.php
Normal file
57
app/Helpers/Csv/Converter/OpposingAccountIban.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class OpposingAccountIban
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class OpposingAccountIban extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* If mapped, return account. Otherwise, only return the name itself.
|
||||
*
|
||||
* @return Account|string
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
|
||||
return $account;
|
||||
} else {
|
||||
if (strlen($this->value) > 0) {
|
||||
$account = $this->findAccount();
|
||||
if (!is_null($account)) {
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
protected function findAccount()
|
||||
{
|
||||
$set = Auth::user()->accounts()->get();
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
if ($account->iban == $this->value) {
|
||||
Log::debug('OpposingAccountIban::convert found an Account (#' . $account->id . ': ' . $account->name . ') with IBAN ' . $this->value);
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
32
app/Helpers/Csv/Converter/OpposingAccountId.php
Normal file
32
app/Helpers/Csv/Converter/OpposingAccountId.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class OpposingName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class OpposingAccountId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
|
||||
} else {
|
||||
$account = Auth::user()->accounts()->find($this->value);
|
||||
}
|
||||
|
||||
return $account;
|
||||
|
||||
}
|
||||
}
|
31
app/Helpers/Csv/Converter/OpposingAccountName.php
Normal file
31
app/Helpers/Csv/Converter/OpposingAccountName.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class OpposingName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class OpposingAccountName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* If mapped, return account. Otherwise, only return the name itself.
|
||||
*
|
||||
* @return Account|string
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if (isset($this->mapped[$this->index][$this->value])) {
|
||||
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
|
||||
|
||||
return $account;
|
||||
} else {
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
}
|
26
app/Helpers/Csv/Converter/RabobankDebetCredit.php
Normal file
26
app/Helpers/Csv/Converter/RabobankDebetCredit.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
|
||||
/**
|
||||
* Class RabobankDebetCredit
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class RabobankDebetCredit extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
if ($this->value == 'D') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
40
app/Helpers/Csv/Converter/TagsComma.php
Normal file
40
app/Helpers/Csv/Converter/TagsComma.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class TagsComma
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class TagsComma extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
$tags = new Collection;
|
||||
|
||||
$strings = explode(',', $this->value);
|
||||
foreach ($strings as $string) {
|
||||
$tag = Tag::firstOrCreateEncrypted(
|
||||
[
|
||||
'tag' => $string,
|
||||
'tagMode' => 'nothing',
|
||||
'user_id' => Auth::user()->id,
|
||||
]
|
||||
);
|
||||
$tags->push($tag);
|
||||
}
|
||||
$tags = $tags->merge($this->data['tags']);
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
40
app/Helpers/Csv/Converter/TagsSpace.php
Normal file
40
app/Helpers/Csv/Converter/TagsSpace.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class TagsSpace
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class TagsSpace extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
$tags = new Collection;
|
||||
|
||||
$strings = explode(' ', $this->value);
|
||||
foreach ($strings as $string) {
|
||||
$tag = Tag::firstOrCreateEncrypted(
|
||||
[
|
||||
'tag' => $string,
|
||||
'tagMode' => 'nothing',
|
||||
'user_id' => Auth::user()->id,
|
||||
]
|
||||
);
|
||||
$tags->push($tag);
|
||||
}
|
||||
$tags = $tags->merge($this->data['tags']);
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
263
app/Helpers/Csv/Data.php
Normal file
263
app/Helpers/Csv/Data.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv;
|
||||
|
||||
use Crypt;
|
||||
use League\Csv\Reader;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class Data
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv
|
||||
*/
|
||||
class Data
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
protected $csvFileContent;
|
||||
|
||||
/** @var string */
|
||||
protected $csvFileLocation;
|
||||
/** @var string */
|
||||
protected $dateFormat;
|
||||
/** @var bool */
|
||||
protected $hasHeaders;
|
||||
|
||||
/** @var array */
|
||||
protected $map;
|
||||
/** @var array */
|
||||
protected $mapped;
|
||||
/** @var Reader */
|
||||
protected $reader;
|
||||
/** @var array */
|
||||
protected $roles;
|
||||
|
||||
/** @var array */
|
||||
protected $specifix;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->sessionHasHeaders();
|
||||
$this->sessionDateFormat();
|
||||
$this->sessionCsvFileLocation();
|
||||
$this->sessionMap();
|
||||
$this->sessionRoles();
|
||||
$this->sessionMapped();
|
||||
$this->sessionSpecifix();
|
||||
}
|
||||
|
||||
protected function sessionHasHeaders()
|
||||
{
|
||||
if (Session::has('csv-has-headers')) {
|
||||
$this->hasHeaders = (bool)Session::get('csv-has-headers');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionDateFormat()
|
||||
{
|
||||
if (Session::has('csv-date-format')) {
|
||||
$this->dateFormat = (string)Session::get('csv-date-format');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionCsvFileLocation()
|
||||
{
|
||||
if (Session::has('csv-file')) {
|
||||
$this->csvFileLocation = (string)Session::get('csv-file');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionMap()
|
||||
{
|
||||
if (Session::has('csv-map')) {
|
||||
$this->map = (array)Session::get('csv-map');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionRoles()
|
||||
{
|
||||
if (Session::has('csv-roles')) {
|
||||
$this->roles = (array)Session::get('csv-roles');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionMapped()
|
||||
{
|
||||
if (Session::has('csv-mapped')) {
|
||||
$this->mapped = (array)Session::get('csv-mapped');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionSpecifix()
|
||||
{
|
||||
if (Session::has('csv-specifix')) {
|
||||
$this->specifix = (array)Session::get('csv-specifix');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDateFormat()
|
||||
{
|
||||
return $this->dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $dateFormat
|
||||
*/
|
||||
public function setDateFormat($dateFormat)
|
||||
{
|
||||
Session::put('csv-date-format', $dateFormat);
|
||||
$this->dateFormat = $dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHeaders()
|
||||
{
|
||||
return $this->hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hasHeaders
|
||||
*/
|
||||
public function setHasHeaders($hasHeaders)
|
||||
{
|
||||
Session::put('csv-has-headers', $hasHeaders);
|
||||
$this->hasHeaders = $hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
return $this->map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $map
|
||||
*/
|
||||
public function setMap(array $map)
|
||||
{
|
||||
Session::put('csv-map', $map);
|
||||
$this->map = $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMapped()
|
||||
{
|
||||
return $this->mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mapped
|
||||
*/
|
||||
public function setMapped(array $mapped)
|
||||
{
|
||||
Session::put('csv-mapped', $mapped);
|
||||
$this->mapped = $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Reader
|
||||
*/
|
||||
public function getReader()
|
||||
{
|
||||
|
||||
if (strlen($this->csvFileContent) === 0) {
|
||||
$this->loadCsvFile();
|
||||
}
|
||||
|
||||
if (is_null($this->reader)) {
|
||||
$this->reader = Reader::createFromString($this->getCsvFileContent());
|
||||
}
|
||||
|
||||
return $this->reader;
|
||||
}
|
||||
|
||||
protected function loadCsvFile()
|
||||
{
|
||||
$file = $this->getCsvFileLocation();
|
||||
$content = file_get_contents($file);
|
||||
$contentDecrypted = Crypt::decrypt($content);
|
||||
$this->setCsvFileContent($contentDecrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCsvFileLocation()
|
||||
{
|
||||
return $this->csvFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $csvFileLocation
|
||||
*/
|
||||
public function setCsvFileLocation($csvFileLocation)
|
||||
{
|
||||
Session::put('csv-file', $csvFileLocation);
|
||||
$this->csvFileLocation = $csvFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCsvFileContent()
|
||||
{
|
||||
return $this->csvFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $csvFileContent
|
||||
*/
|
||||
public function setCsvFileContent($csvFileContent)
|
||||
{
|
||||
$this->csvFileContent = $csvFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRoles()
|
||||
{
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $roles
|
||||
*/
|
||||
public function setRoles(array $roles)
|
||||
{
|
||||
Session::put('csv-roles', $roles);
|
||||
$this->roles = $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSpecifix()
|
||||
{
|
||||
return $this->specifix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $specifix
|
||||
*/
|
||||
public function setSpecifix($specifix)
|
||||
{
|
||||
Session::put('csv-specifix', $specifix);
|
||||
$this->specifix = $specifix;
|
||||
}
|
||||
|
||||
|
||||
}
|
331
app/Helpers/Csv/Importer.php
Normal file
331
app/Helpers/Csv/Importer.php
Normal file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Config;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Csv\Converter\ConverterInterface;
|
||||
use FireflyIII\Helpers\Csv\PostProcessing\PostProcessorInterface;
|
||||
use FireflyIII\Helpers\Csv\Specifix\SpecifixInterface;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Importer
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv
|
||||
*/
|
||||
class Importer
|
||||
{
|
||||
|
||||
/** @var Data */
|
||||
protected $data;
|
||||
/** @var array */
|
||||
protected $errors;
|
||||
/** @var array */
|
||||
protected $importData;
|
||||
/** @var array */
|
||||
protected $importRow;
|
||||
/** @var int */
|
||||
protected $imported = 0;
|
||||
/** @var array */
|
||||
protected $map;
|
||||
/** @var array */
|
||||
protected $mapped;
|
||||
/** @var array */
|
||||
protected $roles;
|
||||
/** @var int */
|
||||
protected $rows = 0;
|
||||
/** @var array */
|
||||
protected $specifix;
|
||||
|
||||
/**
|
||||
* Used by CsvController.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by CsvController
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getImported()
|
||||
{
|
||||
return $this->imported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by CsvController
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRows()
|
||||
{
|
||||
return $this->rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
$this->map = $this->data->getMap();
|
||||
$this->roles = $this->data->getRoles();
|
||||
$this->mapped = $this->data->getMapped();
|
||||
$this->specifix = $this->data->getSpecifix();
|
||||
|
||||
foreach ($this->data->getReader() as $index => $row) {
|
||||
if ($this->parseRow($index)) {
|
||||
$this->rows++;
|
||||
$result = $this->importRow($row);
|
||||
if (!($result === true)) {
|
||||
Log::error('Caught error at row #' . $index . ': ' . $result);
|
||||
$this->errors[$index] = $result;
|
||||
} else {
|
||||
$this->imported++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function parseRow($index)
|
||||
{
|
||||
return (($this->data->hasHeaders() && $index > 1) || !$this->data->hasHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function importRow($row)
|
||||
{
|
||||
$data = $this->getFiller(); // These fields are necessary to create a new transaction journal. Some are optional
|
||||
foreach ($row as $index => $value) {
|
||||
$role = isset($this->roles[$index]) ? $this->roles[$index] : '_ignore';
|
||||
$class = Config::get('csv.roles.' . $role . '.converter');
|
||||
$field = Config::get('csv.roles.' . $role . '.field');
|
||||
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = App::make('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
||||
$converter->setData($data); // the complete array so far.
|
||||
$converter->setField($field);
|
||||
$converter->setIndex($index);
|
||||
$converter->setMapped($this->mapped);
|
||||
$converter->setValue($value);
|
||||
$converter->setRole($role);
|
||||
$data[$field] = $converter->convert();
|
||||
|
||||
}
|
||||
// move to class vars.
|
||||
$this->importData = $data;
|
||||
$this->importRow = $row;
|
||||
unset($data, $row);
|
||||
// post processing and validating.
|
||||
$this->postProcess();
|
||||
$result = $this->validateData();
|
||||
|
||||
if (!($result === true)) {
|
||||
return $result; // return error.
|
||||
}
|
||||
$journal = $this->createTransactionJournal();
|
||||
if ($journal instanceof TransactionJournal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getFiller()
|
||||
{
|
||||
$filler = [];
|
||||
foreach (Config::get('csv.roles') as $role) {
|
||||
if (isset($role['field'])) {
|
||||
$fieldName = $role['field'];
|
||||
$filler[$fieldName] = null;
|
||||
}
|
||||
}
|
||||
// some extra's:
|
||||
$filler['bill-id'] = null;
|
||||
$filler['opposing-account-object'] = null;
|
||||
$filler['amount-modifier'] = '1';
|
||||
|
||||
return $filler;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Row denotes the original data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function postProcess()
|
||||
{
|
||||
// do bank specific fixes (must be enabled but now all of them.
|
||||
|
||||
foreach ($this->getSpecifix() as $className) {
|
||||
/** @var SpecifixInterface $specifix */
|
||||
$specifix = App::make('FireflyIII\Helpers\Csv\Specifix\\' . $className);
|
||||
$specifix->setData($this->importData);
|
||||
$specifix->setRow($this->importRow);
|
||||
$this->importData = $specifix->fix();
|
||||
}
|
||||
|
||||
|
||||
$set = Config::get('csv.post_processors');
|
||||
foreach ($set as $className) {
|
||||
/** @var PostProcessorInterface $postProcessor */
|
||||
$postProcessor = App::make('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
|
||||
$postProcessor->setData($this->importData);
|
||||
$this->importData = $postProcessor->process();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSpecifix()
|
||||
{
|
||||
return $this->specifix;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function validateData()
|
||||
{
|
||||
if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) {
|
||||
return 'No date value for this row.';
|
||||
}
|
||||
if (is_null($this->importData['opposing-account-object'])) {
|
||||
return 'Opposing account is null';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return TransactionJournal|string
|
||||
*/
|
||||
protected function createTransactionJournal()
|
||||
{
|
||||
bcscale(2);
|
||||
$date = $this->importData['date'];
|
||||
if (is_null($this->importData['date'])) {
|
||||
$date = $this->importData['date-rent'];
|
||||
}
|
||||
$transactionType = $this->getTransactionType(); // defaults to deposit
|
||||
$errors = new MessageBag;
|
||||
$journal = TransactionJournal::create(
|
||||
['user_id' => Auth::user()->id, 'transaction_type_id' => $transactionType->id, 'transaction_currency_id' => $this->importData['currency']->id,
|
||||
'description' => $this->importData['description'], 'completed' => 0, 'date' => $date, 'bill_id' => $this->importData['bill-id'],]
|
||||
);
|
||||
if ($journal->getErrors()->count() == 0) {
|
||||
$accountId = $this->importData['asset-account']->id; // create first transaction:
|
||||
$amount = $this->importData['amount'];
|
||||
$transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);
|
||||
$errors = $transaction->getErrors();
|
||||
$accountId = $this->importData['opposing-account-object']->id; // create second transaction:
|
||||
$amount = bcmul($this->importData['amount'], -1);
|
||||
$transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);
|
||||
$errors = $transaction->getErrors()->merge($errors);
|
||||
}
|
||||
if ($errors->count() == 0) {
|
||||
$journal->completed = 1;
|
||||
$journal->save();
|
||||
} else {
|
||||
$text = join(',', $errors->all());
|
||||
|
||||
return $text;
|
||||
}
|
||||
$this->saveBudget($journal);
|
||||
$this->saveCategory($journal);
|
||||
$this->saveTags($journal);
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionType
|
||||
*/
|
||||
protected function getTransactionType()
|
||||
{
|
||||
$transactionType = TransactionType::where('type', 'Deposit')->first();
|
||||
if ($this->importData['amount'] < 0) {
|
||||
$transactionType = TransactionType::where('type', 'Withdrawal')->first();
|
||||
}
|
||||
|
||||
if (in_array($this->importData['opposing-account-object']->accountType->type, ['Asset account', 'Default account'])) {
|
||||
$transactionType = TransactionType::where('type', 'Transfer')->first();
|
||||
}
|
||||
|
||||
return $transactionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*/
|
||||
protected function saveBudget(TransactionJournal $journal)
|
||||
{
|
||||
// add budget:
|
||||
if (!is_null($this->importData['budget'])) {
|
||||
$journal->budgets()->save($this->importData['budget']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*/
|
||||
protected function saveCategory(TransactionJournal $journal)
|
||||
{
|
||||
// add category:
|
||||
if (!is_null($this->importData['category'])) {
|
||||
$journal->categories()->save($this->importData['category']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*/
|
||||
protected function saveTags(TransactionJournal $journal)
|
||||
{
|
||||
if (!is_null($this->importData['tags'])) {
|
||||
foreach ($this->importData['tags'] as $tag) {
|
||||
$journal->tags()->save($tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Data $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
}
|
34
app/Helpers/Csv/Mapper/AnyAccount.php
Normal file
34
app/Helpers/Csv/Mapper/AnyAccount.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class AnyAccount
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class AnyAccount implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$result = Auth::user()->accounts()->with('accountType')->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
|
||||
$list = [];
|
||||
/** @var Account $account */
|
||||
foreach ($result as $account) {
|
||||
$list[$account->id] = $account->name . ' (' . $account->accountType->type . ')';
|
||||
}
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
45
app/Helpers/Csv/Mapper/AssetAccount.php
Normal file
45
app/Helpers/Csv/Mapper/AssetAccount.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* Class AssetAccount
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class AssetAccount implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$result = Auth::user()->accounts()->with(
|
||||
['accountmeta' => function (HasMany $query) {
|
||||
$query->where('name', 'accountRole');
|
||||
}]
|
||||
)->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($result as $account) {
|
||||
$name = $account->name;
|
||||
if (strlen($account->iban) > 0) {
|
||||
$name .= ' (' . $account->iban . ')';
|
||||
}
|
||||
$list[$account->id] = $name;
|
||||
}
|
||||
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
34
app/Helpers/Csv/Mapper/Bill.php
Normal file
34
app/Helpers/Csv/Mapper/Bill.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill as BillModel;
|
||||
|
||||
/**
|
||||
* Class Bill
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class Bill implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$result = Auth::user()->bills()->get(['bills.*']);
|
||||
$list = [];
|
||||
|
||||
/** @var BillModel $bill */
|
||||
foreach ($result as $bill) {
|
||||
$list[$bill->id] = $bill->name . ' [' . $bill->match . ']';
|
||||
}
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
34
app/Helpers/Csv/Mapper/Budget.php
Normal file
34
app/Helpers/Csv/Mapper/Budget.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
|
||||
/**
|
||||
* Class Budget
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class Budget implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$result = Auth::user()->budgets()->get(['budgets.*']);
|
||||
$list = [];
|
||||
|
||||
/** @var BudgetModel $budget */
|
||||
foreach ($result as $budget) {
|
||||
$list[$budget->id] = $budget->name;
|
||||
}
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
34
app/Helpers/Csv/Mapper/Category.php
Normal file
34
app/Helpers/Csv/Mapper/Category.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Category as CategoryModel;
|
||||
|
||||
/**
|
||||
* Class Category
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class Category implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$result = Auth::user()->categories()->get(['categories.*']);
|
||||
$list = [];
|
||||
|
||||
/** @var CategoryModel $category */
|
||||
foreach ($result as $category) {
|
||||
$list[$category->id] = $category->name;
|
||||
}
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
16
app/Helpers/Csv/Mapper/MapperInterface.php
Normal file
16
app/Helpers/Csv/Mapper/MapperInterface.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
/**
|
||||
* Interface MapperInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
interface MapperInterface
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap();
|
||||
}
|
34
app/Helpers/Csv/Mapper/Tag.php
Normal file
34
app/Helpers/Csv/Mapper/Tag.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Tag as TagModel;
|
||||
|
||||
/**
|
||||
* Class Tag
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class Tag implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$result = Auth::user()->budgets()->get(['tags.*']);
|
||||
$list = [];
|
||||
|
||||
/** @var TagModel $tag */
|
||||
foreach ($result as $tag) {
|
||||
$list[$tag->id] = $tag->tag;
|
||||
}
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
32
app/Helpers/Csv/Mapper/TransactionCurrency.php
Normal file
32
app/Helpers/Csv/Mapper/TransactionCurrency.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency as TC;
|
||||
|
||||
/**
|
||||
* Class TransactionCurrency
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Mapper
|
||||
*/
|
||||
class TransactionCurrency implements MapperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$currencies = TC::get();
|
||||
$list = [];
|
||||
foreach ($currencies as $currency) {
|
||||
$list[$currency->id] = $currency->name . ' (' . $currency->code . ')';
|
||||
}
|
||||
|
||||
asort($list);
|
||||
|
||||
array_unshift($list, trans('firefly.csv_do_not_map'));
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
35
app/Helpers/Csv/PostProcessing/Amount.php
Normal file
35
app/Helpers/Csv/PostProcessing/Amount.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\PostProcessing
|
||||
*/
|
||||
class Amount implements PostProcessorInterface
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
bcscale(2);
|
||||
$this->data['amount'] = bcmul($this->data['amount'], $this->data['amount-modifier']);
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
37
app/Helpers/Csv/PostProcessing/Bill.php
Normal file
37
app/Helpers/Csv/PostProcessing/Bill.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
/**
|
||||
* Class Bill
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\PostProcessing
|
||||
*/
|
||||
class Bill implements PostProcessorInterface
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
|
||||
// get bill id.
|
||||
if (!is_null($this->data['bill'])) {
|
||||
$this->data['bill-id'] = $this->data['bill']->id;
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
41
app/Helpers/Csv/PostProcessing/Currency.php
Normal file
41
app/Helpers/Csv/PostProcessing/Currency.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class Currency
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\PostProcessing
|
||||
*/
|
||||
class Currency implements PostProcessorInterface
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
|
||||
// fix currency
|
||||
if (is_null($this->data['currency'])) {
|
||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||
$this->data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
38
app/Helpers/Csv/PostProcessing/Description.php
Normal file
38
app/Helpers/Csv/PostProcessing/Description.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
/**
|
||||
* Class Description
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\PostProcessing
|
||||
*/
|
||||
class Description implements PostProcessorInterface
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
$this->data['description'] = trim($this->data['description']);
|
||||
if (strlen($this->data['description']) == 0) {
|
||||
$this->data['description'] = trans('firefly.csv_empty_description');
|
||||
}
|
||||
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
196
app/Helpers/Csv/PostProcessing/OpposingAccount.php
Normal file
196
app/Helpers/Csv/PostProcessing/OpposingAccount.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use Log;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
* Class OpposingAccount
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\PostProcessing
|
||||
*/
|
||||
class OpposingAccount implements PostProcessorInterface
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
$result = $this->checkIdNameObject();
|
||||
if (!is_null($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = $this->checkIbanString();
|
||||
if (!is_null($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = $this->checkNameString();
|
||||
if (!is_null($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function checkIdNameObject()
|
||||
{
|
||||
if ($this->data['opposing-account-id'] instanceof Account) { // first priority. try to find the account based on ID, if any
|
||||
$this->data['opposing-account-object'] = $this->data['opposing-account-id'];
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
if ($this->data['opposing-account-iban'] instanceof Account) { // second: try to find the account based on IBAN, if any.
|
||||
$this->data['opposing-account-object'] = $this->data['opposing-account-iban'];
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
protected function checkIbanString()
|
||||
{
|
||||
$rules = ['iban' => 'iban'];
|
||||
$check = ['iban' => $this->data['opposing-account-iban']];
|
||||
$validator = Validator::make($check, $rules);
|
||||
if (!$validator->fails()) {
|
||||
$this->data['opposing-account-object'] = $this->parseIbanString();
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
protected function parseIbanString()
|
||||
{
|
||||
// create by name and/or iban.
|
||||
$accounts = Auth::user()->accounts()->get();
|
||||
foreach ($accounts as $entry) {
|
||||
if ($entry->iban == $this->data['opposing-account-iban']) {
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
$account = $this->createAccount();
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
protected function createAccount()
|
||||
{
|
||||
$accountType = $this->getAccountType();
|
||||
|
||||
// create if not exists:
|
||||
$name = is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) > 0 ? $this->data['opposing-account-name']
|
||||
: $this->data['opposing-account-iban'];
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'name' => $name,
|
||||
'iban' => $this->data['opposing-account-iban'],
|
||||
'active' => true,
|
||||
]
|
||||
);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return AccountType
|
||||
*/
|
||||
protected function getAccountType()
|
||||
{
|
||||
// opposing account type:
|
||||
if ($this->data['amount'] < 0) {
|
||||
// create expense account:
|
||||
|
||||
return AccountType::where('type', 'Expense account')->first();
|
||||
} else {
|
||||
// create revenue account:
|
||||
|
||||
return AccountType::where('type', 'Revenue account')->first();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
protected function checkNameString()
|
||||
{
|
||||
if ($this->data['opposing-account-name'] instanceof Account) { // third: try to find account based on name, if any.
|
||||
$this->data['opposing-account-object'] = $this->data['opposing-account-name'];
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
if (is_string($this->data['opposing-account-name'])) {
|
||||
$this->data['opposing-account-object'] = $this->parseNameString();
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
*/
|
||||
protected function parseNameString()
|
||||
{
|
||||
$accountType = $this->getAccountType();
|
||||
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
|
||||
foreach ($accounts as $entry) {
|
||||
if ($entry->name == $this->data['opposing-account-name']) {
|
||||
Log::debug('Found an account with this name (#' . $entry->id . ': ' . $entry->name . ')');
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
// create if not exists:
|
||||
$account = Account::firstOrCreateEncrypted(
|
||||
[
|
||||
'user_id' => Auth::user()->id,
|
||||
'account_type_id' => $accountType->id,
|
||||
'name' => $this->data['opposing-account-name'],
|
||||
'iban' => '',
|
||||
'active' => true,
|
||||
]
|
||||
);
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
29
app/Helpers/Csv/PostProcessing/PostProcessorInterface.php
Normal file
29
app/Helpers/Csv/PostProcessing/PostProcessorInterface.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 05/07/15
|
||||
* Time: 19:20
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
|
||||
/**
|
||||
* Interface PostProcessorInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\PostProcessing
|
||||
*/
|
||||
interface PostProcessorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function process();
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(array $data);
|
||||
}
|
45
app/Helpers/Csv/Specifix/Dummy.php
Normal file
45
app/Helpers/Csv/Specifix/Dummy.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
|
||||
/**
|
||||
* Class Dummy
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
class Dummy
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/** @var array */
|
||||
protected $row;
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function fix()
|
||||
{
|
||||
return $this->data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
public function setRow($row)
|
||||
{
|
||||
$this->row = $row;
|
||||
}
|
||||
|
||||
|
||||
}
|
58
app/Helpers/Csv/Specifix/RabobankDescription.php
Normal file
58
app/Helpers/Csv/Specifix/RabobankDescription.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
|
||||
/**
|
||||
* Class RabobankDescription
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
class RabobankDescription
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/** @var array */
|
||||
protected $row;
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function fix()
|
||||
{
|
||||
$this->rabobankFixEmptyOpposing();
|
||||
|
||||
return $this->data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes Rabobank specific thing.
|
||||
*/
|
||||
protected function rabobankFixEmptyOpposing()
|
||||
{
|
||||
if (strlen($this->data['opposing-account-name']) == 0) {
|
||||
$this->data['opposing-account-name'] = $this->row[10];
|
||||
}
|
||||
$this->data['description'] = trim(str_replace($this->row[10], '', $this->data['description']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
public function setRow($row)
|
||||
{
|
||||
$this->row = $row;
|
||||
}
|
||||
|
||||
|
||||
}
|
25
app/Helpers/Csv/Specifix/SpecifixInterface.php
Normal file
25
app/Helpers/Csv/Specifix/SpecifixInterface.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
|
||||
/**
|
||||
* Interface SpecifixInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
interface SpecifixInterface
|
||||
{
|
||||
/**
|
||||
* Implement bank and locale related fixes.
|
||||
*/
|
||||
public function fix();
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data);
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
public function setRow($row);
|
||||
}
|
180
app/Helpers/Csv/Wizard.php
Normal file
180
app/Helpers/Csv/Wizard.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
namespace FireflyIII\Helpers\Csv;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Config;
|
||||
use Crypt;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Csv\Mapper\MapperInterface;
|
||||
use League\Csv\Reader;
|
||||
use ReflectionException;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class Wizard
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv
|
||||
*/
|
||||
class Wizard implements WizardInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Reader $reader
|
||||
* @param array $map
|
||||
* @param bool $hasHeaders
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMappableValues($reader, array $map, $hasHeaders)
|
||||
{
|
||||
$values = [];
|
||||
/*
|
||||
* Loop over the CSV and collect mappable data:
|
||||
*/
|
||||
$keys = array_keys($map);
|
||||
foreach ($reader as $index => $row) {
|
||||
if ($this->useRow($hasHeaders, $index)) {
|
||||
// collect all map values
|
||||
|
||||
foreach ($keys as $column) {
|
||||
$values[$column][] = $row[$column];
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Make each one unique.
|
||||
*/
|
||||
foreach ($values as $column => $found) {
|
||||
$values[$column] = array_unique($found);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $roles
|
||||
* @param mixed $map
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function processSelectedMapping(array $roles, $map)
|
||||
{
|
||||
$configRoles = Config::get('csv.roles');
|
||||
$maps = [];
|
||||
|
||||
|
||||
if (is_array($map)) {
|
||||
foreach ($map as $index => $field) {
|
||||
if (isset($roles[$index])) {
|
||||
$name = $roles[$index];
|
||||
if ($configRoles[$name]['mappable']) {
|
||||
$maps[$index] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $maps;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function processSelectedRoles($input)
|
||||
{
|
||||
$roles = [];
|
||||
|
||||
|
||||
/*
|
||||
* Store all rows for each column:
|
||||
*/
|
||||
if (is_array($input)) {
|
||||
foreach ($input as $index => $role) {
|
||||
if ($role != '_ignore') {
|
||||
$roles[$index] = $role;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sessionHasValues(array $fields)
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
if (!Session::has($field)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $map
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function showOptions(array $map)
|
||||
{
|
||||
$options = [];
|
||||
foreach ($map as $index => $columnRole) {
|
||||
|
||||
$mapper = Config::get('csv.roles.' . $columnRole . '.mapper');
|
||||
if (is_null($mapper)) {
|
||||
throw new FireflyException('Cannot map field of type "' . $columnRole . '".');
|
||||
}
|
||||
$class = 'FireflyIII\Helpers\Csv\Mapper\\' . $mapper;
|
||||
try {
|
||||
/** @var MapperInterface $mapObject */
|
||||
$mapObject = App::make($class);
|
||||
} catch (ReflectionException $e) {
|
||||
throw new FireflyException('Column "' . $columnRole . '" cannot be mapped because class ' . $mapper . ' does not exist.');
|
||||
}
|
||||
$set = $mapObject->getMap();
|
||||
$options[$index] = $set;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function storeCsvFile($path)
|
||||
{
|
||||
$time = str_replace(' ', '-', microtime());
|
||||
$fileName = 'csv-upload-' . Auth::user()->id . '-' . $time . '.csv.encrypted';
|
||||
$fullPath = storage_path('upload') . DIRECTORY_SEPARATOR . $fileName;
|
||||
$content = file_get_contents($path);
|
||||
$contentEncrypted = Crypt::encrypt($content);
|
||||
file_put_contents($fullPath, $contentEncrypted);
|
||||
|
||||
return $fullPath;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hasHeaders
|
||||
* @param int $index
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function useRow($hasHeaders, $index)
|
||||
{
|
||||
return ($hasHeaders && $index > 1) || !$hasHeaders;
|
||||
}
|
||||
}
|
59
app/Helpers/Csv/WizardInterface.php
Normal file
59
app/Helpers/Csv/WizardInterface.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv;
|
||||
|
||||
use League\Csv\Reader;
|
||||
|
||||
/**
|
||||
* Interface WizardInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv
|
||||
*/
|
||||
interface WizardInterface
|
||||
{
|
||||
/**
|
||||
* @param Reader $reader
|
||||
* @param array $map
|
||||
* @param bool $hasHeaders
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMappableValues($reader, array $map, $hasHeaders);
|
||||
|
||||
/**
|
||||
* @param array $roles
|
||||
* @param mixed $map
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function processSelectedMapping(array $roles, $map);
|
||||
|
||||
/**
|
||||
* @param mixed $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function processSelectedRoles($input);
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sessionHasValues(array $fields);
|
||||
|
||||
/**
|
||||
* @param array $map
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function showOptions(array $map);
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function storeCsvFile($path);
|
||||
|
||||
}
|
@@ -17,6 +17,8 @@ class Help implements HelpInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $key
|
||||
*
|
||||
* @return string
|
||||
@@ -27,16 +29,20 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $route
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFromGithub($route)
|
||||
{
|
||||
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md';
|
||||
$content = [
|
||||
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/en/' . e($route) . '.md';
|
||||
$routeIndex = str_replace('.', '-', $route);
|
||||
$title = trans('help.' . $routeIndex);
|
||||
$content = [
|
||||
'text' => '<p>There is no help for this route!</p>',
|
||||
'title' => $route,
|
||||
'title' => $title,
|
||||
];
|
||||
try {
|
||||
$content['text'] = file_get_contents($uri);
|
||||
@@ -54,6 +60,8 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $route
|
||||
*
|
||||
* @return bool
|
||||
@@ -64,6 +72,20 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $route
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache($route)
|
||||
{
|
||||
return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text');
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $route
|
||||
* @param array $content
|
||||
*
|
||||
@@ -74,14 +96,4 @@ class Help implements HelpInterface
|
||||
Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week.
|
||||
Cache::put('help.' . $route . '.title', $content['title'], 10080);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache($route)
|
||||
{
|
||||
return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text');
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user