Compare commits

..

372 Commits

Author SHA1 Message Date
James Cole
bc5b2085b9 Merge branch 'release/5.3.0-beta.1' into main 2020-06-28 09:25:30 +02:00
James Cole
ebcd751145 Beta to changelog. 2020-06-28 09:25:19 +02:00
James Cole
cdfde3dca8 Update meta files for new release. 2020-06-28 09:19:18 +02:00
James Cole
4e3378451c Update readme. 2020-06-27 17:54:29 +02:00
James Cole
415fb7294c Fix sonarcloud issues 2020-06-27 17:33:18 +02:00
James Cole
1e35f0e7e3 You can logout other sessions. 2020-06-27 15:42:18 +02:00
James Cole
b83d06294d Drop Sandstorm related code. 2020-06-27 15:19:00 +02:00
James Cole
7945220825 Fix #3493 2020-06-27 13:41:27 +02:00
James Cole
3e8a4d55ef Make list grouped. 2020-06-27 13:32:40 +02:00
James Cole
e1fbdca5c1 Make list grouped. 2020-06-27 13:08:51 +02:00
James Cole
1b31d20877 Skip deleted piggies. 2020-06-27 09:56:38 +02:00
James Cole
aaaab03995 New translations 2020-06-26 08:35:59 +02:00
James Cole
affa8a317a Update packages 2020-06-26 07:30:29 +02:00
James Cole
5a03f3395c Fix #3440 2020-06-26 07:28:25 +02:00
James Cole
8da6ec3f5b Fix #3488 2020-06-26 04:04:54 +02:00
James Cole
a0402ac742 Fix text 2020-06-26 04:04:30 +02:00
James Cole
654e0fc74f Pretty basic fix #3490 2020-06-25 15:49:28 +02:00
James Cole
d3bd1f4124 Escape names to fix #3489 2020-06-25 13:37:44 +02:00
James Cole
2aa6067437 New strings. 2020-06-24 06:45:40 +02:00
James Cole
356c87da49 Fix #3427 2020-06-23 20:45:10 +02:00
James Cole
0d76fcd564 Fix #3398 2020-06-23 20:26:13 +02:00
James Cole
963c3b2a68 Fix #3391 2020-06-23 20:18:59 +02:00
James Cole
7617fe3510 Fix null pointer 2020-06-23 15:30:02 +02:00
James Cole
88724be3aa Fix mailer 2020-06-22 18:31:39 +02:00
James Cole
f845c97955 Merge tag '5.3.0-alpha.1' into develop
5.3.0-alpha.1
2020-06-22 18:18:02 +02:00
James Cole
2c69a2eda2 Merge branch 'release/5.3.0-alpha.1' 2020-06-22 18:17:59 +02:00
James Cole
dcce747e92 Mysql instructions. 2020-06-22 18:17:31 +02:00
James Cole
c251ca5daf Update meta files. 2020-06-22 18:08:23 +02:00
James Cole
bcb9794315 Update meta files. 2020-06-22 18:03:57 +02:00
James Cole
1a043e35c2 New meta files 2020-06-22 18:02:28 +02:00
James Cole
4fef316ddd Fix more date issues 2020-06-21 19:16:21 +02:00
James Cole
7196ac3ec9 Fix date issues. 2020-06-21 19:08:57 +02:00
James Cole
1c74db30ed More layout stuff 2020-06-21 18:29:23 +02:00
James Cole
00440f282b API for piggies + groups. 2020-06-21 18:28:51 +02:00
James Cole
dfe099f9c6 Emergency fix for #3479 2020-06-21 14:16:23 +02:00
James Cole
0dbee47182 Fix issue with null pointer 2020-06-20 22:16:03 +02:00
James Cole
46796a8c10 Logo 2020-06-20 19:14:28 +02:00
James Cole
c381067364 New code. 2020-06-20 19:14:06 +02:00
James Cole
19573de5df Fonts 2020-06-20 19:10:44 +02:00
James Cole
77359fbc55 Code for front page 2020-06-20 19:09:37 +02:00
James Cole
45eb758583 Fix list 2020-06-20 18:57:20 +02:00
James Cole
1a154a8d45 API for object groups. 2020-06-20 16:28:23 +02:00
James Cole
c40f6f2864 Add user id. 2020-06-20 10:23:57 +02:00
James Cole
c036c5a2bc Fix user management for groups. 2020-06-20 10:22:07 +02:00
James Cole
5b29e78c4b Group management code. 2020-06-20 10:10:55 +02:00
James Cole
b54ef9f5e5 Fix bad UUID generation. 2020-06-18 18:14:10 +02:00
James Cole
b7f48a19e8 Merge pull request #3467 from sephrat/days-left-for-bills
Fix #3437
2020-06-17 18:23:13 +00:00
James Cole
c8f1e4bbd7 Expand new layout code. 2020-06-17 07:06:45 +02:00
James Cole
5cc1369191 Expand debug. 2020-06-17 07:05:33 +02:00
Florian Dupret
16a511cf79 move 7c78708 logic from transformer to controller 2020-06-16 18:02:48 +02:00
Florian Dupret
7c78708865 Fix #3437 2020-06-16 14:07:40 +02:00
James Cole
0449430ec3 I messed up 2020-06-14 19:24:23 +02:00
James Cole
dd5a179ba1 More stuff for new layout. 2020-06-14 19:17:45 +02:00
James Cole
7c1139e42b First set of code for new layout based on AdminLTE 3.0 2020-06-14 15:51:20 +02:00
James Cole
caddf3d1c6 Fix #3461 2020-06-13 13:48:52 +02:00
James Cole
54d5778bf3 Add attachment to recurring. 2020-06-12 20:56:58 +02:00
James Cole
b1732d0de8 New possibilities for date range triggers #3403 2020-06-12 07:49:39 +02:00
James Cole
48b5f749a1 Fix logout for #3184 2020-06-11 17:55:38 +02:00
James Cole
a63b8322db Updates for #3184 2020-06-11 06:55:13 +02:00
James Cole
2130eef971 Update .env.example for #3184 2020-06-11 06:54:42 +02:00
James Cole
5b829b514f Include notes in export. 2020-06-09 17:40:09 +02:00
James Cole
1bac3258da Merge pull request #3455 from sephrat/debug_translation
Translate debug page
2020-06-09 15:18:17 +00:00
James Cole
d7181100ee Merge pull request #3454 from sephrat/translations
Translations tweaks
2020-06-09 15:17:30 +00:00
James Cole
ccc82858ad Fix drag/drop + sort 2020-06-09 17:16:21 +02:00
Florian Dupret
5dd6b23b09 Translate debug page 2020-06-09 13:51:01 +02:00
James Cole
6a08f52fa5 Update packages and order. 2020-06-09 11:09:23 +02:00
James Cole
18172b7fdb Fix order, fix bar. 2020-06-09 10:33:55 +02:00
James Cole
3eccc56c7a Better column 2020-06-09 08:48:28 +02:00
Florian Dupret
f7545af17a Missing translation on budgets index page 2020-06-09 08:37:40 +02:00
Florian Dupret
aa4da1e2e1 Telemetry count pluralization 2020-06-09 08:35:10 +02:00
James Cole
b4aafefc2b Fix NULL 2020-06-08 18:22:36 +02:00
James Cole
8304ee21f3 Fix #3450 2020-06-07 21:42:52 +02:00
James Cole
ca6479ede6 Update version. 2020-06-07 16:38:25 +02:00
James Cole
471cdefcff Organise object groups 2020-06-07 16:38:15 +02:00
James Cole
16b0307b0a Piggy bank can now have a group. 2020-06-07 11:31:01 +02:00
James Cole
2f63090e7c Split controller 2020-06-07 11:30:02 +02:00
James Cole
8643034945 Upgrade to 7.4 2020-06-06 22:25:52 +02:00
James Cole
6cc4d14fcb Remove import code. 2020-06-06 21:23:26 +02:00
James Cole
389ffa820f Merge branch 'release/5.2.8' 2020-06-06 12:19:11 +02:00
James Cole
60fa0d7244 Merge tag '5.2.8' into develop
5.2.8
2020-06-06 12:19:11 +02:00
James Cole
28d6885178 Update meta files for 5.2.8 2020-06-06 12:18:42 +02:00
James Cole
00f579909e Update meta files. 2020-06-06 12:16:32 +02:00
James Cole
a35bccb940 Fix #3443 2020-06-06 12:14:55 +02:00
James Cole
1cba62aa42 Cleanup changelog, forgot some unused entries. 2020-06-06 07:26:22 +02:00
James Cole
0974591a8f Merge tag '5.2.7' into develop
5.2.7
2020-06-06 07:18:38 +02:00
James Cole
326bef66ee Merge branch 'release/5.2.7' 2020-06-06 07:18:36 +02:00
James Cole
67ba8cee09 Updated meta files. 2020-06-06 07:15:56 +02:00
James Cole
08107f7103 Fix translations. 2020-06-06 07:09:27 +02:00
James Cole
f5c075936f Better generation of installation ID. 2020-06-06 06:57:44 +02:00
James Cole
d493820cc8 Migrate default env file to MySQL 2020-06-06 06:40:59 +02:00
James Cole
af4a006192 New translations. 2020-06-06 06:40:44 +02:00
James Cole
946e3fb540 New changelog. 2020-06-06 06:37:20 +02:00
James Cole
b19338e2f3 Add db connection info. 2020-06-06 06:34:43 +02:00
James Cole
d4a44e6089 Hold the DB changes for now. 2020-06-05 19:44:40 +02:00
James Cole
c90c181785 Basic code for an object group select item thing. 2020-06-05 19:39:09 +02:00
James Cole
b75178a184 New view for #3415 2020-06-05 18:40:02 +02:00
James Cole
a77187135f Fixed #3297 2020-06-05 06:34:55 +02:00
James Cole
61e24a41a2 Add groups, and the option for objects to be linked to one (or more) groups. #3128 2020-06-05 06:25:39 +02:00
James Cole
07c7bf1d49 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-06-04 18:08:53 +02:00
James Cole
d4cb72cb77 Updated strings. 2020-06-04 18:08:18 +02:00
James Cole
948cdf7e5e Merge pull request #3428 from sephrat/fix-reconcile-difference
Fix reconcile difference
2020-06-04 12:23:28 +02:00
Florian Dupret
e93292d98c Fix identation from 7105d34 2020-06-04 08:34:46 +02:00
Florian Dupret
7105d34fb3 Fix wrong reconciliation difference with "select all" button 2020-06-04 08:32:17 +02:00
James Cole
29847c9711 Updated strings. 2020-06-04 06:49:44 +02:00
James Cole
3db778a2b1 Fix #3425 2020-06-04 06:31:34 +02:00
James Cole
361f78542a Add time for #3419 2020-06-04 06:26:14 +02:00
James Cole
15d0e04431 Add timeout for #3427 2020-06-04 06:20:52 +02:00
James Cole
b968ef416a Fix #3419 2020-06-02 19:11:17 +02:00
James Cole
6191362fe0 Merge pull request #3420 from sephrat/fix#3409
Display account names only once when displaying split transactions
2020-06-02 17:59:52 +02:00
Florian Dupret
6d8fd79922 Fix #3409 - Split transactions show source/destination accounts several times 2020-06-01 17:51:07 +02:00
James Cole
0227879a69 Merge pull request #3417 from sephrat/pluralization
Fix typo from #3413
2020-06-01 11:41:49 +02:00
Florian Dupret
e4d2b121c1 Merge branch 'pluralization' of https://github.com/sephrat/firefly-iii into pluralization 2020-06-01 08:25:27 +02:00
Florian Dupret
f8941ab507 Fix string displayed twice 2020-06-01 08:15:19 +02:00
James Cole
f3ac8a5888 Add newlines and remove some unused translations. 2020-05-30 07:33:06 +02:00
James Cole
64ac3927ec Pluralization. 2020-05-29 21:00:10 +02:00
James Cole
a558613189 Merge pull request #3413 from sephrat/pluralization
String pluralization
2020-05-29 20:55:56 +02:00
James Cole
7535ca9a26 Merge branch 'develop' into pluralization 2020-05-29 20:55:31 +02:00
James Cole
03670e2dfe New translations. 2020-05-29 19:53:49 +02:00
Florian Dupret
be797f5353 pluralization wave 2 2020-05-29 19:07:51 +02:00
Florian Dupret
da38df6e4b pluralization wave 1 2020-05-29 18:00:29 +02:00
James Cole
2d53eb300a Some more info in changelog. 2020-05-29 16:08:31 +02:00
James Cole
523ea78166 Error strings. 2020-05-29 07:55:59 +02:00
James Cole
3b33730e48 Remove VSCode 2020-05-29 06:45:01 +02:00
James Cole
351272cc27 Merge pull request #3408 from sephrat/issue/3407
Fix #3407
2020-05-29 06:44:34 +02:00
James Cole
a293827739 Reformat translations. 2020-05-29 06:43:42 +02:00
James Cole
ead2cf92d3 Merge pull request #3405 from sephrat/error_pages_translation
Make error pages translatable
2020-05-29 06:41:55 +02:00
James Cole
dea9e21382 Merge branch 'develop' into error_pages_translation 2020-05-29 06:41:47 +02:00
James Cole
69725eb8c3 Rebuild JS #3404 2020-05-29 06:40:45 +02:00
James Cole
d31bb1f9b6 Regenerated JSON files for all languages. #3404 2020-05-29 06:39:48 +02:00
James Cole
b64979e45a New strings in all languages for #3404 2020-05-29 06:39:24 +02:00
James Cole
3dd3d2cabb Clean up strings #3404 2020-05-29 06:34:39 +02:00
James Cole
94e7c3527f Refactor strings #3404 2020-05-29 06:30:42 +02:00
James Cole
1a71d22146 Add strings to i18n #3404 2020-05-29 06:28:34 +02:00
James Cole
fdc3b80f1f Refactor strings #3404 2020-05-29 06:28:24 +02:00
James Cole
b978de78e4 Refactor strings #3404 2020-05-29 06:22:13 +02:00
James Cole
8b6bd296e1 Refactor string identifiers #3404 2020-05-29 06:19:56 +02:00
James Cole
4d075feed6 Merge pull request #3404 from sephrat/js_translations
Make new profile settings translatable
2020-05-29 06:18:29 +02:00
James Cole
e0e16489a1 Merge branch 'develop' into js_translations 2020-05-29 06:18:22 +02:00
James Cole
deeb4933fc Reformat for readability (PHPStorm) 2020-05-29 06:16:42 +02:00
James Cole
be8a0ddb3e Merge pull request #3393 from bpatath/feature/add-ssl-to-mysql
Add SSL conf to MySQL and LDAP
2020-05-29 06:13:16 +02:00
James Cole
49b1a6d844 Alignment 2020-05-29 06:12:24 +02:00
James Cole
3c1361e377 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-05-29 06:09:27 +02:00
James Cole
a7ab5b7504 A note about telemetry for the next release. 2020-05-29 06:07:12 +02:00
James Cole
0c8229d689 Some language strings. 2020-05-29 06:07:03 +02:00
Florian Dupret
aebf45697f fix #3407 2020-05-28 19:08:34 +02:00
Florian Dupret
d5d5530a8e .gitgnore 2020-05-28 16:06:11 +02:00
bpatath
8aa7776072 Replace unnused MySQL SSL mode 2020-05-28 09:26:42 +02:00
bpatath
f427267f5b Add SSL configuration for LDAP 2020-05-28 09:26:42 +02:00
bpatath
3195dd0db0 Add SSL configuration for MySQL 2020-05-28 09:26:42 +02:00
Florian Dupret
e67c62e6cd ignore node.js built files and vscode files 2020-05-27 19:35:41 +02:00
Florian Dupret
d319a21b01 Make error pages translatable 2020-05-27 17:42:19 +02:00
Florian Dupret
f8963179c3 Make new profile settings translatable 2020-05-27 16:17:24 +02:00
James Cole
d3cd657501 Merge pull request #3395 from sephrat/master
Make email notifications translatable (#3387)
2020-05-27 14:00:49 +00:00
Florian Dupret
6c6bb2cd1e Email translations cleanup 2020-05-27 09:34:52 +02:00
Florian Dupret
1771b3964e Email view cleanup: confirm account is obsolete 2020-05-26 18:50:48 +02:00
Florian Dupret
351c0ee2d7 Email notifications are now translatable 2020-05-26 12:01:39 +02:00
James Cole
1c9c380c8c Expand debug 2020-05-26 06:28:42 +02:00
James Cole
24455bf980 Fix #3133 2020-05-26 06:28:02 +02:00
James Cole
e21b40b46c Remove unused var 2020-05-26 06:27:43 +02:00
James Cole
29eabf9c8a Bad type. 2020-05-25 19:40:22 +02:00
James Cole
60e20ceeb1 Add another telemetry entry 2020-05-25 19:30:38 +02:00
Florian Dupret
37b35661be most email notifications translatable 2020-05-25 19:24:21 +02:00
Florian Dupret
b54bb20617 Make admin test email translatable 2020-05-25 13:13:33 +02:00
James Cole
19ce6b71e2 Some notes. 2020-05-24 16:58:17 +02:00
James Cole
b68663c977 Fix submission command. 2020-05-24 12:32:02 +02:00
James Cole
ac385e2647 Will now accept other values too. 2020-05-24 12:20:21 +02:00
James Cole
bc70174f44 Remove and cleanup commands. 2020-05-24 12:17:53 +02:00
James Cole
b8668b44a0 Enable feature telemetry 2020-05-24 12:12:06 +02:00
James Cole
86a87cc951 More text in .env.example 2020-05-24 12:01:40 +02:00
James Cole
be58b1d2be Enable the feature flag for telemetry. 2020-05-24 12:00:14 +02:00
James Cole
61733f6553 Forgot to remove debug variable. 2020-05-24 11:47:44 +02:00
James Cole
15e772d9dc Update some (disabled) commands. 2020-05-24 11:24:28 +02:00
James Cole
ae7b81bf86 Merge pull request #3390 from sephrat/master
Fix typos and minor text inconsistency
2020-05-24 09:19:02 +00:00
Florian Dupret
2c9ac0982a Fix minor typos 2020-05-24 09:59:34 +02:00
Florian Dupret
2df390065b Minor fix: fix rule action/trigger labels consistency 2020-05-24 09:53:54 +02:00
sephrat
247c9aebf3 Merge pull request #1 from firefly-iii/master
keep up with main repo
2020-05-24 09:51:01 +02:00
James Cole
0783500eaa Fix #3309 2020-05-23 19:54:02 +02:00
James Cole
c2e542004d Add some debug. 2020-05-23 08:14:13 +02:00
James Cole
806ad918f0 Include original collection time. 2020-05-22 20:24:56 +02:00
James Cole
84406a74c3 Merge tag '5.2.6' into develop
5.2.6
2020-05-22 17:54:03 +02:00
James Cole
09990acaa2 Merge branch 'release/5.2.6' 2020-05-22 17:54:02 +02:00
James Cole
a73247ec8c Some last minute translations. 2020-05-22 17:53:09 +02:00
James Cole
e98d43dd65 New meta files for 5.2.6 2020-05-22 14:15:57 +02:00
James Cole
dbd68cedc9 Code for #3309 2020-05-22 13:52:33 +02:00
James Cole
e6e8200912 Merge pull request #3381 from bpatath/feature/add-single-sign-on
Feature/add single sign on
2020-05-22 04:27:39 +00:00
bpatath
7b1380366b Register SSO middleware if enabled in configuration 2020-05-21 21:05:03 +02:00
bpatath
1eda806c17 Fix outdated AdLdap2 configuration files 2020-05-21 21:04:17 +02:00
James Cole
782ecca6a9 Warning if people disabled update checking. Every 4 weeks. 2020-05-20 06:40:18 +02:00
James Cole
e6338705a7 Fix #3376 2020-05-19 19:37:12 +02:00
James Cole
09226e6f12 New translations. 2020-05-19 13:29:47 +02:00
James Cole
5ff1991cdc Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-05-19 11:19:13 +02:00
James Cole
4ebb6de520 Reset rule order on index. #3376 2020-05-19 11:18:58 +02:00
James Cole
1ba7d65582 Warning if demo user. 2020-05-18 21:21:34 +02:00
James Cole
4e6063a4f8 Demo user can't set locale 2020-05-18 21:19:45 +02:00
James Cole
85476f3549 Fix some strings. 2020-05-18 21:17:59 +02:00
James Cole
ef9714b7e0 Fix #3374 2020-05-18 14:50:07 +02:00
James Cole
8d20029557 Fix #3368 2020-05-17 19:17:19 +02:00
James Cole
0f04b44ca1 Fix # 2020-05-17 06:49:26 +02:00
James Cole
44ed45502e Change in error handling. 2020-05-16 16:57:48 +02:00
James Cole
5bcafe1311 Change in error handling. 2020-05-16 16:57:26 +02:00
James Cole
5a771ccc5f Run yarn again #3363 2020-05-16 16:56:08 +02:00
James Cole
c6145b4a3b Auto generated JSON files for new strings in other languages. #3363 2020-05-16 16:35:23 +02:00
James Cole
b20aeca849 Auto-generated translation files from crowdin #3363 2020-05-16 16:33:57 +02:00
James Cole
793918f2f3 Add new strings to global translation files. #3363 2020-05-16 16:30:17 +02:00
James Cole
5d410e577e Merge pull request #3365 from sephrat/master
Fix #3363
2020-05-16 14:27:39 +00:00
James Cole
9ec786ec3a Merge branch 'develop' into master 2020-05-16 14:27:31 +00:00
Florian Dupret
e532b4d4fc Fix #3363 2020-05-16 15:01:19 +02:00
James Cole
58585d03c6 Fix rounding thing. 2020-05-16 13:09:37 +02:00
James Cole
a4f66b3d86 Date before and after triggers 2020-05-16 12:55:54 +02:00
James Cole
c847621874 First "date is" trigger for #3049 2020-05-16 12:11:06 +02:00
James Cole
86f14885eb Added a rule action that will delete the transactions it matches. 2020-05-16 11:21:26 +02:00
James Cole
173e196bc8 Some experimental fixes for #3011 2020-05-16 10:45:40 +02:00
James Cole
7505db871f Update packages. 2020-05-16 06:59:51 +02:00
James Cole
946dde8957 Add ability to store recurring telemetry. Not enabled. 2020-05-16 06:59:41 +02:00
James Cole
9a52cfbfbe Add some debug info 2020-05-16 06:59:15 +02:00
James Cole
b248bd6d0c Remove code. 2020-05-15 19:59:23 +02:00
James Cole
3fff9ad0a2 Updated translations. 2020-05-15 19:31:19 +02:00
James Cole
a695a1bba2 Fix #3355 2020-05-12 20:40:28 +02:00
James Cole
91e384aae8 Fix #3350 2020-05-10 20:08:16 +02:00
James Cole
1ac95b6fa7 Move getCash lower, add IBAN as name when no name is submitted. Search will pick up the rest. 2020-05-09 18:03:32 +02:00
James Cole
6757b6211d https://github.com/firefly-iii/firefly-iii/issues/3348 2020-05-09 17:47:25 +02:00
James Cole
4dfb78837e Slightly smarter menu. 2020-05-09 14:51:04 +02:00
James Cole
af50ad3db4 New action 2020-05-09 14:47:47 +02:00
James Cole
01cb94aabc Room for better translation 2020-05-09 14:47:33 +02:00
James Cole
5ffc5060b9 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-05-07 06:44:27 +02:00
James Cole
43d7c956a4 Fix #3344 2020-05-07 06:44:01 +02:00
James Cole
863b07951a Fix #3339 2020-05-05 20:53:56 +02:00
James Cole
2101717edb Can return without split. 2020-05-05 20:32:04 +02:00
James Cole
e7ac1476c5 Merge pull request #3336 from maksimkurb/develop
WIP: Fix #3335 Reconciliation account currency is wrong when base account has non-default currency
2020-05-05 20:30:05 +02:00
Maxim Kurbatov
5d24c1fee1 #3335 Update language files for reconciliation account name 2020-05-05 22:10:11 +04:00
Maxim Kurbatov
53eb863f9d Fix #3335 Reconciliation account currency is wrong when base account has non-default currency 2020-05-05 22:07:42 +04:00
James Cole
3c3ba637b5 Make sure demo user can't upload attachments. 2020-05-05 07:44:33 +02:00
James Cole
be8286b15c Fix some things in recurring transactions. 2020-05-04 10:26:01 +02:00
James Cole
6f6087995d Add info on expired recurring transactions. 2020-05-04 10:12:38 +02:00
James Cole
2ff8a35171 Add debug. 2020-05-04 10:06:13 +02:00
James Cole
7f8ed7abb6 Merge branch 'release/5.2.5' 2020-05-04 08:59:55 +02:00
James Cole
2ff0c37c12 Merge tag '5.2.5' into develop
5.2.5
2020-05-04 08:59:55 +02:00
James Cole
c593936b32 New meta files for upcoming release. 2020-05-04 08:56:51 +02:00
James Cole
c54204ede9 Fix #3330 2020-05-03 19:38:03 +02:00
James Cole
d9132bbee3 Merge pull request #3323 from lguima/feature/page-icons-update
Update the pages and blocks icons
2020-05-02 17:11:27 +02:00
Lucas Guima
c1be98762e Update the Tags icon around the site 2020-05-01 18:55:23 -03:00
Lucas Guima
c2733e2a8f Update the Categories icon around the site 2020-05-01 18:54:08 -03:00
Lucas Guima
722cf9b4fe Update the Reports icon around the site 2020-05-01 17:39:43 -03:00
Lucas Guima
01e31e73e0 Update the Piggy Banks icon around the site 2020-05-01 17:32:35 -03:00
Lucas Guima
dba7d05296 Update the Budgets icon around the site 2020-05-01 17:29:50 -03:00
James Cole
a8709a4a45 update env. 2020-05-01 20:16:34 +02:00
James Cole
49b1435cba Fix cron controller. #3318 2020-05-01 17:51:30 +02:00
James Cole
6a25b41952 Update translations. 2020-05-01 17:50:53 +02:00
James Cole
c561f99de6 Fix #3321 2020-05-01 17:47:56 +02:00
James Cole
9d9053d828 Fix #3314 2020-05-01 06:24:24 +02:00
James Cole
c3c9a2f3c0 Slightly different icon. 2020-04-30 06:27:53 +02:00
James Cole
28465142e9 Menu changelog. 2020-04-30 06:27:10 +02:00
James Cole
5473a618c9 Warn about locale things. 2020-04-30 06:27:01 +02:00
James Cole
ac1a8d8053 Merge pull request #3305 from lguima/feature/menu-reordering
Menu reordering
2020-04-30 06:10:51 +02:00
James Cole
15ae9203b6 Fix #3307 2020-04-29 06:37:02 +02:00
Lucas Guima
9dfc2ae20b Use the translatable string for Tools 2020-04-28 20:59:22 -03:00
Lucas Guima
230de7cbdd Use the translatable string for Classification 2020-04-28 20:59:10 -03:00
Lucas Guima
feaa003a52 Use the translatable string for Others 2020-04-28 20:57:36 -03:00
Lucas Guima
295d01dc16 Use the translatable string for Automation 2020-04-28 20:57:11 -03:00
Lucas Guima
cbf1fde45e Use the translatable string for Accounting 2020-04-28 20:56:19 -03:00
Lucas Guima
6cc47287d3 Use the translatable string for Financial control 2020-04-28 20:55:52 -03:00
Lucas Guima
4bbe728376 Create translatable string for Classification 2020-04-28 20:43:02 -03:00
Lucas Guima
427a90ec85 Create translatable string for Others 2020-04-28 20:32:10 -03:00
Lucas Guima
55ddb26dac Create translatable string for Automation 2020-04-28 20:16:25 -03:00
Lucas Guima
891777f079 Create translatable string for Accounting 2020-04-28 20:14:15 -03:00
Lucas Guima
1655286b67 Create translatable string for Financial control 2020-04-28 20:10:43 -03:00
Lucas Guima
dd81636bf2 Add an icon for each sub-menu item 2020-04-28 19:29:53 -03:00
Lucas Guima
56a43a707d Update the icon of Bills menu item 2020-04-28 19:07:44 -03:00
Lucas Guima
c2f92c6e45 Update the icon of Options menu item 2020-04-28 19:07:11 -03:00
Lucas Guima
61bd2dc840 Revert "Move the menu items Profile and Logout to the user menu in the main header"
This reverts commit f6a675f2e2.
2020-04-28 18:55:49 -03:00
Lucas Guima
f6a675f2e2 Move the menu items Profile and Logout to the user menu in the main header 2020-04-27 22:29:14 -03:00
Lucas Guima
85b43055a7 Put the menu sub-items text inside a span tag 2020-04-27 21:44:23 -03:00
Lucas Guima
e63f7bcc70 Put a space between arguments 2020-04-27 21:41:00 -03:00
Lucas Guima
384dd37430 Update the menu item Logout 2020-04-27 21:37:20 -03:00
Lucas Guima
c6b336171c Update the menu item Options 2020-04-27 21:36:47 -03:00
Lucas Guima
d2f4399a1a Update the menu item Tools (Import and export) 2020-04-27 21:30:12 -03:00
Lucas Guima
02d1bc093c Update the menu item Reports 2020-04-27 21:14:38 -03:00
Lucas Guima
420e493987 Group Categories and Tags under the new menu item Classification 2020-04-27 21:12:23 -03:00
Lucas Guima
0a15479bff Update the menu item Accounts 2020-04-27 20:53:25 -03:00
Lucas Guima
a9b76a3679 Add menu header for Others 2020-04-27 20:44:39 -03:00
Lucas Guima
d1a3cd9044 Move and update the menu item Automation (Money management) 2020-04-27 20:41:40 -03:00
Lucas Guima
81735d59f8 Move and update the menu item Transactions 2020-04-27 19:59:53 -03:00
Lucas Guima
1d8da7f9f0 Add menu header for Accounting 2020-04-27 18:35:52 -03:00
Lucas Guima
c5f0684030 Place the menu item Piggy banks after Bills 2020-04-26 18:11:20 -03:00
Lucas Guima
25867adcb9 Move the menu item Piggy banks 2020-04-26 18:10:22 -03:00
Lucas Guima
d55694cd68 Move the menu item Bills 2020-04-26 18:07:08 -03:00
Lucas Guima
05f069d61e Move the menu item Budgets 2020-04-26 18:00:28 -03:00
Lucas Guima
5f6e7ad138 Add menu header for Financial Control 2020-04-26 17:50:42 -03:00
Lucas Guima
61bc38921e Update Dashboard menu item 2020-04-26 17:48:13 -03:00
Lucas Guima
94c660545d Update indentation 2020-04-26 17:44:07 -03:00
James Cole
4d3907948d Merge tag '5.2.4' into develop
5.2.4
2020-04-26 10:02:43 +02:00
James Cole
e6442dd8af Merge branch 'release/5.2.4' 2020-04-26 10:02:42 +02:00
James Cole
7905e0bd70 Bump to 5.2.4 2020-04-26 10:02:25 +02:00
James Cole
f4b1da352d no message 2020-04-26 07:08:33 +02:00
James Cole
0d33348941 Fix #3251 2020-04-26 06:57:59 +02:00
James Cole
c7c875e95f Fix #3251 2020-04-26 06:54:12 +02:00
James Cole
19d24b3e2a Clean up templates 2020-04-26 06:45:42 +02:00
James Cole
8fed6b6657 Fix #3287 2020-04-22 09:28:20 +02:00
James Cole
b5eafa1910 Merge tag '5.2.3' into develop
5.2.3
2020-04-22 06:33:23 +02:00
James Cole
c15501937f Merge branch 'release/5.2.3' 2020-04-22 06:33:22 +02:00
James Cole
4c743bd5b0 Update meta files for new release. 2020-04-22 06:29:34 +02:00
James Cole
44289cbd95 Fix #3284 2020-04-22 06:09:29 +02:00
James Cole
b2f1642cfe Fix #3281 2020-04-21 08:17:31 +02:00
James Cole
341ef0220c New translations. 2020-04-19 11:07:14 +02:00
James Cole
9df88115bc Update packages. 2020-04-19 11:05:14 +02:00
James Cole
c7273edb5e Updated language strings and meta config. 2020-04-19 06:52:12 +02:00
James Cole
c398aa2b69 Add support for British English and allow the user to set a locale. 2020-04-19 06:51:40 +02:00
James Cole
aa786eaaf3 Clean up language setting. 2020-04-19 06:11:49 +02:00
James Cole
e58a5e12d6 Fix #3270 2020-04-19 06:10:49 +02:00
James Cole
12b3575c5c Fix method reference 2020-04-19 06:09:55 +02:00
James Cole
3ca186dc8f Remove unused method. 2020-04-19 06:09:43 +02:00
James Cole
1535f596f6 Add two new support functions. 2020-04-19 06:07:43 +02:00
James Cole
2cc326caa1 Fix #3272 2020-04-19 06:05:39 +02:00
James Cole
43436ae942 Fix issue with casting. 2020-04-19 06:00:11 +02:00
James Cole
fbfd8475de Fix #3264 2020-04-15 16:17:45 +02:00
James Cole
405752f353 Merge tag '5.2.2' into develop
5.2.2
2020-04-14 21:01:03 +02:00
James Cole
2af98b259a Merge branch 'release/5.2.2' 2020-04-14 21:01:02 +02:00
James Cole
015242a666 Update meta files for new release. 2020-04-14 20:56:30 +02:00
James Cole
54933fda2e Fix #3263 2020-04-14 17:23:58 +02:00
James Cole
852d057a47 Fix #3259 2020-04-13 07:57:46 +02:00
James Cole
1778f0b4f3 Fix storing of virtual balance. 2020-04-13 07:57:32 +02:00
James Cole
6daf083b3f Clean up some code. 2020-04-12 06:24:35 +02:00
James Cole
4a7d9b130a Fix issue with multi-currency in asset accounts. 2020-04-12 06:23:35 +02:00
James Cole
4163efba55 Clean up phpdoc 2020-04-11 06:42:47 +02:00
James Cole
db5847b49b Consistent in minimum password length 2020-04-11 06:42:40 +02:00
James Cole
6829003f5e Change to safer hash methods. 2020-04-11 06:42:21 +02:00
James Cole
047927718e Merge branch 'release/5.2.1' 2020-04-10 21:23:53 +02:00
James Cole
91deb22a3f Merge tag '5.2.1' into develop
5.2.1
2020-04-10 21:23:53 +02:00
James Cole
1629ca0739 Update for some bugs. 2020-04-10 21:20:04 +02:00
James Cole
8b87204f10 User unable to store budgets without auto budget info. 2020-04-10 21:16:46 +02:00
James Cole
f920d90e3d Fix chart problem 2020-04-10 21:16:29 +02:00
James Cole
1cb91282af Merge tag '5.2.0' into develop
5.2.0
2020-04-10 13:51:23 +02:00
James Cole
a6ce294131 Merge branch 'release/5.2.0' 2020-04-10 13:51:22 +02:00
James Cole
34ceb69776 Update last minute files. 2020-04-10 13:50:37 +02:00
James Cole
eed68b5d95 Fix some code quality issues. 2020-04-10 10:47:24 +02:00
James Cole
79374c11ee Fix for #3248 2020-04-10 10:12:12 +02:00
James Cole
404f9df6d3 Bad link to model. 2020-04-10 07:29:15 +02:00
James Cole
4b716e35b9 Prep changelog for new release. 2020-04-10 07:20:45 +02:00
James Cole
166fc7a3e2 Fix trait 2020-04-09 20:33:55 +02:00
James Cole
06afbc7a0a Fix chart 2020-04-09 06:27:43 +02:00
James Cole
49a98de63a Add YNAB 2020-04-09 06:27:29 +02:00
James Cole
5b572c0da2 Expand readme. 2020-04-09 06:27:20 +02:00
James Cole
59014b1a87 Meta files for the next release. 2020-04-08 06:54:16 +02:00
James Cole
4aec1f06e0 Fix issue updating categories. 2020-04-08 06:43:58 +02:00
James Cole
136af9625a Better link for tags. 2020-04-07 18:19:29 +02:00
James Cole
edac26f757 Merge pull request #3236 from SuperSandro2000/patch-1
Add missing date based on releases page
2020-04-05 07:54:01 +02:00
Sandro
ac54dd05bf Add missing date based on releases page 2020-04-05 07:31:30 +02:00
James Cole
7948058364 Fix #3234 2020-04-05 07:14:17 +02:00
James Cole
f13a6f7bf9 New php docs [skip ci] 2020-04-05 07:10:59 +02:00
James Cole
e1a5d143c5 Merge tag '5.2.0-beta.1' into develop
5.2.0-beta.1
2020-04-02 06:54:50 +02:00
James Cole
f98011cd0d Merge branch 'release/5.2.0-beta.1' 2020-04-02 06:54:49 +02:00
James Cole
e7c10dec5c Update meta files for new release. 2020-04-02 06:39:09 +02:00
James Cole
ae2b28fdee Use correct methods. 2020-03-31 07:41:48 +02:00
James Cole
8d3fc18ca6 Use correct methods. 2020-03-31 07:40:20 +02:00
James Cole
61521cf478 Use correct methods. 2020-03-31 07:39:57 +02:00
James Cole
06c5e4df2c Use correct methods. 2020-03-31 07:39:36 +02:00
James Cole
9e4b7f8bb4 Add IBAN to account validator. 2020-03-31 07:04:00 +02:00
James Cole
144bc29eb3 Fix issue with budgets. 2020-03-31 07:03:37 +02:00
James Cole
2c0d8b9cb3 Fix #3122 2020-03-28 16:06:37 +01:00
James Cole
511b1258ba Merge pull request #3212 from rubenverhoef/CSV-ING
ING CSV
2020-03-27 05:22:02 +00:00
Ruben Verhoef
8cfe0af502 New saving acount function, supports account numbers with chars and make it easier to link when account numbers are the same but name are different 2020-03-26 20:51:07 +01:00
James Cole
54e3c7d729 Fix #3211 2020-03-26 19:59:38 +01:00
James Cole
628b493128 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-03-26 19:58:40 +01:00
Ruben Verhoef
8c552b8fa8 Fix functions moveValutadatumDescription and removeNameIngDescription 2020-03-26 19:52:30 +01:00
James Cole
c864d904b0 Fix #3079 2020-03-26 18:00:18 +01:00
James Cole
ecb61676ab Fix #3210 2020-03-26 12:05:15 +01:00
James Cole
ee5a4caaab Some extra code for #1376 2020-03-26 07:10:39 +01:00
James Cole
84bdd47109 update issue templates. 2020-03-25 19:25:50 +01:00
James Cole
5445752588 Update some phpdocs, courtesy of Psalm. 2020-03-25 07:03:23 +01:00
James Cole
bcfbdcf3f0 Clean up models.
Clean up models.
2020-03-25 06:58:39 +01:00
James Cole
7e6cd77203 Clean up models. 2020-03-25 06:58:29 +01:00
James Cole
5e3d00ecde Merge tag '5.2.0-alpha.1' into develop
5.2.0-alpha.1
2020-03-24 07:22:27 +01:00
1173 changed files with 84761 additions and 41156 deletions

View File

@@ -10,7 +10,7 @@ APP_DEBUG=false
SITE_OWNER=mail@example.com
# The encryption key for your sessions. Keep this very secure.
# If you generate a new one existing data must be considered LOST.
# If you generate a new one all existing attachments must be considered LOST.
# Change it to a string of exactly 32 chars or use something like `php artisan key:generate` to generate it.
# If you use Docker or similar, you can set this variable from a file by using APP_KEY_FILE
APP_KEY=SomeRandomStringOf32CharsExactly
@@ -22,15 +22,15 @@ APP_KEY=SomeRandomStringOf32CharsExactly
# If text is still in English, remember that not everything may have been translated.
DEFAULT_LANGUAGE=en_US
# The locale defines how numbers are formatted.
# by default this value is the same as whatever the language is.
DEFAULT_LOCALE=equal
# Change this value to your preferred time zone.
# Example: Europe/Amsterdam
# For a list of supported time zones, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=Europe/Amsterdam
# This variable must match your installation's external address but keep in mind that
# it's only used on the command line as a fallback value.
APP_URL=http://localhost
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
# Set it to ** and reverse proxies work just fine.
TRUSTED_PROXIES=
@@ -57,14 +57,25 @@ APP_LOG_LEVEL=notice
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
# Use "mysql" for MySQL and MariaDB. Use "sqlite" for SQLite.
DB_CONNECTION=pgsql
DB_HOST=firefly_iii_db
DB_PORT=5432
# Use "pgsql" for PostgreSQL and MariaDB. Use "sqlite" for SQLite.
DB_CONNECTION=mysql
DB_HOST=fireflyiiidb
DB_PORT=3306
DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=secret_firefly_password
# MySQL supports SSL. You can configure it here.
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
MYSQL_USE_SSL=false
MYSQL_SSL_VERIFY_SERVER_CERT=true
# You need to set at least of these options
MYSQL_SSL_CAPATH=/etc/ssl/certs/
MYSQL_SSL_CA=
MYSQL_SSL_CERT=
MYSQL_SSL_KEY=
MYSQL_SSL_CIPHER=
# PostgreSQL supports SSL. You can configure it here.
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
PGSQL_SSL_MODE=prefer
@@ -97,8 +108,8 @@ COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_MAILER=log
MAIL_HOST=null
MAIL_PORT=2525
MAIL_FROM=changeme@example.com
MAIL_USERNAME=null
@@ -156,6 +167,23 @@ FIXER_API_KEY=
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
LOGIN_PROVIDER=eloquent
#
# It's also possible to change the way users are authenticated. You could use Authelia for example.
# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard".
#
# If you do this please read the documentation for instructions and warnings:
# https://docs.firefly-iii.org/advanced-installation/authentication
#
# This function is available in Firefly III v5.3.0 and higher.
AUTHENTICATION_GUARD=web
#
# Likewise, it's impossible to log out users who's authentication is handled by an external system.
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
# Setting this variable only works when AUTHENTICATION_GUARD != web
#
CUSTOM_LOGOUT_URI=
# LDAP connection configuration
# OpenLDAP, FreeIPA or ActiveDirectory
# # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
@@ -170,8 +198,16 @@ ADLDAP_PORT=389
ADLDAP_TIMEOUT=5
ADLDAP_BASEDN=""
ADLDAP_FOLLOW_REFFERALS=false
# SSL/TLS settings
ADLDAP_USE_SSL=false
ADLDAP_USE_TLS=false
ADLDAP_SSL_CACERTDIR=
ADLDAP_SSL_CACERTFILE=
ADLDAP_SSL_CERTFILE=
ADLDAP_SSL_KEYFILE=
ADLDAP_SSL_CIPHER_SUITE=
ADLDAP_SSL_REQUIRE_CERT=
# You can set the following variables from a file by appending them with _FILE:
ADLDAP_ADMIN_USERNAME=
@@ -191,6 +227,7 @@ ADLDAP_AUTH_FIELD=distinguishedname
# Will allow SSO if your server provides an AUTH_USER field.
# You can set the following variables from a file by appending them with _FILE:
WINDOWS_SSO_ENABLED=false
WINDOWS_SSO_DISCOVER=samaccountname
WINDOWS_SSO_KEY=AUTH_USER
@@ -218,8 +255,9 @@ TRACKER_SITE_ID=
TRACKER_URL=
#
# Firefly III could (in the future) collect telemetry on how you use Firefly III.
# In order to allow this, change the following variable to true:
# Firefly III can collect telemetry on how you use Firefly III. This is opt-in.
# In order to allow this, change the following variable to true.
# To read more about this feature, go to this page: https://docs.firefly-iii.org/support/telemetry
SEND_TELEMETRY=false
# You can fine tune the start-up of a Docker container by editing these environment variables.
@@ -266,7 +304,17 @@ PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
USE_ENCRYPTION=false
IS_SANDSTORM=false
IS_DOCKER=false
IS_HEROKU=false
BUNQ_USE_SANDBOX=false
FIREFLY_III_LAYOUT=v1
#
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
# This configuration value WILL NOT HELP.
#
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
# So when configuring anything WEB related this variable doesn't do anything. Nothing
#
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
#
APP_URL=http://localhost

View File

@@ -16,10 +16,10 @@ I am running Firefly III version x.x.x, and my problem is:
<!-- Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom). -->
**Bonus points**
<!-- Earn bonus points by checking the boxes -->
<!-- Before you submit, verify the following please: -->
- [ ] Nobody reported this bug before
- [ ] I have added a stack trace from my log files.
- [ ] I have added a screenshot.
- [ ] I was able to replicate it on the demo site https://demo.firefly-iii.org/
<!-- - [ ] I donated money (this is a joke :wink:)-->
- I searched and nobody reported this bug before
- I have added a stack trace from my log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
- I have added a screenshot.
- I was able to replicate it on the demo site https://demo.firefly-iii.org/
<!-- - I donated money (this is a joke ;)-->

