Compare commits

...

448 Commits

Author SHA1 Message Date
James Cole
b9e2ee7af3 Merge branch 'release/3.10.4' 2016-09-14 20:40:52 +02:00
James Cole
c1a2892788 New changelog.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-14 20:40:12 +02:00
James Cole
2078183e0d Update version and composer file. 2016-09-14 20:37:12 +02:00
James Cole
fab1d53714 Simplified upgrade instructions. 2016-09-14 20:35:45 +02:00
James Cole
3fe831c7d8 Bit of code cleanup courtesy of PHPStorm. 2016-09-13 19:20:09 +02:00
James Cole
6958f71cfd @fuf discovered a bug where FF3 will fall back to the hard-coded system default currency and not the set default currency. See #307 2016-09-13 19:19:58 +02:00
James Cole
a7351f348d Fixed a bug mentioned by @vissert and added some logging for @sandermulders
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-12 18:43:10 +02:00
James Cole
5379e03447 Merge pull request #311 from sandermulders/fix/nullable-values
add migration that correctly sets nullable for description fields on rules and rule_groups
2016-09-12 16:52:14 +02:00
Sander Mulders
539058e32d Fix for #310: add migration that correctly sets nullable for description fields on rules and rule_groups 2016-09-12 14:24:01 +02:00
James Cole
11b6b5a63c Merge branch 'release/3.10.3' into develop 2016-09-11 08:17:42 +02:00
James Cole
1155096226 Merge branch 'release/3.10.3' 2016-09-11 08:17:41 +02:00
James Cole
2920dd356e Updated translations.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:17:35 +02:00
James Cole
9c3dac8170 Config for new version.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:13:22 +02:00
James Cole
49f9909b15 New changelog.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:13:14 +02:00
James Cole
e4fef6dfc3 Fixed an import bug where a new transaction validation rule would break storing of the transaction, while the import would not notice this error happening. The importer will now also correctly set a date on the "import tag" and will not tag an incomplete journal as already imported.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:08:01 +02:00
James Cole
2da087401e Extend audit report
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-10 18:37:16 +02:00
James Cole
629baf9de5 Added invoice date
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-10 18:36:52 +02:00
James Cole
29a930dae5 Updated translations.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:36:19 +02:00
James Cole
d920537dd2 Updated translations.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:29:19 +02:00
James Cole
106b04a5da Update composer.lock [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:19:50 +02:00
James Cole
176752e219 Code for optional fields #301
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:19:40 +02:00
James Cole
8d19f60091 Various translation updates.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:19:19 +02:00
James Cole
e937aa2f74 Fix a bug in piggy bank display [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 06:17:50 +02:00
James Cole
c3ccc4ccdf This should fix #308
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-08 21:10:24 +02:00
James Cole
6c5cd705c0 Some code for new optional fields, see #301
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-04 16:21:51 +02:00
James Cole
ce003f217b Removed unused "budget maximum" preference 2016-09-03 21:13:08 +02:00
James Cole
8c7ef49eb6 New code by @vissert that allows category edit (see #282)
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-03 05:01:48 +02:00
James Cole
29af4bd1b9 This fixes #303 2016-09-03 04:54:57 +02:00
James Cole
2ce5142b06 Small fix for #303
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-01 19:01:08 +02:00
James Cole
f3a8a25872 Fixed #303
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-01 18:31:39 +02:00
James Cole
598e97d028 Forgot to escape things, which causes havoc in the Dutch translation.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-31 18:50:46 +02:00
James Cole
fa110279de Merge branch 'release/3.10.2' 2016-08-29 19:32:49 +02:00
James Cole
8fdeaf73cc Update composer.lock [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-29 19:32:03 +02:00
James Cole
a7ffdf062a Update changelog. [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-29 19:26:31 +02:00
James Cole
3bad92dd6d Upgrade instructions and new version.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-29 19:25:21 +02:00
James Cole
2e88024bca Close #290
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-29 19:21:40 +02:00
James Cole
ca2301959c Merge pull request #298 from Bonno/develop
Fixed wrong conversion to revenue account
2016-08-29 14:49:46 +02:00
Bonno Nachtegaal-Karels
3285fae7f0 Fixed wrong conversion to revenue account 2016-08-29 14:39:43 +02:00
James Cole
312079657b Include files from new import routine in export routine. 2016-08-28 07:05:42 +02:00
James Cole
18c183afd6 Remove form tags in favour of raw html.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 09:38:58 +02:00
James Cole
f424d9cf20 Update change log
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 04:37:04 +02:00
James Cole
5c3da9fd9e New language files.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 04:34:59 +02:00
James Cole
1f321fadd4 Removed some form-tags in favour of plain HTML
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 04:18:02 +02:00
James Cole
65f5d27b12 New pages for administration. More settings will be web-based.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 04:00:48 +02:00
James Cole
cdb591de7f Remove unnecessary setting.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 04:00:19 +02:00
James Cole
a0ea3882e1 Various code cleanup.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-27 03:50:35 +02:00
James Cole
a9444ac702 Code cleanup.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 09:30:52 +02:00
James Cole
d0c6afc3a9 Various code clean up. [skip ci] 2016-08-26 08:21:31 +02:00
James Cole
e7a0a5937c Extend git ignore. [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:41:13 +02:00
James Cole
08992b5298 Extend test-import data set to contain some rules.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:38:00 +02:00
James Cole
6490a4240d Remove references to ImportResult. Add the application of user rules.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:37:47 +02:00
James Cole
43a7544dd7 Catch empty (null) descriptions. Which never happens.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:37:27 +02:00
James Cole
0fe70dae17 Referring to Auth::user will not work from the command line.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:37:09 +02:00
James Cole
7079e76886 Remove some commented code.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:36:33 +02:00
James Cole
0ec021c375 No need to grab journals we don't need.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:36:26 +02:00
James Cole
ff3396e286 Removed the ImportResult class because it was lame.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-26 07:36:13 +02:00
James Cole
78912903ce Change signature of importstorage. 2016-08-26 06:47:12 +02:00
James Cole
4c015e2d12 Re-arrange code. No changes. 2016-08-26 06:44:24 +02:00
James Cole
172634a55a Add some comments. 2016-08-26 06:43:38 +02:00
James Cole
58ca7d551a Rename import procedure method name 2016-08-26 06:43:23 +02:00
James Cole
fd8ed4c9aa Fixed a bug in strict typing.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-25 19:19:12 +02:00
James Cole
c03f5f5ff0 Merge branch 'release/3.10.1' 2016-08-25 11:20:39 +02:00
James Cole
6775fc58c8 Change log and updated config.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-25 11:20:13 +02:00
James Cole
9f250fc61b Renamed migration. 2016-08-25 11:16:17 +02:00
James Cole
94609f1419 Clean up some code. 2016-08-25 06:44:48 +02:00
James Cole
53402aa5e2 Update composer file. 2016-08-25 06:44:41 +02:00
James Cole
5aadb29905 Add some forgotten code to the mobile piggy bank controller things.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-24 20:06:45 +02:00
James Cole
d4f8c41d80 This should fix a bug in the verification routine.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-24 19:36:09 +02:00
James Cole
a2e14f8b8d Various code clean up.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-24 19:33:58 +02:00
James Cole
98c4ac955a Finetune user feedback during import and add a tag to collect transactions. 2016-08-14 11:31:09 +02:00
James Cole
70b63e1736 Better report for finished import. 2016-08-14 10:11:49 +02:00
James Cole
106665a468 Better reporting for double imported rows. See also #164 2016-08-14 09:49:04 +02:00
James Cole
da5e48d769 More language lines. Add a check for double lines. 2016-08-14 09:10:47 +02:00
James Cole
85f484e73c Divide by zero. 2016-08-14 09:10:08 +02:00
James Cole
d287ae97f8 Prep for translations in JS. 2016-08-14 08:34:59 +02:00
James Cole
117bb602dc Extend ImportObject with row hash. 2016-08-14 08:34:51 +02:00
James Cole
e440d55034 Finetune import status page. 2016-08-14 08:10:42 +02:00
James Cole
7f5b94fe43 Fixed a bug in the verify routine. 2016-08-13 23:31:42 +02:00
James Cole
c58eea6654 Fine-tuning the import routine. 2016-08-13 23:28:01 +02:00
James Cole
bbed5d0701 First version of a web-based import status thing. 2016-08-13 21:51:01 +02:00
James Cole
2775690fc8 Extend model to allow for more data during the import. 2016-08-13 18:53:16 +02:00
James Cole
1fd9f6e724 First user interface elements and routes for web import. 2016-08-13 16:38:58 +02:00
James Cole
3d63903128 Make sure import errors end up where the user can read them. 2016-08-13 16:29:24 +02:00
James Cole
ef876a165a Some better feedback in the import process. 2016-08-13 14:22:40 +02:00
James Cole
c4d6aaeef3 Extend scrutinizer config. 2016-08-12 16:06:27 +02:00
James Cole
37b735c2e3 Remove code climate config 2016-08-12 16:06:17 +02:00
James Cole
62d30c7b0e Fix migration (call to empty table name) 2016-08-12 16:06:11 +02:00
James Cole
9cac7d46c0 Merge branch 'release/3.10' 2016-08-12 16:03:30 +02:00
James Cole
99b3e24836 Code optimalization 2016-08-12 15:50:52 +02:00
James Cole
ffb699cb06 Clean up code. 2016-08-12 15:34:15 +02:00
James Cole
2947ec0002 Small optimisations. 2016-08-12 15:27:44 +02:00
James Cole
5c4d010bde Code cleanup. 2016-08-12 15:10:03 +02:00
James Cole
955306d877 Remove travis file and fix NULL error in sqlite. 2016-08-12 14:50:25 +02:00
James Cole
015935ed55 Implemented ABN Amro specific import code. 2016-08-12 12:55:52 +02:00
James Cole
48f4cceb19 Mention new version. 2016-08-12 10:47:09 +02:00
James Cole
9850220aac Add new languages. 2016-08-12 10:46:22 +02:00
James Cole
c4ac1460f0 Expanded translations 2016-08-12 10:44:27 +02:00
James Cole
b9e1e01337 New translations. 2016-08-12 10:34:45 +02:00
James Cole
76649cb7de Extended views and language. 2016-08-12 10:07:53 +02:00
James Cole
5e310776b4 New change log 2016-08-12 09:50:54 +02:00
James Cole
4d7fa11172 Upgrade instructions for 3.10 2016-08-12 09:35:09 +02:00
James Cole
28962007c1 More code for new importer 2016-08-12 09:27:09 +02:00
James Cole
2111873bcf Fixed a bug in tag creation. 2016-08-11 19:01:23 +02:00
James Cole
0aaf9a6fda Extend rule set for import. 2016-08-11 18:44:11 +02:00
James Cole
186b704509 Lots of new code to test the import routine.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-11 10:21:32 +02:00
James Cole
efe9933721 Import storage routine is creating the first transaction journals.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-11 08:00:02 +02:00
James Cole
200366f5be Extended the validator and created more code to handle exceptions.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-10 18:49:16 +02:00
James Cole
c9bd72337d Some notes on the import process. 2016-08-06 09:31:32 +02:00
James Cole
d4510440b8 Split the importer and the setup routine. 2016-08-06 06:28:21 +02:00
James Cole
5a9cf698f7 Configuration for import routine. 2016-08-06 06:21:46 +02:00
James Cole
5826fec519 Some new import stuff. 2016-08-06 06:21:25 +02:00
James Cole
7035600984 Add some logging for #283 2016-08-05 21:50:49 +02:00
James Cole
b1dfb5811f Merge pull request #286 from niekvanderkooy/develop
Generalise Steam::phpBytes
2016-08-05 21:42:40 +02:00
Niek van der Kooy
51570a5d08 Allow phpBytes to work with configs where gigabyte file sizes are allowed 2016-08-05 20:54:59 +02:00
Niek van der Kooy
f065f3a0b8 Make phpBytes case insensitive, since php.ini can contain both capitals and small letters 2016-08-05 20:53:09 +02:00
James Cole
47376f1f35 Fix a problem mentioned in issue #283
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-05 19:29:44 +02:00
James Cole
bcfe2c6410 Fixes #284
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-05 18:52:16 +02:00
James Cole
09d63b584d Save old data; bread crumbs 2016-08-04 06:14:08 +02:00
James Cole
5f5469a7d4 Moved some files around. 2016-08-04 06:10:30 +02:00
James Cole
38800d61b0 New user related code. 2016-08-04 06:07:53 +02:00
James Cole
1186e95c51 Admin view will show some IP addresses.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-03 20:57:01 +02:00
James Cole
d870e0f42e Fix split query. 2016-08-02 19:42:41 +02:00
James Cole
0db9852769 This should fix a bug in split expenses. 2016-08-02 19:12:18 +02:00
James Cole
7e3f9048fe Fixed some fields in split thing. 2016-08-01 20:14:23 +02:00
James Cole
1ba88f182b Various CSV bugs and a config bug fixed. 2016-07-31 17:17:45 +02:00
James Cole
c8f5a6b7ad Ignore deleted columns. 2016-07-30 20:04:24 +02:00
James Cole
d26bbf3cdc Handling import values. This is a dead end but it seemed a good idea. 2016-07-30 19:09:58 +02:00
James Cole
0de72b6914 Ignore result.html 2016-07-30 16:29:49 +02:00
James Cole
e41c89bd59 Does not belong. 2016-07-30 16:29:17 +02:00
James Cole
541d9ebdd9 Optimised some code. 2016-07-30 16:29:04 +02:00
James Cole
1e724712e0 Bug fix in converter 2016-07-29 21:42:12 +02:00
James Cole
3682467ae3 Each CSV converter can set the certainty of their conversion. 2016-07-29 21:40:58 +02:00
James Cole
7707c81b2d Each CSV converter can set the certainty of their conversion. 2016-07-29 21:29:46 +02:00
James Cole
e434de72a3 Expand fields. 2016-07-26 20:40:46 +02:00
James Cole
ce191fa6d3 Fix split deposit. 2016-07-26 20:26:46 +02:00
James Cole
90865a5284 Fix recursive. 2016-07-24 19:24:02 +02:00
James Cole
684f6e0b5c Don't need these. 2016-07-24 19:07:47 +02:00
James Cole
c287bc139c Check new list. 2016-07-24 18:51:39 +02:00
James Cole
1392275b81 Lots of new code for importer and some preferences. 2016-07-24 18:47:55 +02:00
James Cole
87c0f1d86e More CSV related updates. 2016-07-23 21:37:06 +02:00
James Cole
a4a723cfc6 Fixed import error. 2016-07-20 15:57:42 +02:00
James Cole
921e2c06f4 Beta warning for import thing. 2016-07-20 15:47:30 +02:00
James Cole
cb9433f4b9 This should fix #280 2016-07-17 08:50:22 +02:00
James Cole
1be6af820e No map for tags. 2016-07-17 08:35:04 +02:00
James Cole
3b686b6d1c New but empty converters. 2016-07-16 08:25:39 +02:00
James Cole
697566fe42 New importers. 2016-07-16 07:58:25 +02:00
James Cole
5130ba7ea4 Working IBAN account import thing. 2016-07-15 22:37:47 +02:00
James Cole
c9e46a4dd1 Lots of import related code. 2016-07-15 22:26:08 +02:00
James Cole
f5b3dc36e3 Fix view. 2016-07-05 09:02:01 +02:00
James Cole
f1e8d1cf1e Show bill average. 2016-07-05 08:57:45 +02:00
James Cole
e8e7ab01d2 Merge branch 'develop' of github.com:JC5/firefly-iii into develop 2016-07-04 12:38:22 +02:00
James Cole
9244994233 Fix bug that would report wrong file size to browser. 2016-07-04 12:37:33 +02:00
James Cole
ae768a8525 Works up until actual import. 2016-07-02 23:08:47 +02:00
James Cole
162c762973 First set of data mappers. 2016-07-02 20:40:23 +02:00
James Cole
57b5981904 Fix #266 for period-chart. 2016-07-02 17:42:27 +02:00
James Cole
275d19e71d Fix #266 for all-chart. 2016-07-02 17:39:58 +02:00
James Cole
189b11befa Extra page number check for issue #276 2016-07-02 17:36:46 +02:00
James Cole
a56a5fc228 New code for import routine. 2016-07-02 17:33:57 +02:00
James Cole
cbe3fb73a8 Catch decrypt exceptions. 2016-06-27 16:36:28 +02:00
James Cole
3d58fbebec Should not have committed this. 2016-06-27 16:25:17 +02:00
James Cole
b947ff50ed Fix chart thing. 2016-06-27 16:11:49 +02:00
James Cole
18d2741814 More code for the new CSV import 2016-06-27 15:15:46 +02:00
James Cole
93a54780ab Fixes a bug in the 2FA activation thing. 2016-06-24 21:58:57 +02:00
James Cole
3d201db6fc More code for import. 2016-06-24 14:24:34 +02:00
James Cole
9ffc0936ee Merge branch 'feature/new-csv-import' into develop
# Conflicts:
#	app/Helpers/Csv/Importer.php
2016-06-23 12:15:19 +02:00
James Cole
fbf9e00208 Change preferences info. 2016-06-23 12:08:14 +02:00
James Cole
2c826451d1 Fix delete routine and some NULLs 2016-06-23 12:07:31 +02:00
James Cole
617a5c0606 Fix date range. 2016-06-23 08:01:15 +02:00
James Cole
8331a7e34a Rename stuff. 2016-06-18 07:37:12 +02:00
James Cole
8ee1676f0a New migrations. 2016-06-18 07:36:15 +02:00
James Cole
5dc8620c43 More new migrations. 2016-06-17 14:06:38 +02:00
James Cole
d2733a4df0 First attempt at rewriting all migrations. 2016-06-17 06:03:42 +02:00
James Cole
ae649223d8 Mobile add money to piggy routine 2016-06-16 20:52:59 +02:00
James Cole
6267930938 Work on new chart for year report. 2016-06-16 20:52:30 +02:00
James Cole
bdee8cde77 This fixes #273 2016-06-16 08:04:22 +02:00
James Cole
e63f216905 Fix small bug in reorder routine. 2016-06-15 09:58:33 +02:00
James Cole
ec18165698 Fixed #267 2016-06-11 07:38:30 +02:00
James Cole
307e6a2337 Renamed fields #267 2016-06-11 06:36:46 +02:00
James Cole
b80d8cf774 Move date picker stuff to new method. 2016-06-11 06:33:51 +02:00
James Cole
7a5ef6013a Fix #271 2016-06-11 06:31:56 +02:00
James Cole
13b92c47d9 Translations and fixes. 2016-06-11 06:31:40 +02:00
James Cole
5a79bc0a99 Initial code base for new CSV import. 2016-06-10 21:00:00 +02:00
James Cole
beda6ec3a9 Removed old CSV stuff. 2016-06-10 15:25:24 +02:00
James Cole
c619b8730b Implemented #264 2016-06-07 12:22:46 +02:00
James Cole
c14ec8b006 New change log. 2016-06-07 12:22:30 +02:00
James Cole
10c7786248 Merge branch 'release/3.9.1' 2016-06-06 20:25:55 +02:00
James Cole
08ff08685c Small updates for 3.9.1 2016-06-06 20:25:01 +02:00
James Cole
8091dbfdfa Restore views (#262) 2016-06-06 09:28:35 +02:00
James Cole
8dc106b79a Restore config (#262) 2016-06-06 09:28:25 +02:00
James Cole
7527433738 Restore provider (#262) 2016-06-06 09:25:29 +02:00
James Cole
1502e08a7a Restore routes (#262) 2016-06-06 09:24:51 +02:00
James Cole
c9679f1d4f Restore bread crumbs (#262) 2016-06-06 09:23:55 +02:00
James Cole
6b976dd6b9 Restore controller (#262) 2016-06-06 09:22:28 +02:00
James Cole
8da4abf655 Restore helpers (#262) 2016-06-06 09:22:20 +02:00
James Cole
2e26193333 This should fix #266 2016-05-24 16:08:43 +02:00
James Cole
ada43bc0dd Fix #265 2016-05-24 11:28:24 +02:00
James Cole
a447c886c4 Basic for for #262
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-22 21:11:30 +02:00
James Cole
288e713f94 Remove all code related to the CSV importer in preparation of #262
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-22 20:18:16 +02:00
James Cole
f8eb1fa44a Merge branch 'release/3.9.0'
Signed-off-by: James Cole <thegrumpydictator@gmail.com>

# Conflicts:
#	app/Helpers/Csv/Converter/BillName.php
2016-05-22 16:46:11 +02:00
James Cole
afc794513f last minute composer update [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-22 16:43:47 +02:00
James Cole
7e6d3c9d6b Various last minute bug fixes.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-22 16:38:32 +02:00
James Cole
44960e8e42 Various last minute bug fixes. 2016-05-22 15:48:34 +02:00
James Cole
41430c3bb2 Same bug, another line. 2016-05-22 09:08:37 +02:00
James Cole
2f435019e0 Fix bug. 2016-05-22 09:04:16 +02:00
James Cole
480e70dfac Sharper spent in period. [skip ci] 2016-05-20 18:30:48 +02:00
James Cole
c4818334e7 Sharper spent in period. [skip ci] 2016-05-20 18:29:51 +02:00
James Cole
a5d5f86aed Some code cleanup and a better chart [skip ci] 2016-05-20 18:26:43 +02:00
James Cole
78afb771b1 Code cleanup [skip ci] 2016-05-20 17:58:10 +02:00
James Cole
a74a646777 Code cleanup. Moving closer to new release. 2016-05-20 17:53:03 +02:00
James Cole
87f9ca3bb2 Removed some old configuration values. 2016-05-20 17:28:07 +02:00
James Cole
d54e264a91 Cannot create empty tags.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-20 15:09:25 +02:00
James Cole
99aea5ce7a Fix bug in verification.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-20 15:08:24 +02:00
James Cole
e10d5e89e5 Last minute bug fixes.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-20 15:02:52 +02:00
James Cole
0105456828 Copyright notices. [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-20 12:42:21 +02:00
James Cole
5c7df5c04d Copyright notices. [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-20 12:41:23 +02:00
James Cole
563ede822f Copyright notices. [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-05-20 12:27:31 +02:00
James Cole
786cfc21c7 Make strval for bcadd [skip ci] 2016-05-20 12:08:48 +02:00
James Cole
8f0856e31a Make strval for bcadd [skip ci] 2016-05-20 12:07:55 +02:00
James Cole
bea075c74d Make strval for bcadd [skip ci] 2016-05-20 12:06:54 +02:00
James Cole
5f82accb61 Point to other library. [skip ci] 2016-05-20 12:03:28 +02:00
James Cole
95f50ca2fd Point to other library. [skip ci] 2016-05-20 12:02:19 +02:00
James Cole
d8b76bdfd2 Code cleanup [skip ci] 2016-05-20 11:59:54 +02:00
James Cole
74a9edaaf7 Bug fixes in strict types. 2016-05-20 11:53:34 +02:00
James Cole
7dd858be39 Fix bugs. 2016-05-20 11:27:41 +02:00
James Cole
7d7ff71384 New routes. 2016-05-20 11:09:09 +02:00
James Cole
003177fa49 Move stuff around. 2016-05-20 11:09:02 +02:00
James Cole
3c3a83330d More moving stuff around. 2016-05-20 11:02:07 +02:00
James Cole
724f423692 Move some stuff around. 2016-05-20 09:45:24 +02:00
James Cole
65b8882ed4 Clean up repository. 2016-05-20 09:25:17 +02:00
James Cole
66d7fd7d4c Declare strict types. 2016-05-20 08:57:45 +02:00
James Cole
782a6f289c Remove deprecated methods. 2016-05-20 08:11:54 +02:00
James Cole
70d936bb8f Fix filters and other methods that used deprecated methods. 2016-05-20 08:09:53 +02:00
James Cole
dda3082c7e Some code cleanup. 2016-05-20 08:00:35 +02:00
James Cole
ed948cc965 Allow user to split unsplit journal 2016-05-20 07:51:26 +02:00
James Cole
0347649f42 Fix some views. 2016-05-20 06:58:13 +02:00
James Cole
c66fe2b541 Fix some views [skip ci] 2016-05-20 06:27:48 +02:00
James Cole
8c1ae76c7a More tight report thing [skip ci] 2016-05-19 13:39:36 +02:00
James Cole
04dee404c0 More narrow result for popup. [skip ci] 2016-05-19 13:38:12 +02:00
James Cole
b22dd29835 Fix charts. [skip ci] 2016-05-19 08:57:25 +02:00
James Cole
536a5cd1c8 New translations. [skip ci] 2016-05-18 18:13:38 +02:00
James Cole
b7f1bcf7c9 Slightly larger screenshots. [skip ci] 2016-05-18 14:24:59 +02:00
James Cole
5e590072dd Slightly larger screenshots. [skip ci] 2016-05-18 14:24:31 +02:00
James Cole
d204b9b752 Slightly larger screenshots. [skip ci] 2016-05-18 14:23:54 +02:00
James Cole
22d1121193 New read me. [skip ci] 2016-05-18 14:22:48 +02:00
James Cole
e23c6521b9 Add expenses. [skip ci] 2016-05-18 14:19:33 +02:00
James Cole
b0cb9663a6 Updated read me [skip ci] 2016-05-18 07:23:11 +02:00
James Cole
95b7da89f0 Some code cleanup. 2016-05-18 07:01:27 +02:00
James Cole
b0a5b53abb Better number formatting. 2016-05-17 19:23:23 +02:00
James Cole
ce78c8993f Optimise query. [skip ci] 2016-05-17 16:47:43 +02:00
James Cole
2538b4a885 Small changes to audit report. 2016-05-17 16:11:19 +02:00
James Cole
109d96ad16 Small but expensive changes to audit report. 2016-05-17 16:10:32 +02:00
James Cole
4cbb0d9716 Fixed split journals views. 2016-05-17 16:00:27 +02:00
James Cole
65ecea3b1c Small fix to split data. 2016-05-17 15:25:03 +02:00
James Cole
495b80f5ef More code for the split journal support. 2016-05-17 15:19:07 +02:00
James Cole
e113736887 Should fix issue #263 2016-05-17 12:45:31 +02:00
James Cole
042b7a4966 Fix multi-year chart. [skip ci] 2016-05-16 12:51:52 +02:00
James Cole
5ab8cb38d3 Small change in report [skip ci] 2016-05-16 12:47:43 +02:00
James Cole
fc4ab29244 Fixed chart. [skip ci] 2016-05-16 09:05:06 +02:00
James Cole
5a43e6cb9f Better query for no budget. [skip ci] 2016-05-16 07:13:54 +02:00
James Cole
4effc95c5f Fixed some report bugs. 2016-05-15 19:23:19 +02:00
James Cole
962965b5b7 Code cleanup. 2016-05-15 18:36:40 +02:00
James Cole
260b611293 Various fixes in report pages. 2016-05-15 18:16:31 +02:00
James Cole
d2131c371b Fixed more report details. 2016-05-15 17:53:00 +02:00
James Cole
eedf6a07f0 Fixed the income report. 2016-05-15 17:46:53 +02:00
James Cole
5cd1e7c100 Fix charts. [skip ci] 2016-05-15 16:15:17 +02:00
James Cole
6a750a998f Remove category chart from report controller. 2016-05-15 16:13:05 +02:00
James Cole
bd818b2dea Code clean up. 2016-05-15 15:39:22 +02:00
James Cole
4164ebcc69 Added a lot of todo things. 2016-05-15 15:24:23 +02:00
James Cole
60d732067b Made some things less complex. 2016-05-15 15:08:59 +02:00
James Cole
b7b52707fb Fix Travis. 2016-05-15 15:02:07 +02:00
James Cole
f373c72679 Remove tests. 2016-05-15 15:01:29 +02:00
James Cole
ec2027b8db Update git ignore. [skip ci] 2016-05-15 14:48:52 +02:00
James Cole
a84de5db77 Enable caching. Remove stuff for development. 2016-05-15 14:48:21 +02:00
James Cole
5065b1ee03 Enable cache [skip ci] 2016-05-15 12:39:39 +02:00
James Cole
a0aa114ee6 Update balance view. [skip ci] 2016-05-15 12:32:18 +02:00
James Cole
823839fbf6 Better routes and titles. 2016-05-15 12:26:40 +02:00
James Cole
1c93d8bf79 More test data and better views. 2016-05-15 12:08:41 +02:00
James Cole
626404407e More support for #142 2016-05-15 09:00:49 +02:00
James Cole
446ab62d38 View updates. [skip ci] 2016-05-14 23:14:49 +02:00
James Cole
0d39161ec3 Fix iban in test data. 2016-05-14 22:23:55 +02:00
James Cole
29be16dcba Fix complex query. [skip ci] 2016-05-14 22:21:08 +02:00
James Cole
b0bb790386 Experimental query. [skip ci] 2016-05-14 22:12:16 +02:00
James Cole
e64b40d58b Experimental query. [skip ci] 2016-05-14 22:11:49 +02:00
James Cole
4870945af2 Remove references to unused library. 2016-05-14 21:55:43 +02:00
James Cole
a547a5f3f9 New Chart library. [skip ci] 2016-05-14 21:50:02 +02:00
James Cole
e5eabdf7e7 Clean up test data. 2016-05-14 21:49:16 +02:00
James Cole
f78d56b149 Will implement changes to test database. 2016-05-14 17:08:28 +02:00
James Cole
771926c779 No longer needed. 2016-05-14 14:02:37 +02:00
James Cole
6090efe2df Refactoring. 2016-05-14 14:02:12 +02:00
James Cole
863227c55c Some refactoring. 2016-05-14 13:51:33 +02:00
James Cole
5a6967cefd Better formatting for split transactions. 2016-05-13 19:40:13 +02:00
James Cole
5166171e5d More refactoring 2016-05-13 17:22:24 +02:00
James Cole
3e36a29c23 More refactoring. 2016-05-13 15:58:30 +02:00
James Cole
20e1e50032 Refactoring. 2016-05-13 15:53:39 +02:00
James Cole
36bc483edb Reorder some fields. 2016-05-13 10:50:19 +02:00
James Cole
aa59227786 Fixed transactions and attachments. 2016-05-13 09:55:06 +02:00
James Cole
2d8449ed68 This should just about finished split transaction editing. 2016-05-13 07:33:04 +02:00
James Cole
d7ab482ae1 Various updates for split transactions. 2016-05-12 22:44:31 +02:00
James Cole
cfcc4ce88a Let's leave this on false. 2016-05-12 16:34:44 +02:00
James Cole
eda44bbed0 Merge branch 'develop' of github.com:JC5/firefly-iii into develop 2016-05-12 12:13:42 +02:00
James Cole
988049061d Start with edit split journals routine. 2016-05-12 12:13:10 +02:00
James Cole
ebb1c5ae25 Merge pull request #260 from zjean/ssl
Force https schema if APP_FORCE_SSL=true in .env
2016-05-12 11:00:41 +02:00
James Cole
ce7eebac5c Build edit split transactions. 2016-05-12 10:38:44 +02:00
James Cole
b7c446f7db Start with edit and view screens. 2016-05-11 23:03:13 +02:00
James Cole
7c39a04c4b Cleanup. 2016-05-11 17:33:22 +02:00
James Cole
037d84b810 Fixes for transactions. 2016-05-11 17:17:43 +02:00
James Cole
529bf50c85 Removed some dead code. 2016-05-11 10:37:56 +02:00
James Cole
d2b4bd78a9 Removed some dead code. 2016-05-11 10:02:27 +02:00
James Cole
e1c146a5c1 Reinstate chart. 2016-05-11 09:17:47 +02:00
James Cole
ed9acbdfde Reinstate report. 2016-05-11 09:08:18 +02:00
James Cole
dc825d5a9c Fix queries. 2016-05-11 08:40:22 +02:00
James Cole
9f8faf15f1 Reinstate sorting. 2016-05-11 08:10:05 +02:00
James Cole
934656c954 Some small changes. 2016-05-11 07:57:16 +02:00
James Cole
d233a2df3c Merge branch 'develop' of https://github.com/JC5/firefly-iii into develop
* 'develop' of https://github.com/JC5/firefly-iii:
  Should fix frontpage.

# Conflicts:
#	app/Models/TransactionJournal.php
#	app/Repositories/Account/AccountRepository.php
2016-05-11 06:08:05 +02:00
James Cole
7c7740d3ba Should fix frontpage. 2016-05-10 09:33:23 +02:00
James Cole
cda6cfb4cd Fix more charts. 2016-05-09 20:15:26 +02:00
James Cole
a90d095609 More stuff for categories. 2016-05-09 18:06:53 +02:00
James Cole
98e683329e New stuff for categories and transactions. 2016-05-08 13:45:23 +02:00
James Cole
3588bd881c More chart cleanup. 2016-05-06 22:54:36 +02:00
James Cole
0460811e6c Fixed some more charts. 2016-05-06 22:53:08 +02:00
James Cole
27f5fe18df Moving stuff around, optimising charts. 2016-05-06 10:32:26 +02:00
James Cole
6d944ec98f More cleanup for budgets. 2016-05-06 06:15:46 +02:00
James Cole
adf6691470 This breaks everything budget-related. 2016-05-05 22:03:35 +02:00
James Cole
dd8b500efd These budget charts are the worst, I'm telling you. 2016-05-05 21:25:20 +02:00
James Cole
4e1ff8c4a3 Removed phpunit.xml 2016-05-05 19:07:46 +02:00
James Cole
e73d590ead Update composer.lock 2016-05-05 19:05:29 +02:00
James Cole
5cc22f49cf Fix tests. 2016-05-05 19:04:21 +02:00
James Cole
eb3d2b1749 Building split transactions and fixing tests. 2016-05-05 18:59:46 +02:00
James Cole
21a197ba46 More translations. 2016-05-05 07:46:19 +02:00
James Cole
0b74707638 Display and handle errors. 2016-05-05 07:46:11 +02:00
James Cole
16dc8b7d68 Translation for error. 2016-05-05 07:45:52 +02:00
James Cole
5a8abe004e Field rename 2016-05-05 07:45:40 +02:00
James Cole
b211d72c8b Static data must remain static data. 2016-05-05 07:45:29 +02:00
James Cole
36f3eb8b2f Small fix in journal handler. 2016-05-05 07:09:12 +02:00
zjean
cb1cb9f328 Force https schema if APP_FORCE_SSL=true in .env 2016-05-04 22:09:42 +02:00
James Cole
3344bb7263 Code cleanup. 2016-05-02 20:49:19 +02:00
James Cole
5e1167b8ae Code cleanup. 2016-05-01 15:05:29 +02:00
James Cole
b80db054e2 Remove journal collector. 2016-05-01 09:52:58 +02:00
James Cole
c66df3cb2c Code cleanup. 2016-05-01 09:42:08 +02:00
James Cole
ac8ff4e565 Clean up repository. 2016-05-01 07:09:58 +02:00
James Cole
bfa7ee90f4 Reverse stuff 2016-05-01 06:59:08 +02:00
James Cole
77c9e37584 Move some stuff around. 2016-05-01 06:37:47 +02:00
James Cole
80350f8423 Fix for transactions. 2016-04-30 22:30:11 +02:00
James Cole
3c1ff4d21f Fix query. 2016-04-30 22:05:58 +02:00
James Cole
55b8f03590 Some new data thing. 2016-04-30 21:20:39 +02:00
James Cole
1fd7852309 Fix query thing. 2016-04-30 20:24:47 +02:00
James Cole
9c5292962f More stuff for splits. 2016-04-30 19:50:42 +02:00
James Cole
c05c6e72c0 Display budget and category if relevant. 2016-04-30 16:36:58 +02:00
James Cole
bdcd033952 Fix edit routine 2016-04-30 12:46:21 +02:00
James Cole
4ec6bcc8c7 More code for split and small bug fix in attachment helper. 2016-04-30 09:48:39 +02:00
James Cole
11ea4b6d47 Fix migrations. 2016-04-30 07:15:28 +02:00
James Cole
e4f45b5370 List of categories will check transactions as well. #142 2016-04-29 22:00:24 +02:00
James Cole
9baadd3793 Use other method of collecting query fields. #142 2016-04-29 21:52:15 +02:00
James Cole
94a79876ce View for split transactions. #142 2016-04-29 21:49:18 +02:00
James Cole
42c3d1fa68 Expanding support for split transactions #142 2016-04-29 21:36:59 +02:00
James Cole
0e3ccebd0b First attempt at #142. Needs a lot of work still. 2016-04-29 20:59:28 +02:00
James Cole
4af8272faa Updates to transactions. 2016-04-29 17:29:13 +02:00
James Cole
0ef3d0cf03 Better message for issue #247 2016-04-29 17:26:59 +02:00
James Cole
f266b92ef1 This catches issue #247 2016-04-29 17:26:38 +02:00
James Cole
462c9fb3aa Merge pull request #259 from tonicospinelli/pt_BR
add brazilian currency and translation
2016-04-29 15:11:23 +02:00
Antonio Spinelli
568186828c add brazilian currency and translation
fix #257
2016-04-29 07:30:22 -03:00
James Cole
8bcc319b7d Better demo warning and budget indication. 2016-04-29 11:34:48 +02:00
James Cole
baff9780de Smaller report. [skip ci] 2016-04-29 11:05:52 +02:00
James Cole
d8b8f98738 Translations. [skip ci] 2016-04-29 09:56:50 +02:00
James Cole
b714eaac06 Boxes will try to remember their state and auto-collapse. 2016-04-29 09:47:47 +02:00
James Cole
14b94a5bd2 Simplified some code. 2016-04-29 08:56:56 +02:00
James Cole
ea014a6504 Some code simplifications. 2016-04-28 16:30:21 +02:00
James Cole
e28e66e8f1 Fix ABN AMRO importer 2016-04-28 16:23:21 +02:00
James Cole
b47a140c2f Updates to budgets. 2016-04-28 10:59:36 +02:00
James Cole
19d7e27fa9 Code cleanup. 2016-04-28 05:50:29 +02:00
James Cole
2d368f226e Remove parameters. [skip ci] 2016-04-27 19:23:24 +02:00
James Cole
75d81f8f18 Parameter change [skip ci] 2016-04-27 19:22:15 +02:00
James Cole
e3437ba697 Various code cleanup. 2016-04-27 19:21:47 +02:00
James Cole
84f299c33b Forgot a return statement. 2016-04-27 10:39:27 +02:00
James Cole
3d4489efe6 Code cleanup. 2016-04-27 10:38:51 +02:00
James Cole
6aa50e3c00 @roberthorlings I have no idea if this is a correct fix. 2016-04-27 09:20:51 +02:00
James Cole
b70498c337 Some cleaning up. 2016-04-27 06:46:02 +02:00
James Cole
f34aa77d1d Cleaned up some code. 2016-04-27 06:43:17 +02:00
James Cole
3833a41acb Fix sorting. 2016-04-27 06:19:13 +02:00
James Cole
b5a5a216cd Fine tune chart. [skip ci] 2016-04-26 22:32:55 +02:00
James Cole
d9da2a57b6 Fix query error [skip ci] 2016-04-26 22:31:49 +02:00
James Cole
1591b61b77 Expand new charts. 2016-04-26 22:30:53 +02:00
James Cole
66f2df9677 Some code cleanup and I sneaked in a chart optimisation. 2016-04-26 22:21:34 +02:00
James Cole
5199377113 Fixes tests.. for now. 2016-04-26 21:47:16 +02:00
James Cole
da202317c0 Code cleanup. 2016-04-26 21:40:15 +02:00
James Cole
1d2a4e707e Code cleanup in export routine 2016-04-26 20:49:22 +02:00
James Cole
edf9dbc6e8 Some cleaning up [skip ci] 2016-04-26 14:56:42 +02:00
James Cole
dfbe6e5b6e Code clean up. [skip ci] 2016-04-26 12:39:29 +02:00
James Cole
d551333fa2 Some cleaning up and more charts. 2016-04-26 09:21:57 +02:00
James Cole
01cab599bb And now to make sure it works. 2016-04-26 08:11:26 +02:00
James Cole
1c8834fffb Some code cleaning up and refactoring. 2016-04-26 08:09:10 +02:00
James Cole
22e6ea700f Some extensions to budgets. 2016-04-25 21:37:08 +02:00
James Cole
7f7d6cf893 Expand query [skip ci] 2016-04-25 21:07:17 +02:00
James Cole
a94d476b75 Small additions to budget handling [skip ci] 2016-04-25 20:05:09 +02:00
James Cole
eb5e55a272 Some code cleanup. Fixes the tests. 2016-04-25 18:43:09 +02:00
James Cole
53c80aaef8 Small optimizations to reports. 2016-04-25 14:53:41 +02:00
James Cole
607d0115f0 Code improvements for budgets. 2016-04-25 13:20:42 +02:00
James Cole
b4f18dbe77 Database stuff. 2016-04-25 11:44:41 +02:00
James Cole
51d97cdca5 Reinstated a chart. 2016-04-25 09:57:39 +02:00
James Cole
2cd593157f Comment some stuff. 2016-04-25 09:50:46 +02:00
James Cole
ec70fde557 Start of some changes in budget overview related to #256 and #246 2016-04-25 09:49:34 +02:00
James Cole
950576d38b Better date format [skip ci] 2016-04-25 09:12:52 +02:00
James Cole
ce5304277d Translation for popup [skip ci] 2016-04-25 09:11:09 +02:00
James Cole
53760766a0 Fixed budget charts. 2016-04-24 20:41:12 +02:00
James Cole
ed863986a7 Fine tuning. [skip ci] 2016-04-24 20:28:08 +02:00
James Cole
89ff5a83b5 Expand cache. [skip ci] 2016-04-24 20:25:35 +02:00
James Cole
fe0b62b9b4 Cache charts. [skip ci] 2016-04-24 20:23:42 +02:00
James Cole
32c8ddbe1b First render of new budget charts. 2016-04-24 20:23:17 +02:00
James Cole
2cfbfd8649 Start of better budget charts. 2016-04-24 20:00:20 +02:00
James Cole
3f6c19dec4 Merge branch 'release/3.8.4'
# Conflicts:
#	app/Helpers/Csv/PostProcessing/Bill.php
2016-04-24 18:48:16 +02:00
James Cole
93421b50f9 New translations. 2016-04-24 18:47:03 +02:00
James Cole
54e829173a Prep for next release. 2016-04-24 18:44:29 +02:00
James Cole
4fe38bd31b New release 2016-04-24 18:38:58 +02:00
James Cole
fb0638e824 Say what each thing is. 2016-04-24 18:36:44 +02:00
James Cole
108794a6b6 Improved verify command. 2016-04-24 18:35:45 +02:00
James Cole
9c16fc1380 Some small updates. 2016-04-24 18:25:52 +02:00
James Cole
99c219ed97 Three fixes courtesy of user @Bonno 2016-04-24 12:24:59 +02:00
James Cole
ec12238ea1 Some code cleanup. 2016-04-24 09:14:40 +02:00
James Cole
bdbd22f98b Some language and code updates. 2016-04-24 09:02:21 +02:00
James Cole
b8e1944d20 Mass edit #241 2016-04-24 07:18:39 +02:00
James Cole
8883d185fe Fix tests. 2016-04-23 20:00:48 +02:00
James Cole
19e40e9976 Expand transaction lists for mass delete / edit functionality. 2016-04-23 18:55:57 +02:00
James Cole
fa85b2b5b2 Some layout fixes. [skip ci] 2016-04-23 18:53:16 +02:00
James Cole
5cf0131d75 New translations. 2016-04-23 12:14:24 +02:00
James Cole
3948cb8e6c New mass delete form and options. #241 2016-04-23 09:33:54 +02:00
James Cole
f43938726a Simple mass edit JS complete. Fallback for when the list.js is not included. #241 2016-04-23 06:11:31 +02:00
James Cole
8c8bb7a930 Start of mass delete code. #241 2016-04-21 14:57:58 +02:00
James Cole
3972882a33 Fix #251 2016-04-21 11:03:04 +02:00
James Cole
0ef5eeeb55 Take page size into account. [skip ci] 2016-04-21 10:34:16 +02:00
James Cole
ef48a79d0c Take page size into account. [skip ci] 2016-04-21 10:23:19 +02:00
James Cole
2bb883219c Take page size into account. 2016-04-21 09:10:37 +02:00
James Cole
23c0bb49c4 Take page size into account. [skip ci] 2016-04-21 09:04:19 +02:00
James Cole
13e59105ec Set correct path. [skip ci] 2016-04-21 09:01:34 +02:00
James Cole
98c057c516 Take page size into account. 2016-04-21 09:00:32 +02:00
James Cole
e293d69798 Take page size into account. 2016-04-21 08:59:31 +02:00
James Cole
b097e29104 New preference for page size. 2016-04-21 08:59:15 +02:00
James Cole
29fbd46e33 Fixes for translations. [skip ci] 2016-04-20 17:13:25 +02:00
James Cole
6a15afc723 New translations [skip ci] 2016-04-20 17:10:35 +02:00
James Cole
c56a39a726 Update chart js. [skip ci] 2016-04-20 13:54:13 +02:00
James Cole
4b80e46d26 Fix old bug. 2016-04-18 19:55:48 +02:00
James Cole
a6f3e61520 Fix #248 2016-04-18 19:41:16 +02:00
James Cole
cce4ef19e5 Fix #244 2016-04-18 19:34:15 +02:00
James Cole
1951491c04 Merge branch 'develop' of https://github.com/JC5/firefly-iii into develop
* 'develop' of https://github.com/JC5/firefly-iii:
  Fix #243
2016-04-18 19:33:27 +02:00
James Cole
87b72e4bcd Fix #245 2016-04-18 19:33:02 +02:00
James Cole
2c6643d691 Fix #243 2016-04-18 14:15:10 +02:00
James Cole
d02df46517 Fix bug in bill name import routine 2016-04-17 20:40:26 +02:00
James Cole
0c0cc417ee Order chart thing again [skip ci] 2016-04-17 19:59:15 +02:00
James Cole
f0c03e8a3b Update chart order. 2016-04-17 19:58:09 +02:00
749 changed files with 35668 additions and 22071 deletions

View File

@@ -1,50 +0,0 @@
---
engines:
csslint:
enabled: true
duplication:
enabled: true
config:
languages:
- ruby
- javascript
- python
- php
eslint:
enabled: true
fixme:
enabled: true
phpmd:
enabled: true
ratings:
paths:
- "**.css"
- "**.inc"
- "**.js"
- "**.jsx"
- "**.module"
- "**.php"
- "**.py"
- "**.rb"
exclude_paths:
- gulpfile.js
- public/packages/maximebf/php-debugbar/debugbar.js
- public/packages/maximebf/php-debugbar/widgets.js
- public/packages/maximebf/php-debugbar/openhandler.js
- public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js
- public/js/bootstrap3-typeahead.min.js
- public/js/bootstrap-sortable.js
- public/js/bootstrap-tagsinput.min.js
- public/js/bootstrap-tagsinput.min.js.map
- public/js/daterangepicker.js
- public/js/jquery-2.1.3.min.js
- public/js/jquery-2.1.3.min.js.map
- public/js/jquery-ui.min.js
- public/js/metisMenu.js
- public/js/moment.min.js
- public/js/sb-admin-2.js
- public/bootstrap/*
- resources/lang/*
- tests/*
- database/*
- storage/*

View File

@@ -1,5 +1,7 @@
APP_ENV=production
APP_DEBUG=false
APP_FORCE_SSL=false
APP_FORCE_ROOT=
APP_KEY=SomeRandomStringOf32CharsExactly
LOG_LEVEL=warning
@@ -36,9 +38,7 @@ SEND_REGISTRATION_MAIL=true
MUST_CONFIRM_ACCOUNT=false
SHOW_INCOMPLETE_TRANSLATIONS=false
SHOW_DEMO_WARNING=false
ANALYTICS_ID=
RUNCLEANUP=true
SITE_OWNER=mail@example.com
BLOCKED_DOMAINS=

View File

@@ -1,5 +1,6 @@
APP_ENV=testing
APP_DEBUG=true
APP_FORCE_SSL=false
APP_KEY=SomeRandomStringOf32CharsExactly
LOG_LEVEL=debug

7
.gitignore vendored
View File

@@ -1,6 +1,9 @@
/vendor
/node_modules
.env
storage/
_development
.env.local
result.html
test-import.sh
test-import-report.txt
public/google*.html

View File

@@ -4,3 +4,4 @@ tools:
filter:
excluded_paths:
- app/Support/Migration/*
- app/database/migrations/*

View File

@@ -1,23 +0,0 @@
language: php
sudo: false
php:
- 7
install:
- cp _development/phpunit.xml ./phpunit.xml
- phpenv config-rm xdebug.ini
- composer selfupdate
- rm composer.lock
- composer update --no-scripts
- php artisan clear-compiled
- php artisan optimize
- php artisan env
- mv -v .env.testing .env
- php artisan env
- touch storage/upload/at-1.data
- touch storage/upload/at-2.data
- touch storage/database/testing.db
- php artisan migrate --seed
script:
- phpunit

View File

@@ -5,6 +5,137 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
- No unreleased changes yet.
## [3.10.4] - 2015-05-25
### Fixed
- Migration fix by @sandermulders
- Tricky import bug fix thanks to @vissert
- Currency preference will be correctly pulled from user settings, thanks to @fuf
- Simplified code for upgrade instructions.
## [3.10.3] - 2016-08-29
### Added
- More fields for mass-edit, thanks to @Vissert (#282)
- First start of German translation
### Changed
- More optional fields for transactions and the ability to filter them.
### Removed
- Preference for budget maximum.
### Fixed
- A bug in the translation routine broke the import.
- It was possible to destroy your Firefly installation by removing all currencies. Thanks @mondjef
- Translation bugs.
- Import bug.
### Security
- Firefly will not accept registrations beyond the first one, by default.
## [3.10.2] - 2016-08-29
### Added
- New Chinese translations. Set Firefly III to show incomplete translations to follow the progress. Want to translate Firefly III in Chinese, or in any other language? Then check out [the Crowdin project](https://crowdin.com/project/firefly-iii).
- Added more admin pages. They do nothing yet.
### Changed
- Import routine will now also apply user rules.
- Various code cleanup.
- Some small HTML changes.
### Fixed
- Bug in the mass edit routines.
- Firefly III over a proxy will now work (see [issue #290](https://github.com/JC5/firefly-iii/issues/290)), thanks @dfiel for reporting.
- Sneaky bug in the import routine, fixed by @Bonno
## [3.10.1] - 2016-08-25
### Added
- More feedback in the import procedure.
- Extended model for import job.
- Web bases import procedure.
### Changed
- Scrutinizer configuration
- Various code clean up.
### Removed
- Code climate YAML file.
### Fixed
- Fixed a bug where a migration would check an empty table name.
- Fixed various bugs in the import routine.
- Fixed various bugs in the piggy banks pages.
- Fixed a bug in the ``firefly:verify`` routine
## [3.10] - 2015-05-25
### Added
- New charts in year report
- Can add / remove money from piggy bank on mobile device.
- Bill overview shows some useful things.
- Firefly will track registration / activation IP addresses.
### Changed
- Rewrote the import routine.
- The date picker now supports more ranges and periods.
- Rewrote all migrations. #272
### Fixed
- Issue #264
- Issue #265
- Fixed amount calculation problems, #266, thanks @xzaz
- Issue #271
- Issue #278, #273, thanks @StevenReitsma and @rubella
- Bug in attachment download routine would report the wrong size to the user's browser.
- Various NULL errors fixed.
- Various strict typing errors fixed.
- Fixed pagination problems, #276, thanks @xzaz
- Fixed a bug where an expense would be assigned to a piggy bank if you created a transfer first.
- Bulk update problems, #280, thanks @stickgrinder
- Fixed various problems with amount reporting of split transactions.
[3.9.1]
### Fixed
- Fixed a bug where removing money from a piggy bank would not work. See issue #265 and #269
[3.9.0]
### Added
- @zjean has added code that allows you to force "https://"-URL's.
- @tonicospinelli has added Portuguese (Brazil) translations.
- Firefly III supports the *splitting* of transactions:
- A withdrawal (expense) can be split into multiple sub-transactions (with multiple destinations)
- Likewise for deposits (incomes). You can set multiple sources.
- Likewise for transfers.
### Changed
- Update a lot of libraries.
- Big improvement to test data generation.
- Cleaned up many repositories.
### Removed
- Front page boxes will no longer respond to credit card bills.
### Fixed
- Many bugs
## [3.8.4] - 2016-04-24
### Added
- Lots of new translations.
- Can now set page size.
- Can now mass edit transactions.
- Can now mass delete transactions.
- Firefly will now attempt to verify the integrity of your database when updating.
### Changed
- New version of Charts library.
### Fixed
- Several CSV related bugs.
- Several other bugs.
- Bugs fixed by @Bonno.
## [3.8.3] - 2016-04-17
### Added
- New audit report to see what happened.

View File

@@ -1,16 +1,18 @@
# Firefly III
# Firefly III [![Requires PHP7](https://img.shields.io/badge/php-7.0-red.svg)](https://secure.php.net/downloads.php#v7.0.4) [![Latest Stable Version](https://poser.pugx.org/grumpydictator/firefly-iii/v/stable)](https://packagist.org/packages/grumpydictator/firefly-iii) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
[![Requires PHP7](https://img.shields.io/badge/php-7.0-red.svg)](https://secure.php.net/downloads.php#v7.0.4)
[![Latest Stable Version](https://poser.pugx.org/grumpydictator/firefly-iii/v/stable)](https://packagist.org/packages/grumpydictator/firefly-iii)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/build.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102/mini.png)](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
[![Code Climate](https://codeclimate.com/github/JC5/firefly-iii/badges/gpa.svg)](https://codeclimate.com/github/JC5/firefly-iii)
## A personal finances manager
## About
[![Screenshot](https://i.nder.be/hhfv03hp/400)](https://i.nder.be/hhfv03hp) [![Screenshot](https://i.nder.be/hhmwmqw9/400)](https://i.nder.be/hhmwmqw9)
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared
household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
[![Screenshot](https://i.nder.be/g63q05m0/400)](https://i.nder.be/g63q05m0) [![Screenshot](https://i.nder.be/c2g30ngg/400)](https://i.nder.be/c2g30ngg)
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
## Installation
To install Firefly III, you'll need a web server (preferrably on Linux) and access to the command line. Then, please read the [installation guide](https://jc5.github.io/firefly-iii/installation-guide/).
## More about Firefly III
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase their current cashflow. There are tons of ways to save and earn money.
@@ -24,3 +26,5 @@ Firefly works on the principle that if you know where you're money is going, you
- If you feel you're missing something you can just ask me and I'll add it!
Firefly is pretty awesome. [You can read more about Firefly III, and its features, on the Github Pages](https://jc5.github.io/firefly-iii/).
If you want to contact me, please open an issue or [email me](mailto:thegrumpydictator@gmail.com).

View File

@@ -1 +0,0 @@
src_dir: .

View File

@@ -1,2 +0,0 @@
--exclude-exts=.min.css
--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes

View File

@@ -1 +0,0 @@
**/*{.,-}min.js

View File

@@ -1,213 +0,0 @@
ecmaFeatures:
modules: true
jsx: true
env:
amd: true
browser: true
es6: true
jquery: true
node: true
# http://eslint.org/docs/rules/
rules:
# Possible Errors
comma-dangle: [2, never]
no-cond-assign: 2
no-console: 0
no-constant-condition: 2
no-control-regex: 2
no-debugger: 2
no-dupe-args: 2
no-dupe-keys: 2
no-duplicate-case: 2
no-empty: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 2
no-extra-parens: 0
no-extra-semi: 2
no-func-assign: 2
no-inner-declarations: [2, functions]
no-invalid-regexp: 2
no-irregular-whitespace: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-regex-spaces: 2
no-sparse-arrays: 2
no-unexpected-multiline: 2
no-unreachable: 2
use-isnan: 2
valid-jsdoc: 0
valid-typeof: 2
# Best Practices
accessor-pairs: 2
block-scoped-var: 0
complexity: [2, 6]
consistent-return: 0
curly: 0
default-case: 0
dot-location: 0
dot-notation: 0
eqeqeq: 2
guard-for-in: 2
no-alert: 2
no-caller: 2
no-case-declarations: 2
no-div-regex: 2
no-else-return: 0
no-empty-label: 2
no-empty-pattern: 2
no-eq-null: 2
no-eval: 2
no-extend-native: 2
no-extra-bind: 2
no-fallthrough: 2
no-floating-decimal: 0
no-implicit-coercion: 0
no-implied-eval: 2
no-invalid-this: 0
no-iterator: 2
no-labels: 0
no-lone-blocks: 2
no-loop-func: 2
no-magic-number: 0
no-multi-spaces: 0
no-multi-str: 0
no-native-reassign: 2
no-new-func: 2
no-new-wrappers: 2
no-new: 2
no-octal-escape: 2
no-octal: 2
no-proto: 2
no-redeclare: 2
no-return-assign: 2
no-script-url: 2
no-self-compare: 2
no-sequences: 0
no-throw-literal: 0
no-unused-expressions: 2
no-useless-call: 2
no-useless-concat: 2
no-void: 2
no-warning-comments: 0
no-with: 2
radix: 2
vars-on-top: 0
wrap-iife: 2
yoda: 0
# Strict
strict: 0
# Variables
init-declarations: 0
no-catch-shadow: 2
no-delete-var: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-shadow: 0
no-undef-init: 2
no-undef: 0
no-undefined: 0
no-unused-vars: 0
no-use-before-define: 0
# Node.js and CommonJS
callback-return: 2
global-require: 2
handle-callback-err: 2
no-mixed-requires: 0
no-new-require: 0
no-path-concat: 2
no-process-exit: 2
no-restricted-modules: 0
no-sync: 0
# Stylistic Issues
array-bracket-spacing: 0
block-spacing: 0
brace-style: 0
camelcase: 0
comma-spacing: 0
comma-style: 0
computed-property-spacing: 0
consistent-this: 0
eol-last: 0
func-names: 0
func-style: 0
id-length: 0
id-match: 0
indent: 0
jsx-quotes: 0
key-spacing: 0
linebreak-style: 0
lines-around-comment: 0
max-depth: 0
max-len: 0
max-nested-callbacks: 0
max-params: 0
max-statements: [2, 30]
new-cap: 0
new-parens: 0
newline-after-var: 0
no-array-constructor: 0
no-bitwise: 0
no-continue: 0
no-inline-comments: 0
no-lonely-if: 0
no-mixed-spaces-and-tabs: 0
no-multiple-empty-lines: 0
no-negated-condition: 0
no-nested-ternary: 0
no-new-object: 0
no-plusplus: 0
no-restricted-syntax: 0
no-spaced-func: 0
no-ternary: 0
no-trailing-spaces: 0
no-underscore-dangle: 0
no-unneeded-ternary: 0
object-curly-spacing: 0
one-var: 0
operator-assignment: 0
operator-linebreak: 0
padded-blocks: 0
quote-props: 0
quotes: 0
require-jsdoc: 0
semi-spacing: 0
semi: 0
sort-vars: 0
space-after-keywords: 0
space-before-blocks: 0
space-before-function-paren: 0
space-before-keywords: 0
space-in-parens: 0
space-infix-ops: 0
space-return-throw-case: 0
space-unary-ops: 0
spaced-comment: 0
wrap-regex: 0
# ECMAScript 6
arrow-body-style: 0
arrow-parens: 0
arrow-spacing: 0
constructor-super: 0
generator-star-spacing: 0
no-arrow-condition: 0
no-class-assign: 0
no-const-assign: 0
no-dupe-class-members: 0
no-this-before-super: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
prefer-const: 0
prefer-reflect: 0
prefer-spread: 0
prefer-template: 0
require-yield: 0

View File

@@ -1,22 +0,0 @@
{
"undef": true,
"unused": false,
"strict": true,
"browser": true,
"jquery": true,
"devel": true,
"globals": [
"language",
"token",
"currencyCode",
"$",
"token",
"accountID",
"billID",
"currentMonthName",
"previousMonthName",
"nextMonthName",
"everything",
"moment"
]
}

View File

@@ -1,27 +0,0 @@
<?xml version="1.0"?>
<ruleset name="JamesStandard">
<rule ref="Zend">
<exclude name="Zend.NamingConventions.ValidVariableName" />
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace" />
<!--<exclude name="PEAR.Whitespace.ScopeIndent"/>-->
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace"/>
<exclude name="Generic.Formatting.MultipleStatementAlignment.Incorrect" />
<exclude name="PEAR.Functions.FunctionCallSignature" />
</rule>
<!--
Here we change two messages from the same sniff. Note how the
codes are slightly different because the sniff developer has
defined both a MaxExceeded message and a TooLong message. In the
case of this sniff, one is used for warnings and one is used
for errors.
-->
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="160"/>
<property name="absoluteLineLimit" value="160"/>
</properties>
</rule>
</ruleset>

View File

@@ -1,322 +0,0 @@
<code_scheme name="Use This One">
<option name="RIGHT_MARGIN" value="160" />
<CoffeeScriptCodeStyleSettings>
<option name="SPACE_BEFORE_PROPERTY_COLON" value="true" />
</CoffeeScriptCodeStyleSettings>
<JSCodeStyleSettings>
<option name="ALIGN_MULTILINE_VAR_DECLARATION" value="true" />
</JSCodeStyleSettings>
<PHPCodeStyleSettings>
<option name="ALIGN_KEY_VALUE_PAIRS" value="true" />
<option name="ALIGN_PHPDOC_PARAM_NAMES" value="true" />
<option name="ALIGN_PHPDOC_COMMENTS" value="true" />
<option name="ALIGN_ASSIGNMENTS" value="true" />
<option name="COMMA_AFTER_LAST_ARRAY_ELEMENT" value="true" />
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
<option name="PHPDOC_WRAP_LONG_LINES" value="true" />
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
<option name="LOWER_CASE_NULL_CONST" value="true" />
<option name="BLANK_LINE_BEFORE_RETURN_STATEMENT" value="true" />
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
<option name="ALIGN_CLASS_CONSTANTS" value="true" />
<option name="FORCE_SHORT_DECLARATION_ARRAY_STYLE" value="true" />
</PHPCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="CoffeeScript">
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
</codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="RIGHT_MARGIN" value="160" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="ALIGN_GROUP_FIELD_DECLARATIONS" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="FOR_STATEMENT_LPAREN_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_RPAREN_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<arrangement>
<tokens>
<token id="modifiers" name="modifiers">
<rules>
<rule>
<match>
<AND>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
<rule>
<match>
<AND>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
<rule>
<match>
<PUBLIC>true</PUBLIC>
</match>
<order>BY_NAME</order>
</rule>
<rule>
<match>
<PROTECTED>true</PROTECTED>
</match>
<order>BY_NAME</order>
</rule>
<rule>
<match>
<PRIVATE>true</PRIVATE>
</match>
<order>BY_NAME</order>
</rule>
</rules>
</token>
<token id="visibility" name="visibility">
<rules>
<rule>
<match>
<PUBLIC>true</PUBLIC>
</match>
</rule>
<rule>
<match>
<PROTECTED>true</PROTECTED>
</match>
</rule>
<rule>
<match>
<PRIVATE>true</PRIVATE>
</match>
</rule>
</rules>
</token>
</tokens>
<groups>
<group>
<type>GETTERS_AND_SETTERS</type>
<order>KEEP</order>
</group>
</groups>
<rules>
<section>
<rule>
<match>
<CONST />
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD />
<PUBLIC />
<STATIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD />
<PROTECTED />
<STATIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD />
<PRIVATE />
<STATIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD />
<PUBLIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD />
<PROTECTED />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD />
<PRIVATE />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<CONSTRUCTOR />
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD />
<PUBLIC />
<STATIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD />
<PROTECTED />
<STATIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD />
<PRIVATE />
<STATIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD />
<PUBLIC />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD />
<PROTECTED />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD />
<PRIVATE />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<TRAIT />
</match>
</rule>
</section>
<section>
<rule>
<match>
<INTERFACE />
</match>
</rule>
</section>
<section>
<rule>
<match>
<CLASS />
</match>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>

View File

@@ -1,63 +0,0 @@
#!/bin/bash
# set testing environment
cp .env.testing .env
# set cover:
cp phpunit.cover.xml phpunit.xml
# delete test databases:
if [ -f storage/database/testing.db ]
then
echo "Will not remove test db"
# rm storage/database/testing.db
fi
if [ -f storage/database/testing-copy.db ]
then
echo "Will not remove test db"
# rm storage/database/testing-copy.db
fi
# test!
if [ -z "$1" ]
then
echo "Running all tests..."
phpunit
fi
# test selective..
dirs=("acceptance/Controllers" "acceptance/Controllers/Auth" "acceptance/Controllers/Chart" "unit")
#
if [ ! -z "$1" ]
then
for i in "${dirs[@]}"
do
firstFile="./tests/$i/$1.php"
secondFile="./tests/$i/$1Test.php"
if [ -f "$firstFile" ]
then
# run it!
echo "Now running $firstFile"
phpunit $firstFile
result=$?
fi
if [ -f "$secondFile" ]
then
# run it!
echo "Now running $secondFile"
phpunit $secondFile
result=$?
fi
done
fi
# restore .env file
cp .env.local .env
# restore cover
cp phpunit.default.xml phpunit.xml
exit ${result}

Binary file not shown.

View File

@@ -1,16 +0,0 @@
var elixir = require('laravel-elixir');
/*
|--------------------------------------------------------------------------
| Elixir Asset Management
|--------------------------------------------------------------------------
|
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
| for your Laravel application. By default, we are compiling the Sass
| file for our application, as well as publishing vendor resources.
|
*/
elixir(function(mix) {
mix.sass('app.scss');
});

View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="pcsg-generated-ruleset"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>Created with the PHP Coding Standard Generator. http://edorian.github.com/php-coding-standard-generator/
</description>
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
<properties>
<property name="reportLevel" value="5"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/NPathComplexity">
<properties>
<property name="minimum" value="128"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength">
<properties>
<property name="minimum" value="40"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveParameterList">
<properties>
<property name="minimum" value="5"/>
</properties>
</rule>
<!-- Import rule set and exclude rules -->
<rule ref="rulesets/controversial.xml">
<exclude name="CamelCasePropertyName" />
</rule>
</ruleset>

View File

@@ -1,5 +0,0 @@
suites:
main:
namespace: FireflyIII
psr4_prefix: FireflyIII
src_path: app

View File

@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ phpunit.cover.xml
~ Copyright (C) 2016 thegrumpydictator@gmail.com
~
~ This software may be modified and distributed under the terms
~ of the MIT license. See the LICENSE file for details.
-->
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">app/Http</directory>
</whitelist>
<blacklist>
<directory>vendor/</directory>
<directory>app/Console</directory>
<directory>app/Events</directory>
<directory>app/Exceptions</directory>
<directory>app/Generator</directory>
<directory>app/Handlers</directory>
<directory>app/Helpers</directory>
<directory>app/Jobs</directory>
<directory>app/Listeners</directory>
<directory>app/Models</directory>
<directory>app/Policies</directory>
<directory>app/Providers</directory>
<directory>app/Repositories</directory>
<directory>app/Rules</directory>
<directory>app/Sql</directory>
<directory>app/Support</directory>
<directory>app/Validation</directory>
<!-- and other directories, -->
</blacklist>
</filter>
<!--
Code coverage has never been slower.
-->
<logging>
<log type="coverage-clover" target="./storage/build/clover.xml" charset="UTF-8" />
</logging>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true">
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">app/</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
<listeners>
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
</listeners>
</phpunit>

View File

@@ -1,103 +0,0 @@
#!/bin/bash
searchFile=""
deleteDatabases=false
while getopts ":nhf:" opt; do
case $opt in
n)
# echo "-n was triggered: new database!" >&2
deleteDatabases=true
;;
f)
#echo "-f was triggered: file! $OPTARG" >&2
searchFile=$OPTARG
;;
h)
echo "n: new database" >&2
echo "f: which file to run" >&2
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done
# set testing environment
cp .env.testing .env
# set default phpunit.
cp phpunit.default.xml phpunit.xml
# "create" default attachment:
touch storage/upload/at-1.data
touch storage/upload/at-2.data
# delete databses:
if [ "$deleteDatabases" = true ] ; then
echo "Will delete and recreate the databases."
# delete test database:
if [ -f storage/database/testing.db ]
then
echo "Deleted testing.db"
rm storage/database/testing.db
fi
# delete test database copy:
if [ -f storage/database/testing-copy.db ]
then
echo "Delete testing-copy.db"
rm storage/database/testing-copy.db
fi
fi
# do not delete database:
if [ "$deleteDatabases" = false ] ; then
echo "Will not delete databases."
fi
# test!
if [ "$searchFile" == "" ]
then
echo "Running all tests..."
phpunit
result=$?
fi
# test selective..
dirs=("acceptance/Controllers" "acceptance/Controllers/Auth" "acceptance/Controllers/Chart" "unit")
#
if [ "$searchFile" != "" ]
then
echo "Will run test for '$searchFile'"
for i in "${dirs[@]}"
do
firstFile="./tests/$i/$searchFile.php"
secondFile="./tests/$i/"$searchFile"Test.php"
if [ -f "$firstFile" ]
then
# run it!
echo "Found file '$firstFile'"
phpunit --verbose $firstFile
result=$?
fi
if [ -f "$secondFile" ]
then
# run it!
echo "Found file '$secondFile'"
phpunit --verbose $secondFile
result=$?
fi
done
fi
# restore .env file
cp .env.local .env
exit ${result}

View File

@@ -1 +0,0 @@
These are some of the files I use for code formatting, PHPMD and PHPCS.

View File

@@ -7,11 +7,13 @@
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Bootstrap;
use Illuminate\Log\Writer;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bootstrap\ConfigureLogging as IlluminateConfigureLogging;
use Illuminate\Log\Writer;
/**
* Class ConfigureLogging
@@ -24,20 +26,20 @@ class ConfigureLogging extends IlluminateConfigureLogging
* @param Application $app
* @param Writer $log
*/
protected function configureSingleHandler(Application $app, Writer $log)
protected function configureDailyHandler(Application $app, Writer $log)
{
$log->useFiles($app->storagePath().'/logs/firefly-iii.log');
$log->useDailyFiles(
$app->storagePath() . '/logs/firefly-iii.log',
$app->make('config')->get('app.log_max_files', 5)
);
}
/**
* @param Application $app
* @param Writer $log
*/
protected function configureDailyHandler(Application $app, Writer $log)
protected function configureSingleHandler(Application $app, Writer $log)
{
$log->useDailyFiles(
$app->storagePath().'/logs/firefly-iii.log',
$app->make('config')->get('app.log_max_files', 5)
);
$log->useFiles($app->storagePath() . '/logs/firefly-iii.log');
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* EncryptFile.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use Crypt;
use Illuminate\Console\Command;
/**
* Class EncryptFile
*
* @package FireflyIII\Console\Commands
*/
class EncryptFile extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Encrypts a file and places it in the storage/upload directory.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:encrypt {file} {key}';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$file = e(strval($this->argument('file')));
if (!file_exists($file)) {
$this->error(sprintf('File "%s" does not seem to exist.', $file));
return;
}
$content = file_get_contents($file);
$content = Crypt::encrypt($content);
$newName = e(strval($this->argument('key'))) . '.upload';
$path = storage_path('upload') . '/' . $newName;
file_put_contents($path, $content);
$this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path));
}
}

View File

@@ -0,0 +1,120 @@
<?php
/**
* Import.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use FireflyIII\Import\ImportProcedure;
use FireflyIII\Import\Logging\CommandHandler;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Log;
/**
* Class Import
*
* @package FireflyIII\Console\Commands
*/
class Import extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import stuff into Firefly III.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:import {key}';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$jobKey = $this->argument('key');
$job = ImportJob::whereKey($jobKey)->first();
if (!$this->isValid($job)) {
return;
}
$this->line('Going to import job with key "' . $job->key . '" of type ' . $job->file_type);
$monolog = Log::getMonolog();
$handler = new CommandHandler($this);
$monolog->pushHandler($handler);
$result = ImportProcedure::runImport($job);
/**
* @var int $index
* @var TransactionJournal $journal
*/
foreach ($result as $index => $journal) {
if (!is_null($journal->id)) {
$this->line(sprintf('Line #%d has been imported as transaction #%d.', $index, $journal->id));
continue;
}
$this->error(sprintf('Could not store line #%d', $index));
}
$this->line('The import has completed.');
// get any errors from the importer:
$extendedStatus = $job->extended_status;
if (isset($extendedStatus['errors']) && count($extendedStatus['errors']) > 0) {
$this->line(sprintf('The following %d error(s) occured during the import:', count($extendedStatus['errors'])));
foreach ($extendedStatus['errors'] as $error) {
$this->error($error);
}
}
return;
}
/**
* @param ImportJob $job
*
* @return bool
*/
private function isValid(ImportJob $job): bool
{
if (is_null($job)) {
$this->error('This job does not seem to exist.');
return false;
}
if ($job->status != 'settings_complete') {
$this->error('This job is not ready to be imported.');
return false;
}
return true;
}
}

View File

@@ -1,9 +1,16 @@
<?php
/**
* UpgradeFireflyInstructions.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use Config;
use Illuminate\Console\Command;
/**
@@ -18,7 +25,7 @@ class UpgradeFireflyInstructions extends Command
*
* @var string
*/
protected $description = 'Command description';
protected $description = 'Instructions in case of upgrade trouble.';
/**
* The name and signature of the console command.
*
@@ -37,23 +44,29 @@ class UpgradeFireflyInstructions extends Command
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
$version = Config::get('firefly.version');
$config = Config::get('upgrade.text');
$text = $config[$version] ?? null;
/** @var string $version */
$version = config('firefly.version');
$config = config('upgrade.text');
$text = null;
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
if (substr($version, 0, $len) === $compare) {
$text = $config[$compare];
}
}
$this->line('+------------------------------------------------------------------------------+');
$this->line('');
if (is_null($text)) {
$this->line('Thank you for installing Firefly III, v' . $version);
$this->line('If you are upgrading from a previous version,');
$this->info('there are no extra upgrade instructions.');
$this->info('There are no extra upgrade instructions.');
$this->line('Firefly III should be ready for use.');
} else {
$this->line('Thank you for installing Firefly III, v' . $version);

View File

@@ -0,0 +1,309 @@
<?php
/**
* VerifyDatabase.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use Crypt;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use stdClass;
/**
* Class VerifyDatabase
*
* @package FireflyIII\Console\Commands
*/
class VerifyDatabase extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Will verify your database.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:verify';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
// accounts with no transactions.
$this->reportAccounts();
// budgets with no limits
$this->reportBudgetLimits();
// budgets with no transactions
$this->reportBudgets();
// categories with no transactions
$this->reportCategories();
// tags with no transactions
$this->reportTags();
// sum of transactions is not zero.
$this->reportSum();
// any deleted transaction journals that have transactions that are NOT deleted:
$this->reportJournals();
// deleted transactions that are connected to a not deleted journal.
$this->reportTransactions();
// deleted accounts that still have not deleted transactions or journals attached to them.
$this->reportDeletedAccounts();
// report on journals with no transactions at all.
$this->reportNoTransactions();
}
/**
* Reports on accounts with no transactions.
*/
private function reportAccounts()
{
$set = Account
::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
->groupBy('accounts.id')
->having('transaction_count', '=', 0)
->get(
['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email',
DB::raw('COUNT(`transactions`.`id`) AS `transaction_count`')]
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$name = $entry->name;
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $name);
$this->line($line);
}
}
/**
* Reports on budgets with no budget limits (which makes them pointless).
*/
private function reportBudgetLimits()
{
$set = Budget
::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
->groupBy('budgets.id')
->having('budget_limit_count', '=', 0)
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email', DB::raw('COUNT(`budget_limits`.`id`) AS `budget_limit_count`')]);
/** @var stdClass $entry */
foreach ($set as $entry) {
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has budget #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
. '") which has no budget limits.';
$this->line($line);
}
}
/**
* Reports on budgets without any transactions.
*/
private function reportBudgets()
{
$set = Budget
::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
->distinct()
->whereNull('budget_transaction_journal.budget_id')
->whereNull('budgets.deleted_at')
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has budget #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
. '") which has no transactions.';
$this->line($line);
}
}
/**
* Reports on categories without any transactions.
*/
private function reportCategories()
{
$set = Category
::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')
->leftJoin('users', 'categories.user_id', '=', 'users.id')
->distinct()
->whereNull('category_transaction_journal.category_id')
->whereNull('categories.deleted_at')
->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has category #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
. '") which has no transactions.';
$this->line($line);
}
}
/**
* Reports on deleted accounts that still have not deleted transactions or journals attached to them.
*/
private function reportDeletedAccounts()
{
$set = Account
::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->whereNotNull('accounts.deleted_at')
->whereNotNull('transactions.id')
->where(
function (Builder $q) {
$q->whereNull('transactions.deleted_at');
$q->orWhereNull('transaction_journals.deleted_at');
}
)
->get(
['accounts.id as account_id', 'accounts.deleted_at as account_deleted_at', 'transactions.id as transaction_id',
'transactions.deleted_at as transaction_deleted_at', 'transaction_journals.id as journal_id',
'transaction_journals.deleted_at as journal_deleted_at']
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$date = is_null($entry->transaction_deleted_at) ? $entry->journal_deleted_at : $entry->transaction_deleted_at;
$this->error(
'Error: Account #' . $entry->account_id . ' should have been deleted, but has not.' .
' Find it in the table called `accounts` and change the `deleted_at` field to: "' . $date . '"'
);
}
}
/**
* Any deleted transaction journals that have transactions that are NOT deleted:
*/
private function reportJournals()
{
$set = TransactionJournal
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereNotNull('transaction_journals.deleted_at')// USE THIS
->whereNull('transactions.deleted_at')
->whereNotNull('transactions.id')
->get(
[
'transaction_journals.id as journal_id',
'transaction_journals.description',
'transaction_journals.deleted_at as journal_deleted',
'transactions.id as transaction_id',
'transactions.deleted_at as transaction_deleted_at']
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$this->error(
'Error: Transaction #' . $entry->transaction_id . ' should have been deleted, but has not.' .
' Find it in the table called `transactions` and change the `deleted_at` field to: "' . $entry->journal_deleted . '"'
);
}
}
private function reportNoTransactions()
{
/*
* select transaction_journals.id, count(transactions.id) as transaction_count from transaction_journals
left join transactions ON transaction_journals.id = transactions.transaction_journal_id
group by transaction_journals.id
having transaction_count = 0
*/
$set = TransactionJournal
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->groupBy('transaction_journals.id')
->having('transaction_count', '=', 0)
->get(['transaction_journals.id', DB::raw('COUNT(`transactions`.`id`) as `transaction_count`')]);
foreach ($set as $entry) {
$this->error(
'Error: Journal #' . $entry->id . ' has zero transactions. Open table `transaction_journals` and delete the entry with id #' . $entry->id
);
}
}
/**
* Reports for each user when the sum of their transactions is not zero.
*/
private function reportSum()
{
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
/** @var User $user */
foreach ($userRepository->all() as $user) {
$sum = strval($user->transactions()->sum('amount'));
if (bccomp($sum, '0') !== 0) {
$this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!');
}
}
}
/**
* Reports on tags without any transactions.
*/
private function reportTags()
{
$set = Tag
::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
->leftJoin('users', 'tags.user_id', '=', 'users.id')
->distinct()
->whereNull('tag_transaction_journal.tag_id')
->whereNull('tags.deleted_at')
->get(['tags.id', 'tags.tag', 'tags.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has tag #' . $entry->id . ' ("' . $entry->tag
. '") which has no transactions.';
$this->line($line);
}
}
/**
* Reports on deleted transactions that are connected to a not deleted journal.
*/
private function reportTransactions()
{
$set = Transaction
::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereNotNull('transactions.deleted_at')
->whereNull('transaction_journals.deleted_at')
->get(
['transactions.id as transaction_id', 'transactions.deleted_at as transaction_deleted', 'transaction_journals.id as journal_id',
'transaction_journals.deleted_at']
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$this->error(
'Error: Transaction journal #' . $entry->journal_id . ' should have been deleted, but has not.' .
' Find it in the table called `transaction_journals` and change the `deleted_at` field to: "' . $entry->transaction_deleted . '"'
);
}
}
}

View File

@@ -1,6 +1,4 @@
<?php
declare(strict_types = 1);
/**
* Kernel.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -9,10 +7,14 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console;
use FireflyIII\Console\Commands\EncryptFile;
use FireflyIII\Console\Commands\Import;
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
use Illuminate\Console\Scheduling\Schedule;
use FireflyIII\Console\Commands\VerifyDatabase;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
/**
@@ -30,16 +32,17 @@ class Kernel extends ConsoleKernel
*
* @var array
*/
protected $bootstrappers = [
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
'FireflyIII\Bootstrap\ConfigureLogging',
'Illuminate\Foundation\Bootstrap\HandleExceptions',
'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\SetRequestForConsole',
'Illuminate\Foundation\Bootstrap\RegisterProviders',
'Illuminate\Foundation\Bootstrap\BootProviders',
];
protected $bootstrappers
= [
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
'FireflyIII\Bootstrap\ConfigureLogging',
'Illuminate\Foundation\Bootstrap\HandleExceptions',
'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\SetRequestForConsole',
'Illuminate\Foundation\Bootstrap\RegisterProviders',
'Illuminate\Foundation\Bootstrap\BootProviders',
];
/**
* The Artisan commands provided by your application.
@@ -49,18 +52,8 @@ class Kernel extends ConsoleKernel
protected $commands
= [
UpgradeFireflyInstructions::class,
VerifyDatabase::class,
Import::class,
EncryptFile::class,
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
*
* @return void
*
* @SuppressWarnings(PHPMD.UnusedFormalParameters)
*/
protected function schedule(Schedule $schedule)
{
}
}

View File

@@ -0,0 +1,530 @@
<?php
/**
* AccountCrud.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Crud\Account;
use Carbon\Carbon;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Log;
/**
* Class AccountCrud
*
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
*
* @package FireflyIII\Crud\Account
*/
class AccountCrud implements AccountCrudInterface
{
/** @var User */
private $user;
/** @var array */
private $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber'];
/**
* AccountCrud constructor.
*
* @param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* @param Account $account
* @param Account $moveTo
*
* @return bool
*/
public function destroy(Account $account, Account $moveTo): bool
{
if (!is_null($moveTo->id)) {
DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]);
}
if (!is_null($account)) {
$account->delete();
}
return true;
}
/**
* @param $accountId
*
* @return Account
*/
public function find(int $accountId): Account
{
$account = $this->user->accounts()->find($accountId);
if (is_null($account)) {
return new Account;
}
return $account;
}
/**
* @param string $number
* @param array $types
*
* @return Account
*/
public function findByAccountNumber(string $number, array $types): Account
{
$query = $this->user->accounts()
->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id')
->where('account_meta.name', 'accountNumber')
->where('account_meta.data', json_encode($number));
if (count($types) > 0) {
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$query->whereIn('account_types.type', $types);
}
/** @var Collection $accounts */
$accounts = $query->get(['accounts.*']);
if ($accounts->count() > 0) {
return $accounts->first();
}
return new Account;
}
/**
* @param string $iban
* @param array $types
*
* @return Account
*/
public function findByIban(string $iban, array $types): Account
{
$query = $this->user->accounts()->where('iban', '!=', '');
if (count($types) > 0) {
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$query->whereIn('account_types.type', $types);
}
$accounts = $query->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
if ($account->iban === $iban) {
return $account;
}
}
return new Account;
}
/**
* @param string $name
* @param array $types
*
* @return Account
*/
public function findByName(string $name, array $types): Account
{
$query = $this->user->accounts();
if (count($types) > 0) {
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$query->whereIn('account_types.type', $types);
}
$accounts = $query->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
if ($account->name === $name) {
return $account;
}
}
return new Account;
}
/**
* @param array $accountIds
*
* @return Collection
*/
public function getAccountsById(array $accountIds): Collection
{
/** @var Collection $result */
$query = $this->user->accounts()->with(
['accountmeta' => function (HasMany $query) {
$query->where('name', 'accountRole');
}]
);
if (count($accountIds) > 0) {
$query->whereIn('accounts.id', $accountIds);
}
$result = $query->get(['accounts.*']);
$result = $result->sortBy(
function (Account $account) {
return strtolower($account->name);
}
);
return $result;
}
/**
* @param array $types
*
* @return Collection
*/
public function getAccountsByType(array $types): Collection
{
/** @var Collection $result */
$query = $this->user->accounts()->with(
['accountmeta' => function (HasMany $query) {
$query->where('name', 'accountRole');
}]
);
if (count($types) > 0) {
$query->accountTypeIn($types);
}
$result = $query->get(['accounts.*']);
$result = $result->sortBy(
function (Account $account) {
return strtolower($account->name);
}
);
return $result;
}
/**
* @param array $data
*
* @return Account
*/
public function store(array $data): Account
{
$newAccount = $this->storeAccount($data);
if (!is_null($newAccount->id)) {
$this->storeMetadata($newAccount, $data);
}
if ($data['openingBalance'] != 0) {
$this->storeInitialBalance($newAccount, $data);
}
return $newAccount;
}
/**
* @param $account
* @param $name
* @param $value
*
* @return AccountMeta
*/
public function storeMeta(Account $account, string $name, $value): AccountMeta
{
return AccountMeta::create(['name' => $name, 'data' => $value, 'account_id' => $account->id,]);
}
/**
* @param Account $account
* @param array $data
*
* @return Account
*/
public function update(Account $account, array $data): Account
{
// update the account:
$account->name = $data['name'];
$account->active = $data['active'] == '1' ? true : false;
$account->virtual_balance = $data['virtualBalance'];
$account->iban = $data['iban'];
$account->save();
$this->updateMetadata($account, $data);
$this->updateInitialBalance($account, $data);
return $account;
}
/**
* @param Account $account
* @param string $type
*
* @return Account
*/
public function updateAccountType(Account $account, string $type): Account
{
$type = AccountType::whereType($type)->first();
if (!is_null($type)) {
$account->accountType()->associate($type);
$account->save();
}
return $this->find($account->id);
}
/**
* @param array $data
*
* @return Account
*/
protected function storeAccount(array $data): Account
{
$type = config('firefly.accountTypeByIdentifier.' . $data['accountType']);
$accountType = AccountType::whereType($type)->first();
$newAccount = new Account(
[
'user_id' => $data['user'],
'account_type_id' => $accountType->id,
'name' => $data['name'],
'virtual_balance' => $data['virtualBalance'],
'active' => $data['active'] === true ? true : false,
'iban' => $data['iban'],
]
);
if (!$newAccount->isValid()) {
// does the account already exist?
$searchData = [
'user_id' => $data['user'],
'account_type_id' => $accountType->id,
'virtual_balance' => $data['virtualBalance'],
'name' => $data['name'],
'iban' => $data['iban'],
];
$existingAccount = Account::firstOrNullEncrypted($searchData);
if (!$existingAccount) {
Log::error('Account create error', $newAccount->getErrors()->toArray());
return new Account;
}
$newAccount = $existingAccount;
}
$newAccount->save();
return $newAccount;
}
/**
* @param Account $account
* @param array $data
*
* @return TransactionJournal
*/
protected function storeInitialBalance(Account $account, array $data): TransactionJournal
{
$amount = $data['openingBalance'];
$user = $data['user'];
$name = $data['name'];
$opposing = $this->storeOpposingAccount($amount, $user, $name);
$transactionType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
$journal = TransactionJournal::create(
[
'user_id' => $data['user'],
'transaction_type_id' => $transactionType->id,
'transaction_currency_id' => $data['openingBalanceCurrency'],
'description' => 'Initial balance for "' . $account->name . '"',
'completed' => true,
'date' => $data['openingBalanceDate'],
'encrypted' => true,
]
);
$firstAccount = $account;
$secondAccount = $opposing;
$firstAmount = $amount;
$secondAmount = $amount * -1;
if ($data['openingBalance'] < 0) {
$firstAccount = $opposing;
$secondAccount = $account;
$firstAmount = $amount * -1;
$secondAmount = $amount;
}
$one = new Transaction(['account_id' => $firstAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $firstAmount]);
$one->save();// first transaction: from
$two = new Transaction(['account_id' => $secondAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $secondAmount]);
$two->save(); // second transaction: to
return $journal;
}
/**
* @param Account $account
* @param array $data
*/
protected function storeMetadata(Account $account, array $data)
{
foreach ($this->validFields as $field) {
if (isset($data[$field])) {
$metaData = new AccountMeta(
[
'account_id' => $account->id,
'name' => $field,
'data' => $data[$field],
]
);
$metaData->save();
}
}
}
/**
* @param Account $account
* @param array $data
*
* @return bool
*/
protected function updateInitialBalance(Account $account, array $data): bool
{
$openingBalance = $this->openingBalanceTransaction($account);
if ($data['openingBalance'] != 0) {
if (!is_null($openingBalance->id)) {
$date = $data['openingBalanceDate'];
$amount = $data['openingBalance'];
return $this->updateJournal($account, $openingBalance, $date, $amount);
}
$this->storeInitialBalance($account, $data);
return true;
}
// else, delete it:
if ($openingBalance) { // opening balance is zero, should we delete it?
$openingBalance->delete(); // delete existing opening balance.
}
return true;
}
/**
* @param Account $account
* @param array $data
*
*/
protected function updateMetadata(Account $account, array $data)
{
foreach ($this->validFields as $field) {
$entry = $account->accountMeta()->where('name', $field)->first();
if (isset($data[$field])) {
// update if new data is present:
if (!is_null($entry)) {
$entry->data = $data[$field];
$entry->save();
continue;
}
$metaData = new AccountMeta(
[
'account_id' => $account->id,
'name' => $field,
'data' => $data[$field],
]
);
$metaData->save();
}
}
}
/**
* @param Account $account
*
* @return TransactionJournal|null
*/
private function openingBalanceTransaction(Account $account): TransactionJournal
{
$journal = TransactionJournal
::sortCorrectly()
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->transactionTypes([TransactionType::OPENING_BALANCE])
->first(['transaction_journals.*']);
if (is_null($journal)) {
return new TransactionJournal;
}
return $journal;
}
/**
* @param float $amount
* @param int $user
* @param string $name
*
* @return Account
*/
private function storeOpposingAccount(float $amount, int $user, string $name):Account
{
$type = $amount < 0 ? 'expense' : 'revenue';
$opposingData = [
'user' => $user,
'accountType' => $type,
'name' => $name . ' initial balance',
'active' => false,
'iban' => '',
'virtualBalance' => 0,
];
return $this->storeAccount($opposingData);
}
/**
* @param Account $account
* @param TransactionJournal $journal
* @param Carbon $date
* @param float $amount
*
* @return bool
*/
private function updateJournal(Account $account, TransactionJournal $journal, Carbon $date, float $amount): bool
{
// update date:
$journal->date = $date;
$journal->save();
// update transactions:
/** @var Transaction $transaction */
foreach ($journal->transactions()->get() as $transaction) {
if ($account->id == $transaction->account_id) {
$transaction->amount = $amount;
$transaction->save();
}
if ($account->id != $transaction->account_id) {
$transaction->amount = $amount * -1;
$transaction->save();
}
}
return true;
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* AccountCrudInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Crud\Account;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use Illuminate\Support\Collection;
/**
* Interface AccountCrudInterface
*
* @package FireflyIII\Crud\Account
*/
interface AccountCrudInterface
{
/**
* @param Account $account
* @param Account $moveTo
*
* @return bool
*/
public function destroy(Account $account, Account $moveTo): bool;
/**
* @param int $accountId
*
* @return Account
*/
public function find(int $accountId): Account;
/**
* @param string $number
* @param array $types
*
* @return Account
*/
public function findByAccountNumber(string $number, array $types): Account;
/**
* @param string $iban
* @param array $types
*
* @return Account
*/
public function findByIban(string $iban, array $types): Account;
/**
* @param string $name
* @param array $types
*
* @return Account
*/
public function findByName(string $name, array $types): Account;
/**
* @param array $accountIds
*
* @return Collection
*/
public function getAccountsById(array $accountIds): Collection;
/**
* @param array $types
*
* @return Collection
*/
public function getAccountsByType(array $types): Collection;
/**
* @param array $data
*
* @return Account
*/
public function store(array $data) : Account;
/**
* @param $account
* @param $name
* @param $value
*
* @return AccountMeta
*/
public function storeMeta(Account $account, string $name, $value): AccountMeta;
/**
* @param Account $account
* @param array $data
*
* @return Account
*/
public function update(Account $account, array $data): Account;
/**
* @param Account $account
* @param string $type
*
* @return Account
*/
public function updateAccountType(Account $account, string $type): Account;
}

216
app/Crud/Split/Journal.php Normal file
View File

@@ -0,0 +1,216 @@
<?php
/**
* Journal.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Crud\Split;
use FireflyIII\Events\TransactionStored;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
* Class Journal
*
* @package FireflyIII\Crud\Split
*/
class Journal implements JournalInterface
{
/** @var User */
private $user;
/**
* AttachmentRepository constructor.
*
* @param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* @param $journal
*
* @return bool
*/
public function markAsComplete(TransactionJournal $journal)
{
$journal->completed = 1;
$journal->save();
return true;
}
/**
* @param TransactionJournal $journal
* @param array $transaction
*
* @return Collection
*/
public function storeTransaction(TransactionJournal $journal, array $transaction): Collection
{
// store accounts (depends on type)
list($sourceAccount, $destinationAccount) = $this->storeAccounts($journal->transactionType->type, $transaction);
// store transaction one way:
/** @var Transaction $one */
$one = Transaction::create(
['account_id' => $sourceAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'] * -1,
'description' => $transaction['description']]
);
$two = Transaction::create(
['account_id' => $destinationAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'],
'description' => $transaction['description']]
);
if (strlen($transaction['category']) > 0) {
$category = Category::firstOrCreateEncrypted(['name' => $transaction['category'], 'user_id' => $journal->user_id]);
$one->categories()->save($category);
$two->categories()->save($category);
}
if (intval($transaction['budget_id']) > 0) {
$budget = Budget::find($transaction['budget_id']);
$one->budgets()->save($budget);
$two->budgets()->save($budget);
}
if ($transaction['piggy_bank_id'] > 0) {
$transaction['date'] = $journal->date->format('Y-m-d');
event(new TransactionStored($transaction));
}
return new Collection([$one, $two]);
}
/**
* @param TransactionJournal $journal
* @param array $data
*
* @return TransactionJournal
*/
public function updateJournal(TransactionJournal $journal, array $data): TransactionJournal
{
$journal->description = $data['journal_description'];
$journal->transaction_currency_id = $data['journal_currency_id'];
$journal->date = $data['date'];
$journal->interest_date = $data['interest_date'];
$journal->book_date = $data['book_date'];
$journal->process_date = $data['process_date'];
$journal->save();
// delete original transactions, and recreate them.
$journal->transactions()->delete();
foreach ($data['transactions'] as $transaction) {
$this->storeTransaction($journal, $transaction);
}
$journal->completed = true;
$journal->save();
return $journal;
}
/**
* @param string $type
* @param array $transaction
*
* @return array
* @throws FireflyException
*/
private function storeAccounts(string $type, array $transaction): array
{
$sourceAccount = null;
$destinationAccount = null;
switch ($type) {
case TransactionType::WITHDRAWAL:
list($sourceAccount, $destinationAccount) = $this->storeWithdrawalAccounts($transaction);
break;
case TransactionType::DEPOSIT:
list($sourceAccount, $destinationAccount) = $this->storeDepositAccounts($transaction);
break;
case TransactionType::TRANSFER:
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $transaction['source_account_id'])->first();
$destinationAccount = Account::where('user_id', $this->user->id)->where('id', $transaction['destination_account_id'])->first();
break;
default:
throw new FireflyException('Cannot handle ' . e($type));
}
return [$sourceAccount, $destinationAccount];
}
/**
* @param array $data
*
* @return array
*/
private function storeDepositAccounts(array $data): array
{
$destinationAccount = Account::where('user_id', $this->user->id)->where('id', $data['destination_account_id'])->first(['accounts.*']);
if (isset($data['source_account_name']) && strlen($data['source_account_name']) > 0) {
$sourceType = AccountType::where('type', 'Revenue account')->first();
$sourceAccount = Account::firstOrCreateEncrypted(
['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => $data['source_account_name'], 'active' => 1]
);
return [$sourceAccount, $destinationAccount];
}
$sourceType = AccountType::where('type', 'Cash account')->first();
$sourceAccount = Account::firstOrCreateEncrypted(
['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => 'Cash account', 'active' => 1]
);
return [$sourceAccount, $destinationAccount];
}
/**
* @param array $data
*
* @return array
*/
private function storeWithdrawalAccounts(array $data): array
{
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $data['source_account_id'])->first(['accounts.*']);
if (strlen($data['destination_account_name']) > 0) {
$destinationType = AccountType::where('type', 'Expense account')->first();
$destinationAccount = Account::firstOrCreateEncrypted(
[
'user_id' => $this->user->id,
'account_type_id' => $destinationType->id,
'name' => $data['destination_account_name'],
'active' => 1,
]
);
return [$sourceAccount, $destinationAccount];
}
$destinationType = AccountType::where('type', 'Cash account')->first();
$destinationAccount = Account::firstOrCreateEncrypted(
['user_id' => $this->user->id, 'account_type_id' => $destinationType->id, 'name' => 'Cash account', 'active' => 1]
);
return [$sourceAccount, $destinationAccount];
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* JournalInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Crud\Split;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
/**
* Interface JournalInterface
*
* @package FireflyIII\Crud\Split
*/
interface JournalInterface
{
/**
* @param $journal
*
* @return bool
*/
public function markAsComplete(TransactionJournal $journal);
/**
* @param TransactionJournal $journal
* @param array $transaction
*
* @return Collection
*/
public function storeTransaction(TransactionJournal $journal, array $transaction): Collection;
/**
* @param TransactionJournal $journal
* @param array $data
*
* @return TransactionJournal
*/
public function updateJournal(TransactionJournal $journal, array $data): TransactionJournal;
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* BudgetLimitStored.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use Carbon\Carbon;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Queue\SerializesModels;
/**
* Class BudgetLimitStored
*
* @package FireflyIII\Events
*/
class BudgetLimitStored extends Event
{
use SerializesModels;
/** @var BudgetLimit */
public $budgetLimit;
/** @var Carbon */
public $end; // the only variable we can't get from the budget limit (if necessary).
/**
* BudgetLimitEvents constructor.
*
* @param BudgetLimit $budgetLimit
* @param Carbon $end
*/
public function __construct(BudgetLimit $budgetLimit, Carbon $end)
{
//
$this->budgetLimit = $budgetLimit;
$this->end = $end;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* BudgetLimitUpdated.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use Carbon\Carbon;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Queue\SerializesModels;
/**
* Class BudgetLimitUpdated
*
* @package FireflyIII\Events
*/
class BudgetLimitUpdated extends Event
{
use SerializesModels;
/** @var BudgetLimit */
public $budgetLimit;
/** @var Carbon */
public $end; // the only variable we can't get from the budget limit (if necessary).
/**
* BudgetLimitEvents constructor.
*
* @param BudgetLimit $budgetLimit
* @param Carbon $end
*/
public function __construct(BudgetLimit $budgetLimit, Carbon $end)
{
//
$this->budgetLimit = $budgetLimit;
$this->end = $end;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Event.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* ResendConfirmation.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\User;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* TransactionJournalStored.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,11 +7,12 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Queue\SerializesModels;
use Log;
/**
* Class TransactionJournalStored
@@ -35,7 +35,6 @@ class TransactionJournalStored extends Event
*/
public function __construct(TransactionJournal $journal, int $piggyBankId)
{
Log::debug('Created new TransactionJournalStored.');
//
$this->journal = $journal;
$this->piggyBankId = $piggyBankId;

View File

@@ -1,11 +1,18 @@
<?php
/**
* TransactionJournalUpdated.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Queue\SerializesModels;
use Log;
/**
* Class TransactionJournalUpdated
@@ -26,7 +33,6 @@ class TransactionJournalUpdated extends Event
*/
public function __construct(TransactionJournal $journal)
{
Log::debug('Created new TransactionJournalUpdated');
//
$this->journal = $journal;
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* TransactionStored.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use Illuminate\Queue\SerializesModels;
/**
* Class TransactionJournalStored
*
* @package FireflyIII\Events
*/
class TransactionStored extends Event
{
use SerializesModels;
public $transaction = [];
/**
* Create a new event instance.
*
* @param array $transaction
*/
public function __construct(array $transaction)
{
//
$this->transaction = $transaction;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* UserIsConfirmed.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\User;
use Illuminate\Queue\SerializesModels;
/**
* Class UserIsConfirmed
*
* @package FireflyIII\Events
*/
class UserIsConfirmed extends Event
{
use SerializesModels;
public $ipAddress;
public $user;
/**
* Create a new event instance.
*
* @param User $user
* @param string $ipAddress
*/
public function __construct(User $user, string $ipAddress)
{
$this->user = $user;
$this->ipAddress = $ipAddress;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* UserIsDeleted.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\User;
use Illuminate\Queue\SerializesModels;
/**
* Class UserIsDeleted
*
* @package FireflyIII\Events
*/
class UserIsDeleted extends Event
{
use SerializesModels;
public $ipAddress;
public $user;
/**
* Create a new event instance.
*
* @param User $user
* @param string $ipAddress
*/
public function __construct(User $user, string $ipAddress)
{
$this->user = $user;
$this->ipAddress = $ipAddress;
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* UserRegistration.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\User;

View File

@@ -1,4 +1,12 @@
<?php
/**
* FireflyException.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Exceptions;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Handler.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Exceptions;
@@ -6,7 +14,6 @@ use Auth;
use ErrorException;
use Exception;
use FireflyIII\Jobs\MailError;
use FireflyIII\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
@@ -66,9 +73,14 @@ class Handler extends ExceptionHandler
{
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
$user = Auth::check() ? Auth::user() : new User;
$userData = [
'id' => 0,
'email' => 'unknown@example.com',
];
if (Auth::check()) {
$userData['id'] = Auth::user()->id;
$userData['email'] = Auth::user()->email;
}
$data = [
'class' => get_class($exception),
'errorMessage' => $exception->getMessage(),
@@ -80,7 +92,7 @@ class Handler extends ExceptionHandler
];
// create job that will mail.
$job = new MailError($user, env('SITE_OWNER'), Request::ip(), $data);
$job = new MailError($userData, env('SITE_OWNER'), Request::ip(), $data);
dispatch($job);
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* NotImplementedException.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Exceptions;

View File

@@ -1,4 +1,12 @@
<?php
/**
* ValidationException.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Exceptions;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* AttachmentCollector.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Collector;
use Amount;
@@ -44,7 +45,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
*/
public function __construct(ExportJob $job)
{
$this->repository = app('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface');
/** @var AttachmentRepositoryInterface repository */
$this->repository = app(AttachmentRepositoryInterface::class);
// make storage:
$this->uploadDisk = Storage::disk('upload');
$this->exportDisk = Storage::disk('export');
@@ -68,8 +70,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
// put the explanation string in a file and attach it as well.
$file = $this->job->key . '-Source of all your attachments explained.txt';
$this->exportDisk->put($file, $this->explanationString);
Log::debug('Also put explanation file "' . $file . '" in the zip.');
$this->getFiles()->push($file);
return true;
}
@@ -81,15 +83,16 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
/** @var TransactionJournal $journal */
$journal = $attachment->attachable;
$args = [
'attachment_name' => $attachment->filename,
'attachment_name' => e($attachment->filename),
'attachment_id' => $attachment->id,
'type' => strtolower($journal->transactionType->type),
'description' => $journal->description,
'description' => e($journal->description),
'journal_id' => $journal->id,
'date' => $journal->date->formatLocalized(strval(trans('config.month_and_day'))),
'amount' => Amount::formatJournal($journal, false),
];
$string = trans('firefly.attachment_explanation', $args) . "\n";
Log::debug('Appended explanation string', ['string' => $string]);
$this->explanationString .= $string;
}
@@ -102,14 +105,12 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
private function exportAttachment(Attachment $attachment): bool
{
$file = $attachment->fileName();
Log::debug('Original file is at "' . $file . '".');
if ($this->uploadDisk->exists($file)) {
try {
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getFiles()->push($exportFile);
Log::debug('Stored file content in new file "' . $exportFile . '", which will be in the final zip file.');
// explain:
$this->explain($attachment);
@@ -142,8 +143,6 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
{
$attachments = $this->repository->get();
Log::debug('Found ' . $attachments->count() . ' attachments.');
return $attachments;
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BasicCollector.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Collector;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* CollectorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Collector;
use Illuminate\Support\Collection;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* UploadCollector.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Collector;
use Auth;
@@ -28,10 +29,12 @@ class UploadCollector extends BasicCollector implements CollectorInterface
private $expected;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $exportDisk;
private $importKeys = [];
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $uploadDisk;
/**
*
* AttachmentCollector constructor.
*
* @param ExportJob $job
@@ -40,10 +43,17 @@ class UploadCollector extends BasicCollector implements CollectorInterface
{
parent::__construct($job);
Log::debug('Going to collect attachments', ['key' => $job->key]);
// make storage:
$this->uploadDisk = Storage::disk('upload');
$this->exportDisk = Storage::disk('export');
$this->expected = 'csv-upload-' . Auth::user()->id . '-';
// file names associated with the old import routine.
$this->expected = 'csv-upload-' . Auth::user()->id . '-';
// for the new import routine:
$this->getImportKeys();
}
/**
@@ -53,14 +63,28 @@ class UploadCollector extends BasicCollector implements CollectorInterface
{
// grab upload directory.
$files = $this->uploadDisk->files();
Log::debug('Found ' . count($files) . ' files in the upload directory.');
foreach ($files as $entry) {
$this->processOldUpload($entry);
$this->processUpload($entry);
}
return true;
}
/**
*
*/
private function getImportKeys()
{
$set = Auth::user()->importJobs()->where('status', 'import_complete')->get(['import_jobs.*']);
if ($set->count() > 0) {
$keys = $set->pluck('key')->toArray();
$this->importKeys = $keys;
}
Log::debug('Valid import keys are ', $this->importKeys);
}
/**
* @param string $entry
*
@@ -81,15 +105,32 @@ class UploadCollector extends BasicCollector implements CollectorInterface
*
* @return bool
*/
private function isValidFile(string $entry): bool
private function isImportFile(string $entry): bool
{
$len = strlen($this->expected);
if (substr($entry, 0, $len) === $this->expected) {
Log::debug($entry . ' is part of this users original uploads.');
$name = str_replace('.upload', '', $entry);
if (in_array($name, $this->importKeys)) {
Log::debug(sprintf('Import file "%s" is in array', $name), $this->importKeys);
return true;
}
Log::debug(sprintf('Import file "%s" is NOT in array', $name), $this->importKeys);
return false;
}
/**
* @param string $entry
*
* @return bool
*/
private function isOldImport(string $entry): bool
{
$len = strlen($this->expected);
// file is part of the old import routine:
if (substr($entry, 0, $len) === $this->expected) {
return true;
}
Log::debug($entry . ' is not part of this users original uploads.');
return false;
}
@@ -97,24 +138,63 @@ class UploadCollector extends BasicCollector implements CollectorInterface
/**
* @param $entry
*/
private function processOldUpload(string $entry)
private function processUpload(string $entry)
{
$content = '';
if ($this->isValidFile($entry)) {
try {
$content = Crypt::decrypt($this->uploadDisk->get($entry));
} catch (DecryptException $e) {
Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage());
}
// file is old import:
if ($this->isOldImport($entry)) {
$this->saveOldImportFile($entry);
}
if (strlen($content) > 0) {
// continue with file:
$date = $this->getOriginalUploadDate($entry);
$file = $this->job->key . '-Old CSV import dated ' . $date . '.csv';
Log::debug('Will put "' . $file . '" in the zip file.');
// file is current import.
if ($this->isImportFile($entry)) {
$this->saveImportFile($entry);
}
}
/**
* @param string $entry
*/
private function saveImportFile(string $entry)
{
// find job associated with import file:
$name = str_replace('.upload', '', $entry);
$job = Auth::user()->importJobs()->where('key', $name)->first();
$content = '';
try {
$content = Crypt::decrypt($this->uploadDisk->get($entry));
} catch (DecryptException $e) {
Log::error('Could not decrypt old import file ' . $entry . '. Skipped because ' . $e->getMessage());
}
if (!is_null($job) && strlen($content) > 0) {
// add to export disk.
$date = $job->created_at->format('Y-m-d');
$file = sprintf('%s-Old %s import dated %s.%s', $this->job->key, strtoupper($job->file_type), $date, $job->file_type);
$this->exportDisk->put($file, $content);
$this->getFiles()->push($file);
}
}
/**
* @param string $entry
*/
private function saveOldImportFile(string $entry)
{
$content = '';
try {
$content = Crypt::decrypt($this->uploadDisk->get($entry));
} catch (DecryptException $e) {
Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage());
}
if (strlen($content) > 0) {
// add to export disk.
$date = $this->getOriginalUploadDate($entry);
$file = $this->job->key . '-Old import dated ' . $date . '.csv';
$this->exportDisk->put($file, $content);
$this->getFiles()->push($file);
}
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* ConfigurationFile.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,10 +7,12 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export;
use FireflyIII\Export\Entry\Entry;
use FireflyIII\Models\ExportJob;
use Log;
use Storage;
/**
@@ -42,8 +43,8 @@ class ConfigurationFile
*/
public function make(): string
{
$fields = array_keys(get_class_vars(Entry::class));
$types = Entry::getTypes();
$fields = array_keys(Entry::getFieldsAndTypes());
$types = Entry::getFieldsAndTypes();
$configuration = [
'date-format' => 'Y-m-d', // unfortunately, this is hard-coded.
@@ -57,8 +58,6 @@ class ConfigurationFile
$configuration['roles'][] = $types[$field];
}
$file = $this->job->key . '-configuration.json';
Log::debug('Created JSON config file.');
Log::debug('Will put "' . $file . '" in the ZIP file.');
$this->exportDisk->put($file, json_encode($configuration, JSON_PRETTY_PRINT));
return $file;

View File

@@ -1,460 +0,0 @@
<?php
declare(strict_types = 1);
/**
* Entry.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionJournal;
/**
* To extend the exported object, in case of new features in Firefly III for example,
* do the following:
*
* - Add the field(s) to this class
* - Make sure the "fromJournal"-routine fills these fields.
* - Add them to the static function that returns its type (key=value. Remember that the only
* valid types can be found in config/csv.php (under "roles").
*
* These new entries should be should be strings and numbers as much as possible.
*
*
*
* Class Entry
*
* @package FireflyIII\Export
*/
class Entry
{
/** @var string */
public $amount;
/** @var int */
public $billId;
/** @var string */
public $billName;
/** @var int */
public $budgetId;
/** @var string */
public $budgetName;
/** @var int */
public $categoryId;
/** @var string */
public $categoryName;
/** @var string */
public $date;
/** @var string */
public $description;
/** @var string */
public $fromAccountIban;
/** @var int */
public $fromAccountId;
/** @var string */
public $fromAccountName;
public $fromAccountNumber;
/** @var string */
public $fromAccountType;
/** @var string */
public $toAccountIban;
/** @var int */
public $toAccountId;
/** @var string */
public $toAccountName;
public $toAccountNumber;
/** @var string */
public $toAccountType;
/**
* @param TransactionJournal $journal
*
* @return Entry
*/
public static function fromJournal(TransactionJournal $journal)
{
$entry = new self;
$entry->setDescription($journal->description);
$entry->setDate($journal->date->format('Y-m-d'));
$entry->setAmount(TransactionJournal::amount($journal));
/** @var Budget $budget */
$budget = $journal->budgets->first();
if (!is_null($budget)) {
$entry->setBudgetId($budget->id);
$entry->setBudgetName($budget->name);
}
/** @var Category $category */
$category = $journal->categories->first();
if (!is_null($category)) {
$entry->setCategoryId($category->id);
$entry->setCategoryName($category->name);
}
if (!is_null($journal->bill_id)) {
$entry->setBillId($journal->bill_id);
$entry->setBillName($journal->bill->name);
}
/** @var Account $sourceAccount */
$sourceAccount = TransactionJournal::sourceAccount($journal);
$entry->setFromAccountId($sourceAccount->id);
$entry->setFromAccountName($sourceAccount->name);
$entry->setFromAccountIban($sourceAccount->iban);
$entry->setFromAccountType($sourceAccount->accountType->type);
$entry->setFromAccountNumber($sourceAccount->getMeta('accountNumber'));
/** @var Account $destination */
$destination = TransactionJournal::destinationAccount($journal);
$entry->setToAccountId($destination->id);
$entry->setToAccountName($destination->name);
$entry->setToAccountIban($destination->iban);
$entry->setToAccountType($destination->accountType->type);
$entry->setToAccountNumber($destination->getMeta('accountNumber'));
return $entry;
}
/**
* @return array
*/
public static function getTypes(): array
{
// key = field name (see top of class)
// value = field type (see csv.php under 'roles')
return [
'amount' => 'amount',
'date' => 'date-transaction',
'description' => 'description',
'billId' => 'bill-id',
'billName' => 'bill-name',
'budgetId' => 'budget-id',
'budgetName' => 'budget-name',
'categoryId' => 'category-id',
'categoryName' => 'category-name',
'fromAccountId' => 'account-id',
'fromAccountName' => 'account-name',
'fromAccountIban' => 'account-iban',
'fromAccountType' => '_ignore', // no, Firefly cannot import what it exports. I know :D
'toAccountId' => 'opposing-id',
'toAccountName' => 'opposing-name',
'toAccountIban' => 'opposing-iban',
'toAccountType' => '_ignore',
];
}
/**
* @return string
*/
public function getAmount(): string
{
return $this->amount;
}
/**
* @param string $amount
*/
public function setAmount(string $amount)
{
$this->amount = $amount;
}
/**
* @return int
*/
public function getBillId(): int
{
return $this->billId;
}
/**
* @param int $billId
*/
public function setBillId(int $billId)
{
$this->billId = $billId;
}
/**
* @return string
*/
public function getBillName(): string
{
return $this->billName;
}
/**
* @param string $billName
*/
public function setBillName(string $billName)
{
$this->billName = $billName;
}
/**
* @return int
*/
public function getBudgetId(): int
{
return $this->budgetId;
}
/**
* @param int $budgetId
*/
public function setBudgetId(int $budgetId)
{
$this->budgetId = $budgetId;
}
/**
* @return string
*/
public function getBudgetName(): string
{
return $this->budgetName;
}
/**
* @param string $budgetName
*/
public function setBudgetName(string $budgetName)
{
$this->budgetName = $budgetName;
}
/**
* @return int
*/
public function getCategoryId(): int
{
return $this->categoryId;
}
/**
* @param int $categoryId
*/
public function setCategoryId(int $categoryId)
{
$this->categoryId = $categoryId;
}
/**
* @return string
*/
public function getCategoryName(): string
{
return $this->categoryName;
}
/**
* @param string $categoryName
*/
public function setCategoryName(string $categoryName)
{
$this->categoryName = $categoryName;
}
/**
* @return string
*/
public function getDate(): string
{
return $this->date;
}
/**
* @param string $date
*/
public function setDate(string $date)
{
$this->date = $date;
}
/**
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription(string $description)
{
$this->description = $description;
}
/**
* @return string
*/
public function getFromAccountIban(): string
{
return $this->fromAccountIban;
}
/**
* @param string $fromAccountIban
*/
public function setFromAccountIban(string $fromAccountIban)
{
$this->fromAccountIban = $fromAccountIban;
}
/**
* @return int
*/
public function getFromAccountId():int
{
return $this->fromAccountId;
}
/**
* @param int $fromAccountId
*/
public function setFromAccountId(int $fromAccountId)
{
$this->fromAccountId = $fromAccountId;
}
/**
* @return string
*/
public function getFromAccountName(): string
{
return $this->fromAccountName;
}
/**
* @param string $fromAccountName
*/
public function setFromAccountName(string $fromAccountName)
{
$this->fromAccountName = $fromAccountName;
}
/**
* @return string
*/
public function getFromAccountNumber(): string
{
return $this->fromAccountNumber;
}
/**
* @param string $fromAccountNumber
*/
public function setFromAccountNumber(string $fromAccountNumber)
{
$this->fromAccountNumber = $fromAccountNumber;
}
/**
* @return string
*/
public function getFromAccountType(): string
{
return $this->fromAccountType;
}
/**
* @param string $fromAccountType
*/
public function setFromAccountType(string $fromAccountType)
{
$this->fromAccountType = $fromAccountType;
}
/**
* @return string
*/
public function getToAccountIban(): string
{
return $this->toAccountIban;
}
/**
* @param string $toAccountIban
*/
public function setToAccountIban(string $toAccountIban)
{
$this->toAccountIban = $toAccountIban;
}
/**
* @return int
*/
public function getToAccountId(): int
{
return $this->toAccountId;
}
/**
* @param int $toAccountId
*/
public function setToAccountId(int $toAccountId)
{
$this->toAccountId = $toAccountId;
}
/**
* @return string
*/
public function getToAccountName(): string
{
return $this->toAccountName;
}
/**
* @param string $toAccountName
*/
public function setToAccountName(string $toAccountName)
{
$this->toAccountName = $toAccountName;
}
/**
* @return string
*/
public function getToAccountNumber(): string
{
return $this->toAccountNumber;
}
/**
* @param string $toAccountNumber
*/
public function setToAccountNumber(string $toAccountNumber)
{
$this->toAccountNumber = $toAccountNumber;
}
/**
* @return string
*/
public function getToAccountType(): string
{
return $this->toAccountType;
}
/**
* @param string $toAccountType
*/
public function setToAccountType(string $toAccountType)
{
$this->toAccountType = $toAccountType;
}
}

130
app/Export/Entry/Entry.php Normal file
View File

@@ -0,0 +1,130 @@
<?php
/**
* Entry.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
/**
* To extend the exported object, in case of new features in Firefly III for example,
* do the following:
*
* - Add the field(s) to this class. If you add more than one related field, add a new object.
* - Make sure the "fromJournal"-routine fills these fields.
* - Add them to the static function that returns its type (key=value. Remember that the only
* valid types can be found in config/csv.php (under "roles").
*
* These new entries should be should be strings and numbers as much as possible.
*
*
*
* Class Entry
*
* @package FireflyIII\Export\Entry
*/
final class Entry
{
/** @var string */
public $amount;
/** @var EntryBill */
public $bill;
/** @var EntryBudget */
public $budget;
/** @var EntryCategory */
public $category;
/** @var string */
public $date;
/** @var string */
public $description;
/** @var EntryAccount */
public $destinationAccount;
/** @var Collection */
public $destinationAccounts;
/** @var EntryAccount */
public $sourceAccount;
/** @var Collection */
public $sourceAccounts;
/**
* Entry constructor.
*/
private function __construct()
{
$this->sourceAccounts = new Collection;
$this->destinationAccounts = new Collection;
}
/**
* @param TransactionJournal $journal
*
* @return Entry
*/
public static function fromJournal(TransactionJournal $journal)
{
$entry = new self;
$entry->description = $journal->description;
$entry->date = $journal->date->format('Y-m-d');
$entry->amount = TransactionJournal::amount($journal);
$entry->budget = new EntryBudget($journal->budgets->first());
$entry->category = new EntryCategory($journal->categories->first());
$entry->bill = new EntryBill($journal->bill);
$sources = TransactionJournal::sourceAccountList($journal);
$destinations = TransactionJournal::destinationAccountList($journal);
$entry->sourceAccount = new EntryAccount($sources->first());
$entry->destinationAccount = new EntryAccount($destinations->first());
foreach ($sources as $source) {
$entry->sourceAccounts->push(new EntryAccount($source));
}
foreach ($destinations as $destination) {
$entry->destinationAccounts->push(new EntryAccount($destination));
}
return $entry;
}
/**
* @return array
*/
public static function getFieldsAndTypes(): array
{
// key = field name (see top of class)
// value = field type (see csv.php under 'roles')
return [
'description' => 'description',
'amount' => 'amount',
'date' => 'date-transaction',
'source_account_id' => 'account-id',
'source_account_name' => 'account-name',
'source_account_iban' => 'account-iban',
'source_account_type' => '_ignore',
'source_account_number' => 'account-number',
'destination_account_id' => 'opposing-id',
'destination_account_name' => 'opposing-name',
'destination_account_iban' => 'opposing-iban',
'destination_account_type' => '_ignore',
'destination_account_number' => 'account-number',
'budget_id' => 'budget-id',
'budget_name' => 'budget-name',
'category_id' => 'category-id',
'category_name' => 'category-name',
'bill_id' => 'bill-id',
'bill_name' => 'bill-name',
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* EntryAccount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\Account;
/**
* Class EntryAccount
*
* @package FireflyIII\Export\Entry
*/
class EntryAccount
{
/** @var int */
public $accountId;
/** @var string */
public $iban;
/** @var string */
public $name;
/** @var string */
public $number;
/** @var string */
public $type;
/**
* EntryAccount constructor.
*
* @param Account $account
*/
public function __construct(Account $account)
{
$this->accountId = $account->id;
$this->name = $account->name;
$this->iban = $account->iban;
$this->type = $account->accountType->type;
$this->number = $account->getMeta('accountNumber');
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* EntryBill.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\Bill;
/**
* Class EntryBill
*
* @package FireflyIII\Export\Entry
*/
class EntryBill
{
/** @var int */
public $billId = '';
/** @var string */
public $name = '';
/**
* EntryBill constructor.
*
* @param Bill $bill
*/
public function __construct(Bill $bill = null)
{
if (!is_null($bill)) {
$this->billId = $bill->id;
$this->name = $bill->name;
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* EntryBudget.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\Budget;
/**
* Class EntryBudget
*
* @package FireflyIII\Export\Entry
*/
class EntryBudget
{
/** @var int */
public $budgetId = '';
/** @var string */
public $name = '';
/**
* EntryBudget constructor.
*
* @param Budget $budget
*/
public function __construct(Budget $budget = null)
{
if (!is_null($budget)) {
$this->budgetId = $budget->id;
$this->name = $budget->name;
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* EntryCategory.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\Category;
/**
* Class EntryCategory
*
* @package FireflyIII\Export\Entry
*/
class EntryCategory
{
/** @var int */
public $categoryId = '';
/** @var string */
public $name = '';
/**
* EntryCategory constructor.
*
* @param Category $category
*/
public function __construct(Category $category = null)
{
if (!is_null($category)) {
$this->categoryId = $category->id;
$this->name = $category->name;
}
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BasicExporter.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Exporter;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* CsvExporter.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,10 +7,14 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Exporter;
use FireflyIII\Export\Entry;
use FireflyIII\Export\Entry\Entry;
use FireflyIII\Export\Entry\EntryAccount;
use FireflyIII\Models\ExportJob;
use Illuminate\Support\Collection;
use League\Csv\Writer;
use SplFileObject;
@@ -54,27 +57,114 @@ class CsvExporter extends BasicExporter implements ExporterInterface
// necessary for CSV writer:
$fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName;
$writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
$rows = [];
// create CSV writer:
$writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
// all rows:
$rows = [];
// add header:
$first = $this->getEntries()->first();
$rows[] = array_keys(get_object_vars($first));
// then the rest:
// Count the maximum number of sources and destinations each entry has. May need to expand the number of export fields:
$maxSourceAccounts = 1;
$maxDestAccounts = 1;
/** @var Entry $entry */
foreach ($this->getEntries() as $entry) {
$rows[] = array_values(get_object_vars($entry));
$sources = $entry->sourceAccounts->count();
$destinations = $entry->destinationAccounts->count();
$maxSourceAccounts = max($maxSourceAccounts, $sources);
$maxDestAccounts = max($maxDestAccounts, $destinations);
}
$rows[] = array_keys($this->getFieldsAndTypes($maxSourceAccounts, $maxDestAccounts));
/** @var Entry $entry */
foreach ($this->getEntries() as $entry) {
// order is defined in Entry::getFieldsAndTypes.
$current = [$entry->description, $entry->amount, $entry->date];
$sourceData = $this->getAccountData($maxSourceAccounts, $entry->sourceAccounts);
$current = array_merge($current, $sourceData);
$destData = $this->getAccountData($maxDestAccounts, $entry->destinationAccounts);
$current = array_merge($current, $destData);
$rest = [$entry->budget->budgetId, $entry->budget->name, $entry->category->categoryId, $entry->category->name, $entry->bill->billId,
$entry->bill->name];
$current = array_merge($current, $rest);
$rows[] = $current;
}
$writer->insertAll($rows);
return true;
}
/**
* @param int $max
* @param Collection $accounts
*
* @return array
*/
private function getAccountData(int $max, Collection $accounts): array
{
$current = [];
for ($i = 0; $i < $max; $i++) {
/** @var EntryAccount $source */
$source = $accounts->get($i);
$currentId = '';
$currentName = '';
$currentIban = '';
$currentType = '';
$currentNumber = '';
if ($source) {
$currentId = $source->accountId;
$currentName = $source->name;
$currentIban = $source->iban;
$currentType = $source->type;
$currentNumber = $source->number;
}
$current[] = $currentId;
$current[] = $currentName;
$current[] = $currentIban;
$current[] = $currentType;
$current[] = $currentNumber;
}
unset($source);
return $current;
}
/**
* @param int $sources
* @param int $destinations
*
* @return array
*/
private function getFieldsAndTypes(int $sources, int $destinations): array
{
// key = field name (see top of class)
// value = field type (see csv.php under 'roles')
$array = [
'description' => 'description',
'amount' => 'amount',
'date' => 'date-transaction',
];
for ($i = 0; $i < $sources; $i++) {
$array['source_account_' . $i . '_id'] = 'account-id';
$array['source_account_' . $i . '_name'] = 'account-name';
$array['source_account_' . $i . '_iban'] = 'account-iban';
$array['source_account_' . $i . '_type'] = '_ignore';
$array['source_account_' . $i . '_number'] = 'account-number';
}
for ($i = 0; $i < $destinations; $i++) {
$array['destination_account_' . $i . '_id'] = 'account-id';
$array['destination_account_' . $i . '_name'] = 'account-name';
$array['destination_account_' . $i . '_iban'] = 'account-iban';
$array['destination_account_' . $i . '_type'] = '_ignore';
$array['destination_account_' . $i . '_number'] = 'account-number';
}
$array['budget_id'] = 'budget-id';
$array['budget_name'] = 'budget-name';
$array['category_id'] = 'category-id';
$array['category_name'] = 'category-name';
$array['bill_id'] = 'bill-id';
$array['bill_name'] = 'bill-name';
return $array;
}
private function tempFile()
{
$this->fileName = $this->job->key . '-records.csv';

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* ExporterInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export\Exporter;
use Illuminate\Support\Collection;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* Processor.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,15 +7,19 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Export;
use Auth;
use Config;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Export\Collector\AttachmentCollector;
use FireflyIII\Export\Collector\UploadCollector;
use FireflyIII\Export\Entry\Entry;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Collection;
use Log;
use Storage;
use ZipArchive;
@@ -77,9 +80,11 @@ class Processor
*/
public function collectAttachments(): bool
{
$attachmentCollector = app('FireflyIII\Export\Collector\AttachmentCollector', [$this->job]);
/** @var AttachmentCollector $attachmentCollector */
$attachmentCollector = app(AttachmentCollector::class, [$this->job]);
$attachmentCollector->run();
$this->files = $this->files->merge($attachmentCollector->getFiles());
return true;
}
@@ -88,16 +93,10 @@ class Processor
*/
public function collectJournals(): bool
{
$args = [$this->accounts, Auth::user(), $this->settings['startDate'], $this->settings['endDate']];
$journalCollector = app('FireflyIII\Repositories\Journal\JournalCollector', $args);
$this->journals = $journalCollector->collect();
Log::debug(
'Collected ' .
$this->journals->count() . ' journals (between ' .
$this->settings['startDate']->format('Y-m-d') . ' and ' .
$this->settings['endDate']->format('Y-m-d')
. ').'
);
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$this->journals = $repository->getJournalsInRange($this->accounts, $this->settings['startDate'], $this->settings['endDate']);
return true;
}
@@ -106,10 +105,12 @@ class Processor
*/
public function collectOldUploads(): bool
{
$uploadCollector = app('FireflyIII\Export\Collector\UploadCollector', [$this->job]);
/** @var UploadCollector $uploadCollector */
$uploadCollector = app(UploadCollector::class, [$this->job]);
$uploadCollector->run();
$this->files = $this->files->merge($uploadCollector->getFiles());
return true;
}
@@ -124,7 +125,7 @@ class Processor
$this->exportEntries->push(Entry::fromJournal($journal));
$count++;
}
Log::debug('Converted ' . $count . ' journals to "Entry" objects.');
return true;
}
@@ -133,8 +134,9 @@ class Processor
*/
public function createConfigFile(): bool
{
$this->configurationMaker = app('FireflyIII\Export\ConfigurationFile', [$this->job]);
$this->configurationMaker = app(ConfigurationFile::class, [$this->job]);
$this->files->push($this->configurationMaker->make());
return true;
}
@@ -147,7 +149,6 @@ class Processor
$zip = new ZipArchive;
$file = $this->job->key . '.zip';
$fullPath = storage_path('export') . '/' . $file;
Log::debug('Will create zip file at ' . $fullPath);
if ($zip->open($fullPath, ZipArchive::CREATE) !== true) {
throw new FireflyException('Cannot store zip file.');
@@ -157,20 +158,14 @@ class Processor
foreach ($this->getFiles() as $entry) {
// is part of this job?
$zipFileName = str_replace($this->job->key . '-', '', $entry);
$result = $zip->addFromString($zipFileName, $disk->get($entry));
if (!$result) {
Log::error('Could not add "' . $entry . '" into zip file as "' . $zipFileName . '".');
}
$zip->addFromString($zipFileName, $disk->get($entry));
}
$zip->close();
// delete the files:
foreach ($this->getFiles() as $file) {
Log::debug('Will now delete file "' . $file . '".');
$disk->delete($file);
}
Log::debug('Done!');
$this->deleteFiles($disk);
return true;
}
@@ -179,13 +174,12 @@ class Processor
*/
public function exportJournals(): bool
{
$exporterClass = Config::get('firefly.export_formats.' . $this->exportFormat);
$exporterClass = config('firefly.export_formats.' . $this->exportFormat);
$exporter = app($exporterClass, [$this->job]);
Log::debug('Going to export ' . $this->exportEntries->count() . ' export entries into ' . $this->exportFormat . ' format.');
$exporter->setEntries($this->exportEntries);
$exporter->run();
$this->files->push($exporter->getFileName());
Log::debug('Added "' . $exporter->getFileName() . '" to the list of files to include in the zip.');
return true;
}
@@ -196,4 +190,14 @@ class Processor
{
return $this->files;
}
/**
* @param FilesystemAdapter $disk
*/
private function deleteFiles(FilesystemAdapter $disk)
{
foreach ($this->getFiles() as $file) {
$disk->delete($file);
}
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* AccountChartGeneratorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Account;
use Carbon\Carbon;
@@ -42,10 +43,10 @@ interface AccountChartGeneratorInterface
/**
* @param Account $account
* @param Carbon $start
* @param Carbon $end
* @param array $labels
* @param array $dataSet
*
* @return array
*/
public function single(Account $account, Carbon $start, Carbon $end): array;
public function single(Account $account, array $labels, array $dataSet): array;
}

View File

@@ -1,11 +1,18 @@
<?php
/**
* ChartJsAccountChartGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Account;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use Illuminate\Support\Collection;
use Steam;
/**
* Class ChartJsAccountChartGenerator
@@ -29,28 +36,6 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
'labels' => [], 'datasets' => [[
'label' => trans('firefly.spent'),
'data' => []]]];
$start->subDay();
$ids = $this->getIdsFromCollection($accounts);
$startBalances = Steam::balancesById($ids, $start);
$endBalances = Steam::balancesById($ids, $end);
$accounts->each(
function (Account $account) use ($startBalances, $endBalances) {
$id = $account->id;
$startBalance = $this->isInArray($startBalances, $id);
$endBalance = $this->isInArray($endBalances, $id);
$diff = bcsub($endBalance, $startBalance);
$account->difference = round($diff, 2);
}
);
$accounts = $accounts->sortByDesc(
function (Account $account) {
return $account->difference;
}
);
foreach ($accounts as $account) {
if ($account->difference > 0) {
$data['labels'][] = $account->name;
@@ -80,7 +65,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
}
foreach ($accounts as $account) {
$set = [
$data['datasets'][] = [
'label' => $account->name,
'fillColor' => 'rgba(220,220,220,0.2)',
'strokeColor' => 'rgba(220,220,220,1)',
@@ -88,20 +73,8 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
'pointStrokeColor' => '#fff',
'pointHighlightFill' => '#fff',
'pointHighlightStroke' => 'rgba(220,220,220,1)',
'data' => [],
'data' => $account->balances,
];
$current = clone $start;
$range = Steam::balanceInRange($account, $start, clone $end);
$previous = round(array_values($range)[0], 2);
while ($current <= $end) {
$format = $current->format('Y-m-d');
$balance = isset($range[$format]) ? round($range[$format], 2) : $previous;
$set['data'][] = $balance;
$previous = $balance;
$current->addDay();
}
$data['datasets'][] = $set;
}
$data['count'] = count($data['datasets']);
@@ -110,71 +83,25 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
/**
* @param Account $account
* @param Carbon $start
* @param Carbon $end
* @param array $labels
* @param array $dataSet
*
* @return array
*/
public function single(Account $account, Carbon $start, Carbon $end): array
public function single(Account $account, array $labels, array $dataSet): array
{
// language:
$format = (string)trans('config.month_and_day');
$data = [
$data = [
'count' => 1,
'labels' => [],
'labels' => $labels,
'datasets' => [
[
'label' => $account->name,
'data' => [],
'data' => $dataSet,
],
],
];
$range = Steam::balanceInRange($account, $start, $end);
$current = clone $start;
$previous = array_values($range)[0];
while ($end >= $current) {
$theDate = $current->format('Y-m-d');
$balance = $range[$theDate] ?? $previous;
$data['labels'][] = $current->formatLocalized($format);
$data['datasets'][0]['data'][] = $balance;
$previous = $balance;
$current->addDay();
}
return $data;
}
/**
* @param Collection $collection
*
* @return array
*/
protected function getIdsFromCollection(Collection $collection): array
{
$ids = [];
foreach ($collection as $entry) {
$ids[] = $entry->id;
}
return array_unique($ids);
}
/**
* @param $array
* @param $entryId
*
* @return string
*/
protected function isInArray($array, $entryId): string
{
if (isset($array[$entryId])) {
return $array[$entryId];
}
return '0';
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BillChartGeneratorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Bill;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* ChartJsBillChartGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Bill;
use FireflyIII\Models\Bill;
@@ -54,11 +55,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
public function single(Bill $bill, Collection $entries): array
{
$format = (string)trans('config.month');
$data = [
'count' => 3,
'labels' => [],
'datasets' => [],
];
$data = ['count' => 3, 'labels' => [], 'datasets' => [],];
$minAmount = [];
$maxAmount = [];
$actualAmount = [];
@@ -67,9 +64,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
$data['labels'][] = $entry->date->formatLocalized($format);
$minAmount[] = round($bill->amount_min, 2);
$maxAmount[] = round($bill->amount_max, 2);
/*
* journalAmount has been collected in BillRepository::getJournals
*/
// journalAmount has been collected in BillRepository::getJournals
$actualAmount[] = round(TransactionJournal::amountPositive($entry), 2);
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BudgetChartGeneratorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Budget;
use Illuminate\Support\Collection;
@@ -19,19 +20,14 @@ use Illuminate\Support\Collection;
*/
interface BudgetChartGeneratorInterface
{
/**
* @param Collection $entries
*
* @return array
*/
public function budget(Collection $entries): array;
/**
* @param Collection $entries
* @param string $dateFormat
*
* @return array
*/
public function budgetLimit(Collection $entries): array;
public function budgetLimit(Collection $entries, string $dateFormat): array;
/**
* @param Collection $entries
@@ -47,6 +43,14 @@ interface BudgetChartGeneratorInterface
*/
public function multiYear(Collection $entries): array;
/**
* @param Collection $entries
* @param string $viewRange
*
* @return array
*/
public function period(Collection $entries, string $viewRange) : array;
/**
* @param Collection $budgets
* @param Collection $entries

View File

@@ -1,11 +1,18 @@
<?php
/**
* ChartJsBudgetChartGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Budget;
use Config;
use Illuminate\Support\Collection;
use Preferences;
use Navigation;
/**
* Class ChartJsBudgetChartGenerator
@@ -14,20 +21,17 @@ use Preferences;
*/
class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
{
/**
*
* @param Collection $entries
* @param string $dateFormat
*
* @return array
*/
public function budget(Collection $entries, $dateFormat = 'month'): array
public function budgetLimit(Collection $entries, string $dateFormat = 'month_and_day'): array
{
// language:
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
$data = [
$format = strval(trans('config.' . $dateFormat));
$data = [
'labels' => [],
'datasets' => [
[
@@ -49,17 +53,6 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
return $data;
}
/**
*
* @param Collection $entries
*
* @return array
*/
public function budgetLimit(Collection $entries): array
{
return $this->budget($entries, 'monthAndDay');
}
/**
* @param Collection $entries
*
@@ -87,6 +80,10 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
$overspent[] = round(bcmul($entry[3], '-1'), 2); // same
}
$data['datasets'][] = [
'label' => trans('firefly.overspent'),
'data' => $overspent,
];
$data['datasets'][] = [
'label' => trans('firefly.left'),
'data' => $left,
@@ -95,12 +92,8 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
'label' => trans('firefly.spent'),
'data' => $spent,
];
$data['datasets'][] = [
'label' => trans('firefly.overspent'),
'data' => $overspent,
];
$data['count'] = count($data['datasets']);
$data['count'] = 3;
return $data;
}
@@ -139,6 +132,42 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
}
/**
* @param Collection $entries
* @param string $viewRange
*
* @return array
*/
public function period(Collection $entries, string $viewRange) : array
{
$data = [
'labels' => [],
'datasets' => [
0 => [
'label' => trans('firefly.budgeted'),
'data' => [],
],
1 => [
'label' => trans('firefly.spent'),
'data' => [],
],
],
'count' => 2,
];
foreach ($entries as $entry) {
$label = Navigation::periodShow($entry['date'], $viewRange);
$data['labels'][] = $label;
// data set 0 is budgeted
// data set 1 is spent:
$data['datasets'][0]['data'][] = $entry['budgeted'];
$data['datasets'][1]['data'][] = round(($entry['spent'] * -1), 2);
}
return $data;
}
/**
* @param Collection $budgets
* @param Collection $entries

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* CategoryChartGeneratorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Category;
use Illuminate\Support\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* ChartJsCategoryChartGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Category;
@@ -20,8 +28,6 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*/
public function all(Collection $entries): array
{
$data = [
'count' => 2,
'labels' => [],
@@ -42,8 +48,8 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
$spent = $entry[2];
$earned = $entry[3];
$data['datasets'][0]['data'][] = bccomp($spent, '0') === 0 ? null : bcmul($spent, '-1');
$data['datasets'][1]['data'][] = bccomp($earned, '0') === 0 ? null : $earned;
$data['datasets'][0]['data'][] = bccomp($spent, '0') === 0 ? null : round(bcmul($spent, '-1'), 4);
$data['datasets'][1]['data'][] = bccomp($earned, '0') === 0 ? null : round($earned, 4);
}
return $data;
@@ -116,18 +122,9 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*/
public function multiYear(Collection $entries): array
{
// dataset:
$data = [
'count' => 0,
'labels' => [],
'datasets' => [],
];
// get labels from one of the categories (assuming there's at least one):
$first = $entries->first();
$keys = array_keys($first['spent']);
foreach ($keys as $year) {
$data['labels'][] = strval($year);
}
$data = ['count' => 0, 'labels' => array_keys($first['spent']), 'datasets' => [],];
// then, loop all entries and create datasets:
foreach ($entries as $entry) {
@@ -144,7 +141,6 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
$data['count'] = count($data['datasets']);
return $data;
}
/**

View File

@@ -1,4 +1,12 @@
<?php
/**
* ChartJsPiggyBankChartGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\PiggyBank;
@@ -36,9 +44,9 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGeneratorInterface
],
];
$sum = '0';
foreach ($set as $entry) {
$date = new Carbon($entry->date);
$sum = bcadd($sum, $entry->sum);
foreach ($set as $key => $value) {
$date = new Carbon($key);
$sum = bcadd($sum, $value);
$data['labels'][] = $date->formatLocalized($format);
$data['datasets'][0]['data'][] = round($sum, 2);
}

View File

@@ -1,13 +1,14 @@
<?php
declare(strict_types = 1);
/**
* PiggyBankChartGenerator.php
* PiggyBankChartGeneratorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\PiggyBank;
use Illuminate\Support\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* ChartJsReportChartGenerator.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Report;

View File

@@ -1,13 +1,14 @@
<?php
declare(strict_types = 1);
/**
* ReportChartGenerator.php
* ReportChartGeneratorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Report;
use Illuminate\Support\Collection;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* AttachUserRole.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,12 +7,13 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\UserRegistration;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Log;
/**
* Class AttachUserRole
@@ -38,13 +38,11 @@ class AttachUserRole
*/
public function handle(UserRegistration $event)
{
Log::debug('Trigger attachuserrole');
/** @var UserRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\User\UserRepositoryInterface');
$repository = app(UserRepositoryInterface::class);
// first user ever?
if ($repository->count() == 1) {
Log::debug('Will attach role.');
$repository->attachRole($event->user, 'owner');
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* BudgetLimitEventHandler.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\BudgetLimitStored;
use FireflyIII\Events\BudgetLimitUpdated;
use FireflyIII\Models\LimitRepetition;
use Illuminate\Database\QueryException;
use Log;
/**
* Class BudgetLimitEventHandler
*
* @package FireflyIII\Handlers\Events
*/
class BudgetLimitEventHandler
{
/**
* Create the event listener.
*
*/
public function __construct()
{
}
/**
* In a perfect world, the store() routine should be different from the update()
* routine. It would not have to check count() == 0 because there could be NO
* limit repetitions at this point. However, the database can be wrong so we check.
*
* @param BudgetLimitStored $event
*/
public function store(BudgetLimitStored $event)
{
$budgetLimit = $event->budgetLimit;
$end = $event->end;
$set = $budgetLimit->limitrepetitions()
->where('startdate', $budgetLimit->startdate->format('Y-m-d 00:00:00'))
->where('enddate', $end->format('Y-m-d 00:00:00'))
->get();
if ($set->count() == 0) {
$repetition = new LimitRepetition;
$repetition->startdate = $budgetLimit->startdate;
$repetition->enddate = $end;
$repetition->amount = $budgetLimit->amount;
$repetition->budgetLimit()->associate($budgetLimit);
try {
$repetition->save();
} catch (QueryException $e) {
Log::error('Trying to save new LimitRepetition failed: ' . $e->getMessage());
}
}
if ($set->count() == 1) {
$repetition = $set->first();
$repetition->amount = $budgetLimit->amount;
$repetition->save();
}
}
/**
* @param BudgetLimitUpdated $event
*/
public function update(BudgetLimitUpdated $event)
{
$budgetLimit = $event->budgetLimit;
$end = $event->end;
$set = $budgetLimit->limitrepetitions()
->where('startdate', $budgetLimit->startdate->format('Y-m-d 00:00:00'))
->where('enddate', $end->format('Y-m-d 00:00:00'))
->get();
if ($set->count() == 0) {
$repetition = new LimitRepetition;
$repetition->startdate = $budgetLimit->startdate;
$repetition->enddate = $end;
$repetition->amount = $budgetLimit->amount;
$repetition->budgetLimit()->associate($budgetLimit);
try {
$repetition->save();
} catch (QueryException $e) {
Log::error('Trying to save new LimitRepetition failed: ' . $e->getMessage());
}
}
if ($set->count() == 1) {
$repetition = $set->first();
$repetition->amount = $budgetLimit->amount;
$repetition->save();
}
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* ConnectJournalToPiggyBank.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
@@ -31,7 +39,7 @@ class ConnectJournalToPiggyBank
$piggyBankId = $event->piggyBankId;
/** @var PiggyBank $piggyBank */
$piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
$piggyBank = Auth::user()->piggyBanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
if (is_null($piggyBank)) {
return true;
@@ -44,7 +52,8 @@ class ConnectJournalToPiggyBank
$amount = TransactionJournal::amountPositive($journal);
// if piggy account matches source account, the amount is positive
if ($piggyBank->account_id == TransactionJournal::sourceAccount($journal)->id) {
$sources = TransactionJournal::sourceAccountList($journal)->pluck('id')->toArray();
if (in_array($piggyBank->account_id, $sources)) {
$amount = bcmul($amount, '-1');
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* ConnectTransactionToPiggyBank.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\TransactionStored;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
/**
* Class ConnectTransactionToPiggyBank
*
* @package FireflyIII\Handlers\Events
*/
class ConnectTransactionToPiggyBank
{
/**
* Connect a new transaction journal to any related piggy banks.
*
* @param TransactionStored $event
*
* @return bool
*/
public function handle(TransactionStored $event): bool
{
/** @var PiggyBankRepositoryInterface $repository */
$repository = app(PiggyBankRepositoryInterface::class);
$transaction = $event->transaction;
$piggyBank = $repository->find($transaction['piggy_bank_id']);
// valid piggy:
if (is_null($piggyBank->id)) {
return true;
}
$amount = strval($transaction['amount']);
// piggy bank account something with amount:
if ($transaction['source_account_id'] == $piggyBank->account_id) {
// if the source of this transaction is the same as the piggy bank,
// the money is being removed from the piggy bank. So the
// amount must be negative:
$amount = bcmul($amount, '-1');
}
$repetition = $piggyBank->currentRelevantRep();
// add or remove the money from the piggy bank:
$newAmount = bcadd(strval($repetition->currentamount), $amount);
$repetition->currentamount = $newAmount;
$repetition->save();
// now generate a piggy bank event:
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'date' => $transaction['date'], 'amount' => $newAmount]);
return true;
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* FireRulesForStore.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
@@ -17,7 +18,6 @@ use FireflyIII\Models\RuleGroup;
use FireflyIII\Rules\Processor;
use FireflyIII\User;
use Illuminate\Support\Facades\Auth;
use Log;
/**
* Class FireRulesForStore
@@ -36,7 +36,6 @@ class FireRulesForStore
*/
public function handle(TransactionJournalStored $event): bool
{
Log::debug('Now running FireRulesForStore because TransactionJournalStored fired.');
// get all the user's rule groups, with the rules, order by 'order'.
/** @var User $user */
$user = Auth::user();
@@ -44,7 +43,6 @@ class FireRulesForStore
//
/** @var RuleGroup $group */
foreach ($groups as $group) {
Log::debug('Now processing group "' . $group->title . '".');
$rules = $group->rules()
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
->where('rule_triggers.trigger_type', 'user_action')
@@ -54,7 +52,6 @@ class FireRulesForStore
/** @var Rule $rule */
foreach ($rules as $rule) {
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
$processor = Processor::make($rule);
$processor->handleTransactionJournal($event->journal);

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* FireRulesForUpdate.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use Auth;
@@ -16,7 +17,6 @@ use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Rules\Processor;
use FireflyIII\User;
use Log;
/**
* Class FireRulesForUpdate
@@ -34,7 +34,6 @@ class FireRulesForUpdate
*/
public function handle(TransactionJournalUpdated $event): bool
{
Log::debug('Now running FireRulesForUpdate because TransactionJournalUpdated fired.');
// get all the user's rule groups, with the rules, order by 'order'.
/** @var User $user */
$user = Auth::user();
@@ -42,7 +41,6 @@ class FireRulesForUpdate
//
/** @var RuleGroup $group */
foreach ($groups as $group) {
Log::debug('Now processing group "' . $group->title . '".');
$rules = $group->rules()
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
->where('rule_triggers.trigger_type', 'user_action')
@@ -51,9 +49,6 @@ class FireRulesForUpdate
->get(['rules.*']);
/** @var Rule $rule */
foreach ($rules as $rule) {
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
$processor = Processor::make($rule);
$processor->handleTransactionJournal($event->journal);

View File

@@ -1,13 +1,14 @@
<?php
declare(strict_types = 1);
/**
* RescanJournalAfterStore.php
* ScanForBillsAfterStore.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\TransactionJournalStored;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* ScanForBillsAfterUpdate.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\TransactionJournalUpdated;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* SendRegistrationMail.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
@@ -60,6 +61,7 @@ class SendRegistrationMail
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
return true;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* UpdateJournalConnection.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
@@ -19,6 +27,7 @@ class UpdateJournalConnection
* Handle the event.
*
* @param TransactionJournalUpdated $event
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly 5.
*
* @return bool
*/
@@ -26,6 +35,10 @@ class UpdateJournalConnection
{
$journal = $event->journal;
if (!$journal->isTransfer()) {
return true;
}
// get the event connected to this journal:
/** @var PiggyBankEvent $event */
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
@@ -34,7 +47,7 @@ class UpdateJournalConnection
}
$piggyBank = $event->piggyBank()->first();
$repetition = null;
if ($piggyBank) {
if (!is_null($piggyBank)) {
/** @var PiggyBankRepetition $repetition */
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* UserConfirmation.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
@@ -47,6 +48,7 @@ class UserConfirmation
$user = $event->user;
$ipAddress = $event->ipAddress;
$this->doConfirm($user, $ipAddress);
return true;
}
@@ -62,6 +64,7 @@ class UserConfirmation
$user = $event->user;
$ipAddress = $event->ipAddress;
$this->doConfirm($user, $ipAddress);
return true;
}
@@ -71,35 +74,21 @@ class UserConfirmation
*/
private function doConfirm(User $user, string $ipAddress)
{
Log::debug('Trigger UserConfirmation::doConfirm');
// if user must confirm account, send email
$confirmAccount = env('MUST_CONFIRM_ACCOUNT', false);
// otherwise, auto-confirm:
if ($confirmAccount === false) {
Log::debug('Confirm account is false, so user will be auto-confirmed.');
Preferences::setForUser($user, 'user_confirmed', true);
Preferences::setForUser($user, 'user_confirmed_last_mail', 0);
Preferences::mark();
return;
}
// send email message:
$email = $user->email;
$code = str_random(16);
$route = route('do_confirm_account', [$code]);
// set preferences:
Preferences::setForUser($user, 'user_confirmed', false);
Preferences::setForUser($user, 'user_confirmed_last_mail', time());
Preferences::setForUser($user, 'user_confirmed_code', $code);
Log::debug('Set preferences for user.');
// send email.
try {
Log::debug('Now in try block for user email message thing to ' . $email . '.');
Mail::send(
['emails.confirm-account-html', 'emails.confirm-account'], ['route' => $route, 'ip' => $ipAddress],
function (Message $message) use ($email) {
@@ -107,13 +96,10 @@ class UserConfirmation
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
} catch (Exception $e) {
Log::debug('Caught general exception.');
Log::error($e->getMessage());
}
Log::debug('Finished mail handling for activation.');
return;
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* UserEventListener.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use Session;
@@ -21,7 +22,7 @@ class UserEventListener
{
/**
* Handle user logout events.
*
*
* @return bool
*/
public function onUserLogout(): bool

View File

@@ -0,0 +1,61 @@
<?php
/**
* UserSaveIpAddress.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\UserIsConfirmed;
use FireflyIII\Events\UserRegistration;
use Preferences;
/**
* Class UserSaveIpAddress
*
* @package FireflyIII\Handlers\Events
*/
class UserSaveIpAddress
{
/**
* Create the event listener.
*
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param UserIsConfirmed $event
*
* @return bool
*/
public function saveFromConfirmation(UserIsConfirmed $event): bool
{
Preferences::setForUser($event->user, 'confirmation_ip_address', $event->ipAddress);
return true;
}
/**
* Handle the event.
*
* @param UserRegistration $event
*
* @return bool
*/
public function saveFromRegistration(UserRegistration $event): bool
{
Preferences::setForUser($event->user, 'registration_ip_address', $event->ipAddress);
return true;
}
}

View File

@@ -1,9 +1,16 @@
<?php
/**
* AttachmentHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;
use Auth;
use Config;
use Crypt;
use FireflyIII\Models\Attachment;
use Illuminate\Database\Eloquent\Model;
@@ -39,8 +46,8 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function __construct()
{
$this->maxUploadSize = Config::get('firefly.maxUploadSize');
$this->allowedMimes = Config::get('firefly.allowedMimes');
$this->maxUploadSize = config('firefly.maxUploadSize');
$this->allowedMimes = config('firefly.allowedMimes');
$this->errors = new MessageBag;
$this->messages = new MessageBag;
$this->uploadDisk = Storage::disk('upload');
@@ -81,26 +88,14 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function saveAttachmentsForModel(Model $model): bool
{
$files = null;
try {
if (Input::hasFile('attachments')) {
$files = Input::file('attachments');
}
} catch (TypeError $e) {
// Log it, do nothing else.
Log::error($e->getMessage());
$files = $this->getFiles();
if (!is_null($files) && !is_array($files)) {
$this->processFile($files, $model);
}
if (is_array($files)) {
foreach ($files as $entry) {
if (!is_null($entry)) {
$this->processFile($entry, $model);
}
}
} else {
if (!is_null($files)) {
$this->processFile($files, $model);
}
$this->processFiles($files, $model);
}
return true;
@@ -234,5 +229,41 @@ class AttachmentHelper implements AttachmentHelperInterface
return true;
}
/**
* @return array|null|UploadedFile
*/
private function getFiles()
{
$files = null;
try {
if (Input::hasFile('attachments')) {
$files = Input::file('attachments');
}
} catch (TypeError $e) {
// Log it, do nothing else.
Log::error($e->getMessage());
}
return $files;
}
/**
* @param array $files
*
* @param Model $model
*
* @return bool
*/
private function processFiles(array $files, Model $model): bool
{
foreach ($files as $entry) {
if (!is_null($entry)) {
$this->processFile($entry, $model);
}
}
return true;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* AttachmentHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Account.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Balance.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@@ -59,5 +67,13 @@ class Balance
return $this->balanceLines;
}
/**
* @param Collection $balanceLines
*/
public function setBalanceLines(Collection $balanceLines)
{
$this->balanceLines = $balanceLines;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* BalanceEntry.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* BalanceHeader.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,7 +1,16 @@
<?php
/**
* BalanceLine.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;
use FireflyIII\Models\Budget as BudgetModel;
use Illuminate\Support\Collection;
@@ -23,9 +32,12 @@ class BalanceLine
/** @var BudgetModel */
protected $budget;
/** @var Carbon */
protected $endDate;
/** @var int */
protected $role = self::ROLE_DEFAULTROLE;
/** @var Carbon */
protected $startDate;
/**
*
@@ -76,6 +88,22 @@ class BalanceLine
$this->budget = $budget;
}
/**
* @return Carbon
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* @param Carbon $endDate
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
}
/**
* @return int
*/
@@ -92,6 +120,22 @@ class BalanceLine
$this->role = $role;
}
/**
* @return Carbon
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* @param Carbon $startDate
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
}
/**
* @return string
*/

View File

@@ -1,4 +1,12 @@
<?php
/**
* Bill.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* BillLine.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@@ -141,5 +149,4 @@ class BillLine
$this->hit = $hit;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Budget.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@@ -33,46 +41,66 @@ class Budget
/**
* @param BudgetLine $budgetLine
*
* @return Budget
*/
public function addBudgetLine(BudgetLine $budgetLine)
public function addBudgetLine(BudgetLine $budgetLine): Budget
{
$this->budgetLines->push($budgetLine);
return $this;
}
/**
* @param string $add
*
* @return Budget
*/
public function addBudgeted(string $add)
public function addBudgeted(string $add): Budget
{
$add = strval(round($add, 2));
$this->budgeted = bcadd($this->budgeted, $add);
return $this;
}
/**
* @param string $add
*
* @return Budget
*/
public function addLeft(string $add)
public function addLeft(string $add): Budget
{
$add = strval(round($add, 2));
$this->left = bcadd($this->left, $add);
return $this;
}
/**
* @param string $add
*
* @return Budget
*/
public function addOverspent(string $add)
public function addOverspent(string $add): Budget
{
$add = strval(round($add, 2));
$this->overspent = bcadd($this->overspent, $add);
return $this;
}
/**
* @param string $add
*
* @return Budget
*/
public function addSpent(string $add)
public function addSpent(string $add): Budget
{
$add = strval(round($add, 2));
$this->spent = bcadd($this->spent, $add);
return $this;
}
/**
@@ -93,10 +121,14 @@ class Budget
/**
* @param string $budgeted
*
* @return Budget
*/
public function setBudgeted(string $budgeted)
public function setBudgeted(string $budgeted): Budget
{
$this->budgeted = $budgeted;
return $this;
}
/**
@@ -109,10 +141,14 @@ class Budget
/**
* @param string $left
*
* @return Budget
*/
public function setLeft(string $left)
public function setLeft(string $left): Budget
{
$this->left = $left;
return $this;
}
/**
@@ -125,10 +161,14 @@ class Budget
/**
* @param string $overspent
*
* @return Budget
*/
public function setOverspent(string $overspent)
public function setOverspent(string $overspent): Budget
{
$this->overspent = strval(round($overspent, 2));
return $this;
}
/**
@@ -141,10 +181,14 @@ class Budget
/**
* @param string $spent
*
* @return Budget
*/
public function setSpent(string $spent)
public function setSpent(string $spent): Budget
{
$this->spent = strval(round($spent, 2));
return $this;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* BudgetLine.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@@ -37,10 +45,14 @@ class BudgetLine
/**
* @param BudgetModel $budget
*
* @return BudgetLine
*/
public function setBudget(BudgetModel $budget)
public function setBudget(BudgetModel $budget): BudgetLine
{
$this->budget = $budget;
return $this;
}
/**
@@ -53,10 +65,14 @@ class BudgetLine
/**
* @param string $budgeted
*
* @return BudgetLine
*/
public function setBudgeted(string $budgeted)
public function setBudgeted(string $budgeted): BudgetLine
{
$this->budgeted = $budgeted;
return $this;
}
/**
@@ -69,10 +85,14 @@ class BudgetLine
/**
* @param string $left
*
* @return BudgetLine
*/
public function setLeft(string $left)
public function setLeft(string $left): BudgetLine
{
$this->left = $left;
return $this;
}
/**
@@ -85,10 +105,14 @@ class BudgetLine
/**
* @param string $overspent
*
* @return BudgetLine
*/
public function setOverspent(string $overspent)
public function setOverspent(string $overspent): BudgetLine
{
$this->overspent = $overspent;
return $this;
}
/**
@@ -101,10 +125,14 @@ class BudgetLine
/**
* @param LimitRepetition $repetition
*
* @return BudgetLine
*/
public function setRepetition(LimitRepetition $repetition)
public function setRepetition(LimitRepetition $repetition): BudgetLine
{
$this->repetition = $repetition;
return $this;
}
/**
@@ -117,10 +145,14 @@ class BudgetLine
/**
* @param string $spent
*
* @return BudgetLine
*/
public function setSpent(string $spent)
public function setSpent(string $spent): BudgetLine
{
$this->spent = $spent;
return $this;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Category.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

Some files were not shown because too many files have changed in this diff Show More