View File

@@ -16,8 +16,8 @@ I am running Firefly III version x.x.x.
<!-- Complete the following checklist for bonus points -->
- [ ] I have read the FAQ at https://bit.ly/FF3-FAQ
- [ ] I added a screenshot
- [ ] I added log files (see https://bit.ly/FF3-get-logs)
- [ ] I was able to replicate the issue on the demo site.
<!-- - [ ] I donated money (this is a joke :wink:)-->
- I have read the FAQ at https://bit.ly/FF3-FAQ
- I added a screenshot
- I added log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
- I was able to replicate the issue on the demo site.
<!-- - I donated money (this is a joke :wink:)-->

2
.github/lock.yml vendored
View File

@@ -32,4 +32,4 @@ setLockReason: true
# daysUntilLock: 30
# Repository to extend settings from
# _extends: repo
# _extends: repo

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
/node_modules
/frontend/node_modules
/frontend/fonts
/public/hot
/public/storage
/storage/*.key

View File

@@ -50,8 +50,9 @@ use League\Fractal\Resource\Item;
class AccountController extends Controller
{
use AccountFilter, TransactionFilter;
/** @var AccountRepositoryInterface The account repository */
private $repository;
private AccountRepositoryInterface $repository;
public const RESOURCE_KEY = 'accounts';
/**
* AccountController constructor.
@@ -150,7 +151,7 @@ class AccountController extends Controller
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($accounts, $transformer, 'accounts');
$resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
@@ -208,7 +209,7 @@ class AccountController extends Controller
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($account, $transformer, 'accounts');
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
@@ -230,7 +231,7 @@ class AccountController extends Controller
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($account, $transformer, 'accounts');
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
@@ -304,7 +305,7 @@ class AccountController extends Controller
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($account, $transformer, 'accounts');
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}

View File

@@ -23,10 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Middleware\ApiDemoUser;
use FireflyIII\Api\V1\Requests\AttachmentStoreRequest;
use FireflyIII\Api\V1\Requests\AttachmentUpdateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\Transformers\AttachmentTransformer;
@@ -58,6 +60,7 @@ class AttachmentController extends Controller
public function __construct()
{
parent::__construct();
$this->middleware(ApiDemoUser::class)->except(['delete', 'download', 'show', 'index']);
$this->middleware(
function ($request, $next) {
/** @var User $user */
@@ -65,6 +68,7 @@ class AttachmentController extends Controller
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);

View File

@@ -141,49 +141,6 @@ class CategoryController extends Controller
}
}
// foreach ([] as $set) {
// foreach ($set as $currency) {
// $inKey = sprintf('%d-i', $currency['currency_id']);
// $outKey = sprintf('%d-e', $currency['currency_id']);
// $categories[] = (string)trans('firefly.no_category');
// // make data arrays if not yet present.
// $tempData[$inKey] = $tempData[$inKey] ?? [
// 'currency_id' => $currency['currency_id'],
// 'label' => (string)trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
// 'currency_code' => $currency['currency_code'],
// 'currency_symbol' => $currency['currency_symbol'],
// 'currency_decimal_places' => $currency['currency_decimal_places'],
// 'type' => 'bar', // line, area or bar
// 'yAxisID' => 0, // 0, 1, 2
// 'entries' => [
// // per category:
// // "category" => 5,
// ],
// ];
// $tempData[$outKey] = $tempData[$outKey] ?? [
// 'currency_id' => $currency['currency_id'],
// 'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
// 'currency_code' => $currency['currency_code'],
// 'currency_symbol' => $currency['currency_symbol'],
// 'currency_decimal_places' => $currency['currency_decimal_places'],
// 'type' => 'bar', // line, area or bar
// 'yAxisID' => 0, // 0, 1, 2
// 'entries' => [
// // per category:
// // "category" => 5,
// ],
// ];
// foreach ($currency['transaction_journals'] as $journal) {
// // is it expense or income?
// $letter = -1 === bccomp($journal['amount'], '0') ? 'e' : 'i';
// $currentKey = sprintf('%d-%s', $currency['currency_id'], $letter);
// $name = (string)trans('firefly.no_category');
// $tempData[$currentKey]['entries'][$name] = $tempData[$currentKey]['entries'][$name] ?? '0';
// $tempData[$currentKey]['entries'][$name] = bcadd($tempData[$currentKey]['entries'][$name], $journal['amount']);
// }
// }
// }
// re-sort every spent array and add 0 for missing entries.
foreach ($tempData as $index => $set) {
$oldSet = $set['entries'];

View File

@@ -577,7 +577,8 @@ class CurrencyController extends Controller
{
$manager = $this->getManager();
$currency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $currency);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);

View File

@@ -1,181 +0,0 @@
<?php
/**
* ImportController.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\ImportJobTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
/**
* Class ImportController
*
* @deprecated
* @codeCoverageIgnore
*/
class ImportController extends Controller
{
use TransactionFilter;
/** @var ImportJobRepositoryInterface Import job repository. */
private $repository;
/**
* ImportController constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ImportJobRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* @return JsonResponse
* @codeCoverageIgnore
*/
public function listAll(): JsonResponse
{
// create some objects:
$manager = $this->getManager();
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
$count = $collection->count();
$importJobs = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($importJobs, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.import.list') . $this->buildParams());
/** @var ImportJobTransformer $transformer */
$transformer = app(ImportJobTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($importJobs, $transformer, 'import_jobs');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param ImportJob $importJob
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function show(ImportJob $importJob): JsonResponse
{
$manager = $this->getManager();
/** @var ImportJobTransformer $transformer */
$transformer = app(ImportJobTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($importJob, $transformer, 'import_jobs');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show all transactions
*
* @param Request $request
* @param ImportJob $importJob
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function transactions(Request $request, ImportJob $importJob): JsonResponse
{
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
$types = $this->mapTransactionTypes($this->parameters->get('type'));
$manager = $this->getManager();
$tag = $importJob->tag;
$transactions = new Collection();
$paginator = new LengthAwarePaginator($transactions, 0, $pageSize);
$paginator->setPath(route('api.v1.import.transactions', [$importJob->key]) . $this->buildParams());
if (null !== $tag) {
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on tag.
->setTag($tag)
// all info needed for the API:
->withAPIInformation()
// set page size:
->setLimit($pageSize)
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
->setTypes($types);
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
}
$paginator = $collector->getPaginatedGroups();
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
$transactions = $paginator->getCollection();
}
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,196 @@
<?php
/**
* GroupController.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\ObjectGroupUpdateRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
use FireflyIII\Transformers\ObjectGroupTransformer;
use FireflyIII\Transformers\PiggyBankTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
/**
* Class GroupController.
*
*/
class ObjectGroupController extends Controller
{
private ObjectGroupRepositoryInterface $repository;
/**
* ObjectGroupController constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(ObjectGroupRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param ObjectGroup $objectGroup
*
* @codeCoverageIgnore
* @return JsonResponse
*/
public function delete(ObjectGroup $objectGroup): JsonResponse
{
$this->repository->destroy($objectGroup);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @codeCoverageIgnore
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
$count = $collection->count();
$objectGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.object-groups.index') . $this->buildParams());
/** @var ObjectGroupTransformer $transformer */
$transformer = app(ObjectGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($objectGroups, $transformer, 'object_groups');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List all piggies under the object group.
*
* @param ObjectGroup $objectGroup
*
* @return JsonResponse
* @codeCoverageIgnore
*
*/
public function piggyBanks(ObjectGroup $objectGroup): JsonResponse
{
// create some objects:
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of piggy banks. Count it and split it.
$collection = $this->repository->getPiggyBanks($objectGroup);
$count = $collection->count();
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.object-groups.piggy_banks', [$objectGroup->id]) . $this->buildParams());
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show single instance.
*
* @param ObjectGroup $objectGroup
*
* @return JsonResponse
*/
public function show(ObjectGroup $objectGroup): JsonResponse
{
$manager = $this->getManager();
/** @var ObjectGroupTransformer $transformer */
$transformer = app(ObjectGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($objectGroup, $transformer, 'object_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update object.
*
* @param ObjectGroupUpdateRequest $request
* @param Account $account
*
* @return JsonResponse
*/
public function update(ObjectGroupUpdateRequest $request, ObjectGroup $objectGroup): JsonResponse
{
$data = $request->getUpdateData();
$this->repository->update($objectGroup, $data);
$this->repository->sort();
$manager = $this->getManager();
/** @var ObjectGroupTransformer $transformer */
$transformer = app(ObjectGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($objectGroup, $transformer, 'object_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\PiggyBankRequest;
use FireflyIII\Api\V1\Requests\PiggyBankStoreRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
@@ -204,12 +205,12 @@ class PiggyBankController extends Controller
/**
* Store new object.
*
* @param PiggyBankRequest $request
* @param PiggyBankStoreRequest $request
*
* @throws FireflyException
* @return JsonResponse
*/
public function store(PiggyBankRequest $request): JsonResponse
public function store(PiggyBankStoreRequest $request): JsonResponse
{
$piggyBank = $this->repository->store($request->getAll());
$manager = $this->getManager();

View File

@@ -269,6 +269,7 @@ class TransactionController extends Controller
*
* @param TransactionStoreRequest $request
*
* @throws FireflyException
* @return JsonResponse
*/
public function store(TransactionStoreRequest $request): JsonResponse
@@ -283,7 +284,7 @@ class TransactionController extends Controller
try {
$transactionGroup = $this->groupRepository->store($data);
} catch (DuplicateTransactionException $e) {
Log::warning('Caught a duplicate. Return error message.');
Log::warning('Caught a duplicate transaction. Return error message.');
// return bad validation message.
// TODO use Laravel's internal validation thing to do this.
$response = [
@@ -326,7 +327,7 @@ class TransactionController extends Controller
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new NotFoundHttpException(); // @codeCoverageIgnore
throw new FireflyException('Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
}
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);

View File

@@ -1,6 +1,6 @@
<?php
/**
* IsSandStormUser.php
* ApiDemoUser.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@@ -20,38 +20,40 @@
*/
declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
namespace FireflyIII\Api\V1\Middleware;
use Closure;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Class IsSandStormUser.
* Class ApiDemoUser.
*/
class IsSandStormUser
class ApiDemoUser
{
/**
* Handle an incoming request. May not be a limited user (ie. Sandstorm env. or demo user).
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @param string|null $guard
* @param Request $request
* @param Closure $next
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $guard = null)
public function handle(Request $request, Closure $next)
{
if (Auth::guard($guard)->guest()) {
// don't care when not logged in, usual stuff applies:
/** @var User $user */
$user = $request->user();
if (null === $user) {
return $next($request);
}
if (1 === (int) getenv('SANDSTORM')) {
app('session')->flash('warning', (string) trans('firefly.sandstorm_not_available'));
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
return response()->redirectTo(route('index'));
if ($repository->hasRole($user, 'demo')) {
return response('', 403);
}
return $next($request);

View File

@@ -1,6 +1,7 @@
<?php
/**
* RabobankDescription.php
* ObjectGroupUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@@ -18,52 +19,53 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Import\Specifics;
namespace FireflyIII\Api\V1\Requests;
/**
* Class RabobankDescription.
* Class AccountObjectGroupUpdateRequestUpdateRequest
*
* @codeCoverageIgnore
* @deprecated
*/
class RabobankDescription implements SpecificInterface
class ObjectGroupUpdateRequest extends Request
{
/**
* Description of this specific.
* Authorize logged in users.
*
* @return string
* @codeCoverageIgnore
* @return bool
*/
public static function getDescription(): string
public function authorize(): bool
{
return 'import.specific_rabo_descr';
// Only allow authenticated users
return auth()->check();
}
/**
* Name of this specific.
*
* @return string
* @codeCoverageIgnore
* @return array
*/
public static function getName(): string
public function getUpdateData(): array
{
return 'import.specific_rabo_name';
return [
'title' => $this->string('title'),
'order' => $this->integer('order'),
];
}
/**
* Run the specific.
*
* @param array $row
* The rules that the incoming request must be matched against.
*
* @return array
*
*/
public function run(array $row): array
public function rules(): array
{
$row = array_values($row);
$objectGroup = $this->route()->parameter('objectGroup');
return $row;
return [
'title' => sprintf('min:1|uniqueObjectGroup:%d', $objectGroup->id),
'order' => 'numeric',
];
}
}

View File

@@ -0,0 +1,86 @@
<?php
/**
* PiggyBankStoreRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\ZeroOrMore;
/**
*
* Class PiggyBankStoreRequest
*
* @codeCoverageIgnore
*/
class PiggyBankStoreRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'name' => $this->string('name'),
'account_id' => $this->integer('account_id'),
'targetamount' => $this->string('target_amount'),
'current_amount' => $this->string('current_amount'),
'startdate' => $this->date('start_date'),
'targetdate' => $this->date('target_date'),
'notes' => $this->nlString('notes'),
'object_group_id' => $this->integer('object_group_id'),
'object_group' => $this->string('object_group_name'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'current_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount'],
'account_id' => 'required|numeric|belongsToUser:accounts,id',
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
'target_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount', 'required'],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
];
}
}

View File

@@ -263,17 +263,13 @@ class TransactionUpdateRequest extends Request
// TODO if the transaction_journal_id is empty, some fields are mandatory, like the amount!
// all journals must have a description
//$this->validateDescriptions($validator);
// // validate foreign currency info
// $this->validateForeignCurrencyInformation($validator);
//
//
// // make sure all splits have valid source + dest info
// $this->validateSplitAccounts($validator);
// the group must have a description if > 1 journal.
// $this->validateGroupDescription($validator);
}
);
}

View File

@@ -83,8 +83,6 @@ class CorrectDatabase extends Command
echo $result;
}
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* CorrectOpeningBalanceCurrencies.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -76,8 +77,6 @@ class CorrectOpeningBalanceCurrencies extends Command
$this->info('There was nothing to fix in the opening balance transactions.');
}
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -78,8 +78,6 @@ class CreateAccessTokens extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verify access tokens in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -47,7 +47,7 @@ class CreateLinkTypes extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle(): int
{
@@ -79,8 +79,6 @@ class CreateLinkTypes extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified link types in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -50,7 +50,8 @@ class DeleteEmptyGroups extends Command
* Execute the console command.
*
* @throws Exception;
* @return mixed
*
* @return int
*/
public function handle(): int
{
@@ -75,8 +76,6 @@ class DeleteEmptyGroups extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified empty groups in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -58,8 +58,6 @@ class DeleteEmptyJournals extends Command
$this->deleteUnevenJournals();
$this->deleteEmptyJournals();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -62,7 +62,6 @@ class DeleteOrphanedTransactions extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified orphans in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -78,8 +78,6 @@ class DeleteZeroAmount extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified zero-amount integrity in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -52,7 +52,7 @@ class EnableCurrencies extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle(): int
{
@@ -101,8 +101,6 @@ class EnableCurrencies extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified currencies in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -106,7 +106,6 @@ class FixAccountTypes extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verifying account types took %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* FixLongDescriptions.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -65,7 +66,7 @@ class FixLongDescriptions extends Command
$groups = TransactionGroup::get(['id', 'title']);
/** @var TransactionGroup $group */
foreach ($groups as $group) {
if (strlen($group->title) > self::MAX_LENGTH) {
if (strlen((string)$group->title) > self::MAX_LENGTH) {
$group->title = substr($group->title, 0, self::MAX_LENGTH);
$group->save();
$this->line(sprintf('Truncated description of transaction group #%d', $group->id));
@@ -74,7 +75,6 @@ class FixLongDescriptions extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified all transaction group and journal title lengths in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -54,7 +54,7 @@ class FixPiggies extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle(): int
{
@@ -98,7 +98,6 @@ class FixPiggies extends Command
$end = round(microtime(true) - $start, 2);
$this->line(sprintf('Verified the content of %d piggy bank events in %s seconds.', $set->count(), $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* FixRecurringTransactions.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -54,9 +55,9 @@ class FixRecurringTransactions extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle()
public function handle(): int
{
$start = microtime(true);
$this->stupidLaravel();
@@ -66,7 +67,6 @@ class FixRecurringTransactions extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Corrected recurring transactions %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -75,7 +75,6 @@ class FixUnevenAmount extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified amount integrity in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -48,7 +48,7 @@ class RemoveBills extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle(): int
{
@@ -71,7 +71,6 @@ class RemoveBills extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified bills / journals in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -83,7 +83,6 @@ class RenameMetaFields extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Renamed meta fields in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -74,7 +74,6 @@ class TransferBudgets extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified budget/journals in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
@@ -49,9 +50,9 @@ class CreateDatabase extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle()
public function handle(): int
{
if ('mysql' !== env('DB_CONNECTION')) {
$this->info(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION')));

View File

@@ -30,6 +30,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Preference;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
use JsonException;
use Log;
/**
@@ -92,7 +93,11 @@ class DecryptDatabase extends Command
// A separate routine for preferences:
if ('preferences' === $table) {
// try to json_decrypt the value.
$value = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value;
try {
$value = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value;
} catch(JsonException $e) {
Log::error($e->getMessage());
}
Log::debug(sprintf('Decrypted field "%s" "%s" to "%s" in table "%s" (row #%d)', $field, $original, print_r($value, true), $table, $id));
/** @var Preference $object */
@@ -118,7 +123,6 @@ class DecryptDatabase extends Command
}
$this->info('Done!');
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -155,7 +159,6 @@ class DecryptDatabase extends Command
if ('The MAC is invalid.' === $e->getMessage()) {
throw new FireflyException($e->getMessage()); // @codeCoverageIgnore
}
Log::debug(sprintf('Could not decrypt. %s', $e->getMessage()));
}
return $value;

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* ExportData.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -136,11 +137,11 @@ class ExportData extends Command
} catch (FireflyException $e) {
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
// app('telemetry')->feature('executed-command-with-error', $this->signature);
app('telemetry')->feature('system.command.errored', $this->signature);
return 1;
}
// app('telemetry')->feature('executed-command', $this->signature);
app('telemetry')->feature('system.command.executed', $this->signature);
return 0;
}
@@ -238,11 +239,12 @@ class ExportData extends Command
/**
* @throws FireflyException
*
* @return string
*/
private function getExportDirectory(): string
{
$directory = $this->option('export_directory');
$directory = (string) $this->option('export_directory');
if (null === $directory) {
$directory = './';
}

View File

@@ -1,341 +0,0 @@
<?php
/**
* CreateCSVImport.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands\Import;
use Exception;
use FireflyIII\Console\Commands\VerifiesAccessToken;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\Routine\RoutineInterface;
use FireflyIII\Import\Storage\ImportArrayStorage;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use Log;
/**
* Class CreateCSVImport.
*
* @deprecated
* @codeCoverageIgnore
*/
class CreateCSVImport extends Command
{
use VerifiesAccessToken;
/**
* The console command description.
*
* @var string
*/
protected $description = 'Use this command to create a new CSV file import.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature
= 'firefly-iii:csv-import
{file? : The CSV file to import.}
{configuration? : The configuration file to use for the import.}
{--user=1 : The user ID that the import should import for.}
{--token= : The user\'s access token.}';
/** @var ImportJob */
private $importJob;
/** @var ImportJobRepositoryInterface */
private $importRepository;
/** @var UserRepositoryInterface */
private $userRepository;
/**
* Run the command.
*/
public function handle(): int
{
$this->stupidLaravel();
// @codeCoverageIgnoreStart
if (!$this->verifyAccessToken()) {
$this->errorLine('Invalid access token.');
return 1;
}
if (!$this->validArguments()) {
$this->errorLine('Invalid arguments.');
return 1;
}
// @codeCoverageIgnoreEnd
/** @var User $user */
$user = $this->userRepository->findNull((int) $this->option('user'));
$file = (string) $this->argument('file');
$configuration = (string) $this->argument('configuration');
$this->importRepository->setUser($user);
$configurationData = json_decode(file_get_contents($configuration), true, 512, JSON_THROW_ON_ERROR);
$this->importJob = $this->importRepository->create('file');
// inform user (and log it)
$this->infoLine(sprintf('Import file : %s', $file));
$this->infoLine(sprintf('Configuration file : %s', $configuration));
$this->infoLine(sprintf('User : #%d (%s)', $user->id, $user->email));
$this->infoLine(sprintf('Job : %s', $this->importJob->key));
try {
$this->storeFile($file);
} catch (FireflyException $e) {
$this->errorLine($e->getMessage());
return 1;
}
// job is ready to go
$this->importRepository->setConfiguration($this->importJob, $configurationData);
$this->importRepository->setStatus($this->importJob, 'ready_to_run');
$this->infoLine('The import routine has started. The process is not visible. Please wait.');
Log::debug('Go for import!');
// keep repeating this call until job lands on "provider_finished"
try {
$this->processFile();
} catch (FireflyException $e) {
$this->errorLine($e->getMessage());
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
// then store data:
try {
$this->storeData();
} catch (FireflyException $e) {
$this->errorLine($e->getMessage());
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
// give feedback:
$this->giveFeedback();
// clear cache for user:
app('preferences')->setForUser($user, 'lastActivity', microtime());
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
/**
* @param string $message
* @param array|null $data
*
* @codeCoverageIgnore
*/
private function errorLine(string $message, array $data = null): void
{
Log::error($message, $data ?? []);
$this->error($message);
}
/**
*
*/
private function giveFeedback(): void
{
$this->infoLine('Job has finished.');
if (null !== $this->importJob->tag) {
$this->infoLine(sprintf('%d transaction(s) have been imported.', $this->importJob->tag->transactionJournals->count()));
$this->infoLine(sprintf('You can find your transactions under tag "%s"', $this->importJob->tag->tag));
}
if (null === $this->importJob->tag) {
$this->errorLine('No transactions have been imported :(.');
}
if (count($this->importJob->errors) > 0) {
$this->infoLine(sprintf('%d error(s) occurred:', count($this->importJob->errors)));
foreach ($this->importJob->errors as $err) {
$this->errorLine('- ' . $err);
}
}
}
/**
* @param string $message
* @param array $data
*
* @codeCoverageIgnore
*/
private function infoLine(string $message, array $data = null): void
{
Log::info($message, $data ?? []);
$this->line($message);
}
/**
* Keep repeating import call until job lands on "provider_finished".
*
* @throws FireflyException
*/
private function processFile(): void
{
$className = config('import.routine.file');
$valid = ['provider_finished'];
$count = 0;
while (!in_array($this->importJob->status, $valid, true) && $count < 6) {
Log::debug(sprintf('Now in loop #%d.', $count + 1));
/** @var RoutineInterface $routine */
$routine = app($className);
$routine->setImportJob($this->importJob);
try {
$routine->run();
} catch (FireflyException|Exception $e) {
$message = 'The import routine crashed: ' . $e->getMessage();
Log::error($message);
Log::error($e->getTraceAsString());
// set job errored out:
$this->importRepository->setStatus($this->importJob, 'error');
throw new FireflyException($message);
}
$count++;
}
$this->importRepository->setStatus($this->importJob, 'provider_finished');
$this->importJob->status = 'provider_finished';
}
/**
*
* @throws FireflyException
*/
private function storeData(): void
{
if ('provider_finished' === $this->importJob->status) {
$this->infoLine('Import has finished. Please wait for storage of data.');
// set job to be storing data:
$this->importRepository->setStatus($this->importJob, 'storing_data');
/** @var ImportArrayStorage $storage */
$storage = app(ImportArrayStorage::class);
$storage->setImportJob($this->importJob);
try {
$storage->store();
} catch (FireflyException|Exception $e) {
$message = 'The import routine crashed: ' . $e->getMessage();
Log::error($message);
Log::error($e->getTraceAsString());
// set job errored out:
$this->importRepository->setStatus($this->importJob, 'error');
throw new FireflyException($message);
}
// set storage to be finished:
$this->importRepository->setStatus($this->importJob, 'storage_finished');
}
}
/**
* Store the supplied file as an attachment to this job.
*
* @param string $file
*
* @throws FireflyException
*/
private function storeFile(string $file): void
{
// store file as attachment.
if ('' !== $file) {
$messages = $this->importRepository->storeCLIUpload($this->importJob, 'import_file', $file);
if ($messages->count() > 0) {
throw new FireflyException($messages->first());
}
}
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
* @codeCoverageIgnore
*/
private function stupidLaravel(): void
{
$this->userRepository = app(UserRepositoryInterface::class);
$this->importRepository = app(ImportJobRepositoryInterface::class);
}
/**
* Verify user inserts correct arguments.
*
* @noinspection MultipleReturnStatementsInspection
* @return bool
* @codeCoverageIgnore
*/
private function validArguments(): bool
{
$file = (string) $this->argument('file');
$configuration = (string) $this->argument('configuration');
$cwd = getcwd();
$enabled = (bool) config('import.enabled.file');
if (false === $enabled) {
$this->errorLine('CSV Provider is not enabled.');
return false;
}
if (!file_exists($file)) {
$this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
return false;
}
if (!file_exists($configuration)) {
$this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return false;
}
$configurationData = json_decode(file_get_contents($configuration), true, 512, JSON_THROW_ON_ERROR);
if (null === $configurationData) {
$this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return false;
}
return true;
}
}

View File

@@ -64,7 +64,6 @@ class ReportEmptyObjects extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Report on empty objects finished in %s seconds', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -69,7 +69,6 @@ class ReportIntegrity extends Command
echo $result;
}
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -54,7 +54,6 @@ class ReportSum extends Command
{
$this->reportSum();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* RestoreOAuthKeys.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -23,6 +24,7 @@ namespace FireflyIII\Console\Commands\Integrity;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Console\Command;
use Log;
/**
* Class RestoreOAuthKeys
@@ -51,7 +53,6 @@ class RestoreOAuthKeys extends Command
{
$this->restoreOAuthKeys();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -92,7 +93,9 @@ class RestoreOAuthKeys extends Command
*/
private function restoreOAuthKeys(): void
{
Log::debug('Going to restoreOAuthKeys()');
if (!$this->keysInDatabase() && !$this->keysOnDrive()) {
Log::debug('Keys are not in DB and keys are not on the drive.');
$this->generateKeys();
$this->storeKeysInDB();
$this->line('Generated and stored new keys.');
@@ -100,12 +103,14 @@ class RestoreOAuthKeys extends Command
return;
}
if ($this->keysInDatabase() && !$this->keysOnDrive()) {
Log::debug('Keys are in DB and keys are not on the drive. Restore.');
$this->restoreKeysFromDB();
$this->line('Restored OAuth keys from database.');
return;
}
if (!$this->keysInDatabase() && $this->keysOnDrive()) {
Log::debug('Keys are not in DB and keys are on the drive. Save in DB.');
$this->storeKeysInDB();
$this->line('Stored OAuth keys in database.');

View File

@@ -86,7 +86,7 @@ class ScanAttachments extends Command
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
}
// app('telemetry')->feature('executed-command', $this->signature);
app('telemetry')->feature('system.command.executed', $this->signature);
return 0;
}
}

View File

@@ -59,7 +59,7 @@ class SetLatestVersion extends Command
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
$this->line('Updated version.');
// app('telemetry')->feature('executed-command', $this->signature);
app('telemetry')->feature('system.command.executed', $this->signature);
return 0;
}

View File

@@ -60,7 +60,7 @@ class ApplyRules extends Command
*/
protected $signature
= 'firefly-iii:apply-rules
{--user=1 : The user ID that the import should import for.}
{--user=1 : The user ID.}
{--token= : The user\'s access token.}
{--accounts= : A comma-separated list of asset accounts or liabilities to apply your rules to.}
{--rule_groups= : A comma-separated list of rule groups to apply. Take the ID\'s of these rule groups from the Firefly III interface.}
@@ -112,7 +112,7 @@ class ApplyRules extends Command
$result = $this->verifyInput();
if (false === $result) {
// app('telemetry')->feature('executed-command-with-error', $this->signature);
app('telemetry')->feature('system.command.errored', $this->signature);
return 1;
}
@@ -131,7 +131,7 @@ class ApplyRules extends Command
$this->warn(' --rule_groups=1,2,...');
$this->warn(' --all_rules');
// app('telemetry')->feature('executed-command-with-error', $this->signature);
app('telemetry')->feature('system.command.errored', $this->signature);
return 1;
}
@@ -167,7 +167,7 @@ class ApplyRules extends Command
$this->line('');
$this->line('Done!');
// app('telemetry')->feature('executed-command', $this->signature);
app('telemetry')->feature('system.command.executed', $this->signature);
return 0;
}

View File

@@ -94,10 +94,10 @@ class Cron extends Command
}
/*
* Fire telemetry cron job (disabled):
* Fire telemetry cron job
*/
try {
//$this->telemetryCronJob($force, $date);
$this->telemetryCronJob($force, $date);
} catch (FireflyException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
@@ -106,7 +106,7 @@ class Cron extends Command
$this->info('More feedback on the cron jobs can be found in the log files.');
// app('telemetry')->feature('executed-command', $this->signature);
app('telemetry')->feature('system.command.executed', $this->signature);
return 0;
}

View File

@@ -87,7 +87,6 @@ class AccountCurrencies extends Command
$this->info(sprintf('Verified and fixed account currencies in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -78,8 +78,6 @@ class BackToJournals extends Command
$this->info(sprintf('Updated category and budget info for all transaction journals in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -92,8 +92,6 @@ class BudgetLimitCurrency extends Command
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -91,8 +91,6 @@ class CCLiabilities extends Command
$this->info(sprintf('Verified credit card liabilities in %s seconds', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -101,8 +101,6 @@ class MigrateAttachments extends Command
$this->info(sprintf('Migrated attachment notes in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -100,8 +100,6 @@ class MigrateJournalNotes extends Command
$this->info(sprintf('Migrated notes in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* MigrateRecurrenceMeta.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -71,8 +72,6 @@ class MigrateRecurrenceMeta extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Migrated recurrence meta data in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* MigrateTagLocations.php
* Copyright (c) 2020 james@firefly-iii.org
@@ -64,7 +65,6 @@ class MigrateTagLocations extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Migrated tag locations in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -112,8 +112,6 @@ class MigrateToGroups extends Command
$this->markAsMigrated();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -99,7 +99,6 @@ class MigrateToRules extends Command
$this->info(sprintf('Verified and fixed bills in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -212,7 +211,6 @@ class MigrateToRules extends Command
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
$groupTitle = (string) trans('firefly.rulegroup_for_bills_title', [], $lang->data);
$ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle);
//$currency = $this->getCurrency($user);
if (null === $ruleGroup) {
$ruleGroup = $this->ruleGroupRepository->store(

View File

@@ -90,7 +90,6 @@ class OtherCurrenciesCorrections extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified and fixed transaction currencies in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -91,7 +91,6 @@ class RenameAccountMeta extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Fixed account meta data in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -101,7 +101,6 @@ class TransactionIdentifier extends Command
$this->info(sprintf('Verified and fixed transaction identifiers in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -111,7 +111,6 @@ class TransferCurrenciesCorrections extends Command
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified and fixed currency information for transfers in %s seconds.', $end));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -342,19 +341,17 @@ class TransferCurrenciesCorrections extends Command
if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) {
return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore
}
// TODO we can use getAccountCurrency() instead
$currencyId = (int) $this->accountRepos->getMetaValue($account, 'currency_id');
$result = $this->currencyRepos->findNull($currencyId);
if (null === $result) {
$currency = $this->accountRepos->getAccountCurrency($account);
if (null === $currency) {
// @codeCoverageIgnoreStart
$this->accountCurrencies[$accountId] = 0;
return null;
// @codeCoverageIgnoreEnd
}
$this->accountCurrencies[$accountId] = $result;
$this->accountCurrencies[$accountId] = $currency;
return $result;
return $currency;
}
/**

View File

@@ -117,7 +117,6 @@ class UpgradeDatabase extends Command
// index will set FF3 version.
app('fireflyconfig')->set('ff3_version', (string) config('firefly.version'));
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use FireflyIII\Support\System\GeneratesInstallationId;
use Illuminate\Console\Command;
/**
@@ -32,6 +33,8 @@ use Illuminate\Console\Command;
*/
class UpgradeFireflyInstructions extends Command
{
use GeneratesInstallationId;
/**
* The console command description.
*
@@ -50,6 +53,7 @@ class UpgradeFireflyInstructions extends Command
*/
public function handle(): int
{
$this->generateInstallationId();
if ('update' === (string) $this->argument('task')) {
$this->updateInstructions();
}
@@ -57,7 +61,14 @@ class UpgradeFireflyInstructions extends Command
$this->installInstructions();
}
// app('telemetry')->feature('executed-command', $this->signature);
// collect system telemetry
$isDocker = true === env('IS_DOCKER', false) ? 'true' : 'false';
app('telemetry')->feature('system.php.version', PHP_VERSION);
app('telemetry')->feature('system.os.version', PHP_OS);
app('telemetry')->feature('system.database.driver', env('DB_CONNECTION', '(unknown)'));
app('telemetry')->feature('system.os.is_docker', $isDocker);
app('telemetry')->feature('system.command.executed', $this->signature);
return 0;
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* DuplicateTransactionException.php
* Copyright (c) 2019 james@firefly-iii.org

View File

@@ -38,6 +38,7 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Log;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
/**
* Class GracefulNotFoundHandler
@@ -50,9 +51,10 @@ class GracefulNotFoundHandler extends ExceptionHandler
* @param Request $request
* @param Exception $exception
*
* @throws Exception
* @return mixed
*/
public function render($request, Exception $exception)
public function render($request, Throwable $exception)
{
$route = $request->route();
if (null === $route) {
@@ -135,11 +137,12 @@ class GracefulNotFoundHandler extends ExceptionHandler
/**
* @param Request $request
* @param Exception $exception
* @param Throwable $exception
*
* @return \Illuminate\Http\Response|Response
* @throws Exception
* @return Redirector|Response
*/
private function handleAccount($request, Exception $exception)
private function handleAccount(Request $request, Throwable $exception)
{
Log::debug('404 page is probably a deleted account. Redirect to overview of account types.');
/** @var User $user */
@@ -160,7 +163,14 @@ class GracefulNotFoundHandler extends ExceptionHandler
return redirect(route('accounts.index', [$shortType]));
}
private function handleAttachment(Request $request, Exception $exception)
/**
* @param Request $request
* @param Throwable $exception
*
* @throws Exception
* @return RedirectResponse|Redirector|Response
*/
private function handleAttachment(Request $request, Throwable $exception)
{
Log::debug('404 page is probably a deleted attachment. Redirect to parent object.');
/** @var User $user */
@@ -199,12 +209,13 @@ class GracefulNotFoundHandler extends ExceptionHandler
}
/**
* @param $request
* @param Throwable $request
* @param Exception $exception
*
* @throws Exception
* @return RedirectResponse|\Illuminate\Http\Response|Redirector|Response
*/
private function handleGroup($request, Exception $exception)
private function handleGroup(Request $request, Throwable $exception)
{
Log::debug('404 page is probably a deleted group. Redirect to overview of group types.');
/** @var User $user */

View File

@@ -33,9 +33,9 @@ use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException as LaravelValidationException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Http\Request;
use Throwable;
/**
* Class Handler
*
@@ -51,7 +51,7 @@ class Handler extends ExceptionHandler
*
* @return mixed
*/
public function render($request, Exception $exception)
public function render($request, Throwable $exception)
{
if ($exception instanceof LaravelValidationException && $request->expectsJson()) {
// ignore it: controller will handle it.
@@ -87,7 +87,7 @@ class Handler extends ExceptionHandler
);
}
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => get_class($exception)], 500);
return response()->json(['message' => sprintf('Internal Firefly III Exception: %s', $exception->getMessage()), 'exception' => get_class($exception)], 500);
}
if ($exception instanceof NotFoundHttpException) {
@@ -116,10 +116,10 @@ class Handler extends ExceptionHandler
* @param Exception $exception
*
* @throws Exception
* @return mixed|void
*
* @return void
*/
public function report(Exception $exception)
public function report(Throwable $exception)
{
$doMailError = config('firefly.send_error_message');
// if the user wants us to mail:
@@ -143,13 +143,13 @@ class Handler extends ExceptionHandler
'line' => $exception->getLine(),
'code' => $exception->getCode(),
'version' => config('firefly.version'),
'url' => Request::fullUrl(),
'userAgent' => Request::userAgent(),
'json' => Request::acceptsJson(),
'url' => request()->fullUrl(),
'userAgent' => request()->userAgent(),
'json' => request()->acceptsJson(),
];
// create job that will mail.
$ipAddress = Request::ip() ?? '0.0.0.0';
$ipAddress = request()->ip() ?? '0.0.0.0';
$job = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data);
dispatch($job);
}

View File

@@ -98,7 +98,7 @@ class AccountFactory
'user_id' => $this->user->id,
'account_type_id' => $type->id,
'name' => $data['name'],
'virtual_balance' => $data['virtual_balance'] ?? '0',
'virtual_balance' => $data['virtual_balance'] ?? null,
'active' => true === $data['active'],
'iban' => $data['iban'],
];
@@ -109,12 +109,12 @@ class AccountFactory
// remove virtual balance when not an asset account or a liability
if (!in_array($type->type, $this->canHaveVirtual, true)) {
$databaseData['virtual_balance'] = '0';
$databaseData['virtual_balance'] = null;
}
// fix virtual balance when it's empty
if ('' === $databaseData['virtual_balance']) {
$databaseData['virtual_balance'] = '0';
if ('' === (string)$databaseData['virtual_balance']) {
$databaseData['virtual_balance'] = null;
}
$return = Account::create($databaseData);

View File

@@ -275,27 +275,34 @@ class TransactionJournalFactory
return null;
}
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
/** create or get source and destination accounts */
$sourceInfo = [
'id' => (int) $row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
'number' => $row['source_number'],
'bic' => $row['source_bic'],
'id' => (int) $row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
'number' => $row['source_number'],
'bic' => $row['source_bic'],
'currency_id' => $currency->id,
];
$destInfo = [
'id' => (int) $row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
'number' => $row['destination_number'],
'bic' => $row['destination_bic'],
'id' => (int) $row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
'number' => $row['destination_number'],
'bic' => $row['destination_bic'],
'currency_id' => $currency->id,
];
Log::debug('Source info:', $sourceInfo);
Log::debug('Destination info:', $destInfo);
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
Log::debug('Now calling getAccount for the source.');
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
Log::debug('Now calling getAccount for the destination.');
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
Log::debug('Done with getAccount(2x)');
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
@@ -360,19 +367,6 @@ class TransactionJournalFactory
// verify that journal has two transactions. Otherwise, delete and cancel.
// TODO this can't be faked so it can't be tested.
// $count = $journal->transactions()->count();
// if (2 !== $count) {
// // @codeCoverageIgnoreStart
// Log::error(sprintf('The journal unexpectedly has %d transaction(s). This is not OK. Cancel operation.', $count));
// try {
// $journal->delete();
// } catch (Exception $e) {
// Log::debug(sprintf('Dont care: %s.', $e->getMessage()));
// }
//
// return null;
// // @codeCoverageIgnoreEnd
// }
$journal->completed = true;
$journal->save();
@@ -421,7 +415,7 @@ class TransactionJournalFactory
->first();
}
if (null !== $result) {
Log::warning('Found a duplicate!');
Log::warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $result->transactionJournal->transaction_group_id));
}
}
@@ -465,12 +459,13 @@ class TransactionJournalFactory
*/
private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency
{
Log::debug('Now in getCurrency()');
$preference = $this->accountRepository->getAccountCurrency($account);
if (null === $preference && null === $currency) {
// return user's default:
return app('amount')->getDefaultCurrencyByUser($this->user);
}
$result = $preference ?? $currency;
$result = ($preference ?? $currency) ?? app('amount')->getSystemCurrency();
Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
return $result;
@@ -486,6 +481,7 @@ class TransactionJournalFactory
*/
private function getCurrencyByAccount(string $type, ?TransactionCurrency $currency, Account $source, Account $destination): TransactionCurrency
{
Log::debug('Now ingetCurrencyByAccount()');
switch ($type) {
default:
case TransactionType::WITHDRAWAL:
@@ -535,15 +531,15 @@ class TransactionJournalFactory
$dataRow = $row->getArrayCopy();
unset($dataRow['import_hash_v2'], $dataRow['original_source']);
$json = json_encode($dataRow);
$json = json_encode($dataRow, JSON_THROW_ON_ERROR, 512);
if (false === $json) {
// @codeCoverageIgnoreStart
$json = json_encode((string) microtime());
$json = json_encode((string) microtime(), JSON_THROW_ON_ERROR, 512);
Log::error(sprintf('Could not hash the original row! %s', json_last_error_msg()), $dataRow);
// @codeCoverageIgnoreEnd
}
$hash = hash('sha256', $json);
Log::debug(sprintf('The hash is: %s', $hash));
Log::debug(sprintf('The hash is: %s', $hash), $dataRow);
return $hash;
}
@@ -598,8 +594,8 @@ class TransactionJournalFactory
// validate source account.
$sourceId = isset($data['source_id']) ? (int) $data['source_id'] : null;
$sourceName = $data['source_name'] ?? null;
$validSource = $this->accountValidator->validateSource($sourceId, $sourceName);
$sourceName = isset($data['source_name']) ? (string) $data['source_name'] : null;
$validSource = $this->accountValidator->validateSource($sourceId, $sourceName, null);
// do something with result:
if (false === $validSource) {
@@ -608,8 +604,8 @@ class TransactionJournalFactory
Log::debug('Source seems valid.');
// validate destination account
$destinationId = isset($data['destination_id']) ? (int) $data['destination_id'] : null;
$destinationName = $data['destination_name'] ?? null;
$validDestination = $this->accountValidator->validateDestination($destinationId, $destinationName);
$destinationName = isset($data['destination_name']) ? (string) $data['destination_name'] : null;
$validDestination = $this->accountValidator->validateDestination($destinationId, $destinationName, null);
// do something with result:
if (false === $validDestination) {
throw new FireflyException(sprintf('Destination: %s', $this->accountValidator->destError)); // @codeCoverageIgnore

View File

@@ -154,14 +154,14 @@ class MonthReportGenerator implements ReportGeneratorInterface
$journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
}
$locale = app('steam')->getLocale();
$return = [
'journals' => $journals,
'currency' => $currency,
'exists' => count($journals) > 0,
'end' => $this->end->formatLocalized((string) trans('config.month_and_day')),
'end' => $this->end->formatLocalized((string) trans('config.month_and_day', [], $locale)),
'endBalance' => app('steam')->balance($account, $this->end),
'dayBefore' => $date->formatLocalized((string) trans('config.month_and_day')),
'dayBefore' => $date->formatLocalized((string) trans('config.month_and_day', [], $locale)),
'dayBeforeBalance' => $dayBeforeBalance,
];

View File

@@ -118,6 +118,7 @@ class UserEventHandler
if ($repository->hasRole($user, 'demo')) {
// set user back to English.
app('preferences')->setForUser($user, 'language', 'en_US');
app('preferences')->setForUser($user, 'locale', 'equal');
app('preferences')->mark();
}
@@ -165,7 +166,8 @@ class UserEventHandler
$user = $event->user;
$ipAddress = $event->ipAddress;
$token = app('preferences')->getForUser($user, 'email_change_undo_token', 'invalid');
$uri = route('profile.undo-email-change', [$token->data, hash('sha256', $oldEmail)]);
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $oldEmail));
$uri = route('profile.undo-email-change', [$token->data,$hashed]);
try {
Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $uri, $ipAddress));
// @codeCoverageIgnoreStart

View File

@@ -54,6 +54,7 @@ class VersionCheckEventHandler
$value = (int) $permission->data;
if (1 !== $value) {
Log::info('Update check is not enabled.');
$this->warnToCheckForUpdates($event);
return;
}
@@ -85,4 +86,36 @@ class VersionCheckEventHandler
session()->flash($release['level'], $release['message']);
app('fireflyconfig')->set('last_update_check', time());
}
/**
* @param RequestedVersionCheckStatus $event
*/
protected function warnToCheckForUpdates(RequestedVersionCheckStatus $event): void
{
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
/** @var User $user */
$user = $event->user;
if (!$repository->hasRole($user, 'owner')) {
Log::debug('User is not admin, done.');
return;
}
/** @var Configuration $lastCheckTime */
$lastCheckTime = app('fireflyconfig')->get('last_update_warning', time());
$now = time();
$diff = $now - $lastCheckTime->data;
Log::debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
if ($diff < 604800 * 4) {
Log::debug(sprintf('Warned about updates less than four weeks ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data)));
return;
}
// last check time was more than a week ago.
Log::debug('Have warned about a new version in four weeks!');
session()->flash('info', (string) trans('firefly.disabled_but_check'));
app('fireflyconfig')->set('last_update_warning', time());
}
}

View File

@@ -230,4 +230,4 @@ trait AccountCollection
return $this;
}
}
}

View File

@@ -84,4 +84,4 @@ trait AmountCollection
return $this;
}
}
}

View File

@@ -36,6 +36,8 @@ trait CollectorProperties
private $hasAccountInfo;
/** @var bool Will be true if query result includes bill information. */
private $hasBillInformation;
/** @var bool */
private $hasNotesInformation;
/** @var bool Will be true if query result contains budget info. */
private $hasBudgetInformation;
/** @var bool Will be true if query result contains category info. */
@@ -56,4 +58,6 @@ trait CollectorProperties
private $total;
/** @var User The user object. */
private $user;
}
private bool $hasJoinedMetaTables;
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
/**
@@ -36,6 +37,27 @@ use Illuminate\Support\Collection;
trait MetaCollection
{
/**
* @inheritDoc
*/
public function withNotes(): GroupCollectorInterface
{
if (false === $this->hasNotesInformation) {
// join bill table
$this->query->leftJoin(
'notes',
static function (JoinClause $join) {
$join->on('notes.noteable_id', '=', 'transaction_journals.id');
$join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal');
}
);
// add fields
$this->fields[] = 'notes.text as notes';
$this->hasNotesInformation = true;
}
return $this;
}
/**
* Limit the search to a specific bill.
@@ -288,4 +310,36 @@ trait MetaCollection
}
}
/**
* @inheritDoc
*/
public function setExternalId(string $externalId): GroupCollectorInterface
{
if (false === $this->hasJoinedMetaTables) {
$this->hasJoinedMetaTables = true;
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
}
$this->query->where('journal_meta.name', '=', 'external_id');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $externalId));
return $this;
}
/**
* @inheritDoc
*/
public function setInternalReference(string $internalReference): GroupCollectorInterface
{
if (false === $this->hasJoinedMetaTables) {
$this->hasJoinedMetaTables = true;
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
}
$this->query->where('journal_meta.name', '=', 'internal_reference');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $internalReference));
return $this;
}
}

View File

@@ -91,8 +91,9 @@ trait TimeCollection
if ($end < $start) {
[$start, $end] = [$end, $start];
}
$startStr = $start->format('Y-m-d H:i:s');
$endStr = $end->format('Y-m-d H:i:s');
// always got to end of day / start of day for ranges.
$startStr = $start->format('Y-m-d 00:00:00');
$endStr = $end->format('Y-m-d 23:59:59');
$this->query->where('transaction_journals.date', '>=', $startStr);
$this->query->where('transaction_journals.date', '<=', $endStr);
@@ -117,4 +118,4 @@ trait TimeCollection
return $this;
}
}
}

View File

@@ -31,16 +31,11 @@ use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
use FireflyIII\Helpers\Collector\Extensions\CollectorProperties;
use FireflyIII\Helpers\Collector\Extensions\MetaCollection;
use FireflyIII\Helpers\Collector\Extensions\TimeCollection;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
@@ -67,8 +62,10 @@ class GroupCollector implements GroupCollectorInterface
$this->hasCatInformation = false;
$this->hasBudgetInformation = false;
$this->hasBillInformation = false;
$this->hasNotesInformation = false;
$this->hasJoinedTagTables = false;
$this->hasJoinedAttTables = false;
$this->hasJoinedMetaTables = false;
$this->integerFields = [
'transaction_group_id',
'user_id',
@@ -171,13 +168,8 @@ class GroupCollector implements GroupCollectorInterface
*/
public function getGroups(): Collection
{
//$start = microtime(true);
/** @var Collection $result */
$result = $this->query->get($this->fields);
//$end = round(microtime(true) - $start, 5);
// log info about query time.
//Log::info(sprintf('Query took Firefly III %s seconds', $end));
//Log::info($this->query->toSql(), $this->query->getBindings());
// now to parse this into an array.
$collection = $this->parseArray($result);
@@ -316,7 +308,7 @@ class GroupCollector implements GroupCollectorInterface
$this->query->where(
static function (EloquentBuilder $q) use ($array) {
$q->where(
function (EloquentBuilder $q1) use ($array) {
static function (EloquentBuilder $q1) use ($array) {
foreach ($array as $word) {
$keyword = sprintf('%%%s%%', $word);
$q1->where('transaction_journals.description', 'LIKE', $keyword);
@@ -526,7 +518,7 @@ class GroupCollector implements GroupCollectorInterface
}
// or parse the rest.
$journalId = (int) $augumentedJournal->transaction_journal_id;
$groups[$groupId]['count']++;
if (isset($groups[$groupId]['transactions'][$journalId])) {
// append data to existing group + journal (for multiple tags or multiple attachments)
@@ -536,6 +528,7 @@ class GroupCollector implements GroupCollectorInterface
if (!isset($groups[$groupId]['transactions'][$journalId])) {
// create second, third, fourth split:
$groups[$groupId]['count']++;
$groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedJournal($augumentedJournal);
}
}
@@ -556,9 +549,14 @@ class GroupCollector implements GroupCollectorInterface
$result['tags'] = [];
$result['attachments'] = [];
try {
$result['date'] = new Carbon($result['date']);
$result['created_at'] = new Carbon($result['created_at']);
$result['updated_at'] = new Carbon($result['updated_at']);
$result['date'] = new Carbon($result['date'], 'UTC');
$result['created_at'] = new Carbon($result['created_at'], 'UTC');
$result['updated_at'] = new Carbon($result['updated_at'], 'UTC');
// this is going to happen a lot:
$result['date']->setTimezone(env('TZ'));
$result['created_at']->setTimezone(env('TZ'));
$result['updated_at']->setTimezone(env('TZ'));
} catch (Exception $e) {
Log::error($e->getMessage());
}

View File

@@ -398,6 +398,13 @@ interface GroupCollectorInterface
*/
public function withCategoryInformation(): GroupCollectorInterface;
/**
* Will include notes.
*
* @return GroupCollectorInterface
*/
public function withNotes(): GroupCollectorInterface;
/**
* Add tag info.
*
@@ -419,4 +426,22 @@ interface GroupCollectorInterface
*/
public function withoutCategory(): GroupCollectorInterface;
/**
* Look for specific external ID's.
*
* @param string $externalId
*
* @return GroupCollectorInterface
*/
public function setExternalId(string $externalId): GroupCollectorInterface;
/**
* Look for specific external ID's.
*
* @param string $externalId
*
* @return GroupCollectorInterface
*/
public function setInternalReference(string $externalId): GroupCollectorInterface;
}

View File

@@ -109,15 +109,13 @@ class NetWorth implements NetWorthInterface
Log::debug(sprintf('Balance is %s', $balance));
// if the account is a credit card, subtract the virtual balance from the balance,
// to better reflect that this is not money that is actually "yours".
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
// always subtract virtual balance.
$virtualBalance = (string) $account->virtual_balance;
if ('ccAsset' === $role && '' !== $virtualBalance && (float) $virtualBalance > 0) {
if ('' !== $virtualBalance) {
$balance = bcsub($balance, $virtualBalance);
}
Log::debug(sprintf('Balance corrected to %s', $balance));
Log::debug(sprintf('Balance corrected to %s because of virtual balance (%s)', $balance, $virtualBalance));
if (!isset($netWorth[$currencyId])) {
$netWorth[$currencyId] = '0';

View File

@@ -151,7 +151,12 @@ class CreateController extends Controller
// store attachment(s):
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($account, $files);
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore

View File

@@ -71,7 +71,7 @@ class DeleteController extends Controller
*
* @param Account $account
*
* @return Factory|View
* @return Factory|RedirectResponse|Redirector|View
*/
public function delete(Account $account)
{

View File

@@ -49,8 +49,7 @@ class EditController extends Controller
/** @var AccountRepositoryInterface The account repository */
private $repository;
/** @var AttachmentHelperInterface Helper for attachments. */
private $attachments;
private AttachmentHelperInterface $attachments;
/**
* EditController constructor.
@@ -67,7 +66,7 @@ class EditController extends Controller
$this->repository = app(AccountRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class);
$this->attachments = app(AttachmentHelperInterface::class);
return $next($request);
}
@@ -81,8 +80,7 @@ class EditController extends Controller
* @param Account $account
* @param AccountRepositoryInterface $repository
*
* @return Factory|View
*
* @return Factory|RedirectResponse|Redirector|View
*/
public function edit(Request $request, Account $account, AccountRepositoryInterface $repository)
{
@@ -191,9 +189,13 @@ class EditController extends Controller
app('preferences')->mark();
// store new attachment(s):
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($account, $files);
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore

View File

@@ -130,7 +130,6 @@ class ReconcileController extends Controller
$startDate = clone $start;
$startDate->subDay();
$startBalance = round(app('steam')->balance($account, $startDate), $currency->decimal_places);
$endBalance = round(app('steam')->balance($account, $end), $currency->decimal_places);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
@@ -216,7 +215,8 @@ class ReconcileController extends Controller
* @param string $difference
*
* @throws DuplicateTransactionException
* @return string
*
* @return RedirectResponse|Redirector|string
*/
private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference)
{

View File

@@ -46,10 +46,8 @@ class ShowController extends Controller
{
use UserNavigation, PeriodOverview;
/** @var CurrencyRepositoryInterface The currency repository */
private $currencyRepos;
/** @var AccountRepositoryInterface The account repository */
private $repository;
private CurrencyRepositoryInterface $currencyRepos;
private AccountRepositoryInterface $repository;
/**
* ShowController constructor.
@@ -86,7 +84,8 @@ class ShowController extends Controller
* @param Carbon|null $end
*
* @throws Exception
* @return RedirectResponse|Redirector|View
*
* @return RedirectResponse|Redirector|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
{
@@ -158,7 +157,8 @@ class ShowController extends Controller
* @param Account $account
*
* @throws Exception
* @return RedirectResponse|Redirector|View
*
* @return RedirectResponse|Redirector|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function showAll(Request $request, Account $account)
{

View File

@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use FireflyIII\Http\Requests\ConfigurationRequest;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
@@ -55,7 +54,6 @@ class ConfigurationController extends Controller
}
);
$this->middleware(IsDemoUser::class)->except(['index']);
$this->middleware(IsSandStormUser::class);
}
/**

View File

@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Events\AdminRequestedTestMessage;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
@@ -48,7 +47,6 @@ class HomeController extends Controller
{
parent::__construct();
$this->middleware(IsDemoUser::class)->except(['index']);
$this->middleware(IsSandStormUser::class)->except(['index']);
}
/**
@@ -61,9 +59,8 @@ class HomeController extends Controller
Log::channel('audit')->info('User visits admin index.');
$title = (string) trans('firefly.administration');
$mainTitleIcon = 'fa-hand-spock-o';
$sandstorm = 1 === (int) getenv('SANDSTORM');
return view('admin.index', compact('title', 'mainTitleIcon', 'sandstorm'));
return view('admin.index', compact('title', 'mainTitleIcon'));
}
/**

View File

@@ -90,7 +90,7 @@ class LinkController extends Controller
* @param Request $request
* @param LinkType $linkType
*
* @return RedirectResponse|Redirector|View
* @return Factory|RedirectResponse|Redirector|\Illuminate\View\View
*/
public function delete(Request $request, LinkType $linkType)
{

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TelemetryController.php
* Copyright (c) 2020 thegrumpydictator@gmail.com
@@ -55,7 +56,7 @@ class TelemetryController extends Controller
}
/**
* @return string
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function deleteSubmitted()
{
@@ -67,7 +68,7 @@ class TelemetryController extends Controller
}
/**
* @return string
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function deleteAll()
{
@@ -100,7 +101,8 @@ class TelemetryController extends Controller
app('view')->share('subTitleIcon', 'fa-eye');
app('view')->share('subTitle', (string) trans('firefly.telemetry_admin_index'));
$version = config('firefly.version');
$enabled = config('firefly.telemetry', false);
$enabled = config('firefly.send_telemetry', false) && config('firefly.feature_flags.telemetry');
$count = $this->repository->count();
return view('admin.telemetry.index', compact('version', 'enabled', 'count'));

View File

@@ -26,7 +26,6 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Helpers\Update\UpdateTrait;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
@@ -57,7 +56,6 @@ class UpdateController extends Controller
}
);
$this->middleware(IsDemoUser::class)->except(['index']);
$this->middleware(IsSandStormUser::class)->except(['index']);
}
/**

View File

@@ -24,7 +24,6 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use FireflyIII\Http\Requests\UserFormRequest;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
@@ -57,7 +56,6 @@ class UserController extends Controller
}
);
$this->middleware(IsDemoUser::class)->except(['index', 'show']);
$this->middleware(IsSandStormUser::class);
}
/**

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**

View File

@@ -57,10 +57,9 @@ class ForgotPasswordController extends Controller
* Send a reset link to the given user.
*
* @param Request $request
*
* @param UserRepositoryInterface $repository
*
* @return RedirectResponse|JsonResponse
* @return Factory|RedirectResponse|View
*/
public function sendResetLinkEmail(Request $request, UserRepositoryInterface $repository)
{

View File

@@ -82,14 +82,8 @@ class LoginController extends Controller
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get('email')));
Log::info(sprintf('User is trying to login.'));
if ('ldap' === config('auth.providers.users.driver')) {
/**
* Temporary bug fix for something that doesn't seem to work in
* AdLdap.
*/
$schema = config('ldap.connections.default.schema');
/** @var Adldap\Connections\Provider $provider */
Adldap::getProvider('default')->setSchema(new $schema);
Adldap::getProvider('default');
}
$this->validateLogin($request);
@@ -137,6 +131,7 @@ class LoginController extends Controller
return redirect(route('register')); // @codeCoverageIgnore
}
// is allowed to?
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$allowRegistration = true;
@@ -154,6 +149,9 @@ class LoginController extends Controller
$email = $request->old('email');
$remember = $request->old('remember');
// todo must forget 2FA if user ends up here.
return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title'));
}
@@ -178,4 +176,35 @@ class LoginController extends Controller
throw $exception;
}
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
$authGuard = config('firefly.authentication_guard');
$logoutUri = config('firefly.custom_logout_uri');
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
return redirect($logoutUri);
}
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($response = $this->loggedOut($request)) {
return $response;
}
return $request->wantsJson()
? new \Illuminate\Http\Response('', 204)
: redirect('/');
}
}

View File

@@ -104,6 +104,9 @@ class RegisterController extends Controller
$this->registered($request, $user);
// telemetry
\Telemetry::feature('system.users.count', User::count());
return redirect($this->redirectPath());
}

View File

@@ -68,7 +68,8 @@ class ResetPasswordController extends Controller
* @param Request $request
*
* @throws \Illuminate\Validation\ValidationException
* @return RedirectResponse|JsonResponse
*
* @return Factory|JsonResponse|RedirectResponse|View
*/
public function reset(Request $request)
{

View File

@@ -211,14 +211,20 @@ class BillController extends Controller
/** @var Collection $bills */
$bills = $unfiltered->map(
function (Bill $bill) use ($transformer, $defaultCurrency) {
$return = $transformer->transform($bill);
$currency = $bill->transactionCurrency ?? $defaultCurrency;
$return['currency_id'] = $currency->id;
$return['currency_name'] = $currency->name;
$return['currency_symbol'] = $currency->symbol;
$return['currency_code'] = $currency->code;
$return['currency_decimal_places'] = $currency->decimal_places;
$return['attachments'] = $this->billRepository->getAttachments($bill);
$return = $transformer->transform($bill);
$nextExpectedMatch = new Carbon($return['next_expected_match']);
$return['next_expected_match_diff'] = $nextExpectedMatch->isToday()
? trans('firefly.today')
: $nextExpectedMatch->diffForHumans(
today(), Carbon::DIFF_RELATIVE_TO_NOW
);
$currency = $bill->transactionCurrency ?? $defaultCurrency;
$return['currency_id'] = $currency->id;
$return['currency_name'] = $currency->name;
$return['currency_symbol'] = $currency->symbol;
$return['currency_code'] = $currency->code;
$return['currency_decimal_places'] = $currency->decimal_places;
$return['attachments'] = $this->billRepository->getAttachments($bill);
return $return;
}
@@ -284,7 +290,7 @@ class BillController extends Controller
}
$request->session()->flash('success', (string) trans('firefly.rescanned_bill', ['total' => $total]));
$request->session()->flash('success', (string) trans_choice('firefly.rescanned_bill', $total));
app('preferences')->mark();
return redirect(route('bills.show', [$bill->id]));
@@ -383,7 +389,12 @@ class BillController extends Controller
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($bill, $files);
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
@@ -410,7 +421,12 @@ class BillController extends Controller
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($bill, $files);
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
}
// flash messages
if (count($this->attachments->getMessages()->get('attachments')) > 0) {

View File

@@ -59,7 +59,7 @@ class AvailableBudgetController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.budgets'));
app('view')->share('mainTitleIcon', 'fa-tasks');
app('view')->share('mainTitleIcon', 'fa-pie-chart');
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
@@ -157,6 +157,7 @@ class AvailableBudgetController extends Controller
*/
public function edit(AvailableBudget $availableBudget, Carbon $start, Carbon $end)
{
$availableBudget->amount = round($availableBudget->amount, $availableBudget->transactionCurrency->decimal_places);
return view('budgets.available-budgets.edit', compact('availableBudget', 'start', 'end'));
}
@@ -176,12 +177,26 @@ class AvailableBudgetController extends Controller
$end = session()->get('end');
Log::info($e->getMessage());
}
// validate amount
$amount = (string) $request->get('amount');
if ('' === $amount) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
if (0 === bccomp('0', $amount)) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
// find currency
$currency = $this->currencyRepos->find((int) $request->get('currency_id'));
if (null === $currency) {
session()->flash('error', trans('firefly.invalid_currency'));
return redirect(route('budgets.index'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
// find existing AB
@@ -189,7 +204,7 @@ class AvailableBudgetController extends Controller
if (null === $existing) {
$this->abRepository->store(
[
'amount' => $request->get('amount'),
'amount' => $amount,
'currency' => $currency,
'start' => $start,
'end' => $end,
@@ -198,7 +213,7 @@ class AvailableBudgetController extends Controller
}
if (null !== $existing) {
// update amount:
$this->abRepository->update($existing, ['amount' => $request->get('amount')]);
$this->abRepository->update($existing, ['amount' => $amount]);
}
session()->flash('success', trans('firefly.set_ab'));
@@ -216,7 +231,21 @@ class AvailableBudgetController extends Controller
*/
public function update(Request $request, AvailableBudget $availableBudget, Carbon $start, Carbon $end)
{
$this->abRepository->update($availableBudget, ['amount' => $request->get('amount')]);
// validate amount
$amount = (string) $request->get('amount');
if ('' === $amount) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
if (0 === bccomp('0', $amount)) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
$this->abRepository->update($availableBudget, ['amount' => $amount]);
session()->flash('success', trans('firefly.updated_ab'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));

View File

@@ -70,7 +70,7 @@ class BudgetLimitController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.budgets'));
app('view')->share('mainTitleIcon', 'fa-tasks');
app('view')->share('mainTitleIcon', 'fa-pie-chart');
$this->repository = app(BudgetRepositoryInterface::class);
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
@@ -132,6 +132,7 @@ class BudgetLimitController extends Controller
*/
public function store(Request $request)
{
Log::debug('Going to store new budget-limit.', $request->all());
// first search for existing one and update it if necessary.
$currency = $this->currencyRepos->find((int) $request->get('transaction_currency_id'));
$budget = $this->repository->findNull((int) $request->get('budget_id'));
@@ -143,7 +144,6 @@ class BudgetLimitController extends Controller
$start->startOfDay();
$end->endOfDay();
Log::debug(sprintf('Start: %s, end: %s', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
$limit = $this->blRepository->find($budget, $currency, $start, $end);

View File

@@ -58,7 +58,7 @@ class CreateController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.budgets'));
app('view')->share('mainTitleIcon', 'fa-tasks');
app('view')->share('mainTitleIcon', 'fa-pie-chart');
$this->repository = app(BudgetRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class);
@@ -130,9 +130,13 @@ class CreateController extends Controller
app('preferences')->mark();
// store attachment(s):
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($budget, $files);
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($budget, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore

View File

@@ -54,7 +54,7 @@ class DeleteController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.budgets'));
app('view')->share('mainTitleIcon', 'fa-tasks');
app('view')->share('mainTitleIcon', 'fa-pie-chart');
$this->repository = app(BudgetRepositoryInterface::class);
return $next($request);

View File

@@ -59,7 +59,7 @@ class EditController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.budgets'));
app('view')->share('mainTitleIcon', 'fa-tasks');
app('view')->share('mainTitleIcon', 'fa-pie-chart');
$this->repository = app(BudgetRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class);
@@ -137,9 +137,13 @@ class EditController extends Controller
$redirect = redirect($this->getPreviousUri('budgets.edit.uri'));
// store new attachment(s):
/** @var array $files */
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
$this->attachments->saveAttachmentsForModel($budget, $files);
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($budget, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore

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